From d7138f8489995b2f16fe76c7c8d705d397bab211 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Wed, 20 Aug 2025 22:51:14 +0800 Subject: [PATCH 1/4] LoongArch: KVM: Make function kvm_own_lbt() robust commit 4be8cefc132606b4a6e851f37f8e8c40c406c910 upstream Add the flag KVM_LARCH_LBT checking in function kvm_own_lbt(), so that it can be called safely rather than duplicated enabling again. Signed-off-by: Bibo Mao Signed-off-by: Huacai Chen Signed-off-by: Xianglai Li Signed-off-by: Kanglong Wang --- arch/loongarch/kvm/vcpu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index c20d9dc0f52c..8b30abccd9c1 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1253,9 +1253,11 @@ int kvm_own_lbt(struct kvm_vcpu *vcpu) return -EINVAL; preempt_disable(); - set_csr_euen(CSR_EUEN_LBTEN); - _restore_lbt(&vcpu->arch.lbt); - vcpu->arch.aux_inuse |= KVM_LARCH_LBT; + if (!(vcpu->arch.aux_inuse & KVM_LARCH_LBT)) { + set_csr_euen(CSR_EUEN_LBTEN); + _restore_lbt(&vcpu->arch.lbt); + vcpu->arch.aux_inuse |= KVM_LARCH_LBT; + } preempt_enable(); return 0; -- Gitee From 289f42f1de15d12e1ef03ee8327938f61342a622 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Wed, 20 Aug 2025 22:51:15 +0800 Subject: [PATCH 2/4] LoongArch: KVM: Fix stack protector issue in send_ipi_data() commit 5c68549c81bcca70fc464e305ffeefd9af968287 upstream Function kvm_io_bus_read() is called in function send_ipi_data(), buffer size of parameter *val should be at least 8 bytes. Since some emulation functions like loongarch_ipi_readl() and kvm_eiointc_read() will write the buffer *val with 8 bytes signed extension regardless parameter len. Otherwise there will be buffer overflow issue when CONFIG_STACKPROTECTOR is enabled. The bug report is shown as follows: Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: send_ipi_data+0x194/0x1a0 [kvm] CPU: 11 UID: 107 PID: 2692 Comm: CPU 0/KVM Not tainted 6.17.0-rc1+ #102 PREEMPT(full) Stack : 9000000005901568 0000000000000000 9000000003af371c 900000013c68c000 900000013c68f850 900000013c68f858 0000000000000000 900000013c68f998 900000013c68f990 900000013c68f990 900000013c68f6c0 fffffffffffdb058 fffffffffffdb0e0 900000013c68f858 911e1d4d39cf0ec2 9000000105657a00 0000000000000001 fffffffffffffffe 0000000000000578 282049464555206e 6f73676e6f6f4c20 0000000000000001 00000000086b4000 0000000000000000 0000000000000000 0000000000000000 9000000005709968 90000000058f9000 900000013c68fa68 900000013c68fab4 90000000029279f0 900000010153f940 900000010001f360 0000000000000000 9000000003af3734 000000004390000c 00000000000000b0 0000000000000004 0000000000000000 0000000000071c1d ... Call Trace: [<9000000003af3734>] show_stack+0x5c/0x180 [<9000000003aed168>] dump_stack_lvl+0x6c/0x9c [<9000000003ad0ab0>] vpanic+0x108/0x2c4 [<9000000003ad0ca8>] panic+0x3c/0x40 [<9000000004eb0a1c>] __stack_chk_fail+0x14/0x18 [] send_ipi_data+0x190/0x1a0 [kvm] [] __kvm_io_bus_write+0xa4/0xe8 [kvm] [] kvm_io_bus_write+0x54/0x90 [kvm] [] kvm_emu_iocsr+0x180/0x310 [kvm] [] kvm_handle_gspr+0x280/0x478 [kvm] [] kvm_handle_exit+0xc0/0x130 [kvm] Fixes: daee2f9cae55 ("LoongArch: KVM: Add IPI read and write function") Signed-off-by: Bibo Mao Signed-off-by: Huacai Chen Signed-off-by: Xianglai Li Signed-off-by: Kanglong Wang --- arch/loongarch/kvm/intc/ipi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c index 9c68b9aee128..b9e9d70ad9ee 100644 --- a/arch/loongarch/kvm/intc/ipi.c +++ b/arch/loongarch/kvm/intc/ipi.c @@ -226,14 +226,14 @@ static int kvm_loongarch_ipi_read(struct kvm_vcpu *vcpu, static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) { int i, ret; - uint32_t val = 0, mask = 0; + uint64_t val = 0, mask = 0; /* * Bit 27-30 is mask for byte writing. * If the mask is 0, we need not to do anything. */ if ((data >> 27) & 0xf) { /* Read the old val */ - ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); + ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, 4, &val); if (unlikely(ret)) { kvm_err("%s: : read date from addr %llx failed\n", __func__, addr); return ret; @@ -248,7 +248,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) } val |= ((uint32_t)(data >> 32) & ~mask); - ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); + ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, 4, &val); if (unlikely(ret)) kvm_err("%s: : write date to addr %llx failed\n", __func__, addr); -- Gitee From 393db144d2e3984fffdaec5227bb8dbd3ddcd3f3 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Wed, 20 Aug 2025 22:51:15 +0800 Subject: [PATCH 3/4] LoongArch: KVM: Use kvm_get_vcpu_by_id() instead of kvm_get_vcpu() commit 0dfd9ea7bf80fabe11f5b775d762a5cd168cdf41 upstream Since using kvm_get_vcpu() may fail to retrieve the vCPU context, kvm_get_vcpu_by_id() should be used instead. Fixes: 8e3054261bc3 ("LoongArch: KVM: Add IPI user mode read and write function") Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions") Reviewed-by: Yanteng Si Signed-off-by: Song Gao Signed-off-by: Huacai Chen Signed-off-by: Xianglai Li Signed-off-by: Kanglong Wang --- arch/loongarch/kvm/intc/extioi.c | 7 +++---- arch/loongarch/kvm/intc/ipi.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/loongarch/kvm/intc/extioi.c b/arch/loongarch/kvm/intc/extioi.c index 8b3ba649fb68..96bd8d89f2ac 100644 --- a/arch/loongarch/kvm/intc/extioi.c +++ b/arch/loongarch/kvm/intc/extioi.c @@ -29,12 +29,11 @@ static void extioi_update_irq(struct loongarch_extioi *s, int irq, int level) ipnum = (ipnum >= 0 && ipnum < LS3A_INTC_IP) ? ipnum : 0; cpu = s->sw_coremap[irq]; - vcpu = kvm_get_vcpu(s->kvm, cpu); + vcpu = kvm_get_vcpu_by_id(s->kvm, cpu); if (vcpu == NULL) { kvm_info("%s irq %d vcpu %d don't exist\n", __func__, irq, cpu); return; } - irq_index = irq / 32; /* length of accessing core isr is 4 bytes */ irq_mask = 1 << (irq & 0x1f); @@ -84,7 +83,7 @@ static void extioi_set_sw_coreisr(struct loongarch_extioi *s) cpu = (cpu >= 4) ? 0 : cpu; } - vcpu = kvm_get_vcpu(s->kvm, cpu); + vcpu = kvm_get_vcpu_by_id(s->kvm, cpu); if ((!vcpu) || (vcpu->vcpu_id != cpu)) cpu = 0; @@ -143,7 +142,7 @@ static inline void extioi_update_sw_coremap(struct loongarch_extioi *s, cpu = (cpu >= 4) ? 0 : cpu; } - vcpu = kvm_get_vcpu(s->kvm, cpu); + vcpu = kvm_get_vcpu_by_id(s->kvm, cpu); if ((!vcpu) || (vcpu->vcpu_id != cpu)) { cpu = 0; kvm_info("Warning %s: The wrong extioi coremap data was delivered!!\n", diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c index b9e9d70ad9ee..fdbafc5e29b6 100644 --- a/arch/loongarch/kvm/intc/ipi.c +++ b/arch/loongarch/kvm/intc/ipi.c @@ -346,7 +346,7 @@ static int kvm_loongarch_ipi_regs_access(struct kvm_device *dev, cpu = (attr->attr >> 16) & 0x3ff; addr = attr->attr & 0xff; - vcpu = kvm_get_vcpu(dev->kvm, cpu); + vcpu = kvm_get_vcpu_by_id(dev->kvm, cpu); if (unlikely(vcpu == NULL)) { kvm_err("%s: invalid target cpu: %d\n", __func__, cpu); return -EINVAL; -- Gitee From 55b216b7aab7bed9de4edc881c50d8c069ffa6cb Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Wed, 20 Aug 2025 22:51:15 +0800 Subject: [PATCH 4/4] LoongArch: KVM: Add address alignment check in pch_pic register access commit 538c06e3964a8e94b645686cc58ccc4a06fa6330 upstream With pch_pic device, its register is based on MMIO address space, different access size 1/2/4/8 is supported. And base address should be naturally aligned with its access size, here add alignment check in its register access emulation function. Signed-off-by: Bibo Mao Signed-off-by: Huacai Chen Signed-off-by: Xianglai Li Signed-off-by: Kanglong Wang --- arch/loongarch/kvm/intc/pch_pic.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c index 2edaac808057..8d6d6873cd73 100644 --- a/arch/loongarch/kvm/intc/pch_pic.c +++ b/arch/loongarch/kvm/intc/pch_pic.c @@ -219,6 +219,11 @@ static int kvm_loongarch_pch_pic_write(struct kvm_vcpu *vcpu, return -EINVAL; } + if (addr & (len - 1)) { + kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len); + return -EINVAL; + } + /* statistics of pch pic writing */ vcpu->kvm->stat.pch_pic_write_exits++; ret = loongarch_pch_pic_write(s, addr, len, val); @@ -304,6 +309,11 @@ static int kvm_loongarch_pch_pic_read(struct kvm_vcpu *vcpu, return -EINVAL; } + if (addr & (len - 1)) { + kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len); + return -EINVAL; + } + /* statistics of pch pic reading */ vcpu->kvm->stat.pch_pic_read_exits++; ret = loongarch_pch_pic_read(s, addr, len, val); -- Gitee