From: Janosch Frank <frankja@linux.ibm.com>
To: qemu-devel@nongnu.org
Cc: mihajlov@linux.ibm.com, qemu-s390x@nongnu.org, cohuck@redhat.com,
david@redhat.com
Subject: [PATCH v3 04/17] s390x: protvirt: Add diag308 subcodes 8 - 10
Date: Fri, 14 Feb 2020 10:16:23 -0500 [thread overview]
Message-ID: <20200214151636.8764-5-frankja@linux.ibm.com> (raw)
In-Reply-To: <20200214151636.8764-1-frankja@linux.ibm.com>
For diag308 subcodes 8 - 10 we have a new ipib of type 5. The ipib
holds the address and length of the secure execution header, as well
as a list of guest components.
Each component is a block of memory, for example kernel or initrd,
which needs to be decrypted by the Ultravisor in order to run a
protected VM. The secure execution header instructs the Ultravisor on
how to handle the protected VM and its components.
Subcodes 8 and 9 are similiar to 5 and 6 and subcode 10 will finally
start the protected guest.
Subcodes 8-10 are not valid in protected mode, we have to do a subcode
3 and then the 8 and 10 combination for a protected reboot.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
hw/s390x/ipl.c | 48 ++++++++++++++++++++++++++++++++++++++++++---
hw/s390x/ipl.h | 31 +++++++++++++++++++++++++++++
target/s390x/diag.c | 27 ++++++++++++++++++++++---
3 files changed, 100 insertions(+), 6 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 7773499d7f..db97a888ff 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -538,15 +538,56 @@ static bool is_virtio_scsi_device(IplParameterBlock *iplb)
return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
}
+int s390_ipl_pv_check_components(IplParameterBlock *iplb)
+{
+ int i;
+ IPLBlockPV *ipib_pv = &iplb->pv;
+
+ if (ipib_pv->num_comp == 0) {
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ipib_pv->num_comp; i++) {
+
+ /* Addr must be 4k aligned */
+ if (ipib_pv->components[i].addr & ~TARGET_PAGE_MASK) {
+ return -EINVAL;
+ }
+
+ /* Tweak prefix is monotonously increasing with each component */
+ if (i < ipib_pv->num_comp - 1 &&
+ ipib_pv->components[i].tweak_pref >
+ ipib_pv->components[i + 1].tweak_pref) {
+ return -EINVAL;
+ }
+ }
+ return 1;
+}
+
void s390_ipl_update_diag308(IplParameterBlock *iplb)
{
S390IPLState *ipl = get_ipl_device();
- ipl->iplb = *iplb;
- ipl->iplb_valid = true;
+ if (iplb->pbt == 5) {
+ ipl->iplb_pbt5 = *iplb;
+ ipl->iplb_valid_pbt5 = true;
+ } else {
+ ipl->iplb = *iplb;
+ ipl->iplb_valid = true;
+ }
ipl->netboot = is_virtio_net_device(iplb);
}
+IplParameterBlock *s390_ipl_get_iplb_secure(void)
+{
+ S390IPLState *ipl = get_ipl_device();
+
+ if (!ipl->iplb_valid_pbt5) {
+ return NULL;
+ }
+ return &ipl->iplb_pbt5;
+}
+
IplParameterBlock *s390_ipl_get_iplb(void)
{
S390IPLState *ipl = get_ipl_device();
@@ -561,7 +602,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 {
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index d4813105db..d0b8d90fa4 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -15,6 +15,23 @@
#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 reserved[87];
+ uint8_t version;
+ uint32_t num_comp;
+ uint64_t pv_header_addr;
+ uint64_t pv_header_len;
+ struct IPLBlockPVComp components[];
+} QEMU_PACKED;
+typedef struct IPLBlockPV IPLBlockPV;
+
struct IplBlockCcw {
uint8_t reserved0[85];
uint8_t ssid;
@@ -71,6 +88,7 @@ union IplParameterBlock {
union {
IplBlockCcw ccw;
IplBlockFcp fcp;
+ IPLBlockPV pv;
IplBlockQemuScsi scsi;
};
} QEMU_PACKED;
@@ -84,9 +102,11 @@ union IplParameterBlock {
typedef union IplParameterBlock IplParameterBlock;
int s390_ipl_set_loadparm(uint8_t *loadparm);
+int s390_ipl_pv_check_components(IplParameterBlock *iplb);
void s390_ipl_update_diag308(IplParameterBlock *iplb);
void s390_ipl_prepare_cpu(S390CPU *cpu);
IplParameterBlock *s390_ipl_get_iplb(void);
+IplParameterBlock *s390_ipl_get_iplb_secure(void);
enum s390_reset {
/* default is a reset not triggered by a CPU e.g. issued by QMP */
@@ -94,6 +114,7 @@ enum s390_reset {
S390_RESET_REIPL,
S390_RESET_MODIFIED_CLEAR,
S390_RESET_LOAD_NORMAL,
+ S390_RESET_PV,
};
void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type);
void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type);
@@ -133,6 +154,7 @@ struct S390IPLState {
/*< private >*/
DeviceState parent_obj;
IplParameterBlock iplb;
+ IplParameterBlock iplb_pbt5;
QemuIplParameters qipl;
uint64_t start_addr;
uint64_t compat_start_addr;
@@ -140,6 +162,7 @@ struct S390IPLState {
uint64_t compat_bios_start_addr;
bool enforce_bios;
bool iplb_valid;
+ bool iplb_valid_pbt5;
bool netboot;
/* reset related properties don't have to be migrated or reset */
enum s390_reset reset_type;
@@ -161,9 +184,11 @@ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
#define S390_IPL_TYPE_FCP 0x00
#define S390_IPL_TYPE_CCW 0x02
+#define S390_IPL_TYPE_PV 0x05
#define S390_IPL_TYPE_QEMU_SCSI 0xff
#define S390_IPLB_HEADER_LEN 8
+#define S390_IPLB_MIN_PV_LEN 148
#define S390_IPLB_MIN_CCW_LEN 200
#define S390_IPLB_MIN_FCP_LEN 384
#define S390_IPLB_MIN_QEMU_SCSI_LEN 200
@@ -185,4 +210,10 @@ static inline bool iplb_valid_fcp(IplParameterBlock *iplb)
iplb->pbt == S390_IPL_TYPE_FCP;
}
+static inline bool iplb_valid_pv(IplParameterBlock *iplb)
+{
+ return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_PV_LEN &&
+ iplb->pbt == S390_IPL_TYPE_PV;
+}
+
#endif
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index b5aec06d6b..4ba6033609 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -52,6 +52,8 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
#define DIAG_308_RC_OK 0x0001
#define DIAG_308_RC_NO_CONF 0x0102
#define DIAG_308_RC_INVALID 0x0402
+#define DIAG_308_RC_NO_PV_CONF 0x0a02
+#define DIAG_308_RC_INV_FOR_PV 0x0b02
#define DIAG308_RESET_MOD_CLR 0
#define DIAG308_RESET_LOAD_NORM 1
@@ -59,6 +61,9 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
#define DIAG308_LOAD_NORMAL_DUMP 4
#define DIAG308_SET 5
#define DIAG308_STORE 6
+#define DIAG308_PV_SET 8
+#define DIAG308_PV_STORE 9
+#define DIAG308_PV_START 10
static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
uintptr_t ra, bool write)
@@ -105,6 +110,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
s390_ipl_reset_request(cs, S390_RESET_REIPL);
break;
case DIAG308_SET:
+ case DIAG308_PV_SET:
if (diag308_parm_check(env, r1, addr, ra, false)) {
return;
}
@@ -117,7 +123,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
- if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {
+ if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb) &&
+ !(iplb_valid_pv(iplb) && s390_ipl_pv_check_components(iplb) >= 0)) {
env->regs[r1 + 1] = DIAG_308_RC_INVALID;
goto out;
}
@@ -128,17 +135,31 @@ out:
g_free(iplb);
return;
case DIAG308_STORE:
+ case DIAG308_PV_STORE:
if (diag308_parm_check(env, r1, addr, ra, true)) {
return;
}
- iplb = s390_ipl_get_iplb();
+ if (subcode == DIAG308_PV_STORE) {
+ iplb = s390_ipl_get_iplb_secure();
+ } else {
+ iplb = s390_ipl_get_iplb();
+ }
if (iplb) {
cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
env->regs[r1 + 1] = DIAG_308_RC_OK;
} else {
env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
}
- return;
+ break;
+ case DIAG308_PV_START:
+ iplb = s390_ipl_get_iplb_secure();
+ if (!iplb || !iplb_valid_pv(iplb)) {
+ env->regs[r1 + 1] = DIAG_308_RC_NO_PV_CONF;
+ return;
+ }
+
+ s390_ipl_reset_request(cs, S390_RESET_PV);
+ break;
default:
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
break;
--
2.20.1
next prev parent reply other threads:[~2020-02-14 15:21 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-14 15:16 [PATCH v3 00/17] s390x: Protected Virtualization support Janosch Frank
2020-02-14 15:16 ` [PATCH v3 01/17] Header sync Janosch Frank
2020-02-14 15:16 ` [PATCH v3 02/17] s390x: Add missing vcpu reset functions Janosch Frank
2020-02-18 12:29 ` Cornelia Huck
2020-02-18 13:12 ` Janosch Frank
2020-02-18 17:17 ` Cornelia Huck
2020-02-14 15:16 ` [PATCH v3 03/17] Sync pv Janosch Frank
2020-02-14 15:16 ` Janosch Frank [this message]
2020-02-20 10:07 ` [PATCH v3 04/17] s390x: protvirt: Add diag308 subcodes 8 - 10 Cornelia Huck
2020-02-20 11:06 ` Janosch Frank
2020-02-14 15:16 ` [PATCH v3 05/17] s390x: protvirt: Support unpack facility Janosch Frank
2020-02-20 10:39 ` Cornelia Huck
2020-02-20 11:21 ` Janosch Frank
2020-02-14 15:16 ` [PATCH v3 06/17] s390x: protvirt: Add migration blocker Janosch Frank
2020-02-20 10:48 ` Cornelia Huck
2020-02-20 11:24 ` Janosch Frank
2020-02-20 11:39 ` Cornelia Huck
2020-02-20 11:42 ` Janosch Frank
2020-02-14 15:16 ` [PATCH v3 07/17] s390x: protvirt: Handle diag 308 subcodes 0,1,3,4 Janosch Frank
2020-02-14 15:16 ` [PATCH v3 08/17] s390x: protvirt: KVM intercept changes Janosch Frank
2020-02-14 15:16 ` [PATCH v3 09/17] s390: protvirt: Move STSI data over SIDAD Janosch Frank
2020-02-20 10:54 ` Cornelia Huck
2020-02-20 11:25 ` Janosch Frank
2020-02-14 15:16 ` [PATCH v3 10/17] s390x: Add SIDA memory ops Janosch Frank
2020-02-14 15:16 ` [PATCH v3 11/17] s390x: protvirt: SCLP interpretation Janosch Frank
2020-02-14 15:16 ` [PATCH v3 12/17] s390x: protvirt: Set guest IPL PSW Janosch Frank
2020-02-14 15:16 ` [PATCH v3 13/17] s390x: protvirt: Move diag 308 data over SIDAD Janosch Frank
2020-02-20 11:00 ` Cornelia Huck
2020-02-20 11:29 ` Janosch Frank
2020-02-14 15:16 ` [PATCH v3 14/17] s390x: protvirt: Disable address checks for PV guest IO emulation Janosch Frank
2020-02-14 15:16 ` [PATCH v3 15/17] s390x: protvirt: Move IO control structures over SIDA Janosch Frank
2020-02-14 15:16 ` [PATCH v3 16/17] s390x: protvirt: Handle SIGP store status correctly Janosch Frank
2020-02-20 11:02 ` Cornelia Huck
2020-02-20 11:30 ` Janosch Frank
2020-02-20 11:34 ` Cornelia Huck
2020-02-14 15:16 ` [PATCH v3 17/17] s390x: For now add unpack feature to GA1 Janosch Frank
2020-02-14 16:33 ` [PATCH v3 00/17] s390x: Protected Virtualization support no-reply
2020-02-18 13:13 ` Cornelia Huck
2020-02-18 13:15 ` Janosch Frank
2020-02-18 13:24 ` Cornelia Huck
2020-02-18 13:56 ` Janosch Frank
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200214151636.8764-5-frankja@linux.ibm.com \
--to=frankja@linux.ibm.com \
--cc=cohuck@redhat.com \
--cc=david@redhat.com \
--cc=mihajlov@linux.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.