pc-bios: s390x: Save iplb location in lowcore

The POP states that for a list directed IPL the IPLB is stored into
memory by the machine loader and its address is stored at offset 0x14
of the lowcore.

ZIPL currently uses the address in offset 0x14 to access the IPLB and
acquire flags about secure boot. If the IPLB address points into
memory which has an unsupported mix of flags set, ZIPL will panic
instead of booting the OS.

As the lowcore can have quite a high entropy for a guest that did drop
out of protected mode (i.e. rebooted) we encountered the ZIPL panic
quite often.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Message-Id: <20200304114231.23493-19-frankja@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
Janosch Frank 2020-03-04 06:42:31 -05:00 committed by Christian Borntraeger
parent 373c7068dd
commit 9bfc04f9ef
5 changed files with 18 additions and 3 deletions

View File

@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
{ {
/* store the subsystem information _after_ the bootmap was loaded */ /* store the subsystem information _after_ the bootmap was loaded */
write_subsystem_identification(); write_subsystem_identification();
write_iplb_location();
/* prevent unknown IPL types in the guest */ /* prevent unknown IPL types in the guest */
if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {

View File

@ -9,6 +9,7 @@
*/ */
#include "libc.h" #include "libc.h"
#include "helper.h"
#include "s390-arch.h" #include "s390-arch.h"
#include "s390-ccw.h" #include "s390-ccw.h"
#include "cio.h" #include "cio.h"
@ -22,7 +23,7 @@ QemuIplParameters qipl;
IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
static bool have_iplb; static bool have_iplb;
static uint16_t cutype; 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_PROMPT "PROMPT "
#define LOADPARM_EMPTY " " #define LOADPARM_EMPTY " "
@ -42,6 +43,11 @@ void write_subsystem_identification(void)
*zeroes = 0; *zeroes = 0;
} }
void write_iplb_location(void)
{
lowcore->ptr_iplb = ptr2u32(&iplb);
}
void panic(const char *string) void panic(const char *string)
{ {
sclp_print(string); sclp_print(string);

View File

@ -40,6 +40,7 @@
#define DEFAULT_TFTP_RETRIES 20 #define DEFAULT_TFTP_RETRIES 20
extern char _start[]; extern char _start[];
void write_iplb_location(void) {}
#define KERNEL_ADDR ((void *)0L) #define KERNEL_ADDR ((void *)0L)
#define KERNEL_MAX_SIZE ((long)_start) #define KERNEL_MAX_SIZE ((long)_start)

View File

@ -36,7 +36,13 @@ typedef struct LowCore {
/* prefix area: defined by architecture */ /* prefix area: defined by architecture */
PSWLegacy ipl_psw; /* 0x000 */ PSWLegacy ipl_psw; /* 0x000 */
uint32_t ccw1[2]; /* 0x008 */ uint32_t ccw1[2]; /* 0x008 */
union {
uint32_t ccw2[2]; /* 0x010 */ uint32_t ccw2[2]; /* 0x010 */
struct {
uint32_t reserved10;
uint32_t ptr_iplb;
};
};
uint8_t pad1[0x80 - 0x18]; /* 0x018 */ uint8_t pad1[0x80 - 0x18]; /* 0x018 */
uint32_t ext_params; /* 0x080 */ uint32_t ext_params; /* 0x080 */
uint16_t cpu_addr; /* 0x084 */ uint16_t cpu_addr; /* 0x084 */
@ -85,7 +91,7 @@ typedef struct LowCore {
PSW io_new_psw; /* 0x1f0 */ PSW io_new_psw; /* 0x1f0 */
} __attribute__((packed, aligned(8192))) LowCore; } __attribute__((packed, aligned(8192))) LowCore;
extern LowCore const *lowcore; extern LowCore *lowcore;
static inline void set_prefix(uint32_t address) static inline void set_prefix(uint32_t address)
{ {

View File

@ -57,6 +57,7 @@ void consume_io_int(void);
/* main.c */ /* main.c */
void panic(const char *string); void panic(const char *string);
void write_subsystem_identification(void); void write_subsystem_identification(void);
void write_iplb_location(void);
extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
unsigned int get_loadparm_index(void); unsigned int get_loadparm_index(void);