aboutsummaryrefslogtreecommitdiff
path: root/hw/s390x/ipl.c
diff options
context:
space:
mode:
authorJanosch Frank <frankja@linux.ibm.com>2020-03-23 04:36:06 -0400
committerCornelia Huck <cohuck@redhat.com>2020-04-29 14:30:54 +0200
commitc3347ed0d2ee42a7dcf7bfe7f9c3884a9596727a (patch)
treef53ebc5ea6b896de2b8b63cbd34eac6941611737 /hw/s390x/ipl.c
parent9b39d29470e9dbef24ee842a44ea56bd92b855ea (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.c59
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();