Skip to content

Commit 4256175

Browse files
Ricardo KollerMarc Zyngier
authored andcommitted
KVM: selftests: aarch64: Do not default to dirty PTE pages on all S1PTWs
Only Stage1 Page table walks (S1PTW) trying to write into a PTE should result in the PTE page being dirty in the log. However, the dirty log tests in page_fault_test default to treat all S1PTW accesses as writes. Fix the relevant tests by asserting dirty pages only for S1PTW writes, which in these tests only applies to when Hardware management of the Access Flag is enabled. Signed-off-by: Ricardo Koller <[email protected]> Reviewed-by: Oliver Upton <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0dd8d22 commit 4256175

File tree

1 file changed

+60
-33
lines changed

1 file changed

+60
-33
lines changed

tools/testing/selftests/kvm/aarch64/page_fault_test.c

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ static void guest_check_s1ptw_wr_in_dirty_log(void)
237237
GUEST_SYNC(CMD_CHECK_S1PTW_WR_IN_DIRTY_LOG);
238238
}
239239

240+
static void guest_check_no_s1ptw_wr_in_dirty_log(void)
241+
{
242+
GUEST_SYNC(CMD_CHECK_NO_S1PTW_WR_IN_DIRTY_LOG);
243+
}
244+
240245
static void guest_exec(void)
241246
{
242247
int (*code)(void) = (int (*)(void))TEST_EXEC_GVA;
@@ -791,21 +796,20 @@ static void help(char *name)
791796
.expected_events = { .uffd_faults = _uffd_faults, }, \
792797
}
793798

794-
#define TEST_DIRTY_LOG(_access, _with_af, _test_check) \
799+
#define TEST_DIRTY_LOG(_access, _with_af, _test_check, _pt_check) \
795800
{ \
796801
.name = SCAT3(dirty_log, _access, _with_af), \
797802
.data_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \
798803
.pt_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \
799804
.guest_prepare = { _PREPARE(_with_af), \
800805
_PREPARE(_access) }, \
801806
.guest_test = _access, \
802-
.guest_test_check = { _CHECK(_with_af), _test_check, \
803-
guest_check_s1ptw_wr_in_dirty_log}, \
807+
.guest_test_check = { _CHECK(_with_af), _test_check, _pt_check }, \
804808
.expected_events = { 0 }, \
805809
}
806810

