Message ID | 20190826081455.GA7402@blackberry (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: PPC: Book3S: Enable XIVE native capability only if OPAL has required functions | expand |
On Mon, Aug 26, 2019 at 06:14:55PM +1000, Paul Mackerras wrote: > 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. > > Signed-off-by: Paul Mackerras <paulus@ozlabs.org> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> > --- > arch/powerpc/include/asm/kvm_ppc.h | 1 + > arch/powerpc/include/asm/xive.h | 1 + > arch/powerpc/kvm/book3s.c | 8 +++++--- > arch/powerpc/kvm/book3s_xive_native.c | 5 +++++ > arch/powerpc/kvm/powerpc.c | 3 ++- > 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 2484e6a..8e8514e 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, > 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, > diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h > index efb0e59..818989e 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, > 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 > > diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c > index 9524d92..d7fcdfa 100644 > --- a/arch/powerpc/kvm/book3s.c > +++ b/arch/powerpc/kvm/book3s.c > @@ -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); > diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c > index f0cab43..248c1ea 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) > 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; > diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c > index 0dba7eb..7012dd7 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) > * 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 > > diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c > index 2f26b74..37987c8 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) > } > 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;
On 26/08/2019 10:14, Paul Mackerras wrote: > 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. > > Signed-off-by: Paul Mackerras <paulus@ozlabs.org> Reviewed-by: Cédric Le Goater <clg@kaod.org> Thanks, C. > --- > arch/powerpc/include/asm/kvm_ppc.h | 1 + > arch/powerpc/include/asm/xive.h | 1 + > arch/powerpc/kvm/book3s.c | 8 +++++--- > arch/powerpc/kvm/book3s_xive_native.c | 5 +++++ > arch/powerpc/kvm/powerpc.c | 3 ++- > 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 2484e6a..8e8514e 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, > 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, > diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h > index efb0e59..818989e 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, > 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 > > diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c > index 9524d92..d7fcdfa 100644 > --- a/arch/powerpc/kvm/book3s.c > +++ b/arch/powerpc/kvm/book3s.c > @@ -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); > diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c > index f0cab43..248c1ea 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) > 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; > diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c > index 0dba7eb..7012dd7 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) > * 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 > > diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c > index 2f26b74..37987c8 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) > } > 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; >
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 2484e6a..8e8514e 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, 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, diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index efb0e59..818989e 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, 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 diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 9524d92..d7fcdfa 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -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); diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index f0cab43..248c1ea 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) 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; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 0dba7eb..7012dd7 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) * 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 diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 2f26b74..37987c8 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) } 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;
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. Signed-off-by: Paul Mackerras <paulus@ozlabs.org> --- arch/powerpc/include/asm/kvm_ppc.h | 1 + arch/powerpc/include/asm/xive.h | 1 + arch/powerpc/kvm/book3s.c | 8 +++++--- arch/powerpc/kvm/book3s_xive_native.c | 5 +++++ arch/powerpc/kvm/powerpc.c | 3 ++- arch/powerpc/sysdev/xive/native.c | 7 +++++++ 6 files changed, 21 insertions(+), 4 deletions(-)