Re: [PATCH 2/2] KVM: LoongArch: selftests: Add in-kernel MMIO read fast path test
Huacai Chen <[email protected]> Sat, 25 Jul 2026 17:41:10 +0800
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAAhV-H7pLEUeKWGmCZqDdF+2vr=2aexOFVCMa_UxTrDpUY+gvA@mail.gmail.com> |
On Fri, Jul 24, 2026 at 9:28=E2=80=AFAM Bibo Mao <[email protected]> wrot= e: > > > > On 2026/7/23 =E4=B8=8B=E5=8D=887:16, Zeng Chi wrote: > > From: Zeng Chi <[email protected]> > > > > Add a test that exercises the in-kernel MMIO read fast path of > > kvm_emu_mmio_read(). The guest performs an MMIO read from an in-kernel > > emulated PCH-PIC, immediately followed by a marker instruction, and the > > test verifies that the marker instruction is executed, i.e. that the PC > > advances by exactly one instruction instead of skipping the instruction > > after the MMIO read. > > > > The test skips gracefully when the host KVM cannot create a PCH-PIC > > device. > > > > Signed-off-by: Zeng Chi <[email protected]> > > --- > > tools/testing/selftests/kvm/Makefile.kvm | 3 +- > > .../selftests/kvm/loongarch/mmio_read_test.c | 89 ++++++++++++++++++= + > > 2 files changed, 91 insertions(+), 1 deletion(-) > > create mode 100644 tools/testing/selftests/kvm/loongarch/mmio_read_te= st.c > > > > diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/s= elftests/kvm/Makefile.kvm > > index 6fc34e9bf8e1..4daf90caaabc 100644 > > --- a/tools/testing/selftests/kvm/Makefile.kvm > > +++ b/tools/testing/selftests/kvm/Makefile.kvm > > @@ -228,7 +228,8 @@ TEST_GEN_PROGS_riscv +=3D mmu_stress_test > > TEST_GEN_PROGS_riscv +=3D rseq_test > > TEST_GEN_PROGS_riscv +=3D steal_time > > > > -TEST_GEN_PROGS_loongarch =3D loongarch/pmu_test > > +TEST_GEN_PROGS_loongarch =3D loongarch/mmio_read_test > > +TEST_GEN_PROGS_loongarch +=3D loongarch/pmu_test > > TEST_GEN_PROGS_loongarch +=3D arch_timer > > TEST_GEN_PROGS_loongarch +=3D coalesced_io_test > > TEST_GEN_PROGS_loongarch +=3D demand_paging_test > > diff --git a/tools/testing/selftests/kvm/loongarch/mmio_read_test.c b/t= ools/testing/selftests/kvm/loongarch/mmio_read_test.c > > new file mode 100644 > > index 000000000000..7f64ca91ca8f > > --- /dev/null > > +++ b/tools/testing/selftests/kvm/loongarch/mmio_read_test.c > > @@ -0,0 +1,89 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * LoongArch KVM in-kernel MMIO read fast path test > > + * > > + * When an MMIO read hits a device emulated inside KVM (such as the > > + * PCH-PIC), kvm_emu_mmio_read() completes the access without returnin= g > > + * to user space and advances the guest PC by one instruction. > > + * > > + * This test issues such an in-kernel MMIO read immediately followed b= y > > + * a marker instruction and checks that the marker instruction actuall= y > > + * runs, i.e. that the PC advanced by exactly one instruction (4 bytes= ) > > + * rather than skipping the instruction after the MMIO read. > > + */ > > +#include "kvm_util.h" > > +#include "processor.h" > > +#include "test_util.h" > > +#include "loongarch/processor.h" > > + > > +/* Physical base the in-kernel PCH-PIC is mapped at (no memslot backs = it) */ > > +#define PCH_PIC_BASE 0x10000000UL > > + > > +static void guest_code(void) > > +{ > > + unsigned long marker =3D 0; > > + unsigned int val =3D 0; > > + > > + /* > > + * 'ld.w' faults out as an MMIO read and is emulated in kernel. > > + * The following 'addi.d' must execute; it is skipped if the MMIO > > + * read fast path advances the PC twice (by 8 instead of 4). > > + */ > > + asm volatile( > > + "ld.w %[val], %[base], 0\n\t" > > + "addi.d %[marker], %[marker], 1\n\t" > > + : [val] "=3D&r" (val), [marker] "+&r" (marker) > > + : [base] "r" (PCH_PIC_BASE) > > + : "memory"); > By my understanding, the kvm selftest is mainly to test function. It > will be better if it is to verify irq handling with in-kernel PCH-PIC > irqchip. I think the fist patch is just enough. :) Huacai > > Regards > Bibo Mao > > + > > + GUEST_PRINTF("mmio read val=3D0x%x, marker=3D%lu\n", val, marker)= ; > > + GUEST_ASSERT_EQ(marker, 1); > > + GUEST_DONE(); > > +} > > + > > +int main(int argc, char *argv[]) > > +{ > > + struct kvm_vcpu *vcpu; > > + struct kvm_vm *vm; > > + struct ucall uc; > > + uint64_t addr =3D PCH_PIC_BASE; > > + int dev_fd; > > + > > + vm =3D vm_create(VM_MODE_P47V47_16K); > > + vcpu =3D vm_vcpu_add(vm, 0, guest_code); > > + > > + /* Create the in-kernel PCH-PIC and map it at PCH_PIC_BASE */ > > + dev_fd =3D __kvm_create_device(vm, KVM_DEV_TYPE_LOONGARCH_PCHPIC)= ; > > + if (dev_fd < 0) { > > + print_skip("PCH-PIC device not supported by host KVM"); > > + kvm_vm_free(vm); > > + return KSFT_SKIP; > > + } > > + kvm_device_attr_set(dev_fd, KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL, > > + KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT, &addr); > > + close(dev_fd); > > + > > + /* Identity-map the MMIO page so the guest can reach the device *= / > > + virt_map(vm, PCH_PIC_BASE, PCH_PIC_BASE, 1); > > + > > + while (1) { > > + vcpu_run(vcpu); > > + switch (get_ucall(vcpu, &uc)) { > > + case UCALL_PRINTF: > > + pr_info("%s", uc.buffer); > > + break; > > + case UCALL_DONE: > > + goto done; > > + case UCALL_ABORT: > > + REPORT_GUEST_ASSERT(uc); > > + goto done; > > + default: > > + TEST_FAIL("Unexpected exit: %s", > > + exit_reason_str(vcpu->run->exit_reason)= ); > > + } > > + } > > + > > +done: > > + kvm_vm_free(vm); > > + return 0; > > +} > > >