Loading arch/arm64/include/asm/kvm_emulate.h +1 −1 Original line number Diff line number Diff line Loading @@ -333,7 +333,7 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu) } else { u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); sctlr |= (1 << 25); vcpu_write_sys_reg(vcpu, SCTLR_EL1, sctlr); vcpu_write_sys_reg(vcpu, sctlr, SCTLR_EL1); } } Loading arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c +19 −5 Original line number Diff line number Diff line Loading @@ -18,11 +18,20 @@ #include <linux/compiler.h> #include <linux/irqchip/arm-gic.h> #include <linux/kvm_host.h> #include <linux/swab.h> #include <asm/kvm_emulate.h> #include <asm/kvm_hyp.h> #include <asm/kvm_mmu.h> static bool __hyp_text __is_be(struct kvm_vcpu *vcpu) { if (vcpu_mode_is_32bit(vcpu)) return !!(read_sysreg_el2(spsr) & COMPAT_PSR_E_BIT); return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE); } /* * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the * guest. Loading Loading @@ -64,14 +73,19 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) addr += fault_ipa - vgic->vgic_cpu_base; if (kvm_vcpu_dabt_iswrite(vcpu)) { u32 data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rd), sizeof(u32)); u32 data = vcpu_get_reg(vcpu, rd); if (__is_be(vcpu)) { /* guest pre-swabbed data, undo this for writel() */ data = swab32(data); } writel_relaxed(data, addr); } else { u32 data = readl_relaxed(addr); vcpu_set_reg(vcpu, rd, vcpu_data_host_to_guest(vcpu, data, sizeof(u32))); if (__is_be(vcpu)) { /* guest expects swabbed data */ data = swab32(data); } vcpu_set_reg(vcpu, rd, data); } return 1; Loading include/kvm/arm_vgic.h +1 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ struct vgic_irq { u32 mpidr; /* GICv3 target VCPU */ }; u8 source; /* GICv2 SGIs only */ u8 active_source; /* GICv2 SGIs only */ u8 priority; enum vgic_irq_config config; /* Level or edge */ Loading virt/kvm/arm/vgic/vgic-init.c +1 −1 Original line number Diff line number Diff line Loading @@ -423,7 +423,7 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data) * We cannot rely on the vgic maintenance interrupt to be * delivered synchronously. This means we can only use it to * exit the VM, and we perform the handling of EOIed * interrupts on the exit path (see vgic_process_maintenance). * interrupts on the exit path (see vgic_fold_lr_state). */ return IRQ_HANDLED; } Loading virt/kvm/arm/vgic/vgic-mmio.c +8 −2 Original line number Diff line number Diff line Loading @@ -289,10 +289,16 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, irq->vcpu->cpu != -1) /* VCPU thread is running */ cond_resched_lock(&irq->irq_lock); if (irq->hw) if (irq->hw) { vgic_hw_irq_change_active(vcpu, irq, active, !requester_vcpu); else } else { u32 model = vcpu->kvm->arch.vgic.vgic_model; irq->active = active; if (model == KVM_DEV_TYPE_ARM_VGIC_V2 && active && vgic_irq_is_sgi(irq->intid)) irq->active_source = requester_vcpu->vcpu_id; } if (irq->active) vgic_queue_irq_unlock(vcpu->kvm, irq, flags); Loading Loading
arch/arm64/include/asm/kvm_emulate.h +1 −1 Original line number Diff line number Diff line Loading @@ -333,7 +333,7 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu) } else { u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); sctlr |= (1 << 25); vcpu_write_sys_reg(vcpu, SCTLR_EL1, sctlr); vcpu_write_sys_reg(vcpu, sctlr, SCTLR_EL1); } } Loading
arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c +19 −5 Original line number Diff line number Diff line Loading @@ -18,11 +18,20 @@ #include <linux/compiler.h> #include <linux/irqchip/arm-gic.h> #include <linux/kvm_host.h> #include <linux/swab.h> #include <asm/kvm_emulate.h> #include <asm/kvm_hyp.h> #include <asm/kvm_mmu.h> static bool __hyp_text __is_be(struct kvm_vcpu *vcpu) { if (vcpu_mode_is_32bit(vcpu)) return !!(read_sysreg_el2(spsr) & COMPAT_PSR_E_BIT); return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE); } /* * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the * guest. Loading Loading @@ -64,14 +73,19 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) addr += fault_ipa - vgic->vgic_cpu_base; if (kvm_vcpu_dabt_iswrite(vcpu)) { u32 data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rd), sizeof(u32)); u32 data = vcpu_get_reg(vcpu, rd); if (__is_be(vcpu)) { /* guest pre-swabbed data, undo this for writel() */ data = swab32(data); } writel_relaxed(data, addr); } else { u32 data = readl_relaxed(addr); vcpu_set_reg(vcpu, rd, vcpu_data_host_to_guest(vcpu, data, sizeof(u32))); if (__is_be(vcpu)) { /* guest expects swabbed data */ data = swab32(data); } vcpu_set_reg(vcpu, rd, data); } return 1; Loading
include/kvm/arm_vgic.h +1 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ struct vgic_irq { u32 mpidr; /* GICv3 target VCPU */ }; u8 source; /* GICv2 SGIs only */ u8 active_source; /* GICv2 SGIs only */ u8 priority; enum vgic_irq_config config; /* Level or edge */ Loading
virt/kvm/arm/vgic/vgic-init.c +1 −1 Original line number Diff line number Diff line Loading @@ -423,7 +423,7 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data) * We cannot rely on the vgic maintenance interrupt to be * delivered synchronously. This means we can only use it to * exit the VM, and we perform the handling of EOIed * interrupts on the exit path (see vgic_process_maintenance). * interrupts on the exit path (see vgic_fold_lr_state). */ return IRQ_HANDLED; } Loading
virt/kvm/arm/vgic/vgic-mmio.c +8 −2 Original line number Diff line number Diff line Loading @@ -289,10 +289,16 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, irq->vcpu->cpu != -1) /* VCPU thread is running */ cond_resched_lock(&irq->irq_lock); if (irq->hw) if (irq->hw) { vgic_hw_irq_change_active(vcpu, irq, active, !requester_vcpu); else } else { u32 model = vcpu->kvm->arch.vgic.vgic_model; irq->active = active; if (model == KVM_DEV_TYPE_ARM_VGIC_V2 && active && vgic_irq_is_sgi(irq->intid)) irq->active_source = requester_vcpu->vcpu_id; } if (irq->active) vgic_queue_irq_unlock(vcpu->kvm, irq, flags); Loading