mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
genprotimg: boot: initial bootloader support
Add a boot loader for protected virtualization (PV) that can be combined with a kernel/initrd/parmfile to form a single bootable file. This file must be constructed in a way that it can be used (1) for a QEMU direct kernel boot and (2) it can be zipl'ed by the normal, unmodified zipl program. This new boot loader consists of two parts: 1. stage3a boot loader (cleartext), this loader is responsible for the transition into the protected mode by doing diag308 subcode 8 and 10 calls. 2. stage3b boot loader (encrypted), this loader is very similar to the normal zipl stage3 boot loader. It will be loaded by the Ultravisor after the successful transition into protected mode. Like the zipl stage3 boot loader it moves the kernel and patches in the values for initrd and parmline. The requirements for (1) and (2) result in the following constraints: 1. It must be possible to place stage3a and stage3b at a location >= 0x10000 because the zipl stage3 loader zeroes out everything at addresses lower than 0x10000 of the image. 2. As the stage3 loader of zipl assumes that the passed kernel image looks like a normal kernel image, the zipl stage3 loader modifies the content at the memory area 0x10400 - 0x10800, therefore we leave this area unused in our stage3a loader. 3. The default entry address used by the zipl stage3 loader is 0x10000 so we add a simple branch to 0x11000 at 0x10000 so the zipl stage3 loader can modify the area 0x10400 - 0x10800 without affecting the stage3a loader. The stage3b loader is linked at address 0x9000, therefore it will not work at another address. The relocation support for the stage3b loader, so that it can be placed at addresses != 0x9000, is added in the next patch. This loader with relocation support has the name 'stage3b_reloc'. The memory layout of the single bootable file looks like: +-----------------------+-----------+------------------------+ |Start |End |Use | +=======================+===========+========================+ |0 |0x7 |Short PSW, starting | | | |instruction at 0x11000 | +-----------------------+-----------+------------------------+ |0x10000 |0x10012 |Branch to 0x11000 | +-----------------------+-----------+------------------------+ |0x10013 |0x10fff |Left intentionally | | | |unused | +-----------------------+-----------+------------------------+ |0x11000 |0x12fff |Stage3a | +-----------------------+-----------+------------------------+ |0x13000 |0x13fff |IPIB used as argument | | | |for the diag308 call | +-----------------------+-----------+------------------------+ |0x14000 |0x1[45]fff |UV header used for the | | | |diag308 call (size can | | | |be either 1 or 2 pages) | +-----------------------+-----------+------------------------+ |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Kernel | +-----------------------+-----------+------------------------+ |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Cmdline | +-----------------------+-----------+------------------------+ |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Initrd | +-----------------------+-----------+------------------------+ |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Stage3b_reloc | +-----------------------+-----------+------------------------+ Reviewed-by: Philipp Rudo <prudo@linux.ibm.com> Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
67aef9bbf3
commit
3356d6f4fa
@@ -89,6 +89,30 @@ struct ipl_pb0_ccw {
|
||||
uint8_t reserved5[8];
|
||||
} __packed;
|
||||
|
||||
/* Structure must not have any padding */
|
||||
struct ipl_pb0_pv_comp {
|
||||
uint64_t tweak_pref;
|
||||
uint64_t addr;
|
||||
uint64_t len;
|
||||
};
|
||||
STATIC_ASSERT(sizeof(struct ipl_pb0_pv_comp) == 3 * 8)
|
||||
|
||||
/* IPL Parameter Block 0 for PV */
|
||||
struct ipl_pb0_pv {
|
||||
uint32_t len;
|
||||
uint8_t pbt;
|
||||
uint8_t reserved1[3];
|
||||
uint8_t loadparm[8];
|
||||
uint8_t reserved2[84];
|
||||
uint8_t reserved3[3];
|
||||
uint8_t version;
|
||||
uint8_t reserved4[4];
|
||||
uint32_t num_comp;
|
||||
uint64_t pv_hdr_addr;
|
||||
uint64_t pv_hdr_size;
|
||||
struct ipl_pb0_pv_comp components[];
|
||||
} __packed;
|
||||
|
||||
struct ipl_parameter_block {
|
||||
struct ipl_pl_hdr hdr;
|
||||
union {
|
||||
@@ -96,6 +120,7 @@ struct ipl_parameter_block {
|
||||
struct ipl_pb0_common common;
|
||||
struct ipl_pb0_fcp fcp;
|
||||
struct ipl_pb0_ccw ccw;
|
||||
struct ipl_pb0_pv pv;
|
||||
char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)];
|
||||
};
|
||||
} __packed __aligned(PAGE_SIZE);
|
||||
|
||||
+17
-5
@@ -18,6 +18,12 @@
|
||||
|
||||
#define PAGE_SIZE _AC(4096, UL)
|
||||
|
||||
/* Minimum size of a stack frame in bytes */
|
||||
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
||||
|
||||
/* Facilities */
|
||||
#define UNPACK_FACILITY _AC(161, U)
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
@@ -262,11 +268,17 @@ static __always_inline void __ctl_set_bit(unsigned int cr, unsigned int bit)
|
||||
* DIAG 308 support
|
||||
*/
|
||||
enum diag308_subcode {
|
||||
DIAG308_REL_HSA = 2,
|
||||
DIAG308_IPL = 3,
|
||||
DIAG308_DUMP = 4,
|
||||
DIAG308_SET = 5,
|
||||
DIAG308_STORE = 6,
|
||||
DIAG308_REL_HSA = 2,
|
||||
DIAG308_IPL = 3,
|
||||
DIAG308_DUMP = 4,
|
||||
DIAG308_SET = 5,
|
||||
DIAG308_STORE = 6,
|
||||
DIAG308_SET_PV = 8,
|
||||
DIAG308_UNPACK_PV = 10,
|
||||
};
|
||||
|
||||
enum diag308_rc {
|
||||
DIAG308_RC_OK = 0x0001,
|
||||
};
|
||||
|
||||
static __always_inline unsigned long diag308(unsigned long subcode, void *addr)
|
||||
|
||||
Reference in New Issue
Block a user