From nobody Wed Oct 29 06:36:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1524735114142643.8150223876055; Thu, 26 Apr 2018 02:31:54 -0700 (PDT) Received: from localhost ([::1]:41175 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBdFp-0005ny-BY for importer@patchew.org; Thu, 26 Apr 2018 05:31:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51556) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBdCm-0003jY-G5 for qemu-devel@nongnu.org; Thu, 26 Apr 2018 05:28:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fBdCj-0002pn-SO for qemu-devel@nongnu.org; Thu, 26 Apr 2018 05:28:44 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:52098 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fBdCj-0002pb-Mg; Thu, 26 Apr 2018 05:28:41 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0BD1A10D43F; Thu, 26 Apr 2018 09:28:38 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-75.ams2.redhat.com [10.36.116.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id 537EE2166BAD; Thu, 26 Apr 2018 09:28:36 +0000 (UTC) From: Thomas Huth To: Christian Borntraeger , qemu-s390x@nongnu.org, Viktor Mihajlovski Date: Thu, 26 Apr 2018 11:28:28 +0200 Message-Id: <1524734910-17970-2-git-send-email-thuth@redhat.com> In-Reply-To: <1524734910-17970-1-git-send-email-thuth@redhat.com> References: <1524734910-17970-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Thu, 26 Apr 2018 09:28:38 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Thu, 26 Apr 2018 09:28:38 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v4 1/3] pc-bios/s390-ccw/net: Split up net_load() into init, load and release parts X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Farhan Ali , Collin Walling , Cornelia Huck , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When we want to support pxelinux-style network booting later, we've got to do several TFTP transfers - and we do not want to apply for a new IP address via DHCP each time. So split up net_load into three parts: 1. net_init(), which initializes virtio-net, gets an IP address via DHCP and prints out the related information. 2. The tftp_load call is now moved directly into the main() function 3. A new net_release() function which should tear down the network stack before we are done in the firmware. This will make it easier to extend the code in the next patches. Signed-off-by: Thomas Huth Acked-by: Christian Borntraeger --- pc-bios/s390-ccw/netmain.c | 63 +++++++++++++++++++++++++++---------------= ---- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c index d86d46b..8fa9e6c 100644 --- a/pc-bios/s390-ccw/netmain.c +++ b/pc-bios/s390-ccw/netmain.c @@ -128,13 +128,13 @@ static void seed_rng(uint8_t mac[]) srand(seed); } =20 -static int tftp_load(filename_ip_t *fnip, void *buffer, int len, - unsigned int retries, int ip_vers) +static int tftp_load(filename_ip_t *fnip, void *buffer, int len) { tftp_err_t tftp_err; int rc; =20 - rc =3D tftp(fnip, buffer, len, retries, &tftp_err, 1, 1428, ip_vers); + rc =3D tftp(fnip, buffer, len, DEFAULT_TFTP_RETRIES, &tftp_err, 1, 142= 8, + ip_version); =20 if (rc > 0) { printf(" TFTP: Received %s (%d KBytes)\n", fnip->filename, @@ -199,20 +199,19 @@ static int tftp_load(filename_ip_t *fnip, void *buffe= r, int len, return rc; } =20 -static int net_load(char *buffer, int len) +static int net_init(filename_ip_t *fn_ip) { - filename_ip_t fn_ip; uint8_t mac[6]; int rc; =20 - memset(&fn_ip, 0, sizeof(filename_ip_t)); + memset(fn_ip, 0, sizeof(filename_ip_t)); =20 rc =3D virtio_net_init(mac); if (rc < 0) { puts("Could not initialize network device"); return -101; } - fn_ip.fd =3D rc; + fn_ip->fd =3D rc; =20 printf(" Using MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); @@ -220,10 +219,10 @@ static int net_load(char *buffer, int len) set_mac_address(mac); /* init ethernet layer */ seed_rng(mac); =20 - rc =3D dhcp(&fn_ip, DEFAULT_BOOT_RETRIES); + rc =3D dhcp(fn_ip, DEFAULT_BOOT_RETRIES); if (rc >=3D 0) { if (ip_version =3D=3D 4) { - set_ipv4_address(fn_ip.own_ip); + set_ipv4_address(fn_ip->own_ip); } } else { puts("Could not get IP address"); @@ -232,18 +231,18 @@ static int net_load(char *buffer, int len) =20 if (ip_version =3D=3D 4) { printf(" Using IPv4 address: %d.%d.%d.%d\n", - (fn_ip.own_ip >> 24) & 0xFF, (fn_ip.own_ip >> 16) & 0xFF, - (fn_ip.own_ip >> 8) & 0xFF, fn_ip.own_ip & 0xFF); + (fn_ip->own_ip >> 24) & 0xFF, (fn_ip->own_ip >> 16) & 0xFF, + (fn_ip->own_ip >> 8) & 0xFF, fn_ip->own_ip & 0xFF); } else if (ip_version =3D=3D 6) { char ip6_str[40]; - ipv6_to_str(fn_ip.own_ip6.addr, ip6_str); + ipv6_to_str(fn_ip->own_ip6.addr, ip6_str); printf(" Using IPv6 address: %s\n", ip6_str); } =20 if (rc =3D=3D -2) { printf("ARP request to TFTP server (%d.%d.%d.%d) failed\n", - (fn_ip.server_ip >> 24) & 0xFF, (fn_ip.server_ip >> 16) & 0= xFF, - (fn_ip.server_ip >> 8) & 0xFF, fn_ip.server_ip & 0xFF); + (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) &= 0xFF, + (fn_ip->server_ip >> 8) & 0xFF, fn_ip->server_ip & 0xFF); return -102; } if (rc =3D=3D -4 || rc =3D=3D -3) { @@ -251,28 +250,31 @@ static int net_load(char *buffer, int len) return -107; } =20 + printf(" Using TFTP server: "); if (ip_version =3D=3D 4) { - printf(" Requesting file \"%s\" via TFTP from %d.%d.%d.%d\n", - fn_ip.filename, - (fn_ip.server_ip >> 24) & 0xFF, (fn_ip.server_ip >> 16) & 0= xFF, - (fn_ip.server_ip >> 8) & 0xFF, fn_ip.server_ip & 0xFF); + printf("%d.%d.%d.%d\n", + (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) &= 0xFF, + (fn_ip->server_ip >> 8) & 0xFF, fn_ip->server_ip & 0xFF); } else if (ip_version =3D=3D 6) { char ip6_str[40]; - printf(" Requesting file \"%s\" via TFTP from ", fn_ip.filename); - ipv6_to_str(fn_ip.server_ip6.addr, ip6_str); + ipv6_to_str(fn_ip->server_ip6.addr, ip6_str); printf("%s\n", ip6_str); } =20 - /* Do the TFTP load and print error message if necessary */ - rc =3D tftp_load(&fn_ip, buffer, len, DEFAULT_TFTP_RETRIES, ip_version= ); - - if (ip_version =3D=3D 4) { - dhcp_send_release(fn_ip.fd); + if (strlen((char *)fn_ip->filename) > 0) { + printf(" Bootfile name: '%s'\n", fn_ip->filename); } =20 return rc; } =20 +static void net_release(filename_ip_t *fn_ip) +{ + if (ip_version =3D=3D 4) { + dhcp_send_release(fn_ip->fd); + } +} + void panic(const char *string) { sclp_print(string); @@ -344,6 +346,7 @@ static void virtio_setup(void) =20 void main(void) { + filename_ip_t fn_ip; int rc; =20 sclp_setup(); @@ -351,7 +354,15 @@ void main(void) =20 virtio_setup(); =20 - rc =3D net_load(NULL, (long)_start); + rc =3D net_init(&fn_ip); + if (rc) { + panic("Network initialization failed. Halting.\n"); + } + + rc =3D tftp_load(&fn_ip, NULL, (long)_start); + + net_release(&fn_ip); + if (rc > 0) { sclp_print("Network loading done, starting kernel...\n"); asm volatile (" lpsw 0(%0) " : : "r"(0) : "memory"); --=20 1.8.3.1 From nobody Wed Oct 29 06:36:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1524735237080603.2962985594361; Thu, 26 Apr 2018 02:33:57 -0700 (PDT) Received: from localhost ([::1]:41181 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBdHk-00071V-7A for importer@patchew.org; Thu, 26 Apr 2018 05:33:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51555) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBdCm-0003jX-Fr for qemu-devel@nongnu.org; Thu, 26 Apr 2018 05:28:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fBdCj-0002pu-Sd for qemu-devel@nongnu.org; Thu, 26 Apr 2018 05:28:44 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:52988 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fBdCj-0002pa-NI; Thu, 26 Apr 2018 05:28:41 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C660C406C752; Thu, 26 Apr 2018 09:28:39 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-75.ams2.redhat.com [10.36.116.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id 69BDC2166BAD; Thu, 26 Apr 2018 09:28:38 +0000 (UTC) From: Thomas Huth To: Christian Borntraeger , qemu-s390x@nongnu.org, Viktor Mihajlovski Date: Thu, 26 Apr 2018 11:28:29 +0200 Message-Id: <1524734910-17970-3-git-send-email-thuth@redhat.com> In-Reply-To: <1524734910-17970-1-git-send-email-thuth@redhat.com> References: <1524734910-17970-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Thu, 26 Apr 2018 09:28:39 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Thu, 26 Apr 2018 09:28:39 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v4 2/3] pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to the OS X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Farhan Ali , Collin Walling , Cornelia Huck , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The netboot firmware so far simply jumped directly into the OS kernel after the download has been completed. This, however, bears the risk that the virtio-net device still might be active in the background and incoming packets are still placed into the buffers - which could destroy memory of the now-running Linux kernel in case it did not take over the device fast enough. Also the SCLP console is not put into a well-defined state here. We should hand over the system in a clean state when jumping into the kernel, so let's use the same mechanism as it's done in the main s390-ccw firmware and reset the machine with diag308 into a clean state before jumping into the OS kernel code. To be able to share the code with the main s390-ccw firmware, the related functions are now extracted from bootmap.c into a new file called jump2ipl.c. Since we now also set the boot device schid at address 184 for the network boot device, this patch also slightly changes the way how we detect the entry points for non-ELF binary images: The code now looks for the "S390EP" magic first and then jumps to 0x10000 in case it has been found. This is necessary for booting from network devices, since the normal kernel code (where the PSW at ddress 0 points to) tries to do a block load from the boot device. This of course fails for a virtio-net device and causes the kernel to abort with a panic-PSW silently. Signed-off-by: Thomas Huth Acked-by: Christian Borntraeger --- pc-bios/s390-ccw/Makefile | 4 +- pc-bios/s390-ccw/bootmap.c | 63 +----------------------------- pc-bios/s390-ccw/bootmap.h | 4 -- pc-bios/s390-ccw/jump2ipl.c | 91 ++++++++++++++++++++++++++++++++++++++++= ++++ pc-bios/s390-ccw/netboot.mak | 3 +- pc-bios/s390-ccw/netmain.c | 11 +++++- pc-bios/s390-ccw/s390-ccw.h | 4 ++ 7 files changed, 111 insertions(+), 69 deletions(-) create mode 100644 pc-bios/s390-ccw/jump2ipl.c diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 1712c2d..439e3cc 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -9,7 +9,9 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw) =20 .PHONY : all clean build-all =20 -OBJECTS =3D start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-= blkdev.o libc.o menu.o +OBJECTS =3D start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \ + virtio.o virtio-scsi.o virtio-blkdev.o libc.o + QEMU_CFLAGS :=3D $(filter -W%, $(QEMU_CFLAGS)) QEMU_CFLAGS +=3D -ffreestanding -fno-delete-null-pointer-checks -msoft-flo= at QEMU_CFLAGS +=3D -march=3Dz900 -fPIE -fno-strict-aliasing diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 9287b7a..7e63e6b 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -29,14 +29,6 @@ /* Scratch space */ static uint8_t sec[MAX_SECTOR_SIZE*4] __attribute__((__aligned__(PAGE_SIZE= ))); =20 -typedef struct ResetInfo { - uint32_t ipl_mask; - uint32_t ipl_addr; - uint32_t ipl_continue; -} ResetInfo; - -static ResetInfo save; - const uint8_t el_torito_magic[] =3D "EL TORITO SPECIFICATION" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; =20 @@ -57,53 +49,6 @@ static inline bool is_iso_vd_valid(IsoVolDesc *vd) vd->type <=3D VOL_DESC_TYPE_PARTITION; } =20 -static void jump_to_IPL_2(void) -{ - ResetInfo *current =3D 0; - - void (*ipl)(void) =3D (void *) (uint64_t) current->ipl_continue; - *current =3D save; - ipl(); /* should not return */ -} - -static void jump_to_IPL_code(uint64_t address) -{ - /* store the subsystem information _after_ the bootmap was loaded */ - write_subsystem_identification(); - - /* prevent unknown IPL types in the guest */ - if (iplb.pbt =3D=3D S390_IPL_TYPE_QEMU_SCSI) { - iplb.pbt =3D S390_IPL_TYPE_CCW; - set_iplb(&iplb); - } - - /* - * The IPL PSW is at address 0. We also must not overwrite the - * content of non-BIOS memory after we loaded the guest, so we - * save the original content and restore it in jump_to_IPL_2. - */ - ResetInfo *current =3D 0; - - save =3D *current; - current->ipl_addr =3D (uint32_t) (uint64_t) &jump_to_IPL_2; - current->ipl_continue =3D address & 0x7fffffff; - - debug_print_int("set IPL addr to", current->ipl_continue); - - /* Ensure the guest output starts fresh */ - sclp_print("\n"); - - /* - * HACK ALERT. - * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2 - * can then use r15 as its stack pointer. - */ - asm volatile("lghi 1,1\n\t" - "diag 1,1,0x308\n\t" - : : : "1", "memory"); - panic("\n! IPL returns !\n"); -} - /*********************************************************************** * IPL an ECKD DASD (CDL or LDL/CMS format) */ @@ -727,13 +672,7 @@ static void load_iso_bc_entry(IsoBcSection *load) (void *)((uint64_t)bswap16(s.load_segment)), blks_to_load); =20 - /* Trying to get PSW at zero address */ - if (*((uint64_t *)0) & IPL_PSW_MASK) { - jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff); - } - - /* Try default linux start address */ - jump_to_IPL_code(KERN_IMAGE_START); + jump_to_low_kernel(); } =20 static uint32_t find_iso_bc(void) diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 07eb600..bef81ff 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -355,10 +355,6 @@ static inline uint32_t iso_733_to_u32(uint64_t x) #define ISO_SECTOR_SIZE 2048 /* El Torito specifies boot image size in 512 byte blocks */ #define ET_SECTOR_SHIFT 2 -#define KERN_IMAGE_START 0x010000UL -#define PSW_MASK_64 0x0000000100000000ULL -#define PSW_MASK_32 0x0000000080000000ULL -#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) =20 #define ISO_PRIMARY_VD_SECTOR 16 =20 diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c new file mode 100644 index 0000000..266f150 --- /dev/null +++ b/pc-bios/s390-ccw/jump2ipl.c @@ -0,0 +1,91 @@ +/* + * QEMU s390-ccw firmware - jump to IPL code + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "libc.h" +#include "s390-ccw.h" + +#define KERN_IMAGE_START 0x010000UL +#define PSW_MASK_64 0x0000000100000000ULL +#define PSW_MASK_32 0x0000000080000000ULL +#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) + +typedef struct ResetInfo { + uint32_t ipl_mask; + uint32_t ipl_addr; + uint32_t ipl_continue; +} ResetInfo; + +static ResetInfo save; + +static void jump_to_IPL_2(void) +{ + ResetInfo *current =3D 0; + + void (*ipl)(void) =3D (void *) (uint64_t) current->ipl_continue; + *current =3D save; + ipl(); /* should not return */ +} + +void jump_to_IPL_code(uint64_t address) +{ + /* store the subsystem information _after_ the bootmap was loaded */ + write_subsystem_identification(); + + /* prevent unknown IPL types in the guest */ + if (iplb.pbt =3D=3D S390_IPL_TYPE_QEMU_SCSI) { + iplb.pbt =3D S390_IPL_TYPE_CCW; + set_iplb(&iplb); + } + + /* + * The IPL PSW is at address 0. We also must not overwrite the + * content of non-BIOS memory after we loaded the guest, so we + * save the original content and restore it in jump_to_IPL_2. + */ + ResetInfo *current =3D 0; + + save =3D *current; + current->ipl_addr =3D (uint32_t) (uint64_t) &jump_to_IPL_2; + current->ipl_continue =3D address & 0x7fffffff; + + debug_print_int("set IPL addr to", current->ipl_continue); + + /* Ensure the guest output starts fresh */ + sclp_print("\n"); + + /* + * HACK ALERT. + * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2 + * can then use r15 as its stack pointer. + */ + asm volatile("lghi 1,1\n\t" + "diag 1,1,0x308\n\t" + : : : "1", "memory"); + panic("\n! IPL returns !\n"); +} + +void jump_to_low_kernel(void) +{ + /* + * If it looks like a Linux binary, i.e. there is the "S390EP" magic f= rom + * arch/s390/kernel/head.S here, then let's jump to the well-known Lin= ux + * kernel start address (when jumping to the PSW-at-zero address inste= ad, + * the kernel startup code fails when we booted from a network device). + */ + if (!memcmp((char *)0x10008, "S390EP", 6)) { + jump_to_IPL_code(KERN_IMAGE_START); + } + + /* Trying to get PSW at zero address */ + if (*((uint64_t *)0) & IPL_PSW_MASK) { + jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff); + } + + /* No other option left, so use the Linux kernel start address */ + jump_to_IPL_code(KERN_IMAGE_START); +} diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak index a25d238..4f64128 100644 --- a/pc-bios/s390-ccw/netboot.mak +++ b/pc-bios/s390-ccw/netboot.mak @@ -1,7 +1,8 @@ =20 SLOF_DIR :=3D $(SRC_PATH)/roms/SLOF =20 -NETOBJS :=3D start.o sclp.o virtio.o virtio-net.o netmain.o libnet.a libc.a +NETOBJS :=3D start.o sclp.o virtio.o virtio-net.o jump2ipl.o netmain.o \ + libnet.a libc.a =20 LIBC_INC :=3D -nostdinc -I$(SLOF_DIR)/lib/libc/include LIBNET_INC :=3D -I$(SLOF_DIR)/lib/libnet diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c index 8fa9e6c..69a82c0 100644 --- a/pc-bios/s390-ccw/netmain.c +++ b/pc-bios/s390-ccw/netmain.c @@ -283,6 +283,15 @@ void panic(const char *string) } } =20 +void write_subsystem_identification(void) +{ + SubChannelId *schid =3D (SubChannelId *) 184; + uint32_t *zeroes =3D (uint32_t *) 188; + + *schid =3D net_schid; + *zeroes =3D 0; +} + static bool find_net_dev(Schib *schib, int dev_no) { int i, r; @@ -365,7 +374,7 @@ void main(void) =20 if (rc > 0) { sclp_print("Network loading done, starting kernel...\n"); - asm volatile (" lpsw 0(%0) " : : "r"(0) : "memory"); + jump_to_low_kernel(); } =20 panic("Failed to load OS from network\n"); diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index fd18da2..d88e637 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -87,6 +87,10 @@ ulong get_second(void); /* bootmap.c */ void zipl_load(void); =20 +/* jump2ipl.c */ +void jump_to_IPL_code(uint64_t address); +void jump_to_low_kernel(void); + /* menu.c */ void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout); int menu_get_zipl_boot_index(const char *menu_data); --=20 1.8.3.1 From nobody Wed Oct 29 06:36:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1524735001219651.8344221496948; Thu, 26 Apr 2018 02:30:01 -0700 (PDT) Received: from localhost ([::1]:41162 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBdE0-0004UA-GQ for importer@patchew.org; Thu, 26 Apr 2018 05:30:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51554) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBdCm-0003jW-Fr for qemu-devel@nongnu.org; Thu, 26 Apr 2018 05:28:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fBdCk-0002q9-KX for qemu-devel@nongnu.org; Thu, 26 Apr 2018 05:28:44 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:45894 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fBdCk-0002q2-El; Thu, 26 Apr 2018 05:28:42 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 09EF481A88C4; Thu, 26 Apr 2018 09:28:42 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-75.ams2.redhat.com [10.36.116.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A86A2166BAD; Thu, 26 Apr 2018 09:28:39 +0000 (UTC) From: Thomas Huth To: Christian Borntraeger , qemu-s390x@nongnu.org, Viktor Mihajlovski Date: Thu, 26 Apr 2018 11:28:30 +0200 Message-Id: <1524734910-17970-4-git-send-email-thuth@redhat.com> In-Reply-To: <1524734910-17970-1-git-send-email-thuth@redhat.com> References: <1524734910-17970-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Thu, 26 Apr 2018 09:28:42 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Thu, 26 Apr 2018 09:28:42 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v4 3/3] pc-bios/s390-ccw/net: Add support for .INS config files X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Farhan Ali , Collin Walling , Cornelia Huck , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The .INS config files can normally be found on CD-ROM ISO images, so by supporting these files, it is now possible to boot directly when the TFTP server is set up with the contents of such an CD-ROM image. Signed-off-by: Thomas Huth Acked-by: Christian Borntraeger --- pc-bios/s390-ccw/netmain.c | 100 +++++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c index 69a82c0..6000241 100644 --- a/pc-bios/s390-ccw/netmain.c +++ b/pc-bios/s390-ccw/netmain.c @@ -39,8 +39,12 @@ =20 extern char _start[]; =20 +#define KERNEL_ADDR ((void *)0L) +#define KERNEL_MAX_SIZE ((long)_start) + char stack[PAGE_SIZE * 8] __attribute__((aligned(PAGE_SIZE))); IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE))); +static char cfgbuf[2048]; =20 static SubChannelId net_schid =3D { .one =3D 1 }; static int ip_version =3D 4; @@ -136,9 +140,15 @@ static int tftp_load(filename_ip_t *fnip, void *buffer= , int len) rc =3D tftp(fnip, buffer, len, DEFAULT_TFTP_RETRIES, &tftp_err, 1, 142= 8, ip_version); =20 - if (rc > 0) { - printf(" TFTP: Received %s (%d KBytes)\n", fnip->filename, - rc / 1024); + if (rc < 0) { + /* Make sure that error messages are put into a new line */ + printf("\n "); + } + + if (rc > 1024) { + printf(" TFTP: Received %s (%d KBytes)\n", fnip->filename, rc / 1= 024); + } else if (rc > 0) { + printf(" TFTP: Received %s (%d Bytes)\n", fnip->filename, rc); } else if (rc =3D=3D -1) { puts("unknown TFTP error"); } else if (rc =3D=3D -2) { @@ -275,6 +285,83 @@ static void net_release(filename_ip_t *fn_ip) } } =20 +/** + * Load via information from a .INS file (which can be found on CD-ROMs + * for example) + */ +static int handle_ins_cfg(filename_ip_t *fn_ip, char *cfg, int cfgsize) +{ + char *ptr; + int rc =3D -1, llen; + void *destaddr; + char *insbuf =3D cfg; + + ptr =3D strchr(insbuf, '\n'); + if (!ptr) { + puts("Does not seem to be a valid .INS file"); + return -1; + } + + *ptr =3D 0; + printf("\nParsing .INS file:\n %s\n", &insbuf[2]); + + insbuf =3D ptr + 1; + while (*insbuf && insbuf < cfg + cfgsize) { + ptr =3D strchr(insbuf, '\n'); + if (ptr) { + *ptr =3D 0; + } + llen =3D strlen(insbuf); + if (!llen) { + insbuf =3D ptr + 1; + continue; + } + ptr =3D strchr(insbuf, ' '); + if (!ptr) { + puts("Missing space separator in .INS file"); + return -1; + } + *ptr =3D 0; + strncpy((char *)fn_ip->filename, insbuf, sizeof(fn_ip->filename)); + destaddr =3D (char *)atol(ptr + 1); + rc =3D tftp_load(fn_ip, destaddr, (long)_start - (long)destaddr); + if (rc <=3D 0) { + break; + } + insbuf +=3D llen + 1; + } + + return rc; +} + +static int net_try_direct_tftp_load(filename_ip_t *fn_ip) +{ + int rc; + void *loadaddr =3D (void *)0x2000; /* Load right after the low-core */ + + rc =3D tftp_load(fn_ip, loadaddr, KERNEL_MAX_SIZE - (long)loadaddr); + if (rc < 0) { + return rc; + } else if (rc < 8) { + printf("'%s' is too small (%i bytes only).\n", fn_ip->filename, rc= ); + return -1; + } + + /* Check whether it is a configuration file instead of a kernel */ + if (rc < sizeof(cfgbuf) - 1) { + memcpy(cfgbuf, loadaddr, rc); + cfgbuf[rc] =3D 0; /* Make sure that it is NUL-terminated */ + if (!strncmp("* ", cfgbuf, 2)) { + return handle_ins_cfg(fn_ip, cfgbuf, rc); + } + } + + /* Move kernel to right location */ + memmove(KERNEL_ADDR, loadaddr, rc); + + return rc; +} + void panic(const char *string) { sclp_print(string); @@ -356,7 +443,7 @@ static void virtio_setup(void) void main(void) { filename_ip_t fn_ip; - int rc; + int rc, fnlen; =20 sclp_setup(); sclp_print("Network boot starting...\n"); @@ -368,7 +455,10 @@ void main(void) panic("Network initialization failed. Halting.\n"); } =20 - rc =3D tftp_load(&fn_ip, NULL, (long)_start); + fnlen =3D strlen((char *)fn_ip.filename); + if (fnlen > 0 && fn_ip.filename[fnlen - 1] !=3D '/') { + rc =3D net_try_direct_tftp_load(&fn_ip); + } =20 net_release(&fn_ip); =20 --=20 1.8.3.1