On 04/16/2018 01:13 PM, Pierre Morel wrote:
On 16/04/2018 12:51, Pierre Morel wrote:See patch #13. I guess the check above is anyway good as defensive
On 15/04/2018 23:22, Tony Krowiak wrote:If I misunderstood and FEAT_AP really mean AP instructions available in the guest,
The VFIO AP device model exploits interpretive execution of APDo we really need to test CPU_FEAT_AP?
instructions (APIE) to provide guests passthrough access to AP
devices. This patch introduces a new interface to enable and
disable APIE.
Signed-off-by: Tony Krowiak <akrowiak@xxxxxxxxxxxxxxxxxx>
---
arch/s390/include/asm/kvm-ap.h | 16 ++++++++++++++++
arch/s390/include/asm/kvm_host.h | 1 +
arch/s390/kvm/kvm-ap.c | 20 ++++++++++++++++++++
arch/s390/kvm/kvm-s390.c | 9 +++++++++
4 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/arch/s390/include/asm/kvm-ap.h b/arch/s390/include/asm/kvm-ap.h
index 736e93e..a6c092e 100644
--- a/arch/s390/include/asm/kvm-ap.h
+++ b/arch/s390/include/asm/kvm-ap.h
@@ -35,4 +35,20 @@
*/
void kvm_ap_build_crycbd(struct kvm *kvm);
+/**
+ * kvm_ap_interpret_instructions
+ *
+ * Indicate whether AP instructions shall be interpreted. If they are not
+ * interpreted, all AP instructions will be intercepted and routed back to
+ * userspace.
+ *
+ * @kvm: the virtual machine attributes
+ * @enable: indicates whether AP instructions are to be interpreted (true) or
+ * or not (false).
+ *
+ * Returns 0 if completed successfully; otherwise, returns -EOPNOTSUPP
+ * indicating that AP instructions are not installed on the guest.
+ */
+int kvm_ap_interpret_instructions(struct kvm *kvm, bool enable);
+
#endif /* _ASM_KVM_AP */
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 3162783..5470685 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -715,6 +715,7 @@ struct kvm_s390_crypto {
__u32 crycbd;
__u8 aes_kw;
__u8 dea_kw;
+ __u8 apie;
};
#define APCB0_MASK_SIZE 1
diff --git a/arch/s390/kvm/kvm-ap.c b/arch/s390/kvm/kvm-ap.c
index 991bae4..55d11b5 100644
--- a/arch/s390/kvm/kvm-ap.c
+++ b/arch/s390/kvm/kvm-ap.c
@@ -58,3 +58,23 @@ void kvm_ap_build_crycbd(struct kvm *kvm)
}
}
EXPORT_SYMBOL(kvm_ap_build_crycbd);
+
+int kvm_ap_interpret_instructions(struct kvm *kvm, bool enable)
+{
+ int ret = 0;
+
+ mutex_lock(&kvm->lock);
+
+ if (!test_kvm_cpu_feat(kvm, KVM_S390_VM_CPU_FEAT_AP)) {
I understand that KVM_S390_VM_CPU_FEAT_AP means AP instructions are interpreted.
shouldn't we add this information in the name?
like KVM_S390_VM_CPU_FEAT_APIE
same question:
is this function called if AP instructions are not available in the guest?
programming. This implementation should be sane regardless of
the answer to your question.
Yes, this function can be called with AP instructions available to the guest.sorry, I should have written AP instructions here:+ ret = -EOPNOTSUPP;Do we call xxx_crypto_setup() if KVM does not support AP interpretation?
+ goto done;
+ }
+
+ kvm->arch.crypto.apie = enable;
+ kvm_s390_vcpu_crypto_reset_all(kvm);
+
+done:
+ mutex_unlock(&kvm->lock);
+ return ret;
+}
+EXPORT_SYMBOL(kvm_ap_interpret_instructions);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 55cd897..1dc8566 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1901,6 +1901,9 @@ static void kvm_s390_crypto_init(struct kvm *kvm)
kvm->arch.crypto.crycb = &kvm->arch.sie_page2->crycb;
kvm_ap_build_crycbd(kvm);
+ /* Default setting indicating SIE shall interpret AP instructions */
+ kvm->arch.crypto.apie = 1;
+
if (!test_kvm_facility(kvm, 76))
return;
@@ -2434,6 +2437,12 @@ static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
{
vcpu->arch.sie_block->crycbd = vcpu->kvm->arch.crypto.crycbd;
+ vcpu->arch.sie_block->eca &= ~ECA_APIE;
+ if (vcpu->kvm->arch.crypto.apie &&
+ test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_AP))
is this function called if AP instructions are not available in the guest?
Please have a look at patch 2 (kvm_s390_vm_set_crypto and the rest).
Also this function is called on initialization regardless of AP instructions.
+ vcpu->arch.sie_block->eca |= ECA_APIE;
+
+
if (!test_kvm_facility(vcpu->kvm, 76))
return;