KVM: PPC: Book3S: Enable XIVE native capability only if OPAL has required functions
authorPaul Mackerras <paulus@ozlabs.org>
Mon, 26 Aug 2019 06:21:21 +0000 (16:21 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 27 Aug 2019 01:45:49 +0000 (11:45 +1000)
There are some POWER9 machines where the OPAL firmware does not support
the OPAL_XIVE_GET_QUEUE_STATE and OPAL_XIVE_SET_QUEUE_STATE calls.
The impact of this is that a guest using XIVE natively will not be able
to be migrated successfully.  On the source side, the get_attr operation
on the KVM native device for the KVM_DEV_XIVE_GRP_EQ_CONFIG attribute
will fail; on the destination side, the set_attr operation for the same
attribute will fail.

This adds tests for the existence of the OPAL get/set queue state
functions, and if they are not supported, the XIVE-native KVM device
is not created and the KVM_CAP_PPC_IRQ_XIVE capability returns false.
Userspace can then either provide a software emulation of XIVE, or
else tell the guest that it does not have a XIVE controller available
to it.

Cc: stable@vger.kernel.org # v5.2+
Fixes: 3fab2d10588e ("KVM: PPC: Book3S HV: XIVE: Activate XIVE exploitation mode")
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/include/asm/xive.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s_xive_native.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/sysdev/xive/native.c

index 2484e6a8f5ca7a0fce8fb6a866e0b27984eb6b42..8e8514efb124394813e2a6ef09505f6491e86d76 100644 (file)
@@ -598,6 +598,7 @@ extern int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu,
                                     union kvmppc_one_reg *val);
 extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu,
                                     union kvmppc_one_reg *val);
+extern bool kvmppc_xive_native_supported(void);
 
 #else
 static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server,
index efb0e597b272554abeae16aa4b2c0450078542a5..818989e1167892f379cf2b4db16631dbb1ecf7aa 100644 (file)
@@ -135,6 +135,7 @@ extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle,
 extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle,
                                       u32 qindex);
 extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state);
+extern bool xive_native_has_queue_state_support(void);
 
 #else
 
index 9524d92bc45d69934944ab1b36236a32da72d382..d7fcdfa7fee40833a2b3d8fb586d6fa13fa34b3e 100644 (file)
@@ -1083,9 +1083,11 @@ static int kvmppc_book3s_init(void)
        if (xics_on_xive()) {
                kvmppc_xive_init_module();
                kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS);
-               kvmppc_xive_native_init_module();
-               kvm_register_device_ops(&kvm_xive_native_ops,
-                                       KVM_DEV_TYPE_XIVE);
+               if (kvmppc_xive_native_supported()) {
+                       kvmppc_xive_native_init_module();
+                       kvm_register_device_ops(&kvm_xive_native_ops,
+                                               KVM_DEV_TYPE_XIVE);
+               }
        } else
 #endif
                kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS);
index f0cab43e6f4bb57ec91c054360420ef174352184..248c1ea9e7881f2ebfc09f2149f5f7a4158ee413 100644 (file)
@@ -1179,6 +1179,11 @@ int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val)
        return 0;
 }
 
+bool kvmppc_xive_native_supported(void)
+{
+       return xive_native_has_queue_state_support();
+}
+
 static int xive_native_debug_show(struct seq_file *m, void *private)
 {
        struct kvmppc_xive *xive = m->private;
index 0dba7eb24f92072616460ae7cee6f90205025917..7012dd7097874317386c86a6995929feb69acf68 100644 (file)
@@ -566,7 +566,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                 * a POWER9 processor) and the PowerNV platform, as
                 * nested is not yet supported.
                 */
-               r = xive_enabled() && !!cpu_has_feature(CPU_FTR_HVMODE);
+               r = xive_enabled() && !!cpu_has_feature(CPU_FTR_HVMODE) &&
+                       kvmppc_xive_native_supported();
                break;
 #endif
 
index 2f26b74f6cfa66093b4e8aeb4a0cca6d257a154a..37987c815913a9f5a32e423e16d9ebf6791fa95d 100644 (file)
@@ -800,6 +800,13 @@ int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex)
 }
 EXPORT_SYMBOL_GPL(xive_native_set_queue_state);
 
+bool xive_native_has_queue_state_support(void)
+{
+       return opal_check_token(OPAL_XIVE_GET_QUEUE_STATE) &&
+               opal_check_token(OPAL_XIVE_SET_QUEUE_STATE);
+}
+EXPORT_SYMBOL_GPL(xive_native_has_queue_state_support);
+
 int xive_native_get_vp_state(u32 vp_id, u64 *out_state)
 {
        __be64 state;