mirror of
https://github.com/qemu/qemu.git
synced 2024-12-14 15:03:33 +08:00
target/s390x: AP-passthrough for PV guests
Enabling AP-passthrough(AP-pt) for PV-guest by using the new CPU features for PV-AP-pt of KVM. As usual QEMU first checks which CPU features are available and then sets them if available and selected by user. An additional check is done to verify that PV-AP can only be enabled if "regular" AP-pt is enabled as well. Note that KVM itself does not enforce this restriction. Reviewed-by: Michael Mueller <mimu@linux.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Message-ID: <20230823142219.1046522-6-seiden@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
354383c122
commit
5ac951519c
@ -43,6 +43,7 @@ typedef enum {
|
||||
S390_FEAT_TYPE_KDSA,
|
||||
S390_FEAT_TYPE_SORTL,
|
||||
S390_FEAT_TYPE_DFLTCC,
|
||||
S390_FEAT_TYPE_UV_FEAT_GUEST,
|
||||
} S390FeatType;
|
||||
|
||||
/* Definition of a CPU feature */
|
||||
|
@ -379,3 +379,7 @@ DEF_FEAT(DEFLATE_GHDT, "dfltcc-gdht", DFLTCC, 1, "DFLTCC GDHT")
|
||||
DEF_FEAT(DEFLATE_CMPR, "dfltcc-cmpr", DFLTCC, 2, "DFLTCC CMPR")
|
||||
DEF_FEAT(DEFLATE_XPND, "dfltcc-xpnd", DFLTCC, 4, "DFLTCC XPND")
|
||||
DEF_FEAT(DEFLATE_F0, "dfltcc-f0", DFLTCC, 192, "DFLTCC format 0 parameter-block")
|
||||
|
||||
/* Features exposed via the UV-CALL instruction */
|
||||
DEF_FEAT(UV_FEAT_AP, "appv", UV_FEAT_GUEST, 4, "AP instructions installed for secure guests")
|
||||
DEF_FEAT(UV_FEAT_AP_INTR, "appvi", UV_FEAT_GUEST, 5, "AP instructions interruption support for secure guests")
|
||||
|
@ -483,6 +483,8 @@ static void check_consistency(const S390CPUModel *model)
|
||||
{ S390_FEAT_DIAG_318, S390_FEAT_EXTENDED_LENGTH_SCCB },
|
||||
{ S390_FEAT_NNPA, S390_FEAT_VECTOR },
|
||||
{ S390_FEAT_RDP, S390_FEAT_LOCAL_TLB_CLEARING },
|
||||
{ S390_FEAT_UV_FEAT_AP, S390_FEAT_AP },
|
||||
{ S390_FEAT_UV_FEAT_AP_INTR, S390_FEAT_UV_FEAT_AP },
|
||||
};
|
||||
int i;
|
||||
|
||||
|
@ -576,6 +576,8 @@ static uint16_t full_GEN16_GA1[] = {
|
||||
S390_FEAT_RDP,
|
||||
S390_FEAT_PAI,
|
||||
S390_FEAT_PAIE,
|
||||
S390_FEAT_UV_FEAT_AP,
|
||||
S390_FEAT_UV_FEAT_AP_INTR,
|
||||
};
|
||||
|
||||
|
||||
|
@ -2299,6 +2299,42 @@ static bool ap_enabled(const S390FeatBitmap features)
|
||||
return test_bit(S390_FEAT_AP, features);
|
||||
}
|
||||
|
||||
static bool uv_feat_supported(void)
|
||||
{
|
||||
return kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
|
||||
KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST);
|
||||
}
|
||||
|
||||
static int query_uv_feat_guest(S390FeatBitmap features)
|
||||
{
|
||||
struct kvm_s390_vm_cpu_uv_feat prop = {};
|
||||
struct kvm_device_attr attr = {
|
||||
.group = KVM_S390_VM_CPU_MODEL,
|
||||
.attr = KVM_S390_VM_CPU_MACHINE_UV_FEAT_GUEST,
|
||||
.addr = (uint64_t) &prop,
|
||||
};
|
||||
int rc;
|
||||
|
||||
/* AP support check is currently the only user of the UV feature test */
|
||||
if (!(uv_feat_supported() && ap_available())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (prop.ap) {
|
||||
set_bit(S390_FEAT_UV_FEAT_AP, features);
|
||||
}
|
||||
if (prop.ap_intr) {
|
||||
set_bit(S390_FEAT_UV_FEAT_AP_INTR, features);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_to_feat[][2] = {
|
||||
{ KVM_S390_VM_CPU_FEAT_ESOP, S390_FEAT_ESOP },
|
||||
{ KVM_S390_VM_CPU_FEAT_SIEF2, S390_FEAT_SIE_F2 },
|
||||
@ -2493,11 +2529,38 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
|
||||
set_bit(S390_FEAT_DIAG_318, model->features);
|
||||
}
|
||||
|
||||
/* Test for Ultravisor features that influence secure guest behavior */
|
||||
query_uv_feat_guest(model->features);
|
||||
|
||||
/* strip of features that are not part of the maximum model */
|
||||
bitmap_and(model->features, model->features, model->def->full_feat,
|
||||
S390_FEAT_MAX);
|
||||
}
|
||||
|
||||
static int configure_uv_feat_guest(const S390FeatBitmap features)
|
||||
{
|
||||
struct kvm_s390_vm_cpu_uv_feat uv_feat = {};
|
||||
struct kvm_device_attr attribute = {
|
||||
.group = KVM_S390_VM_CPU_MODEL,
|
||||
.attr = KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST,
|
||||
.addr = (__u64) &uv_feat,
|
||||
};
|
||||
|
||||
/* AP support check is currently the only user of the UV feature test */
|
||||
if (!(uv_feat_supported() && ap_enabled(features))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (test_bit(S390_FEAT_UV_FEAT_AP, features)) {
|
||||
uv_feat.ap = 1;
|
||||
}
|
||||
if (test_bit(S390_FEAT_UV_FEAT_AP_INTR, features)) {
|
||||
uv_feat.ap_intr = 1;
|
||||
}
|
||||
|
||||
return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attribute);
|
||||
}
|
||||
|
||||
static void kvm_s390_configure_apie(bool interpret)
|
||||
{
|
||||
uint64_t attr = interpret ? KVM_S390_VM_CRYPTO_ENABLE_APIE :
|
||||
@ -2561,6 +2624,13 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
|
||||
if (ap_enabled(model->features)) {
|
||||
kvm_s390_configure_apie(true);
|
||||
}
|
||||
|
||||
/* configure UV-features for the guest indicated via query / test_bit */
|
||||
rc = configure_uv_feat_guest(model->features);
|
||||
if (rc) {
|
||||
error_setg(errp, "KVM: Error configuring CPU UV features %d", rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_s390_restart_interrupt(S390CPU *cpu)
|
||||
|
Loading…
Reference in New Issue
Block a user