diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-03-10 16:50:28 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-03-10 16:50:28 +0000 |
commit | ba29883206d92a29ad5a466e679ccfc2ee6132ef (patch) | |
tree | 4a81cf63afe5dfbc38c001b951eff628461b10bb | |
parent | 7bc4d1980f95387c4cc921d7a066217ff4e42b70 (diff) | |
parent | 94c21436e5a89143f8b9cb4d089d1a2f3f4fd377 (diff) |
Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20200310' into staging
s390x/ipl: Fixes for ipl and bios
- provide a pointer to the loadparm. This fixes crashes in zipl
- do not throw away guest changes of the IPL parameter during reset
- refactor IPLB checks
# gpg: Signature made Tue 10 Mar 2020 14:50:31 GMT
# gpg: using RSA key 117BBC80B5A61C7C
# gpg: Good signature from "Christian Borntraeger (2nd IBM address) <borntraeger@linux.ibm.com>" [unknown]
# gpg: aka "Christian Borntraeger (IBM) <borntraeger@de.ibm.com>" [full]
# gpg: aka "Christian Borntraeger (kernel.org email address) <borntraeger@kernel.org>" [unknown]
# Primary key fingerprint: F922 9381 A334 08F9 DBAB FBCA 117B BC80 B5A6 1C7C
* remotes/borntraeger/tags/s390x-20200310:
s390x: ipl: Consolidate iplb validity check into one function
s390/ipl: sync back loadparm
s390x/bios: rebuild s390-ccw.img
pc-bios: s390x: Save iplb location in lowcore
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/s390x/ipl.c | 25 | ||||
-rw-r--r-- | hw/s390x/ipl.h | 18 | ||||
-rw-r--r-- | pc-bios/s390-ccw.img | bin | 42608 -> 42608 bytes | |||
-rw-r--r-- | pc-bios/s390-ccw/jump2ipl.c | 1 | ||||
-rw-r--r-- | pc-bios/s390-ccw/main.c | 8 | ||||
-rw-r--r-- | pc-bios/s390-ccw/netmain.c | 1 | ||||
-rw-r--r-- | pc-bios/s390-ccw/s390-arch.h | 10 | ||||
-rw-r--r-- | pc-bios/s390-ccw/s390-ccw.h | 1 | ||||
-rw-r--r-- | target/s390x/diag.c | 2 |
9 files changed, 53 insertions, 13 deletions
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 9c1ecd423c..b81942e1e6 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -538,6 +538,30 @@ static bool is_virtio_scsi_device(IplParameterBlock *iplb) return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI); } +static void update_machine_ipl_properties(IplParameterBlock *iplb) +{ + Object *machine = qdev_get_machine(); + Error *err = NULL; + + /* Sync loadparm */ + if (iplb->flags & DIAG308_FLAGS_LP_VALID) { + uint8_t *ebcdic_loadparm = iplb->loadparm; + char ascii_loadparm[8]; + int i; + + for (i = 0; i < 8 && ebcdic_loadparm[i]; i++) { + ascii_loadparm[i] = ebcdic2ascii[(uint8_t) ebcdic_loadparm[i]]; + } + ascii_loadparm[i] = 0; + object_property_set_str(machine, ascii_loadparm, "loadparm", &err); + } else { + object_property_set_str(machine, "", "loadparm", &err); + } + if (err) { + warn_report_err(err); + } +} + void s390_ipl_update_diag308(IplParameterBlock *iplb) { S390IPLState *ipl = get_ipl_device(); @@ -545,6 +569,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb) ipl->iplb = *iplb; ipl->iplb_valid = true; ipl->netboot = is_virtio_net_device(iplb); + update_machine_ipl_properties(iplb); } IplParameterBlock *s390_ipl_get_iplb(void) diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index d4813105db..3e44abe1c6 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -173,16 +173,16 @@ static inline bool iplb_valid_len(IplParameterBlock *iplb) return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock); } -static inline bool iplb_valid_ccw(IplParameterBlock *iplb) +static inline bool iplb_valid(IplParameterBlock *iplb) { - return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN && - iplb->pbt == S390_IPL_TYPE_CCW; -} - -static inline bool iplb_valid_fcp(IplParameterBlock *iplb) -{ - return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN && - iplb->pbt == S390_IPL_TYPE_FCP; + switch (iplb->pbt) { + case S390_IPL_TYPE_FCP: + return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN; + case S390_IPL_TYPE_CCW: + return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN; + default: + return false; + } } #endif diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img Binary files differindex 91cdee4436..b9da9d8ecb 100644 --- a/pc-bios/s390-ccw.img +++ b/pc-bios/s390-ccw.img diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c index da13c43cc0..4eba2510b0 100644 --- a/pc-bios/s390-ccw/jump2ipl.c +++ b/pc-bios/s390-ccw/jump2ipl.c @@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address) { /* store the subsystem information _after_ the bootmap was loaded */ write_subsystem_identification(); + write_iplb_location(); /* prevent unknown IPL types in the guest */ if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index a21b386280..4e65b411e1 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -9,6 +9,7 @@ */ #include "libc.h" +#include "helper.h" #include "s390-arch.h" #include "s390-ccw.h" #include "cio.h" @@ -22,7 +23,7 @@ QemuIplParameters qipl; IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); static bool have_iplb; static uint16_t cutype; -LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */ +LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */ #define LOADPARM_PROMPT "PROMPT " #define LOADPARM_EMPTY " " @@ -42,6 +43,11 @@ void write_subsystem_identification(void) *zeroes = 0; } +void write_iplb_location(void) +{ + lowcore->ptr_iplb = ptr2u32(&iplb); +} + void panic(const char *string) { sclp_print(string); diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c index f2dcc01e27..309ffa30d9 100644 --- a/pc-bios/s390-ccw/netmain.c +++ b/pc-bios/s390-ccw/netmain.c @@ -40,6 +40,7 @@ #define DEFAULT_TFTP_RETRIES 20 extern char _start[]; +void write_iplb_location(void) {} #define KERNEL_ADDR ((void *)0L) #define KERNEL_MAX_SIZE ((long)_start) diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h index 504fc7c2f0..5f36361c02 100644 --- a/pc-bios/s390-ccw/s390-arch.h +++ b/pc-bios/s390-ccw/s390-arch.h @@ -36,7 +36,13 @@ typedef struct LowCore { /* prefix area: defined by architecture */ PSWLegacy ipl_psw; /* 0x000 */ uint32_t ccw1[2]; /* 0x008 */ - uint32_t ccw2[2]; /* 0x010 */ + union { + uint32_t ccw2[2]; /* 0x010 */ + struct { + uint32_t reserved10; + uint32_t ptr_iplb; + }; + }; uint8_t pad1[0x80 - 0x18]; /* 0x018 */ uint32_t ext_params; /* 0x080 */ uint16_t cpu_addr; /* 0x084 */ @@ -85,7 +91,7 @@ typedef struct LowCore { PSW io_new_psw; /* 0x1f0 */ } __attribute__((packed, aligned(8192))) LowCore; -extern LowCore const *lowcore; +extern LowCore *lowcore; static inline void set_prefix(uint32_t address) { diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index 11bce7d73c..21f27e7990 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -57,6 +57,7 @@ void consume_io_int(void); /* main.c */ void panic(const char *string); 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); diff --git a/target/s390x/diag.c b/target/s390x/diag.c index b5aec06d6b..54e5670b3f 100644 --- a/target/s390x/diag.c +++ b/target/s390x/diag.c @@ -117,7 +117,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); - if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) { + if (!iplb_valid(iplb)) { env->regs[r1 + 1] = DIAG_308_RC_INVALID; goto out; } |