807811
#define TEST_UFFD_AND_DIRTY_LOG(_access, _with_af, _uffd_data_handler, \
808-
_uffd_faults, _test_check) \
812+
_uffd_faults, _test_check, _pt_check) \
809813
{ \
810814
.name = SCAT3(uffd_and_dirty_log, _access, _with_af), \
811815
.data_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \
@@ -814,7 +818,7 @@ static void help(char *name)
814818
_PREPARE(_access) }, \
815819
.guest_test = _access, \
816820
.mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \
817-
.guest_test_check = { _CHECK(_with_af), _test_check }, \
821+
.guest_test_check = { _CHECK(_with_af), _test_check, _pt_check }, \
818822
.uffd_data_handler = _uffd_data_handler, \
819823
.uffd_pt_handler = uffd_pt_handler, \
820824
.expected_events = { .uffd_faults = _uffd_faults, }, \
@@ -953,16 +957,25 @@ static struct test_desc tests[] = {
953957
* Try accesses when the data and PT memory regions are both
954958
* tracked for dirty logging.
955959
*/
956-
TEST_DIRTY_LOG(guest_read64, with_af, guest_check_no_write_in_dirty_log),
957-
/* no_af should also lead to a PT write. */
958-
TEST_DIRTY_LOG(guest_read64, no_af, guest_check_no_write_in_dirty_log),
959-
TEST_DIRTY_LOG(guest_ld_preidx, with_af, guest_check_no_write_in_dirty_log),
960-
TEST_DIRTY_LOG(guest_at, no_af, guest_check_no_write_in_dirty_log),
961-
TEST_DIRTY_LOG(guest_exec, with_af, guest_check_no_write_in_dirty_log),
962-
TEST_DIRTY_LOG(guest_write64, with_af, guest_check_write_in_dirty_log),
963-
TEST_DIRTY_LOG(guest_cas, with_af, guest_check_write_in_dirty_log),
964-
TEST_DIRTY_LOG(guest_dc_zva, with_af, guest_check_write_in_dirty_log),
965-
TEST_DIRTY_LOG(guest_st_preidx, with_af, guest_check_write_in_dirty_log),
960+
TEST_DIRTY_LOG(guest_read64, with_af, guest_check_no_write_in_dirty_log,
961+
guest_check_s1ptw_wr_in_dirty_log),
962+
TEST_DIRTY_LOG(guest_read64, no_af, guest_check_no_write_in_dirty_log,
963+
guest_check_no_s1ptw_wr_in_dirty_log),
964+
TEST_DIRTY_LOG(guest_ld_preidx, with_af,
965+
guest_check_no_write_in_dirty_log,
966+
guest_check_s1ptw_wr_in_dirty_log),
967+
TEST_DIRTY_LOG(guest_at, no_af, guest_check_no_write_in_dirty_log,
968+
guest_check_no_s1ptw_wr_in_dirty_log),
969+
TEST_DIRTY_LOG(guest_exec, with_af, guest_check_no_write_in_dirty_log,
970+
guest_check_s1ptw_wr_in_dirty_log),
971+
TEST_DIRTY_LOG(guest_write64, with_af, guest_check_write_in_dirty_log,
972+
guest_check_s1ptw_wr_in_dirty_log),
973+
TEST_DIRTY_LOG(guest_cas, with_af, guest_check_write_in_dirty_log,
974+
guest_check_s1ptw_wr_in_dirty_log),
975+
TEST_DIRTY_LOG(guest_dc_zva, with_af, guest_check_write_in_dirty_log,
976+
guest_check_s1ptw_wr_in_dirty_log),
977+
TEST_DIRTY_LOG(guest_st_preidx, with_af, guest_check_write_in_dirty_log,
978+
guest_check_s1ptw_wr_in_dirty_log),
966979

967980
/*
968981
* Access when the data and PT memory regions are both marked for
@@ -972,27 +985,41 @@ static struct test_desc tests[] = {
972985
* fault, and nothing in the dirty log. Any S1PTW should result in
973986
* a write in the dirty log and a userfaultfd write.
974987
*/
975-
TEST_UFFD_AND_DIRTY_LOG(guest_read64, with_af, uffd_data_handler, 2,
976-
guest_check_no_write_in_dirty_log),
977-
/* no_af should also lead to a PT write. */
978-
TEST_UFFD_AND_DIRTY_LOG(guest_read64, no_af, uffd_data_handler, 2,
979-
guest_check_no_write_in_dirty_log),
980-
TEST_UFFD_AND_DIRTY_LOG(guest_ld_preidx, with_af, uffd_data_handler,
981-
2, guest_check_no_write_in_dirty_log),
988+
TEST_UFFD_AND_DIRTY_LOG(guest_read64, with_af,
989+
uffd_data_handler, 2,
990+
guest_check_no_write_in_dirty_log,
991+
guest_check_s1ptw_wr_in_dirty_log),
992+
TEST_UFFD_AND_DIRTY_LOG(guest_read64, no_af,
993+
uffd_data_handler, 2,
994+
guest_check_no_write_in_dirty_log,
995+
guest_check_no_s1ptw_wr_in_dirty_log),
996+
TEST_UFFD_AND_DIRTY_LOG(guest_ld_preidx, with_af,
997+
uffd_data_handler,
998+
2, guest_check_no_write_in_dirty_log,
999+
guest_check_s1ptw_wr_in_dirty_log),
9821000
TEST_UFFD_AND_DIRTY_LOG(guest_at, with_af, uffd_no_handler, 1,
983-
guest_check_no_write_in_dirty_log),
984-
TEST_UFFD_AND_DIRTY_LOG(guest_exec, with_af, uffd_data_handler, 2,
985-
guest_check_no_write_in_dirty_log),
986-
TEST_UFFD_AND_DIRTY_LOG(guest_write64, with_af, uffd_data_handler,
987-
2, guest_check_write_in_dirty_log),
988-
TEST_UFFD_AND_DIRTY_LOG(guest_cas, with_af, uffd_data_handler, 2,
989-
guest_check_write_in_dirty_log),
990-
TEST_UFFD_AND_DIRTY_LOG(guest_dc_zva, with_af, uffd_data_handler,
991-
2, guest_check_write_in_dirty_log),
1001+
guest_check_no_write_in_dirty_log,
1002+
guest_check_s1ptw_wr_in_dirty_log),
1003+
TEST_UFFD_AND_DIRTY_LOG(guest_exec, with_af,
1004+
uffd_data_handler, 2,
1005+
guest_check_no_write_in_dirty_log,
1006+
guest_check_s1ptw_wr_in_dirty_log),
1007+
TEST_UFFD_AND_DIRTY_LOG(guest_write64, with_af,
1008+
uffd_data_handler,
1009+
2, guest_check_write_in_dirty_log,
1010+
guest_check_s1ptw_wr_in_dirty_log),
1011+
TEST_UFFD_AND_DIRTY_LOG(guest_cas, with_af,
1012+
uffd_data_handler, 2,
1013+
guest_check_write_in_dirty_log,
1014+
guest_check_s1ptw_wr_in_dirty_log),
1015+
TEST_UFFD_AND_DIRTY_LOG(guest_dc_zva, with_af,
1016+
uffd_data_handler,
1017+
2, guest_check_write_in_dirty_log,
1018+
guest_check_s1ptw_wr_in_dirty_log),
9921019
TEST_UFFD_AND_DIRTY_LOG(guest_st_preidx, with_af,
9931020
uffd_data_handler, 2,
994-
guest_check_write_in_dirty_log),
995-
1021+
guest_check_write_in_dirty_log,
1022+
guest_check_s1ptw_wr_in_dirty_log),
9961023
/*
9971024
* Try accesses when the data memory region is marked read-only
9981025
* (with KVM_MEM_READONLY). Writes with a syndrome result in an

0 commit comments

Comments
 (0)