160 lines
4.8 KiB
Diff
160 lines
4.8 KiB
Diff
|
From 548a415cff7d590d86033902fb29d5e15f57d17f Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Huth <thuth@redhat.com>
|
||
|
Date: Thu, 16 Jan 2025 12:58:25 +0100
|
||
|
Subject: [PATCH 4/6] pc-bios/s390-ccw: Fix boot problem with virtio-net
|
||
|
devices
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
RH-Author: Thomas Huth <thuth@redhat.com>
|
||
|
RH-MergeRequest: 331: Fix boot problems when falling back from network to another boot device on s390x [RHEL10]
|
||
|
RH-Jira: RHEL-72717
|
||
|
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||
|
RH-Commit: [3/4] f7ef8c63507c7f1ee8d05083f9540bee1697071c (thuth/qemu-kvm-cs)
|
||
|
|
||
|
When we are trying to boot from virtio-net devices, the
|
||
|
s390-ccw bios currently leaves the virtio-net device enabled
|
||
|
after using it. That means that the receiving virt queues will
|
||
|
continue to happily write incoming network packets into memory.
|
||
|
This can corrupt data of the following boot process. For example,
|
||
|
if you set up a second guest on a virtual network and create a
|
||
|
lot of broadcast traffic there, e.g. with:
|
||
|
|
||
|
ping -i 0.02 -s 1400 -b 192.168.1.255
|
||
|
|
||
|
and then you try to boot a guest with two boot devices, a network
|
||
|
device first (which should not be bootable) and e.g. a bootable SCSI
|
||
|
CD second, then this guest will fail to load the kernel from the CD
|
||
|
image:
|
||
|
|
||
|
$ qemu-system-s390x -m 2G -nographic -device virtio-scsi-ccw \
|
||
|
-netdev tap,id=net0 -device virtio-net-ccw,netdev=net0,bootindex=1 \
|
||
|
-drive if=none,file=test.iso,format=raw,id=cd1 \
|
||
|
-device scsi-cd,drive=cd1,bootindex=2
|
||
|
LOADPARM=[ ]
|
||
|
|
||
|
Network boot device detected
|
||
|
Network boot starting...
|
||
|
Using MAC address: 52:54:00:12:34:56
|
||
|
Requesting information via DHCP: done
|
||
|
Using IPv4 address: 192.168.1.76
|
||
|
Using TFTP server: 192.168.1.1
|
||
|
Trying pxelinux.cfg files...
|
||
|
TFTP error: ICMP ERROR "port unreachable"
|
||
|
Receiving data: 0 KBytes
|
||
|
Repeating TFTP read request...
|
||
|
TFTP error: ICMP ERROR "port unreachable"
|
||
|
Failed to load OS from network.
|
||
|
Failed to IPL from this network!
|
||
|
LOADPARM=[ ]
|
||
|
|
||
|
Using virtio-scsi.
|
||
|
|
||
|
! virtio-scsi:setup:inquiry: response VS RESP=ff !
|
||
|
ERROR: No suitable device for IPL. Halting...
|
||
|
|
||
|
We really have to shut up the virtio-net devices after we're not
|
||
|
using it anymore. The easiest way to do this is to simply reset
|
||
|
the device, so let's do that now.
|
||
|
|
||
|
Reviewed-by: Jared Rossi <jrossi@linux.ibm.com>
|
||
|
Reviewed-by: Eric Farman <farman@linux.ibm.com>
|
||
|
Tested-by: Jared Rossi <jrossi@linux.ibm.com>
|
||
|
Message-ID: <20250116115826.192047-3-thuth@redhat.com>
|
||
|
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||
|
(cherry picked from commit 68c95ed1db070f7545e487e742715f01a545aab0)
|
||
|
---
|
||
|
pc-bios/s390-ccw/netmain.c | 33 +++++++++++++++++++++++----------
|
||
|
pc-bios/s390-ccw/virtio-net.c | 5 +++++
|
||
|
pc-bios/s390-ccw/virtio.h | 1 +
|
||
|
3 files changed, 29 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
|
||
|
index e46e470db4..335ea9b63e 100644
|
||
|
--- a/pc-bios/s390-ccw/netmain.c
|
||
|
+++ b/pc-bios/s390-ccw/netmain.c
|
||
|
@@ -153,19 +153,10 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len)
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
-static int net_init(filename_ip_t *fn_ip)
|
||
|
+static int net_init_ip(filename_ip_t *fn_ip)
|
||
|
{
|
||
|
int rc;
|
||
|
|
||
|
- memset(fn_ip, 0, sizeof(filename_ip_t));
|
||
|
-
|
||
|
- rc = virtio_net_init(mac);
|
||
|
- if (rc < 0) {
|
||
|
- puts("Could not initialize network device");
|
||
|
- return -101;
|
||
|
- }
|
||
|
- fn_ip->fd = rc;
|
||
|
-
|
||
|
printf(" Using MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||
|
|
||
|
@@ -221,11 +212,33 @@ static int net_init(filename_ip_t *fn_ip)
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
+static int net_init(filename_ip_t *fn_ip)
|
||
|
+{
|
||
|
+ int rc;
|
||
|
+
|
||
|
+ memset(fn_ip, 0, sizeof(filename_ip_t));
|
||
|
+
|
||
|
+ rc = virtio_net_init(mac);
|
||
|
+ if (rc < 0) {
|
||
|
+ puts("Could not initialize network device");
|
||
|
+ return -101;
|
||
|
+ }
|
||
|
+ fn_ip->fd = rc;
|
||
|
+
|
||
|
+ rc = net_init_ip(fn_ip);
|
||
|
+ if (rc < 0) {
|
||
|
+ virtio_net_deinit();
|
||
|
+ }
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
static void net_release(filename_ip_t *fn_ip)
|
||
|
{
|
||
|
if (fn_ip->ip_version == 4) {
|
||
|
dhcp_send_release(fn_ip->fd);
|
||
|
}
|
||
|
+ virtio_net_deinit();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c
|
||
|
index 578c89d0c5..301445bf97 100644
|
||
|
--- a/pc-bios/s390-ccw/virtio-net.c
|
||
|
+++ b/pc-bios/s390-ccw/virtio-net.c
|
||
|
@@ -140,3 +140,8 @@ int recv(int fd, void *buf, int maxlen, int flags)
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
+
|
||
|
+void virtio_net_deinit(void)
|
||
|
+{
|
||
|
+ virtio_reset(virtio_get_device());
|
||
|
+}
|
||
|
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
|
||
|
index f13fa6f5fe..5c5e808a50 100644
|
||
|
--- a/pc-bios/s390-ccw/virtio.h
|
||
|
+++ b/pc-bios/s390-ccw/virtio.h
|
||
|
@@ -278,5 +278,6 @@ int virtio_reset(VDev *vdev);
|
||
|
int virtio_setup_ccw(VDev *vdev);
|
||
|
|
||
|
int virtio_net_init(void *mac_addr);
|
||
|
+void virtio_net_deinit(void);
|
||
|
|
||
|
#endif /* VIRTIO_H */
|
||
|
--
|
||
|
2.39.3
|
||
|
|