
From: Xiang Chen <chenxiang66@hisilicon.com> virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IBPH85 ------------------------------------------------------------------------ Only disable ICC_SGI1R_EL1 trap when enabled ipiv and set GICD_CTLR_nASSGIreq for register GICD_CTLR of virtual machine. Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com> --- arch/arm64/kvm/vgic/vgic-mmio-v3.c | 1 + drivers/irqchip/irq-gic-v3-its.c | 13 +++++++++++-- include/linux/irqchip/arm-gic-v4.h | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index e4c48e0baa6f..0edea419baf3 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -136,6 +136,7 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu, /* Switching HW SGIs? */ dist->nassgireq = val & GICD_CTLR_nASSGIreq; + dist->its_vm.nassgireq = dist->nassgireq; if (is_hwsgi != dist->nassgireq) vgic_v4_configure_vsgis(vcpu->kvm); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 72fe63f78952..49a2b3b050c5 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -4574,7 +4574,8 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe, u64 val = 0; u32 nr_vpes; - if (static_branch_unlikely(&ipiv_enable)) { + if (static_branch_unlikely(&ipiv_enable) && + vm->nassgireq) { /* wait gicr_ipiv_busy */ WARN_ON_ONCE(readl_relaxed_poll_timeout_atomic( vlpi_base + GICR_IPIV_ST, @@ -4606,6 +4607,12 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe, asm volatile("msr s3_4_c15_c7_2, %0" : : "r" (val)); asm volatile("mrs %0, s3_4_c15_c7_2" : "=r" (val)); + } else { + /* enable guest access ICC_SGI1R_EL1 trap, disable ipiv */ + asm volatile("mrs %0, s3_4_c15_c7_2" : "=r" (val)); + val &= ~1UL; + asm volatile("msr s3_4_c15_c7_2, %0" : : "r" (val)); + asm volatile("mrs %0, s3_4_c15_c7_2" : "=r" (val)); } /* Schedule the VPE */ @@ -4621,6 +4628,7 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe, struct its_cmd_info *info) { void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); + struct its_vm *vm = vpe->its_vm; u64 val; if (info->req_db) { @@ -4653,7 +4661,8 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe, vpe->pending_last = true; } - if (static_branch_unlikely(&ipiv_enable)) { + if (static_branch_unlikely(&ipiv_enable) && + vm->nassgireq) { if (!static_branch_unlikely(&ipiv_direct)) { /* wait gicr_ipiv_busy */ diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h index ea29e773d139..20a1f6b8f2ea 100644 --- a/include/linux/irqchip/arm-gic-v4.h +++ b/include/linux/irqchip/arm-gic-v4.h @@ -35,6 +35,7 @@ struct its_vm { */ raw_spinlock_t vmapp_lock; u32 vlpi_count[GICv4_ITS_LIST_MAX]; + bool nassgireq; }; /* Embedded in kvm_vcpu.arch */ -- 2.33.0