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
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJeZ6k3AAoJEBF7vIC1phx8MMIQAK6fvh7dhT9TRsA4U69Zu908
 6vK5Cxw/rEIdaA0qco+K+DOl+Ofp1sXP8Zof61db43oEXqtS2Pm0M8xbjANSVzJo
 7yRM75ZeLSJCxCFjVdzSZJK23N8CkF7ISuV5xan2AsDN+eXAVmPorGeNUzsA1jJS
 Pidb9l/flL4Cps6BXI8apqhnrre4stqC+5RsDp+mkc3mmtbvZKKKlf4i6rQ/RzAT
 MTC2lbzk+XOyeyiHZul8veulw3bdu1rYtCY8GaaB5BPryZFE8lCeIuvMV/umbMlH
 aS4vbrghg8n2WzB6sGkHSDsXiiShxSsr8yqPJM0SOzizFQP3AWAKUC8XArPTEaS8
 qzJP3i19Pfq/d9fFsgeU/F/tL2zc/7u3+tdKm2/I7FLKM1gzL6wtldBQ4kuQ1rmz
 2baCv1xYETbW4dcuCW2JCot98TrGhXioqeIeoZDSLt9trGlHhnVGEO7Vm8WP4bEm
 nWwXVR262xFw8zxOaQN8uPEes6TNQQS4fxutRICd63BJ4a3dNuvKpoKpVgzEbgrA
 YaQEVrmkiiMe/Ar0dQI+SVr/4xcRA8dYEGo29/xp83XvQwJBpB9cANti9WQQuP6l
 AlDjXyFudwNx5ADzTl8TAbdJ2JzFvPt64Ck9ixnx7qBAR/Tx93z61dFgD0h88VAX
 bq7/aeCaRuh+XSkLZIPt
 =bhfs
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2020-03-10 16:50:28 +00:00
commit ba29883206
9 changed files with 53 additions and 13 deletions

View File

@ -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)

View File

@ -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

Binary file not shown.

View File

@ -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) {

View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}