Commit 08ddbbdf authored by Ricardo Koller's avatar Ricardo Koller Committed by Marc Zyngier

KVM: selftests: aarch64: Test read-only PT memory regions

Extend the read-only memslot tests in page_fault_test to test
read-only PT (Page table) memslots. Note that this was not allowed
before commit 406504c7 ("KVM: arm64: Fix S1PTW handling on RO
memslots") as all S1PTW faults were treated as writes which resulted
in an (unrecoverable) exception inside the guest.
Signed-off-by: default avatarRicardo Koller <ricarkol@google.com>
Reviewed-by: default avatarOliver Upton <oliver.upton@linux.dev>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230127214353.245671-5-ricarkol@google.com
parent 8b03c97f
...@@ -829,8 +829,9 @@ static void help(char *name) ...@@ -829,8 +829,9 @@ static void help(char *name)
#define TEST_RO_MEMSLOT(_access, _mmio_handler, _mmio_exits) \ #define TEST_RO_MEMSLOT(_access, _mmio_handler, _mmio_exits) \
{ \ { \
.name = SCAT3(ro_memslot, _access, _with_af), \ .name = SCAT2(ro_memslot, _access), \
.data_memslot_flags = KVM_MEM_READONLY, \ .data_memslot_flags = KVM_MEM_READONLY, \
.pt_memslot_flags = KVM_MEM_READONLY, \
.guest_prepare = { _PREPARE(_access) }, \ .guest_prepare = { _PREPARE(_access) }, \
.guest_test = _access, \ .guest_test = _access, \
.mmio_handler = _mmio_handler, \ .mmio_handler = _mmio_handler, \
...@@ -841,6 +842,7 @@ static void help(char *name) ...@@ -841,6 +842,7 @@ static void help(char *name)
{ \ { \
.name = SCAT2(ro_memslot_no_syndrome, _access), \ .name = SCAT2(ro_memslot_no_syndrome, _access), \
.data_memslot_flags = KVM_MEM_READONLY, \ .data_memslot_flags = KVM_MEM_READONLY, \
.pt_memslot_flags = KVM_MEM_READONLY, \
.guest_test = _access, \ .guest_test = _access, \
.fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \ .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \
.expected_events = { .fail_vcpu_runs = 1 }, \ .expected_events = { .fail_vcpu_runs = 1 }, \
...@@ -849,9 +851,9 @@ static void help(char *name) ...@@ -849,9 +851,9 @@ static void help(char *name)
#define TEST_RO_MEMSLOT_AND_DIRTY_LOG(_access, _mmio_handler, _mmio_exits, \ #define TEST_RO_MEMSLOT_AND_DIRTY_LOG(_access, _mmio_handler, _mmio_exits, \
_test_check) \ _test_check) \
{ \ { \
.name = SCAT3(ro_memslot, _access, _with_af), \ .name = SCAT2(ro_memslot, _access), \
.data_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \ .data_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \
.pt_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \ .pt_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \
.guest_prepare = { _PREPARE(_access) }, \ .guest_prepare = { _PREPARE(_access) }, \
.guest_test = _access, \ .guest_test = _access, \
.guest_test_check = { _test_check }, \ .guest_test_check = { _test_check }, \
...@@ -863,7 +865,7 @@ static void help(char *name) ...@@ -863,7 +865,7 @@ static void help(char *name)
{ \ { \
.name = SCAT2(ro_memslot_no_syn_and_dlog, _access), \ .name = SCAT2(ro_memslot_no_syn_and_dlog, _access), \
.data_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \ .data_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \
.pt_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \ .pt_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \
.guest_test = _access, \ .guest_test = _access, \
.guest_test_check = { _test_check }, \ .guest_test_check = { _test_check }, \
.fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \ .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \
...@@ -875,6 +877,7 @@ static void help(char *name) ...@@ -875,6 +877,7 @@ static void help(char *name)
{ \ { \
.name = SCAT2(ro_memslot_uffd, _access), \ .name = SCAT2(ro_memslot_uffd, _access), \
.data_memslot_flags = KVM_MEM_READONLY, \ .data_memslot_flags = KVM_MEM_READONLY, \
.pt_memslot_flags = KVM_MEM_READONLY, \
.mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \ .mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \
.guest_prepare = { _PREPARE(_access) }, \ .guest_prepare = { _PREPARE(_access) }, \
.guest_test = _access, \ .guest_test = _access, \
...@@ -890,6 +893,7 @@ static void help(char *name) ...@@ -890,6 +893,7 @@ static void help(char *name)
{ \ { \
.name = SCAT2(ro_memslot_no_syndrome, _access), \ .name = SCAT2(ro_memslot_no_syndrome, _access), \
.data_memslot_flags = KVM_MEM_READONLY, \ .data_memslot_flags = KVM_MEM_READONLY, \
.pt_memslot_flags = KVM_MEM_READONLY, \
.mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \ .mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \
.guest_test = _access, \ .guest_test = _access, \
.uffd_data_handler = _uffd_data_handler, \ .uffd_data_handler = _uffd_data_handler, \
...@@ -1024,7 +1028,7 @@ static struct test_desc tests[] = { ...@@ -1024,7 +1028,7 @@ static struct test_desc tests[] = {
guest_check_write_in_dirty_log, guest_check_write_in_dirty_log,
guest_check_s1ptw_wr_in_dirty_log), guest_check_s1ptw_wr_in_dirty_log),
/* /*
* Try accesses when the data memory region is marked read-only * Access when both the PT and data regions are marked read-only
* (with KVM_MEM_READONLY). Writes with a syndrome result in an * (with KVM_MEM_READONLY). Writes with a syndrome result in an
* MMIO exit, writes with no syndrome (e.g., CAS) result in a * MMIO exit, writes with no syndrome (e.g., CAS) result in a
* failed vcpu run, and reads/execs with and without syndroms do * failed vcpu run, and reads/execs with and without syndroms do
...@@ -1040,7 +1044,7 @@ static struct test_desc tests[] = { ...@@ -1040,7 +1044,7 @@ static struct test_desc tests[] = {
TEST_RO_MEMSLOT_NO_SYNDROME(guest_st_preidx), TEST_RO_MEMSLOT_NO_SYNDROME(guest_st_preidx),
/* /*
* Access when both the data region is both read-only and marked * The PT and data regions are both read-only and marked
* for dirty logging at the same time. The expected result is that * for dirty logging at the same time. The expected result is that
* for writes there should be no write in the dirty log. The * for writes there should be no write in the dirty log. The
* readonly handling is the same as if the memslot was not marked * readonly handling is the same as if the memslot was not marked
...@@ -1065,7 +1069,7 @@ static struct test_desc tests[] = { ...@@ -1065,7 +1069,7 @@ static struct test_desc tests[] = {
guest_check_no_write_in_dirty_log), guest_check_no_write_in_dirty_log),
/* /*
* Access when the data region is both read-only and punched with * The PT and data regions are both read-only and punched with
* holes tracked with userfaultfd. The expected result is the * holes tracked with userfaultfd. The expected result is the
* union of both userfaultfd and read-only behaviors. For example, * union of both userfaultfd and read-only behaviors. For example,
* write accesses result in a userfaultfd write fault and an MMIO * write accesses result in a userfaultfd write fault and an MMIO
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment