mbox series

[v10,00/14] KVM: selftests: Add aarch64/page_fault_test

Message ID 20221017195834.2295901-1-ricarkol@google.com (mailing list archive)
Headers show
Series KVM: selftests: Add aarch64/page_fault_test | expand

Message

Ricardo Koller Oct. 17, 2022, 7:58 p.m. UTC
This series adds a new aarch64 selftest for testing stage 2 fault handling
for various combinations of guest accesses (e.g., write, S1PTW), backing
sources (e.g., anon), and types of faults (e.g., read on hugetlbfs with a
hole, write on a readonly memslot). Each test tries a different combination
and then checks that the access results in the right behavior (e.g., uffd
faults with the right address and write/read flag). Some interesting
combinations are:

- loading an instruction leads to a stage 1 page-table-walk that misses on
  stage 2 because the backing memslot for the page table it not in host
  memory (a hole was punched right there) and the fault is handled using
  userfaultfd.  The expected behavior is that this leads to a userfaultfd
  fault marked as a write. See commit c4ad98e4b72c ("KVM: arm64: Assume
  write fault on S1PTW permission fault on instruction fetch") for why
  that's a write.
- a cas (compare-and-swap) on a readonly memslot leads to a failed vcpu
  run.
- write-faulting on a memslot that's marked for userfaultfd handling and
  dirty logging should result in a uffd fault and having the respective bit
  set in the dirty log.

The first 8 commits of this series add library support. The first one adds
a new userfaultfd library. Commits 2-5 add some misc library changes that
will be used by the new test, like a library function to get the GPA of a
PTE.  Commits 6-8 breaks the implicit assumption that code and page tables
live in memslot memslots should allocators use. This is then used by the
new test to place the page tables in a specific memslot.  The last 5
commits add the new selftest, one type of test at a time. It first adds
core tests, then uffd, then dirty logging, then readonly memslots tests,
and finally combinations of the previous ones (like uffd and dirty logging
at the same time).

v9 -> v10: https://lore.kernel.org/kvmarm/20221011010628.1734342-1-ricarkol@google.com/
- collected r-b's from Andrew
- fixed indentation in several places (mainly alignment of params) [Sean]
- renamed args in uffd_setup [Sean]

v8 -> v9: https://lore.kernel.org/kvmarm/20220922031857.2588688-1-ricarkol@google.com/
- removed check before trying madvise(MADV_DONTNEED) on anon hugetlb. [Sean]
- renamed punch_hole_in_memslot() [Sean]
- changed the comment describing the accesses on "holes" [Sean]
- collectd r-b's from Sean

v7 -> v8: https://lore.kernel.org/kvmarm/20220920042551.3154283-1-ricarkol@google.com/
- applied Sean's suggestion of adding a fourth region: DATA, and renamed
  the old DATA one to DATA_TEST. [Sean]
- removed some unneeded code in page_fault_test.c. [Andrew]
- removed r-b's from Andrew and Oliver in commit "KVM: selftests: Use the
  right memslot for code, page-tables, and data allocations", as the commit
  changed quite a bit (again). Thanks for the reviews! would it have been OK
  to keep it? not sure how strict we all are about collecting r-b's on a
  commit that changed.

Ricardo Koller (14):
  KVM: selftests: Add a userfaultfd library
  KVM: selftests: aarch64: Add virt_get_pte_hva() library function
  KVM: selftests: Add missing close and munmap in
    __vm_mem_region_delete()
  KVM: selftests: aarch64: Construct DEFAULT_MAIR_EL1 using sysreg.h
    macros
  tools: Copy bitfield.h from the kernel sources
  KVM: selftests: Stash backing_src_type in struct userspace_mem_region
  KVM: selftests: Add vm->memslots[] and enum kvm_mem_region_type
  KVM: selftests: Fix alignment in virt_arch_pgd_alloc() and
    vm_vaddr_alloc()
  KVM: selftests: Use the right memslot for code, page-tables, and data
    allocations
  KVM: selftests: aarch64: Add aarch64/page_fault_test
  KVM: selftests: aarch64: Add userfaultfd tests into page_fault_test
  KVM: selftests: aarch64: Add dirty logging tests into page_fault_test
  KVM: selftests: aarch64: Add readonly memslot tests into
    page_fault_test
  KVM: selftests: aarch64: Add mix of tests into page_fault_test

 tools/include/linux/bitfield.h                |  176 +++
 tools/testing/selftests/kvm/.gitignore        |    1 +
 tools/testing/selftests/kvm/Makefile          |    2 +
 .../selftests/kvm/aarch64/page_fault_test.c   | 1112 +++++++++++++++++
 .../selftests/kvm/demand_paging_test.c        |  228 +---
 .../selftests/kvm/include/aarch64/processor.h |   35 +-
 .../selftests/kvm/include/kvm_util_base.h     |   31 +-
 .../selftests/kvm/include/userfaultfd_util.h  |   45 +
 .../selftests/kvm/lib/aarch64/processor.c     |   48 +-
 tools/testing/selftests/kvm/lib/elf.c         |    3 +-
 tools/testing/selftests/kvm/lib/kvm_util.c    |   82 +-
 .../selftests/kvm/lib/riscv/processor.c       |   29 +-
 .../selftests/kvm/lib/s390x/processor.c       |    8 +-
 .../selftests/kvm/lib/userfaultfd_util.c      |  186 +++
 .../selftests/kvm/lib/x86_64/processor.c      |   13 +-
 15 files changed, 1723 insertions(+), 276 deletions(-)
 create mode 100644 tools/include/linux/bitfield.h
 create mode 100644 tools/testing/selftests/kvm/aarch64/page_fault_test.c
 create mode 100644 tools/testing/selftests/kvm/include/userfaultfd_util.h
 create mode 100644 tools/testing/selftests/kvm/lib/userfaultfd_util.c

Comments

Sean Christopherson Oct. 19, 2022, 11:47 p.m. UTC | #1
On Mon, Oct 17, 2022, Ricardo Koller wrote:
> This series adds a new aarch64 selftest for testing stage 2 fault handling
> for various combinations of guest accesses (e.g., write, S1PTW), backing
> sources (e.g., anon), and types of faults (e.g., read on hugetlbfs with a
> hole, write on a readonly memslot). Each test tries a different combination
> and then checks that the access results in the right behavior (e.g., uffd
> faults with the right address and write/read flag). Some interesting
> combinations are:

...

> Ricardo Koller (14):
>   KVM: selftests: Add a userfaultfd library
>   KVM: selftests: aarch64: Add virt_get_pte_hva() library function
>   KVM: selftests: Add missing close and munmap in
>     __vm_mem_region_delete()
>   KVM: selftests: aarch64: Construct DEFAULT_MAIR_EL1 using sysreg.h
>     macros
>   tools: Copy bitfield.h from the kernel sources
>   KVM: selftests: Stash backing_src_type in struct userspace_mem_region
>   KVM: selftests: Add vm->memslots[] and enum kvm_mem_region_type
>   KVM: selftests: Fix alignment in virt_arch_pgd_alloc() and
>     vm_vaddr_alloc()
>   KVM: selftests: Use the right memslot for code, page-tables, and data
>     allocations
>   KVM: selftests: aarch64: Add aarch64/page_fault_test
>   KVM: selftests: aarch64: Add userfaultfd tests into page_fault_test
>   KVM: selftests: aarch64: Add dirty logging tests into page_fault_test
>   KVM: selftests: aarch64: Add readonly memslot tests into
>     page_fault_test
>   KVM: selftests: aarch64: Add mix of tests into page_fault_test

One alignment nit in the first patch, but definitely not worthy of a v11.  If it
gets fixed up when applying, yay.  If not, no big deal.
Marc Zyngier Nov. 10, 2022, 7:13 p.m. UTC | #2
On Mon, 17 Oct 2022 19:58:20 +0000, Ricardo Koller wrote:
> This series adds a new aarch64 selftest for testing stage 2 fault handling
> for various combinations of guest accesses (e.g., write, S1PTW), backing
> sources (e.g., anon), and types of faults (e.g., read on hugetlbfs with a
> hole, write on a readonly memslot). Each test tries a different combination
> and then checks that the access results in the right behavior (e.g., uffd
> faults with the right address and write/read flag). Some interesting
> combinations are:
> 
> [...]

Applied to next, thanks!

[01/14] KVM: selftests: Add a userfaultfd library
        commit: a93871d0ea9fd59fb5eb783619334183d7f07f51
[02/14] KVM: selftests: aarch64: Add virt_get_pte_hva() library function
        commit: 228f324dc718f702e8777164c4e2e7426824fb13
[03/14] KVM: selftests: Add missing close and munmap in __vm_mem_region_delete()
        commit: b6b03b86c0250a80b671313dbc0d7bcdbab78f41
[04/14] KVM: selftests: aarch64: Construct DEFAULT_MAIR_EL1 using sysreg.h macros
        commit: 41f5189ea9c08f7fc28340a7aefc93d0d2dcb769
[05/14] tools: Copy bitfield.h from the kernel sources
        commit: 590b949597b1e811d35df2f32021dd17d8e47f8c
[06/14] KVM: selftests: Stash backing_src_type in struct userspace_mem_region
        commit: bd3ed7e1a47eb7b3838ca09439f1eb289ec3be1f
[07/14] KVM: selftests: Add vm->memslots[] and enum kvm_mem_region_type
        commit: 290c5b54012b7f05e9c51af32d557574bf69a654
[08/14] KVM: selftests: Fix alignment in virt_arch_pgd_alloc() and vm_vaddr_alloc()
        commit: 5485e822e31a75dfac3713d94b6b22025d4895da
[09/14] KVM: selftests: Use the right memslot for code, page-tables, and data allocations
        commit: 1446e331432d7f24ed56b870ad605a4345fee43f
[10/14] KVM: selftests: aarch64: Add aarch64/page_fault_test
        commit: 35c5810157124cb71aaa939cd2d5508192714877
[11/14] KVM: selftests: aarch64: Add userfaultfd tests into page_fault_test
        commit: 3b1d915659c64dce079f4926a648f2271faea008
[12/14] KVM: selftests: aarch64: Add dirty logging tests into page_fault_test
        commit: a4edf25b3e25656c69cbc768d1c704868e4a616f
[13/14] KVM: selftests: aarch64: Add readonly memslot tests into page_fault_test
        commit: 45acde40f538a30e759f3b3f4aa5089edf097b2f
[14/14] KVM: selftests: aarch64: Add mix of tests into page_fault_test
        commit: ff2b5509e1d252cd18bb1430b5461d5044701559

Cheers,

	M.
Mark Brown Feb. 3, 2023, 2:49 p.m. UTC | #3
On Mon, Oct 17, 2022 at 07:58:20PM +0000, Ricardo Koller wrote:
> This series adds a new aarch64 selftest for testing stage 2 fault handling
> for various combinations of guest accesses (e.g., write, S1PTW), backing
> sources (e.g., anon), and types of faults (e.g., read on hugetlbfs with a
> hole, write on a readonly memslot). Each test tries a different combination
> and then checks that the access results in the right behavior (e.g., uffd
> faults with the right address and write/read flag). Some interesting
> combinations are:

I'm seeing issues with the page_fault_test tests in both -next and
mainline all the way back to v6.1 when they were introduced running on
both the fast model and hardware.  With -next the reports come back as:

# selftests: kvm: page_fault_test
# ==== Test Assertion Failure ====
#   aarch64/page_fault_test.c:316: __a == __b
#   pid=851 tid=860 errno=0 - Success
#      1	0x0000000000402253: uffd_generic_handler at page_fault_test.c:316
#      2	0x000000000040be07: uffd_handler_thread_fn at userfaultfd_util.c:97
#      3	0x0000ffff8b39edd7: ?? ??:0
#      4	0x0000ffff8b407e9b: ?? ??:0
#   ASSERT_EQ(!!(flags & UFFD_PAGEFAULT_FLAG_WRITE), expect_write) failed.
# 	!!(flags & UFFD_PAGEFAULT_FLAG_WRITE) is 0
# 	expect_write is 0x1
not ok 6 selftests: kvm: page_fault_test # exit=254

(addr2line seemed to be not doing much, I've not poked too hard at
that).  I've been unable to find any case where the program passes.
Is this expected?

Some random full runs on hardware:

4xA53: https://lava.sirena.org.uk/scheduler/job/244678
4xA72: https://lkft.validation.linaro.org/scheduler/job/6114427
Ricardo Koller Feb. 3, 2023, 3:36 p.m. UTC | #4
Hi Mark,

On Fri, Feb 3, 2023 at 6:49 AM Mark Brown <broonie@kernel.org> wrote:
>
> On Mon, Oct 17, 2022 at 07:58:20PM +0000, Ricardo Koller wrote:
> > This series adds a new aarch64 selftest for testing stage 2 fault handling
> > for various combinations of guest accesses (e.g., write, S1PTW), backing
> > sources (e.g., anon), and types of faults (e.g., read on hugetlbfs with a
> > hole, write on a readonly memslot). Each test tries a different combination
> > and then checks that the access results in the right behavior (e.g., uffd
> > faults with the right address and write/read flag). Some interesting
> > combinations are:
>
> I'm seeing issues with the page_fault_test tests in both -next and
> mainline all the way back to v6.1 when they were introduced running on
> both the fast model and hardware.  With -next the reports come back as:
>
> # selftests: kvm: page_fault_test
> # ==== Test Assertion Failure ====
> #   aarch64/page_fault_test.c:316: __a == __b
> #   pid=851 tid=860 errno=0 - Success
> #      1        0x0000000000402253: uffd_generic_handler at page_fault_test.c:316
> #      2        0x000000000040be07: uffd_handler_thread_fn at userfaultfd_util.c:97
> #      3        0x0000ffff8b39edd7: ?? ??:0
> #      4        0x0000ffff8b407e9b: ?? ??:0
> #   ASSERT_EQ(!!(flags & UFFD_PAGEFAULT_FLAG_WRITE), expect_write) failed.
> #       !!(flags & UFFD_PAGEFAULT_FLAG_WRITE) is 0
> #       expect_write is 0x1
> not ok 6 selftests: kvm: page_fault_test # exit=254
>
> (addr2line seemed to be not doing much, I've not poked too hard at
> that).  I've been unable to find any case where the program passes.
> Is this expected?
>
> Some random full runs on hardware:

That failure was fixed with this series:
"KVM: selftests: aarch64: page_fault_test S1PTW related fixes"
https://lore.kernel.org/kvmarm/20230127214353.245671-1-ricarkol@google.com/

which made it into kvmarm/fixes and should get into 6.2:
https://lore.kernel.org/kvmarm/20230129190142.2481354-1-maz@kernel.org/

Note that the failing assert does not exist after the mentioned series:
> #   ASSERT_EQ(!!(flags & UFFD_PAGEFAULT_FLAG_WRITE), expect_write) failed.

>
> 4xA53: https://lava.sirena.org.uk/scheduler/job/244678
> 4xA72: https://lkft.validation.linaro.org/scheduler/job/6114427

Thanks,
Ricardo
Mark Brown Feb. 3, 2023, 5:27 p.m. UTC | #5
On Fri, Feb 03, 2023 at 07:36:37AM -0800, Ricardo Koller wrote:
> On Fri, Feb 3, 2023 at 6:49 AM Mark Brown <broonie@kernel.org> wrote:
> > On Mon, Oct 17, 2022 at 07:58:20PM +0000, Ricardo Koller wrote:

> > # ==== Test Assertion Failure ====
> > #   aarch64/page_fault_test.c:316: __a == __b
> > #   pid=851 tid=860 errno=0 - Success

> > #   ASSERT_EQ(!!(flags & UFFD_PAGEFAULT_FLAG_WRITE), expect_write) failed.
> > #       !!(flags & UFFD_PAGEFAULT_FLAG_WRITE) is 0
> > #       expect_write is 0x1

> That failure was fixed with this series:
> "KVM: selftests: aarch64: page_fault_test S1PTW related fixes"
> https://lore.kernel.org/kvmarm/20230127214353.245671-1-ricarkol@google.com/

> which made it into kvmarm/fixes and should get into 6.2:
> https://lore.kernel.org/kvmarm/20230129190142.2481354-1-maz@kernel.org/

> Note that the failing assert does not exist after the mentioned series:
> > #   ASSERT_EQ(!!(flags & UFFD_PAGEFAULT_FLAG_WRITE), expect_write) failed.

Ah, good.  That's not made it into -next yet unfortunately so far as I
can see but hopefully it'll turn up shortly and everything will start
passing.  Thanks!