diff options
author | Janosch Frank <frankja@linux.ibm.com> | 2020-03-23 04:36:06 -0400 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2020-04-29 14:30:54 +0200 |
commit | c3347ed0d2ee42a7dcf7bfe7f9c3884a9596727a (patch) | |
tree | f53ebc5ea6b896de2b8b63cbd34eac6941611737 /hw/s390x/ipl.c | |
parent | 9b39d29470e9dbef24ee842a44ea56bd92b855ea (diff) |
s390x: protvirt: Support unpack facility
The unpack facility provides the means to setup a protected guest. A
protected guest cannot 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 separately 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 <frankja@linux.ibm.com>
Co-developed-by: Christian Borntraeger <borntraeger@de.ibm.com> [Changes
to machine]
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20200323083606.24520-1-frankja@linux.ibm.com>
[CH: fixed up KVM_PV_VM_ -> KVM_PV_]
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'hw/s390x/ipl.c')
-rw-r--r-- | hw/s390x/ipl.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 8c3e019571..ce21494c08 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -1,10 +1,11 @@ /* * bootloader support * - * Copyright IBM, Corp. 2012 + * Copyright IBM, Corp. 2012, 2020 * * Authors: * Christian Borntraeger <borntraeger@de.ibm.com> + * Janosch Frank <frankja@linux.ibm.com> * * This work is licensed under the terms of the GNU GPL, version 2 or (at your * option) any later version. See the COPYING file in the top-level directory. @@ -27,6 +28,7 @@ #include "hw/s390x/vfio-ccw.h" #include "hw/s390x/css.h" #include "hw/s390x/ebcdic.h" +#include "hw/s390x/pv.h" #include "ipl.h" #include "qemu/error-report.h" #include "qemu/config-file.h" @@ -566,12 +568,31 @@ 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); update_machine_ipl_properties(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(); @@ -660,6 +681,38 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu) cpu_physical_memory_unmap(addr, len, 1, len); } +int s390_ipl_prepare_pv_header(void) +{ + IplParameterBlock *ipib = s390_ipl_get_iplb_pv(); + IPLBlockPV *ipib_pv = &ipib->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((uintptr_t)hdr, + ipib_pv->pv_header_len); + g_free(hdr); + return rc; +} + +int s390_ipl_pv_unpack(void) +{ + IplParameterBlock *ipib = s390_ipl_get_iplb_pv(); + IPLBlockPV *ipib_pv = &ipib->pv; + int i, rc = 0; + + 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(); |