When QEMU is started with the option kernel_irqchip=òff, the kvm XICS
hcalls are being used even though a kvm XICS device has not been
created on the host, resulting quickly in a failure and a broken
guest.

The test checking if there is a XIVE device in the VM before executing
the XICS hcalls is missing from the recent XICS-over-XIVE glue.

Signed-off-by: Cédric Le Goater <c...@kaod.org>
---
 arch/powerpc/kvm/book3s_xive_template.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/powerpc/kvm/book3s_xive_template.c 
b/arch/powerpc/kvm/book3s_xive_template.c
index c7a5deadd1cc..7aa4e02df97c 100644
--- a/arch/powerpc/kvm/book3s_xive_template.c
+++ b/arch/powerpc/kvm/book3s_xive_template.c
@@ -276,11 +276,15 @@ static u32 GLUE(X_PFX,scan_interrupts)(struct 
kvmppc_xive_vcpu *xc,
 X_STATIC unsigned long GLUE(X_PFX,h_xirr)(struct kvm_vcpu *vcpu)
 {
        struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
+       struct kvmppc_xive *xive = vcpu->kvm->arch.xive;
        u8 old_cppr;
        u32 hirq;
 
        pr_devel("H_XIRR\n");
 
+       if (!xive)
+               return H_TOO_HARD;
+
        xc->GLUE(X_STAT_PFX,h_xirr)++;
 
        /* First collect pending bits from HW */
@@ -335,11 +339,15 @@ X_STATIC unsigned long GLUE(X_PFX,h_xirr)(struct kvm_vcpu 
*vcpu)
 X_STATIC unsigned long GLUE(X_PFX,h_ipoll)(struct kvm_vcpu *vcpu, unsigned 
long server)
 {
        struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
+       struct kvmppc_xive *xive = vcpu->kvm->arch.xive;
        u8 pending = xc->pending;
        u32 hirq;
 
        pr_devel("H_IPOLL(server=%ld)\n", server);
 
+       if (!xive)
+               return H_TOO_HARD;
+
        xc->GLUE(X_STAT_PFX,h_ipoll)++;
 
        /* Grab the target VCPU if not the current one */
@@ -388,8 +396,12 @@ static void GLUE(X_PFX,push_pending_to_hw)(struct 
kvmppc_xive_vcpu *xc)
 X_STATIC int GLUE(X_PFX,h_cppr)(struct kvm_vcpu *vcpu, unsigned long cppr)
 {
        struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
+       struct kvmppc_xive *xive = vcpu->kvm->arch.xive;
        u8 old_cppr;
 
+       if (!xive)
+               return H_TOO_HARD;
+
        pr_devel("H_CPPR(cppr=%ld)\n", cppr);
 
        xc->GLUE(X_STAT_PFX,h_cppr)++;
@@ -435,6 +447,9 @@ X_STATIC int GLUE(X_PFX,h_eoi)(struct kvm_vcpu *vcpu, 
unsigned long xirr)
        u16 src;
        int rc = 0;
 
+       if (!xive)
+               return H_TOO_HARD;
+
        pr_devel("H_EOI(xirr=%08lx)\n", xirr);
 
        xc->GLUE(X_STAT_PFX,h_eoi)++;
@@ -532,9 +547,13 @@ X_STATIC int GLUE(X_PFX,h_ipi)(struct kvm_vcpu *vcpu, 
unsigned long server,
                               unsigned long mfrr)
 {
        struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
+       struct kvmppc_xive *xive = vcpu->kvm->arch.xive;
 
        pr_devel("H_IPI(server=%08lx,mfrr=%ld)\n", server, mfrr);
 
+       if (!xive)
+               return H_TOO_HARD;
+
        xc->GLUE(X_STAT_PFX,h_ipi)++;
 
        /* Find target */
-- 
2.13.6

Reply via email to