diff options
author | Paul Mackerras <paulus@ozlabs.org> | 2019-08-26 02:21:21 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@ozlabs.org> | 2019-08-26 21:45:49 -0400 |
commit | 2ad7a27deaf6d78545d97ab80874584f6990360e (patch) | |
tree | afadf8ab79c6a31384a9467761779a3d6dd80f57 | |
parent | d22deab6960a6cb015a36e74a2dcbab6ca9f5544 (diff) |
KVM: PPC: Book3S: Enable XIVE native capability only if OPAL has required functions
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>
-rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/xive.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_xive_native.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xive/native.c | 7 |
6 files changed, 21 insertions, 4 deletions
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 2484e6a8f5ca..8e8514efb124 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -598,6 +598,7 @@ extern int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu, | |||
598 | union kvmppc_one_reg *val); | 598 | union kvmppc_one_reg *val); |
599 | extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, | 599 | extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, |
600 | union kvmppc_one_reg *val); | 600 | union kvmppc_one_reg *val); |
601 | extern bool kvmppc_xive_native_supported(void); | ||
601 | 602 | ||
602 | #else | 603 | #else |
603 | static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server, | 604 | static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server, |
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index efb0e597b272..818989e11678 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h | |||
@@ -135,6 +135,7 @@ extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle, | |||
135 | extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle, | 135 | extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle, |
136 | u32 qindex); | 136 | u32 qindex); |
137 | extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state); | 137 | extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state); |
138 | extern bool xive_native_has_queue_state_support(void); | ||
138 | 139 | ||
139 | #else | 140 | #else |
140 | 141 | ||
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 9524d92bc45d..d7fcdfa7fee4 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -1083,9 +1083,11 @@ static int kvmppc_book3s_init(void) | |||
1083 | if (xics_on_xive()) { | 1083 | if (xics_on_xive()) { |
1084 | kvmppc_xive_init_module(); | 1084 | kvmppc_xive_init_module(); |
1085 | kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS); | 1085 | kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS); |
1086 | kvmppc_xive_native_init_module(); | 1086 | if (kvmppc_xive_native_supported()) { |
1087 | kvm_register_device_ops(&kvm_xive_native_ops, | 1087 | kvmppc_xive_native_init_module(); |
1088 | KVM_DEV_TYPE_XIVE); | 1088 | kvm_register_device_ops(&kvm_xive_native_ops, |
1089 | KVM_DEV_TYPE_XIVE); | ||
1090 | } | ||
1089 | } else | 1091 | } else |
1090 | #endif | 1092 | #endif |
1091 | kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS); | 1093 | kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS); |
diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index f0cab43e6f4b..248c1ea9e788 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c | |||
@@ -1179,6 +1179,11 @@ int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val) | |||
1179 | return 0; | 1179 | return 0; |
1180 | } | 1180 | } |
1181 | 1181 | ||
1182 | bool kvmppc_xive_native_supported(void) | ||
1183 | { | ||
1184 | return xive_native_has_queue_state_support(); | ||
1185 | } | ||
1186 | |||
1182 | static int xive_native_debug_show(struct seq_file *m, void *private) | 1187 | static int xive_native_debug_show(struct seq_file *m, void *private) |
1183 | { | 1188 | { |
1184 | struct kvmppc_xive *xive = m->private; | 1189 | struct kvmppc_xive *xive = m->private; |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 0dba7eb24f92..7012dd709787 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -566,7 +566,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
566 | * a POWER9 processor) and the PowerNV platform, as | 566 | * a POWER9 processor) and the PowerNV platform, as |
567 | * nested is not yet supported. | 567 | * nested is not yet supported. |
568 | */ | 568 | */ |
569 | r = xive_enabled() && !!cpu_has_feature(CPU_FTR_HVMODE); | 569 | r = xive_enabled() && !!cpu_has_feature(CPU_FTR_HVMODE) && |
570 | kvmppc_xive_native_supported(); | ||
570 | break; | 571 | break; |
571 | #endif | 572 | #endif |
572 | 573 | ||
diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 2f26b74f6cfa..37987c815913 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c | |||
@@ -800,6 +800,13 @@ int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex) | |||
800 | } | 800 | } |
801 | EXPORT_SYMBOL_GPL(xive_native_set_queue_state); | 801 | EXPORT_SYMBOL_GPL(xive_native_set_queue_state); |
802 | 802 | ||
803 | bool xive_native_has_queue_state_support(void) | ||
804 | { | ||
805 | return opal_check_token(OPAL_XIVE_GET_QUEUE_STATE) && | ||
806 | opal_check_token(OPAL_XIVE_SET_QUEUE_STATE); | ||
807 | } | ||
808 | EXPORT_SYMBOL_GPL(xive_native_has_queue_state_support); | ||
809 | |||
803 | int xive_native_get_vp_state(u32 vp_id, u64 *out_state) | 810 | int xive_native_get_vp_state(u32 vp_id, u64 *out_state) |
804 | { | 811 | { |
805 | __be64 state; | 812 | __be64 state; |