From f7f2f96f33774a32dae2c3d183c6f02aa97639fb Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 10 May 2023 16:39:25 +0200 Subject: [PATCH 1/8] s390-ccw: Getting rid of ulong MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Any good reason why this still exist? I can understand u* and __u* to be linux kernel like, but ulong? Reviewed-by: Thomas Huth Signed-off-by: Juan Quintela Message-Id: <20230629104821.194859-2-thuth@redhat.com> Reviewed-by: Claudio Imbrenda Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/helper.h | 2 +- pc-bios/s390-ccw/s390-ccw.h | 7 +++---- pc-bios/s390-ccw/virtio-blkdev.c | 12 ++++++------ pc-bios/s390-ccw/virtio-scsi.c | 4 ++-- pc-bios/s390-ccw/virtio-scsi.h | 2 +- pc-bios/s390-ccw/virtio.c | 12 ++++++------ pc-bios/s390-ccw/virtio.h | 4 ++-- 7 files changed, 21 insertions(+), 22 deletions(-) diff --git a/pc-bios/s390-ccw/helper.h b/pc-bios/s390-ccw/helper.h index 3d0731c4c6..8e3dfcb6d6 100644 --- a/pc-bios/s390-ccw/helper.h +++ b/pc-bios/s390-ccw/helper.h @@ -38,7 +38,7 @@ static inline void yield(void) static inline void sleep(unsigned int seconds) { - ulong target = get_time_seconds() + seconds; + unsigned long target = get_time_seconds() + seconds; while (get_time_seconds() < target) { yield(); diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index b88e0550ab..f849fba74b 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -17,7 +17,6 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; -typedef unsigned long ulong; typedef unsigned char __u8; typedef unsigned short __u16; typedef unsigned int __u32; @@ -67,11 +66,11 @@ void sclp_get_loadparm_ascii(char *loadparm); int sclp_read(char *str, size_t count); /* virtio.c */ -unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, - ulong subchan_id, void *load_addr); +unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2, + unsigned long subchan_id, void *load_addr); bool virtio_is_supported(SubChannelId schid); int virtio_blk_setup_device(SubChannelId schid); -int virtio_read(ulong sector, void *load_addr); +int virtio_read(unsigned long sector, void *load_addr); /* bootmap.c */ void zipl_load(void); diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c index 794f99b42c..a81207b52e 100644 --- a/pc-bios/s390-ccw/virtio-blkdev.c +++ b/pc-bios/s390-ccw/virtio-blkdev.c @@ -16,7 +16,7 @@ #define VIRTIO_BLK_F_GEOMETRY (1 << 4) #define VIRTIO_BLK_F_BLK_SIZE (1 << 6) -static int virtio_blk_read_many(VDev *vdev, ulong sector, void *load_addr, +static int virtio_blk_read_many(VDev *vdev, unsigned long sector, void *load_addr, int sec_num) { VirtioBlkOuthdr out_hdr; @@ -49,7 +49,7 @@ static int virtio_blk_read_many(VDev *vdev, ulong sector, void *load_addr, return status; } -int virtio_read_many(ulong sector, void *load_addr, int sec_num) +int virtio_read_many(unsigned long sector, void *load_addr, int sec_num) { VDev *vdev = virtio_get_device(); @@ -63,14 +63,14 @@ int virtio_read_many(ulong sector, void *load_addr, int sec_num) return -1; } -unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, - ulong subchan_id, void *load_addr) +unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2, + unsigned long subchan_id, void *load_addr) { u8 status; int sec = rec_list1; int sec_num = ((rec_list2 >> 32) & 0xffff) + 1; int sec_len = rec_list2 >> 48; - ulong addr = (ulong)load_addr; + unsigned long addr = (unsigned long)load_addr; if (sec_len != virtio_get_block_size()) { return -1; @@ -86,7 +86,7 @@ unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, return addr; } -int virtio_read(ulong sector, void *load_addr) +int virtio_read(unsigned long sector, void *load_addr) { return virtio_read_many(sector, load_addr, 1); } diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c index dcce696a33..d1a84b937c 100644 --- a/pc-bios/s390-ccw/virtio-scsi.c +++ b/pc-bios/s390-ccw/virtio-scsi.c @@ -150,7 +150,7 @@ static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) } static bool scsi_read_10(VDev *vdev, - ulong sector, int sectors, void *data, + unsigned long sector, int sectors, void *data, unsigned int data_size) { ScsiCdbRead10 cdb = { @@ -269,7 +269,7 @@ static int virtio_scsi_locate_device(VDev *vdev) } int virtio_scsi_read_many(VDev *vdev, - ulong sector, void *load_addr, int sec_num) + unsigned long sector, void *load_addr, int sec_num) { int sector_count; int f = vdev->blk_factor; diff --git a/pc-bios/s390-ccw/virtio-scsi.h b/pc-bios/s390-ccw/virtio-scsi.h index e6b6cd4815..c5612e16a2 100644 --- a/pc-bios/s390-ccw/virtio-scsi.h +++ b/pc-bios/s390-ccw/virtio-scsi.h @@ -68,7 +68,7 @@ static inline bool virtio_scsi_response_ok(const VirtioScsiCmdResp *r) } int virtio_scsi_read_many(VDev *vdev, - ulong sector, void *load_addr, int sec_num); + unsigned long sector, void *load_addr, int sec_num); int virtio_scsi_setup_device(SubChannelId schid); #endif /* VIRTIO_SCSI_H */ diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c index f37510f312..5edd058d88 100644 --- a/pc-bios/s390-ccw/virtio.c +++ b/pc-bios/s390-ccw/virtio.c @@ -48,10 +48,10 @@ VirtioDevType virtio_get_device_type(void) static long kvm_hypercall(unsigned long nr, unsigned long param1, unsigned long param2, unsigned long param3) { - register ulong r_nr asm("1") = nr; - register ulong r_param1 asm("2") = param1; - register ulong r_param2 asm("3") = param2; - register ulong r_param3 asm("4") = param3; + register unsigned long r_nr asm("1") = nr; + register unsigned long r_param1 asm("2") = param1; + register unsigned long r_param2 asm("3") = param2; + register unsigned long r_param3 asm("4") = param3; register long retval asm("2"); asm volatile ("diag %%r2,%%r4,0x500" @@ -145,7 +145,7 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags) vr->avail->ring[vr->avail->idx % vr->num] = vr->next_idx; } - vr->desc[vr->next_idx].addr = (ulong)p; + vr->desc[vr->next_idx].addr = (unsigned long)p; vr->desc[vr->next_idx].len = len; vr->desc[vr->next_idx].flags = flags & ~VRING_HIDDEN_IS_CHAIN; vr->desc[vr->next_idx].next = vr->next_idx; @@ -182,7 +182,7 @@ int vr_poll(VRing *vr) */ int vring_wait_reply(void) { - ulong target_second = get_time_seconds() + vdev.wait_reply_timeout; + unsigned long target_second = get_time_seconds() + vdev.wait_reply_timeout; /* Wait for any queue to be updated by the host */ do { diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h index e657d381ec..85bd9d1695 100644 --- a/pc-bios/s390-ccw/virtio.h +++ b/pc-bios/s390-ccw/virtio.h @@ -190,14 +190,14 @@ int virtio_get_block_size(void); uint8_t virtio_get_heads(void); uint8_t virtio_get_sectors(void); uint64_t virtio_get_blocks(void); -int virtio_read_many(ulong sector, void *load_addr, int sec_num); +int virtio_read_many(unsigned long sector, void *load_addr, int sec_num); #define VIRTIO_SECTOR_SIZE 512 #define VIRTIO_ISO_BLOCK_SIZE 2048 #define VIRTIO_SCSI_BLOCK_SIZE 512 #define VIRTIO_DASD_DEFAULT_BLOCK_SIZE 4096 -static inline ulong virtio_sector_adjust(ulong sector) +static inline unsigned long virtio_sector_adjust(unsigned long sector) { return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE); } From 0c2a6e124228caf776647050cfbba4faedf950fb Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 27 Jun 2023 13:41:01 +0200 Subject: [PATCH 2/8] pc-bios/s390-ccw: Get rid of the the __u* types The types starting with double underscores have likely been introduced into the s390-ccw bios to be able to re-use structs from the Linux kernel in the past, but the corresponding structs in cio.h have been changed there a long time ago already to not use the variants with the double underscores anymore: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/drivers/s390/cio/cio.h?id=cd6b4f27b9bb2a So it would be good to replace these in the s390-ccw bios now, too. Message-Id: <20230627114101.122231-1-thuth@redhat.com> Reviewed-by: Claudio Imbrenda Reviewed-by: Eric Farman Reviewed-by: Juan Quintela Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/cio.h | 232 ++++++++++++++++++------------------ pc-bios/s390-ccw/s390-ccw.h | 4 - 2 files changed, 116 insertions(+), 120 deletions(-) diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h index 88a88adfd2..8b18153deb 100644 --- a/pc-bios/s390-ccw/cio.h +++ b/pc-bios/s390-ccw/cio.h @@ -17,32 +17,32 @@ * path management control word */ struct pmcw { - __u32 intparm; /* interruption parameter */ - __u32 qf:1; /* qdio facility */ - __u32 w:1; - __u32 isc:3; /* interruption subclass */ - __u32 res5:3; /* reserved zeros */ - __u32 ena:1; /* enabled */ - __u32 lm:2; /* limit mode */ - __u32 mme:2; /* measurement-mode enable */ - __u32 mp:1; /* multipath mode */ - __u32 tf:1; /* timing facility */ - __u32 dnv:1; /* device number valid */ - __u32 dev:16; /* device number */ - __u8 lpm; /* logical path mask */ - __u8 pnom; /* path not operational mask */ - __u8 lpum; /* last path used mask */ - __u8 pim; /* path installed mask */ - __u16 mbi; /* measurement-block index */ - __u8 pom; /* path operational mask */ - __u8 pam; /* path available mask */ - __u8 chpid[8]; /* CHPID 0-7 (if available) */ - __u32 unused1:8; /* reserved zeros */ - __u32 st:3; /* subchannel type */ - __u32 unused2:18; /* reserved zeros */ - __u32 mbfc:1; /* measurement block format control */ - __u32 xmwme:1; /* extended measurement word mode enable */ - __u32 csense:1; /* concurrent sense; can be enabled ...*/ + u32 intparm; /* interruption parameter */ + u32 qf:1; /* qdio facility */ + u32 w:1; + u32 isc:3; /* interruption subclass */ + u32 res5:3; /* reserved zeros */ + u32 ena:1; /* enabled */ + u32 lm:2; /* limit mode */ + u32 mme:2; /* measurement-mode enable */ + u32 mp:1; /* multipath mode */ + u32 tf:1; /* timing facility */ + u32 dnv:1; /* device number valid */ + u32 dev:16; /* device number */ + u8 lpm; /* logical path mask */ + u8 pnom; /* path not operational mask */ + u8 lpum; /* last path used mask */ + u8 pim; /* path installed mask */ + u16 mbi; /* measurement-block index */ + u8 pom; /* path operational mask */ + u8 pam; /* path available mask */ + u8 chpid[8]; /* CHPID 0-7 (if available) */ + u32 unused1:8; /* reserved zeros */ + u32 st:3; /* subchannel type */ + u32 unused2:18; /* reserved zeros */ + u32 mbfc:1; /* measurement block format control */ + u32 xmwme:1; /* extended measurement word mode enable */ + u32 csense:1; /* concurrent sense; can be enabled ...*/ /* ... per MSCH, however, if facility */ /* ... is not installed, this results */ /* ... in an operand exception. */ @@ -50,24 +50,24 @@ struct pmcw { /* Target SCHIB configuration. */ struct schib_config { - __u64 mba; - __u32 intparm; - __u16 mbi; - __u32 isc:3; - __u32 ena:1; - __u32 mme:2; - __u32 mp:1; - __u32 csense:1; - __u32 mbfc:1; + u64 mba; + u32 intparm; + u16 mbi; + u32 isc:3; + u32 ena:1; + u32 mme:2; + u32 mp:1; + u32 csense:1; + u32 mbfc:1; } __attribute__ ((packed)); struct scsw { - __u16 flags; - __u16 ctrl; - __u32 cpa; - __u8 dstat; - __u8 cstat; - __u16 count; + u16 flags; + u16 ctrl; + u32 cpa; + u8 dstat; + u8 cstat; + u16 count; } __attribute__ ((packed)); /* Function Control */ @@ -117,42 +117,42 @@ struct scsw { typedef struct schib { struct pmcw pmcw; /* path management control word */ struct scsw scsw; /* subchannel status word */ - __u64 mba; /* measurement block address */ - __u8 mda[4]; /* model dependent area */ + u64 mba; /* measurement block address */ + u8 mda[4]; /* model dependent area */ } __attribute__ ((packed, aligned(4))) Schib; typedef struct subchannel_id { union { struct { - __u16 cssid:8; - __u16 reserved:4; - __u16 m:1; - __u16 ssid:2; - __u16 one:1; + u16 cssid:8; + u16 reserved:4; + u16 m:1; + u16 ssid:2; + u16 one:1; }; - __u16 sch_id; + u16 sch_id; }; - __u16 sch_no; + u16 sch_no; } __attribute__ ((packed, aligned(4))) SubChannelId; struct chsc_header { - __u16 length; - __u16 code; + u16 length; + u16 code; } __attribute__((packed)); typedef struct chsc_area_sda { struct chsc_header request; - __u8 reserved1:4; - __u8 format:4; - __u8 reserved2; - __u16 operation_code; - __u32 reserved3; - __u32 reserved4; - __u32 operation_data_area[252]; + u8 reserved1:4; + u8 format:4; + u8 reserved2; + u16 operation_code; + u32 reserved3; + u32 reserved4; + u32 operation_data_area[252]; struct chsc_header response; - __u32 reserved5:4; - __u32 format2:4; - __u32 reserved6:24; + u32 reserved5:4; + u32 format2:4; + u32 reserved6:24; } __attribute__((packed)) ChscAreaSda; /* @@ -160,37 +160,37 @@ typedef struct chsc_area_sda { */ struct tpi_info { struct subchannel_id schid; - __u32 intparm; /* interruption parameter */ - __u32 adapter_IO:1; - __u32 reserved2:1; - __u32 isc:3; - __u32 reserved3:12; - __u32 int_type:3; - __u32 reserved4:12; + u32 intparm; /* interruption parameter */ + u32 adapter_IO:1; + u32 reserved2:1; + u32 isc:3; + u32 reserved3:12; + u32 int_type:3; + u32 reserved4:12; } __attribute__ ((packed, aligned(4))); /* channel command word (format 0) */ typedef struct ccw0 { - __u8 cmd_code; - __u32 cda:24; - __u32 chainData:1; - __u32 chain:1; - __u32 sli:1; - __u32 skip:1; - __u32 pci:1; - __u32 ida:1; - __u32 suspend:1; - __u32 mida:1; - __u8 reserved; - __u16 count; + u8 cmd_code; + u32 cda:24; + u32 chainData:1; + u32 chain:1; + u32 sli:1; + u32 skip:1; + u32 pci:1; + u32 ida:1; + u32 suspend:1; + u32 mida:1; + u8 reserved; + u16 count; } __attribute__ ((packed, aligned(8))) Ccw0; /* channel command word (format 1) */ typedef struct ccw1 { - __u8 cmd_code; - __u8 flags; - __u16 count; - __u32 cda; + u8 cmd_code; + u8 flags; + u16 count; + u32 cda; } __attribute__ ((packed, aligned(8))) Ccw1; /* do_cio() CCW formats */ @@ -234,31 +234,31 @@ typedef struct ccw1 { * Command-mode operation request block */ typedef struct cmd_orb { - __u32 intparm; /* interruption parameter */ - __u32 key:4; /* flags, like key, suspend control, etc. */ - __u32 spnd:1; /* suspend control */ - __u32 res1:1; /* reserved */ - __u32 mod:1; /* modification control */ - __u32 sync:1; /* synchronize control */ - __u32 fmt:1; /* format control */ - __u32 pfch:1; /* prefetch control */ - __u32 isic:1; /* initial-status-interruption control */ - __u32 alcc:1; /* address-limit-checking control */ - __u32 ssic:1; /* suppress-suspended-interr. control */ - __u32 res2:1; /* reserved */ - __u32 c64:1; /* IDAW/QDIO 64 bit control */ - __u32 i2k:1; /* IDAW 2/4kB block size control */ - __u32 lpm:8; /* logical path mask */ - __u32 ils:1; /* incorrect length */ - __u32 zero:6; /* reserved zeros */ - __u32 orbx:1; /* ORB extension control */ - __u32 cpa; /* channel program address */ + u32 intparm; /* interruption parameter */ + u32 key:4; /* flags, like key, suspend control, etc. */ + u32 spnd:1; /* suspend control */ + u32 res1:1; /* reserved */ + u32 mod:1; /* modification control */ + u32 sync:1; /* synchronize control */ + u32 fmt:1; /* format control */ + u32 pfch:1; /* prefetch control */ + u32 isic:1; /* initial-status-interruption control */ + u32 alcc:1; /* address-limit-checking control */ + u32 ssic:1; /* suppress-suspended-interr. control */ + u32 res2:1; /* reserved */ + u32 c64:1; /* IDAW/QDIO 64 bit control */ + u32 i2k:1; /* IDAW 2/4kB block size control */ + u32 lpm:8; /* logical path mask */ + u32 ils:1; /* incorrect length */ + u32 zero:6; /* reserved zeros */ + u32 orbx:1; /* ORB extension control */ + u32 cpa; /* channel program address */ } __attribute__ ((packed, aligned(4))) CmdOrb; struct ciw { - __u8 type; - __u8 command; - __u16 count; + u8 type; + u8 command; + u16 count; }; #define CU_TYPE_UNKNOWN 0x0000 @@ -271,12 +271,12 @@ struct ciw { */ typedef struct senseid { /* common part */ - __u8 reserved; /* always 0x'FF' */ - __u16 cu_type; /* control unit type */ - __u8 cu_model; /* control unit model */ - __u16 dev_type; /* device type */ - __u8 dev_model; /* device model */ - __u8 unused; /* padding byte */ + u8 reserved; /* always 0x'FF' */ + u16 cu_type; /* control unit type */ + u8 cu_model; /* control unit model */ + u16 dev_type; /* device type */ + u8 dev_model; /* device model */ + u8 unused; /* padding byte */ /* extended part */ struct ciw ciw[62]; } __attribute__ ((packed, aligned(4))) SenseId; @@ -342,9 +342,9 @@ typedef struct SenseDataEckdDasd { /* interruption response block */ typedef struct irb { struct scsw scsw; - __u32 esw[5]; - __u32 ecw[8]; - __u32 emw[8]; + u32 esw[5]; + u32 ecw[8]; + u32 emw[8]; } __attribute__ ((packed, aligned(4))) Irb; /* Used for SEEK ccw commands */ diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index f849fba74b..f68a832718 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -17,10 +17,6 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; -typedef unsigned char __u8; -typedef unsigned short __u16; -typedef unsigned int __u32; -typedef unsigned long long __u64; #define true 1 #define false 0 From 442ef32ee5b6059a8f247fb2def9d449578d0a89 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 22 Jun 2023 15:08:22 +0200 Subject: [PATCH 3/8] pc-bios/s390-ccw/Makefile: Use -z noexecstack to silence linker warning Recent versions of ld complain when linking the s390-ccw bios: /usr/bin/ld: warning: start.o: missing .note.GNU-stack section implies executable stack /usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker We can silence the warning by telling the linker to mark the stack as not executable. Message-Id: <20230622130822.396793-1-thuth@redhat.com> Acked-by: Christian Borntraeger Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 2e8cc015aa..acfcd1e71a 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -55,7 +55,7 @@ config-cc.mak: Makefile $(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak -include config-cc.mak -LDFLAGS += -Wl,-pie -nostdlib +LDFLAGS += -Wl,-pie -nostdlib -z noexecstack build-all: s390-ccw.img s390-netboot.img From f52420fa4fd9f519dc42c20d2616aba4149adc25 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 27 Jun 2023 09:47:00 +0200 Subject: [PATCH 4/8] pc-bios/s390-ccw: Fix indentation in start.S MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit start.S is currently indented with a mixture of spaces and tabs, which is quite ugly. QEMU coding style says indentation should be 4 spaces, and this is also what we are using in the assembler files in the tests/tcg/s390x/ folder already, so let's adjust start.S accordingly. Reviewed-by: Cédric Le Goater Message-Id: <20230627074703.99608-2-thuth@redhat.com> Reviewed-by: Claudio Imbrenda Reviewed-by: Eric Farman Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/start.S | 136 +++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S index 6072906df4..d29de09cc6 100644 --- a/pc-bios/s390-ccw/start.S +++ b/pc-bios/s390-ccw/start.S @@ -10,37 +10,37 @@ * directory. */ - .globl _start + .globl _start _start: - larl %r15, stack + 0x8000 /* Set up stack */ + larl %r15,stack + 0x8000 /* Set up stack */ - /* clear bss */ - larl %r2, __bss_start - larl %r3, _end - slgr %r3, %r2 /* get sizeof bss */ - ltgr %r3,%r3 /* bss empty? */ - jz done - aghi %r3,-1 - srlg %r4,%r3,8 /* how many 256 byte chunks? */ - ltgr %r4,%r4 - lgr %r1,%r2 - jz remainder + /* clear bss */ + larl %r2,__bss_start + larl %r3,_end + slgr %r3,%r2 /* get sizeof bss */ + ltgr %r3,%r3 /* bss empty? */ + jz done + aghi %r3,-1 + srlg %r4,%r3,8 /* how many 256 byte chunks? */ + ltgr %r4,%r4 + lgr %r1,%r2 + jz remainder loop: - xc 0(256,%r1),0(%r1) - la %r1,256(%r1) - brctg %r4,loop + xc 0(256,%r1),0(%r1) + la %r1,256(%r1) + brctg %r4,loop remainder: - larl %r2,memsetxc - ex %r3,0(%r2) + larl %r2,memsetxc + ex %r3,0(%r2) done: - /* set up a pgm exception disabled wait psw */ - larl %r2, disabled_wait_psw - mvc 0x01d0(16), 0(%r2) - j main /* And call C */ + /* set up a pgm exception disabled wait psw */ + larl %r2,disabled_wait_psw + mvc 0x01d0(16),0(%r2) + j main /* And call C */ memsetxc: - xc 0(1,%r1),0(%r1) + xc 0(1,%r1),0(%r1) /* @@ -48,11 +48,11 @@ memsetxc: * * stops the current guest cpu. */ - .globl disabled_wait + .globl disabled_wait disabled_wait: - larl %r1,disabled_wait_psw - lpswe 0(%r1) -1: j 1b + larl %r1,disabled_wait_psw + lpswe 0(%r1) +1: j 1b /* @@ -60,61 +60,61 @@ disabled_wait: * * eats one sclp interrupt */ - .globl consume_sclp_int + .globl consume_sclp_int consume_sclp_int: - /* enable service interrupts in cr0 */ - stctg %c0,%c0,0(%r15) - oi 6(%r15),0x2 - lctlg %c0,%c0,0(%r15) - /* prepare external call handler */ - larl %r1, external_new_code - stg %r1, 0x1b8 - larl %r1, external_new_mask - mvc 0x1b0(8),0(%r1) - /* load enabled wait PSW */ - larl %r1, enabled_wait_psw - lpswe 0(%r1) + /* enable service interrupts in cr0 */ + stctg %c0,%c0,0(%r15) + oi 6(%r15),0x2 + lctlg %c0,%c0,0(%r15) + /* prepare external call handler */ + larl %r1,external_new_code + stg %r1,0x1b8 + larl %r1,external_new_mask + mvc 0x1b0(8),0(%r1) + /* load enabled wait PSW */ + larl %r1,enabled_wait_psw + lpswe 0(%r1) /* * void consume_io_int(void) * * eats one I/O interrupt */ - .globl consume_io_int + .globl consume_io_int consume_io_int: - /* enable I/O interrupts in cr6 */ - stctg %c6,%c6,0(%r15) - oi 4(%r15), 0xff - lctlg %c6,%c6,0(%r15) - /* prepare i/o call handler */ - larl %r1, io_new_code - stg %r1, 0x1f8 - larl %r1, io_new_mask - mvc 0x1f0(8),0(%r1) - /* load enabled wait PSW */ - larl %r1, enabled_wait_psw - lpswe 0(%r1) + /* enable I/O interrupts in cr6 */ + stctg %c6,%c6,0(%r15) + oi 4(%r15), 0xff + lctlg %c6,%c6,0(%r15) + /* prepare i/o call handler */ + larl %r1,io_new_code + stg %r1,0x1f8 + larl %r1,io_new_mask + mvc 0x1f0(8),0(%r1) + /* load enabled wait PSW */ + larl %r1,enabled_wait_psw + lpswe 0(%r1) external_new_code: - /* disable service interrupts in cr0 */ - stctg %c0,%c0,0(%r15) - ni 6(%r15),0xfd - lctlg %c0,%c0,0(%r15) - br %r14 + /* disable service interrupts in cr0 */ + stctg %c0,%c0,0(%r15) + ni 6(%r15),0xfd + lctlg %c0,%c0,0(%r15) + br %r14 io_new_code: - /* disable I/O interrupts in cr6 */ - stctg %c6,%c6,0(%r15) - ni 4(%r15), 0x00 - lctlg %c6,%c6,0(%r15) - br %r14 + /* disable I/O interrupts in cr6 */ + stctg %c6,%c6,0(%r15) + ni 4(%r15),0x00 + lctlg %c6,%c6,0(%r15) + br %r14 - .align 8 + .align 8 disabled_wait_psw: - .quad 0x0002000180000000,0x0000000000000000 + .quad 0x0002000180000000,0x0000000000000000 enabled_wait_psw: - .quad 0x0302000180000000,0x0000000000000000 + .quad 0x0302000180000000,0x0000000000000000 external_new_mask: - .quad 0x0000000180000000 + .quad 0x0000000180000000 io_new_mask: - .quad 0x0000000180000000 + .quad 0x0000000180000000 From 74fe98ee7fb3344dbd085d1fa32c0dc2fc2c831f Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 27 Jun 2023 09:47:01 +0200 Subject: [PATCH 5/8] pc-bios/s390-ccw: Provide space for initial stack frame in start.S MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Providing the space of a stack frame is the duty of the caller, so we should reserve 160 bytes before jumping into the main function. Otherwise the main() function might write past the stack array. While we're at it, add a proper STACK_SIZE macro for the stack size instead of using magic numbers (this is also required for the following patch). Reviewed-by: Christian Borntraeger Reviewed-by: Cédric Le Goater Message-Id: <20230627074703.99608-3-thuth@redhat.com> Reviewed-by: Eric Farman Reviewed-by: Claudio Imbrenda Reviewed-by: Marc Hartmayer Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/start.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S index d29de09cc6..abd6fe6639 100644 --- a/pc-bios/s390-ccw/start.S +++ b/pc-bios/s390-ccw/start.S @@ -10,10 +10,13 @@ * directory. */ +#define STACK_SIZE 0x8000 +#define STACK_FRAME_SIZE 160 + .globl _start _start: - larl %r15,stack + 0x8000 /* Set up stack */ + larl %r15,stack + STACK_SIZE - STACK_FRAME_SIZE /* Set up stack */ /* clear bss */ larl %r2,__bss_start From e31f08dc748bad980f2092be165bd091f9cf3c48 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 27 Jun 2023 09:47:02 +0200 Subject: [PATCH 6/8] pc-bios/s390-ccw: Move the stack array into start.S The stack array is only referenced from the start-up code (which is shared between the s390-ccw.img and the s390-netboot.img), but it is currently declared twice, once in main.c and once in netmain.c. It makes more sense to declare this in start.S instead - which will also be helpful in the next patch, since we need to mention the .bss section in start.S in that patch. While we're at it, let's also drop the huge alignment of the stack, since there is no technical requirement for aligning it to page boundaries. Message-Id: <20230627074703.99608-4-thuth@redhat.com> Reviewed-by: Claudio Imbrenda Reviewed-by: Eric Farman Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/main.c | 1 - pc-bios/s390-ccw/netmain.c | 1 - pc-bios/s390-ccw/s390-ccw.h | 1 - pc-bios/s390-ccw/start.S | 6 ++++++ tests/tcg/s390x/head64.S | 7 ++----- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index a2def83e82..5506798098 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -17,7 +17,6 @@ #include "virtio-scsi.h" #include "dasd-ipl.h" -char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); static SubChannelId blk_schid = { .one = 1 }; static char loadparm_str[LOADPARM_LEN + 1]; QemuIplParameters qipl; diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c index 056e93a818..5cd619b2d6 100644 --- a/pc-bios/s390-ccw/netmain.c +++ b/pc-bios/s390-ccw/netmain.c @@ -50,7 +50,6 @@ void write_iplb_location(void) {} /* STSI 3.2.2 offset of first vmdb + offset of uuid inside vmdb */ #define STSI322_VMDB_UUID_OFFSET ((8 + 12) * 4) -char stack[PAGE_SIZE * 8] __attribute__((aligned(PAGE_SIZE))); IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE))); static char cfgbuf[2048]; diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index f68a832718..c977a52b50 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -50,7 +50,6 @@ void consume_io_int(void); /* main.c */ void write_subsystem_identification(void); void write_iplb_location(void); -extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); unsigned int get_loadparm_index(void); void main(void); diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S index abd6fe6639..429a2b30a1 100644 --- a/pc-bios/s390-ccw/start.S +++ b/pc-bios/s390-ccw/start.S @@ -121,3 +121,9 @@ external_new_mask: .quad 0x0000000180000000 io_new_mask: .quad 0x0000000180000000 + +.bss + .align 8 +stack: + .space STACK_SIZE + .size stack,STACK_SIZE diff --git a/tests/tcg/s390x/head64.S b/tests/tcg/s390x/head64.S index c6f36dfea4..4fe288388a 100644 --- a/tests/tcg/s390x/head64.S +++ b/tests/tcg/s390x/head64.S @@ -8,6 +8,8 @@ #include "../../../pc-bios/s390-ccw/start.S" #undef main +.text + main_pre: aghi %r15,-160 /* reserve stack for C code */ brasl %r14,sclp_setup @@ -24,8 +26,3 @@ success_psw: .quad 0x2000180000000,0xfff /* see is_special_wait_psw() */ failure_psw: .quad 0x2000180000000,0 /* disabled wait */ - - .section .bss - .align 0x1000 -stack: - .skip 0x8000 From 7cd50cbe4ca3e2860b31b06ec92c17c54bd82d48 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 27 Jun 2023 09:47:03 +0200 Subject: [PATCH 7/8] pc-bios/s390-ccw: Don't use __bss_start with the "larl" instruction start.S currently cannot be compiled with Clang 16 and binutils 2.40: ld: start.o(.text+0x8): misaligned symbol `__bss_start' (0xc1e5) for relocation R_390_PC32DBL According to the built-in linker script of ld, the symbol __bss_start can actually point *before* the .bss section and does not need to have any alignment, so in certain situations (like when using the internal assembler of Clang), the __bss_start symbol can indeed be unaligned and thus it is not suitable for being used with the "larl" instruction that needs an address that is at least aligned to halfwords. The problem went unnoticed so far since binutils <= 2.39 did not check the alignment, but starting with binutils 2.40, such unaligned addresses are now refused. Fix it by loading the address indirectly instead. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2216662 Reported-by: Miroslav Rezanina Suggested-by: Andreas Krebbel Message-Id: <20230629104821.194859-8-thuth@redhat.com> Reviewed-by: Claudio Imbrenda Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/start.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S index 429a2b30a1..061b06591c 100644 --- a/pc-bios/s390-ccw/start.S +++ b/pc-bios/s390-ccw/start.S @@ -19,7 +19,8 @@ _start: larl %r15,stack + STACK_SIZE - STACK_FRAME_SIZE /* Set up stack */ /* clear bss */ - larl %r2,__bss_start + larl %r2,bss_start_literal /* __bss_start might be unaligned ... */ + lg %r2,0(%r2) /* ... so load it indirectly */ larl %r3,_end slgr %r3,%r2 /* get sizeof bss */ ltgr %r3,%r3 /* bss empty? */ @@ -45,7 +46,6 @@ done: memsetxc: xc 0(1,%r1),0(%r1) - /* * void disabled_wait(void) * @@ -113,6 +113,8 @@ io_new_code: br %r14 .align 8 +bss_start_literal: + .quad __bss_start disabled_wait_psw: .quad 0x0002000180000000,0x0000000000000000 enabled_wait_psw: From b806bc8d9cc16172f0cf2c9e42ca1d75b72f6555 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 29 Jun 2023 12:01:56 +0200 Subject: [PATCH 8/8] pc-bios: Update the s390 bios images with the recent changes The startup code of the bios has slightly been changed, apart from that, there should not be any functional changes this time. Signed-off-by: Thomas Huth --- pc-bios/s390-ccw.img | Bin 42608 -> 42608 bytes pc-bios/s390-netboot.img | Bin 67232 -> 67232 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img index c9a5a21c50b9e78a7048d456d842ddbfdf9e6ba3..f0d9ef6d4d86eb8d8ace19cac3929b9c06ae826f 100644 GIT binary patch delta 2507 zcmZ`*dr(tX8b9YtOu|FB;SmA`ykHQ5x^2ks_Tts@eZ@^IX)yJ=^wN;fFASd{EJH}nrXvnP}L zo%8#C=bZ0+k8^ME3Iwk}?L?{^5I>E4-%Ql@zWKoIq}57zaPntTvslG7<&Lmk-~!lR z7alh#VfpiUR3#EZ1uUbBs166~bMYb-(*Gad5nhKnaF}K%xDNj-C$#u8mu2rr`6vF0 z9q;_`@9mfmYiS$SLXvs&7@3O*BO%f1n9c0~6VNj3g{&N%qJlpu$!SA)eCp1#_}GDO`kuEexf|1)%Z5t+aGigtHSif-%BH* z#mYB?#3k@&R=>i0RNSkGgh(%6j}0~pFj{TL>**;sUKGN~U`mq?kmPiFP7QWW;S`J|~*Ae7lyvVvTk- zJ%Z=7(B6Q9sAXUjiZ%TE$N2( z*JG()B+}4mXD<=hk6TR2P|(@NFTJj(o-w2lUAoNivltQ_L#+5GU3R2i&*-e3HejQ! zn7)a(bsM3jUS6V)rxD$3bMAm>e96$I-^lyR%W+=BtTeY#vJs2ZX(!i-g9t=*Z&v6r zr?}t1+K5Rs5zjBZ74)0rrug5GCLTWv7GtfqBMt;@!)Z=Q$ zQ~@-08M-a>XzHM=bDvCwZLlcZI|sCWqJwPTfWEA%|V2gWtfa|ui1W@i3<{&WWm zM(EO^6P}68+QE)^4=_2vt-jfyG!oMD5q=OioxY1V<1*l8C630K;pWR|j(-Vyae;m%LK&CdkM{5-y|C{^Wc( z&0L*w5WL6vX5c-DpQg;D@8JEE{d6Jjm|&xJY@M(k&fdjH%VhYl2lFgW`UP&Y*ytH- zuxx^Bn=mrf0@v1Jc4{?TOTiPVhZDU#MFM4PXRXr{Y~;z}zl0TOdkp?6ZjXOEHyHfP zscFM$T@M3-XPKHn4wgVmSpq#^vXocrqJB&e^P%esE)iG8*0G3vUY8eitE#urBW{JR z->3$3m10TyF6fHJ3+Y!PueO+*dbbDNK{v*vn&B!tSH=an$}(ZnAE9#yA5F4C=eKCF zcG7)#*E)&rz?e)|%)o+s{|#0$2eBj=D8coaOKAe0%*+=DXuwW*K?|W!NDkQ98LR=p zPsmPwocrG)OrB1^#r(+!VQ3Ftp8O)+iuSBh(@-w6*r#VrDI+AWj4wQti3hW$#oIVK zhUcsJIPA{Kr3TbyZ-j?!_-gjdiEYw}(5Pf4H1W7}o+PQ2#}=A?k-PL^J$kd(z{7Qz zW=p4=&|&+XhKyLS)iy%UVpGnRsGVO@vfFQ9d3_nLPDzssrmUioe6Pn6OO*~hI(3SM zJZ1(@T}CV9lxeGB1{t2i3B%J%LOUpm7gw&pJ4 zm7DukL|d3!d`7Oa7Xm#bpUZoL>igI|ND2pVUVeJiEq2*|&7D@*A#co2rR=@7d*)LO zdGfKmdzO#VuW-p68_%#gzlG0V!R|SgaDEhB&z+^3x`Grqk7y~FO}+T5fnQm2m|rM@Zz@(49!oap_4l>}?JSgjLTm%l$kRKlcBuC*#uS-E?|D|V)cdxx za?s3fG{VZ_60x!u(j9hEs&vW=iaZoLp5UY6{j>&mJGO%2#vdIPP!6HlIS-U7tZ){A z;=*^GqCuI>@{uZe*zU}Rju75)TA(9{x{_U>)X95Fj!-&?)&+N{U4oa&IxJ8M$0yJ0(3uO)X~txg1K)G!Mhu71ox|vN&o(OIQNx&I-%{q5c9spjEl2(b D-K0M$ delta 2326 zcmZ`*4Nz3q6~5=}>Mr=h?g9(TuCj~E&k}@HK@kJ&5`?IXqK?K;Yb-&>A*~w5q0`zj zkkB-faRPE2VxkqI;2L8#m^bOjB$Z7~aRX>JU;rB`AewQYNnR|Zc0laC59~}b)BEP# z_wG68e&@UAoO|DsyHM`J+Gsd;)cWV(w`8WYx8$Qk5zhu@2Hu}MRq2Xc^`dh|uM-dC z_uQHBsh`+Co)0r>28;?JA2eh;kwRBNXZwHlv-seo2api<^ZGd{FCQLvZTvndyMFun zWAMV3qm+t2gGQ>wh{)U-bj3-Kp0W8eV;{Al5m|uxFrJJm{bRfL@NvZK z&wW6?g%r*#=6U>sXN2tpOfVMUqY>b7L1Q;}UsR5>54U6UaX| z8;G=;eRyG)RHg}qpqtzm$9OkDuWLWo{7SrU-9sfoE3qV&P6kEcyP0$;XbCuIAZVQ< zNHAJ6Ay|eOg>6aZh)$Ji<=T4v`f`@4{Ck!fRa6rTT@N`s5BxP`9s(erm`G&nPUGvtVNw3k24a)mwa-G%cnfz|Im^sWS zdEo;bdYKYJoH$fUMIrlfXgPI+B;t^Teh8U_Gjv}U4>c5}cffBcSD%N2o9T!?5(jhX ztiB8fgDJ{TgtrE$+>i$CbirWJ-u}SX$k?qm3K*8b3Bu4A%k65hPV+UM{X@{|NoOc3 zNaXPLVRD7;O}_P%$H8=kI{AWP_^Kf$vW%PV6~*b@wnNu)T3~vezFOXA(v8r+;&3M& z4|@Zu$r+xD!#k-w{1qIIr0MVjaF_NQU&n#tG;Orwz#qsSQH%py>D7p8!+^F`&FV&U zawCrhk5reI7Dq;gbxsPurXfKPO}-Y!I`2#CBVB-B@%5S(<5zCFV2VU3mD)}Ag#)KK z!X=Kt>3n3S2c}f~hzB$37~z37ebUJ<8}LQYieZjl>B#QF!QV)1L* z{yIUwzlLt*O{IL}k`zLeBC^`di&{xk>D@{08c`mSNwE zimSe2Dz&|YeOCI`)`h*T^l^+8dpYx%cI@T(T~dy{JUn(ge)*7c?bmp{8)BD06|IcT zTR5>}>^u1&4}p%ciS6`S>;_1n-q=)}2&egR7Mwszj9UiZ($2VJICYBd$L)b%(~kI! z#;K<`r7IfVe1(iHFBAw0}IxA0AhYb$UKF9MaP&w(kV-hY?N8$l^Map=h5`uZY+c*^PFn^l#gbILjN!kRZ zQqIz6aRsmfp=4`wtS&a<LP%(ta|T5LO*y)D{SDT?27NcEgR>FDQs z3OX9x2fvTxTaxjT_A@&_*6#_ee^~luRtunCM~huGaGboZGOPcRXB}gFNsI$Ie0Lu` zdiWo4qGJeOBKY4Sm-|Wd*HMK#3;jiO*=^POH}Jv(e;$49PC$Ps>2fUSS5tD%OXxo< zeUS4ezz+> z5Pl(*Z~8aD9@@Y8Fyu?4n;QY!H%mvh_9dD}MH$T$DF3qU7EEvaOY~R%AyrgtLw&Qd zv7C*3V+rbQ&2*=-2-|ujS5@^Qa-K-1Pfs0&bL46Wqml-*^7-G6-T=J~M*Wf5ueXoQ zv;aM7h|oVC%?i;a#W&V~z9+y1EBFnHLe)c8-!8>vtE3gD?Z`dsXiCvHDk`R$eO5T> icvDJ{n8;gIfC5dc^s}SKzbpK=B(nK3?54ivH~$OL01Kf2 diff --git a/pc-bios/s390-netboot.img b/pc-bios/s390-netboot.img index 682da24a05d3b13d9530fe1123b242e38109e1c3..6908e49f06801808b826d3a01f88132cf1b2f57c 100644 GIT binary patch delta 11001 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 delta 11064 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 QKDCiJCjPcw+gNP)Z{f56JOBUy