Commit 2ad7a27d authored by Paul Mackerras's avatar Paul Mackerras

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: 3fab2d10 ("KVM: PPC: Book3S HV: XIVE: Activate XIVE exploitation mode")
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Reviewed-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent d22deab6
...@@ -598,6 +598,7 @@ extern int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu, ...@@ -598,6 +598,7 @@ extern int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu,
union kvmppc_one_reg *val); union kvmppc_one_reg *val);
extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu,
union kvmppc_one_reg *val); union kvmppc_one_reg *val);
extern bool kvmppc_xive_native_supported(void);
#else #else
static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server, static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server,
......
...@@ -135,6 +135,7 @@ extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle, ...@@ -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, extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle,
u32 qindex); u32 qindex);
extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state); extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state);
extern bool xive_native_has_queue_state_support(void);
#else #else
......
...@@ -1083,9 +1083,11 @@ static int kvmppc_book3s_init(void) ...@@ -1083,9 +1083,11 @@ static int kvmppc_book3s_init(void)
if (xics_on_xive()) { if (xics_on_xive()) {
kvmppc_xive_init_module(); kvmppc_xive_init_module();
kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS); kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS);
kvmppc_xive_native_init_module(); if (kvmppc_xive_native_supported()) {
kvm_register_device_ops(&kvm_xive_native_ops, kvmppc_xive_native_init_module();
KVM_DEV_TYPE_XIVE); kvm_register_device_ops(&kvm_xive_native_ops,
KVM_DEV_TYPE_XIVE);
}
} else } else
#endif #endif
kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS); kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS);
......
...@@ -1179,6 +1179,11 @@ int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val) ...@@ -1179,6 +1179,11 @@ int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val)
return 0; 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) static int xive_native_debug_show(struct seq_file *m, void *private)
{ {
struct kvmppc_xive *xive = m->private; struct kvmppc_xive *xive = m->private;
......
...@@ -566,7 +566,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) ...@@ -566,7 +566,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
* a POWER9 processor) and the PowerNV platform, as * a POWER9 processor) and the PowerNV platform, as
* nested is not yet supported. * 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; break;
#endif #endif
......
...@@ -800,6 +800,13 @@ int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex) ...@@ -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); 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) int xive_native_get_vp_state(u32 vp_id, u64 *out_state)
{ {
__be64 state; __be64 state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment