On 3/9/20 3:28 PM, Viktor Mihajlovski wrote: > > > On 3/9/20 12:21 PM, Janosch Frank wrote: >> The unpack facility provides the means to setup a protected guest. A >> protected guest can not be introspected by the hypervisor or any >> user/administrator of the machine it is running on. >> >> Protected guests are encrypted at rest and need a special boot >> mechanism via diag308 subcode 8 and 10. >> >> Code 8 sets the PV specific IPLB which is retained seperately from >> those set via code 5. >> >> Code 10 is used to unpack the VM into protected memory, verify its >> integrity and start it. >> >> Signed-off-by: Janosch Frank <fran...@linux.ibm.com> >> Signed-off-by: Christian Borntraeger <borntrae...@de.ibm.com> [Changes >> to machine] > A nit: [Changes...] should go before the s-o-b.
Will be changed anyway >> --- >> hw/s390x/Makefile.objs | 1 + >> hw/s390x/ipl.c | 59 ++++++++++++- >> hw/s390x/ipl.h | 72 ++++++++++++++-- >> hw/s390x/pv.c | 104 +++++++++++++++++++++++ >> hw/s390x/pv.h | 34 ++++++++ >> hw/s390x/s390-virtio-ccw.c | 127 +++++++++++++++++++++++++++- >> include/hw/s390x/s390-virtio-ccw.h | 1 + >> target/s390x/cpu.c | 17 ++++ >> target/s390x/cpu.h | 1 + >> target/s390x/cpu_features_def.inc.h | 1 + >> target/s390x/diag.c | 34 +++++++- >> 11 files changed, 436 insertions(+), 15 deletions(-) >> create mode 100644 hw/s390x/pv.c >> create mode 100644 hw/s390x/pv.h >> >> diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs >> index e02ed80b68..a46a1c7894 100644 >> --- a/hw/s390x/Makefile.objs >> +++ b/hw/s390x/Makefile.objs >> @@ -31,6 +31,7 @@ obj-y += tod-qemu.o >> obj-$(CONFIG_KVM) += tod-kvm.o >> obj-$(CONFIG_KVM) += s390-skeys-kvm.o >> obj-$(CONFIG_KVM) += s390-stattrib-kvm.o >> +obj-$(CONFIG_KVM) += pv.o >> obj-y += s390-ccw.o >> obj-y += ap-device.o >> obj-y += ap-bridge.o >> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c >> index 9c1ecd423c..ba3eac30c6 100644 >> --- a/hw/s390x/ipl.c >> +++ b/hw/s390x/ipl.c >> @@ -33,6 +33,7 @@ >> #include "qemu/cutils.h" >> #include "qemu/option.h" >> #include "exec/exec-all.h" >> +#include "pv.h" >> >> #define KERN_IMAGE_START 0x010000UL >> #define LINUX_MAGIC_ADDR 0x010008UL >> @@ -542,11 +543,30 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb) >> { >> S390IPLState *ipl = get_ipl_device(); >> >> - ipl->iplb = *iplb; >> - ipl->iplb_valid = true; >> + /* >> + * The IPLB set and retrieved by subcodes 8/9 is completely >> + * separate from the one managed via subcodes 5/6. >> + */ >> + if (iplb->pbt == S390_IPL_TYPE_PV) { >> + ipl->iplb_pv = *iplb; >> + ipl->iplb_valid_pv = true; >> + } else { >> + ipl->iplb = *iplb; >> + ipl->iplb_valid = true; >> + } >> ipl->netboot = is_virtio_net_device(iplb); >> } >> >> +IplParameterBlock *s390_ipl_get_iplb_pv(void) >> +{ >> + S390IPLState *ipl = get_ipl_device(); >> + >> + if (!ipl->iplb_valid_pv) { >> + return NULL; >> + } >> + return &ipl->iplb_pv; >> +} >> + >> IplParameterBlock *s390_ipl_get_iplb(void) >> { >> S390IPLState *ipl = get_ipl_device(); >> @@ -561,7 +581,8 @@ void s390_ipl_reset_request(CPUState *cs, enum >> s390_reset reset_type) >> { >> S390IPLState *ipl = get_ipl_device(); >> >> - if (reset_type == S390_RESET_EXTERNAL || reset_type == >> S390_RESET_REIPL) { >> + if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL >> || >> + reset_type == S390_RESET_PV) { >> /* use CPU 0 for full resets */ >> ipl->reset_cpu_index = 0; >> } else { >> @@ -635,6 +656,38 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu) >> cpu_physical_memory_unmap(addr, len, 1, len); >> } >> >> +int s390_ipl_prepare_pv_header(void) >> +{ >> + S390IPLState *ipl = get_ipl_device(); >> + IPLBlockPV *ipib_pv = &ipl->iplb_pv.pv; >> + void *hdr = g_malloc(ipib_pv->pv_header_len); >> + int rc; >> + >> + cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr, >> + ipib_pv->pv_header_len); >> + rc = s390_pv_set_sec_parms((uint64_t)hdr, >> + ipib_pv->pv_header_len); >> + g_free(hdr); >> + return rc; >> +} >> + >> +int s390_ipl_pv_unpack(void) >> +{ >> + int i, rc = 0; >> + S390IPLState *ipl = get_ipl_device(); >> + IPLBlockPV *ipib_pv = &ipl->iplb_pv.pv; >> + >> + for (i = 0; i < ipib_pv->num_comp; i++) { >> + rc = s390_pv_unpack(ipib_pv->components[i].addr, >> + TARGET_PAGE_ALIGN(ipib_pv->components[i].size), >> + ipib_pv->components[i].tweak_pref); >> + if (rc) { >> + break; >> + } >> + } >> + return rc; >> +} >> + >> void s390_ipl_prepare_cpu(S390CPU *cpu) >> { >> S390IPLState *ipl = get_ipl_device(); >> diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h >> index d4813105db..b2ccdd9dae 100644 >> --- a/hw/s390x/ipl.h >> +++ b/hw/s390x/ipl.h >> @@ -15,6 +15,24 @@ >> #include "cpu.h" >> #include "hw/qdev-core.h" >> >> +struct IPLBlockPVComp { >> + uint64_t tweak_pref; >> + uint64_t addr; >> + uint64_t size; >> +} QEMU_PACKED; >> +typedef struct IPLBlockPVComp IPLBlockPVComp; >> + >> +struct IPLBlockPV { >> + uint8_t reserved18[87]; /* 0x18 */ >> + uint8_t version; /* 0x6f */ >> + uint32_t reserved70; /* 0x70 */ >> + uint32_t num_comp; /* 0x70 */ > Another nit: offset should be 0x74 Ups >> + uint64_t pv_header_addr; /* 0x74 */ >> + uint64_t pv_header_len; /* 0x7c */ >> + struct IPLBlockPVComp components[]; >> +} QEMU_PACKED; >> +typedef struct IPLBlockPV IPLBlockPV; >> + >> struct IplBlockCcw { >> uint8_t reserved0[85]; >> uint8_t ssid;[...]
signature.asc
Description: OpenPGP digital signature