| @@ -237,6 +237,11 @@ static void guest_check_s1ptw_wr_in_dirty_log(void) · 236 unmodified lines |
| 237 | 237 | GUEST_SYNC(CMD_CHECK_S1PTW_WR_IN_DIRTY_LOG); |
| 238 | 238 | } |
| 239 | 239 | |
| 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 | + |
| 240 | 245 | static void guest_exec(void) |
| 241 | 246 | { |
| 242 | 247 | int (*code)(void) = (int (*)(void))TEST_EXEC_GVA; |
| @@ -304,7 +309,7 @@ static struct uffd_args { · 61 unmodified lines |
| 304 | 309 | |
| 305 | 310 | /* Returns true to continue the test, and false if it should be skipped. */ |
| 306 | 311 | static int uffd_generic_handler(int uffd_mode, int uffd, struct uffd_msg *msg, |
| 307 | | − struct uffd_args *args, bool expect_write) |
| 312 | + struct uffd_args *args) |
| 308 | 313 | { |
| 309 | 314 | uint64_t addr = msg->arg.pagefault.address; |
| 310 | 315 | uint64_t flags = msg->arg.pagefault.flags; |
| @@ -313,7 +318,6 @@ static int uffd_generic_handler(int uffd_mode, int uffd, struct uffd_msg *msg, · 2 unmodified lines |
| 313 | 318 | |
| 314 | 319 | TEST_ASSERT(uffd_mode == UFFDIO_REGISTER_MODE_MISSING, |
| 315 | 320 | "The only expected UFFD mode is MISSING"); |
| 316 | | − ASSERT_EQ(!!(flags & UFFD_PAGEFAULT_FLAG_WRITE), expect_write); |
| 317 | 321 | ASSERT_EQ(addr, (uint64_t)args->hva); |
| 318 | 322 | |
| 319 | 323 | pr_debug("uffd fault: addr=%p write=%d\n", |
| @@ -337,19 +341,14 @@ static int uffd_generic_handler(int uffd_mode, int uffd, struct uffd_msg *msg, · 17 unmodified lines |
| 337 | 341 | return 0; |
| 338 | 342 | } |
| 339 | 343 | |
| 340 | | −static int uffd_pt_write_handler(int mode, int uffd, struct uffd_msg *msg) |
| 341 | | −{ |
| 342 | | − return uffd_generic_handler(mode, uffd, msg, &pt_args, true); |
| 343 | | −} |
| 344 | | − |
| 345 | | −static int uffd_data_write_handler(int mode, int uffd, struct uffd_msg *msg) |
| 344 | +static int uffd_pt_handler(int mode, int uffd, struct uffd_msg *msg) |
| 346 | 345 | { |
| 347 | | − return uffd_generic_handler(mode, uffd, msg, &data_args, true); |
| 346 | + return uffd_generic_handler(mode, uffd, msg, &pt_args); |
| 348 | 347 | } |
| 349 | 348 | |
| 350 | | −static int uffd_data_read_handler(int mode, int uffd, struct uffd_msg *msg) |
| 349 | +static int uffd_data_handler(int mode, int uffd, struct uffd_msg *msg) |
| 351 | 350 | { |
| 352 | | − return uffd_generic_handler(mode, uffd, msg, &data_args, false); |
| 351 | + return uffd_generic_handler(mode, uffd, msg, &data_args); |
| 353 | 352 | } |
| 354 | 353 | |
| 355 | 354 | static void setup_uffd_args(struct userspace_mem_region *region, |
| @@ -471,9 +470,12 @@ static bool handle_cmd(struct kvm_vm *vm, int cmd) · 115 unmodified lines |
| 471 | 470 | { |
| 472 | 471 | struct userspace_mem_region *data_region, *pt_region; |
| 473 | 472 | bool continue_test = true; |
| 473 | + uint64_t pte_gpa, pte_pg; |
| 474 | 474 | |
| 475 | 475 | data_region = vm_get_mem_region(vm, MEM_REGION_TEST_DATA); |
| 476 | 476 | pt_region = vm_get_mem_region(vm, MEM_REGION_PT); |
| 477 | + pte_gpa = addr_hva2gpa(vm, virt_get_pte_hva(vm, TEST_GVA)); |
| 478 | + pte_pg = (pte_gpa - pt_region->region.guest_phys_addr) / getpagesize(); |
| 477 | 479 | |
| 478 | 480 | if (cmd == CMD_SKIP_TEST) |
| 479 | 481 | continue_test = false; |
| @@ -486,13 +488,13 @@ static bool handle_cmd(struct kvm_vm *vm, int cmd) · 6 unmodified lines |
| 486 | 488 | TEST_ASSERT(check_write_in_dirty_log(vm, data_region, 0), |
| 487 | 489 | "Missing write in dirty log"); |
| 488 | 490 | if (cmd & CMD_CHECK_S1PTW_WR_IN_DIRTY_LOG) |
| 489 | | − TEST_ASSERT(check_write_in_dirty_log(vm, pt_region, 0), |
| 491 | + TEST_ASSERT(check_write_in_dirty_log(vm, pt_region, pte_pg), |
| 490 | 492 | "Missing s1ptw write in dirty log"); |
| 491 | 493 | if (cmd & CMD_CHECK_NO_WRITE_IN_DIRTY_LOG) |
| 492 | 494 | TEST_ASSERT(!check_write_in_dirty_log(vm, data_region, 0), |
| 493 | 495 | "Unexpected write in dirty log"); |
| 494 | 496 | if (cmd & CMD_CHECK_NO_S1PTW_WR_IN_DIRTY_LOG) |
| 495 | | − TEST_ASSERT(!check_write_in_dirty_log(vm, pt_region, 0), |
| 497 | + TEST_ASSERT(!check_write_in_dirty_log(vm, pt_region, pte_pg), |
| 496 | 498 | "Unexpected s1ptw write in dirty log"); |
| 497 | 499 | |
| 498 | 500 | return continue_test; |
| @@ -797,7 +799,7 @@ static void help(char *name) · 298 unmodified lines |
| 797 | 799 | .expected_events = { .uffd_faults = _uffd_faults, }, \ |
| 798 | 800 | } |
| 799 | 801 | |
| 800 | | −#define TEST_DIRTY_LOG(_access, _with_af, _test_check) \ |
| 802 | +#define TEST_DIRTY_LOG(_access, _with_af, _test_check, _pt_check) \ |
| 801 | 803 | { \ |
| 802 | 804 | .name = SCAT3(dirty_log, _access, _with_af), \ |
| 803 | 805 | .data_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \ |
| @@ -805,13 +807,12 @@ static void help(char *name) · 1 unmodified line |
| 805 | 807 | .guest_prepare = { _PREPARE(_with_af), \ |
| 806 | 808 | _PREPARE(_access) }, \ |
| 807 | 809 | .guest_test = _access, \ |
| 808 | | − .guest_test_check = { _CHECK(_with_af), _test_check, \ |
| 809 | | − guest_check_s1ptw_wr_in_dirty_log}, \ |
| 810 | + .guest_test_check = { _CHECK(_with_af), _test_check, _pt_check }, \ |
| 810 | 811 | .expected_events = { 0 }, \ |
| 811 | 812 | } |
| 812 | 813 | |
| 813 | 814 | #define TEST_UFFD_AND_DIRTY_LOG(_access, _with_af, _uffd_data_handler, \ |
| 814 | | − _uffd_faults, _test_check) \ |
| 815 | + _uffd_faults, _test_check, _pt_check) \ |
| 815 | 816 | { \ |
| 816 | 817 | .name = SCAT3(uffd_and_dirty_log, _access, _with_af), \ |
| 817 | 818 | .data_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \ |
| @@ -820,16 +821,17 @@ static void help(char *name) · 2 unmodified lines |
| 820 | 821 | _PREPARE(_access) }, \ |
| 821 | 822 | .guest_test = _access, \ |
| 822 | 823 | .mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \ |
| 823 | | − .guest_test_check = { _CHECK(_with_af), _test_check }, \ |
| 824 | + .guest_test_check = { _CHECK(_with_af), _test_check, _pt_check }, \ |
| 824 | 825 | .uffd_data_handler = _uffd_data_handler, \ |
| 825 | | − .uffd_pt_handler = uffd_pt_write_handler, \ |
| 826 | + .uffd_pt_handler = uffd_pt_handler, \ |
| 826 | 827 | .expected_events = { .uffd_faults = _uffd_faults, }, \ |
| 827 | 828 | } |
| 828 | 829 | |
| 829 | 830 | #define TEST_RO_MEMSLOT(_access, _mmio_handler, _mmio_exits) \ |
| 830 | 831 | { \ |
| 831 | | − .name = SCAT3(ro_memslot, _access, _with_af), \ |
| 832 | + .name = SCAT2(ro_memslot, _access), \ |
| 832 | 833 | .data_memslot_flags = KVM_MEM_READONLY, \ |
| 834 | + .pt_memslot_flags = KVM_MEM_READONLY, \ |
| 833 | 835 | .guest_prepare = { _PREPARE(_access) }, \ |
| 834 | 836 | .guest_test = _access, \ |
| 835 | 837 | .mmio_handler = _mmio_handler, \ |
| @@ -840,6 +842,7 @@ static void help(char *name) · 4 unmodified lines |
| 840 | 842 | { \ |
| 841 | 843 | .name = SCAT2(ro_memslot_no_syndrome, _access), \ |
| 842 | 844 | .data_memslot_flags = KVM_MEM_READONLY, \ |
| 845 | + .pt_memslot_flags = KVM_MEM_READONLY, \ |
| 843 | 846 | .guest_test = _access, \ |
| 844 | 847 | .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \ |
| 845 | 848 | .expected_events = { .fail_vcpu_runs = 1 }, \ |
| @@ -848,9 +851,9 @@ static void help(char *name) · 2 unmodified lines |
| 848 | 851 | #define TEST_RO_MEMSLOT_AND_DIRTY_LOG(_access, _mmio_handler, _mmio_exits, \ |
| 849 | 852 | _test_check) \ |
| 850 | 853 | { \ |
| 851 | | − .name = SCAT3(ro_memslot, _access, _with_af), \ |
| 854 | + .name = SCAT2(ro_memslot, _access), \ |
| 852 | 855 | .data_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \ |
| 853 | | − .pt_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \ |
| 856 | + .pt_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \ |
| 854 | 857 | .guest_prepare = { _PREPARE(_access) }, \ |
| 855 | 858 | .guest_test = _access, \ |
| 856 | 859 | .guest_test_check = { _test_check }, \ |
| @@ -862,7 +865,7 @@ static void help(char *name) · 5 unmodified lines |
| 862 | 865 | { \ |
| 863 | 866 | .name = SCAT2(ro_memslot_no_syn_and_dlog, _access), \ |
| 864 | 867 | .data_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \ |
| 865 | | − .pt_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \ |
| 868 | + .pt_memslot_flags = KVM_MEM_READONLY | KVM_MEM_LOG_DIRTY_PAGES, \ |
| 866 | 869 | .guest_test = _access, \ |
| 867 | 870 | .guest_test_check = { _test_check }, \ |
| 868 | 871 | .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \ |
| @@ -874,11 +877,12 @@ static void help(char *name) · 5 unmodified lines |
| 874 | 877 | { \ |
| 875 | 878 | .name = SCAT2(ro_memslot_uffd, _access), \ |
| 876 | 879 | .data_memslot_flags = KVM_MEM_READONLY, \ |
| 880 | + .pt_memslot_flags = KVM_MEM_READONLY, \ |
| 877 | 881 | .mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \ |
| 878 | 882 | .guest_prepare = { _PREPARE(_access) }, \ |
| 879 | 883 | .guest_test = _access, \ |
| 880 | 884 | .uffd_data_handler = _uffd_data_handler, \ |
| 881 | | − .uffd_pt_handler = uffd_pt_write_handler, \ |
| 885 | + .uffd_pt_handler = uffd_pt_handler, \ |
| 882 | 886 | .mmio_handler = _mmio_handler, \ |
| 883 | 887 | .expected_events = { .mmio_exits = _mmio_exits, \ |
| 884 | 888 | .uffd_faults = _uffd_faults }, \ |
| @@ -889,10 +893,11 @@ static void help(char *name) · 4 unmodified lines |
| 889 | 893 | { \ |
| 890 | 894 | .name = SCAT2(ro_memslot_no_syndrome, _access), \ |
| 891 | 895 | .data_memslot_flags = KVM_MEM_READONLY, \ |
| 896 | + .pt_memslot_flags = KVM_MEM_READONLY, \ |
| 892 | 897 | .mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \ |
| 893 | 898 | .guest_test = _access, \ |
| 894 | 899 | .uffd_data_handler = _uffd_data_handler, \ |
| 895 | | − .uffd_pt_handler = uffd_pt_write_handler, \ |
| 900 | + .uffd_pt_handler = uffd_pt_handler, \ |
| 896 | 901 | .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \ |
| 897 | 902 | .expected_events = { .fail_vcpu_runs = 1, \ |
| 898 | 903 | .uffd_faults = _uffd_faults }, \ |
| @@ -933,44 +938,51 @@ static struct test_desc tests[] = { · 34 unmodified lines |
| 933 | 938 | * (S1PTW). |
| 934 | 939 | */ |
| 935 | 940 | TEST_UFFD(guest_read64, with_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 936 | | − uffd_data_read_handler, uffd_pt_write_handler, 2), |
| 937 | | − /* no_af should also lead to a PT write. */ |
| 941 | + uffd_data_handler, uffd_pt_handler, 2), |
| 938 | 942 | TEST_UFFD(guest_read64, no_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 939 | | − uffd_data_read_handler, uffd_pt_write_handler, 2), |
| 940 | | − /* Note how that cas invokes the read handler. */ |
| 943 | + uffd_data_handler, uffd_pt_handler, 2), |
| 941 | 944 | TEST_UFFD(guest_cas, with_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 942 | | − uffd_data_read_handler, uffd_pt_write_handler, 2), |
| 945 | + uffd_data_handler, uffd_pt_handler, 2), |
| 943 | 946 | /* |
| 944 | 947 | * Can't test guest_at with_af as it's IMPDEF whether the AF is set. |
| 945 | 948 | * The S1PTW fault should still be marked as a write. |
| 946 | 949 | */ |
| 947 | 950 | TEST_UFFD(guest_at, no_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 948 | | − uffd_data_read_handler, uffd_pt_write_handler, 1), |
| 951 | + uffd_no_handler, uffd_pt_handler, 1), |
| 949 | 952 | TEST_UFFD(guest_ld_preidx, with_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 950 | | − uffd_data_read_handler, uffd_pt_write_handler, 2), |
| 953 | + uffd_data_handler, uffd_pt_handler, 2), |
| 951 | 954 | TEST_UFFD(guest_write64, with_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 952 | | − uffd_data_write_handler, uffd_pt_write_handler, 2), |
| 955 | + uffd_data_handler, uffd_pt_handler, 2), |
| 953 | 956 | TEST_UFFD(guest_dc_zva, with_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 954 | | − uffd_data_write_handler, uffd_pt_write_handler, 2), |
| 957 | + uffd_data_handler, uffd_pt_handler, 2), |
| 955 | 958 | TEST_UFFD(guest_st_preidx, with_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 956 | | − uffd_data_write_handler, uffd_pt_write_handler, 2), |
| 959 | + uffd_data_handler, uffd_pt_handler, 2), |
| 957 | 960 | TEST_UFFD(guest_exec, with_af, CMD_HOLE_DATA | CMD_HOLE_PT, |
| 958 | | − uffd_data_read_handler, uffd_pt_write_handler, 2), |
| 961 | + uffd_data_handler, uffd_pt_handler, 2), |
| 959 | 962 | |
| 960 | 963 | /* |
| 961 | 964 | * Try accesses when the data and PT memory regions are both |
| 962 | 965 | * tracked for dirty logging. |
| 963 | 966 | */ |
| 964 | | − TEST_DIRTY_LOG(guest_read64, with_af, guest_check_no_write_in_dirty_log), |
| 965 | | − /* no_af should also lead to a PT write. */ |
| 966 | | − TEST_DIRTY_LOG(guest_read64, no_af, guest_check_no_write_in_dirty_log), |
| 967 | | − TEST_DIRTY_LOG(guest_ld_preidx, with_af, guest_check_no_write_in_dirty_log), |
| 968 | | − TEST_DIRTY_LOG(guest_at, no_af, guest_check_no_write_in_dirty_log), |
| 969 | | − TEST_DIRTY_LOG(guest_exec, with_af, guest_check_no_write_in_dirty_log), |
| 970 | | − TEST_DIRTY_LOG(guest_write64, with_af, guest_check_write_in_dirty_log), |
| 971 | | − TEST_DIRTY_LOG(guest_cas, with_af, guest_check_write_in_dirty_log), |
| 972 | | − TEST_DIRTY_LOG(guest_dc_zva, with_af, guest_check_write_in_dirty_log), |
| 973 | | − TEST_DIRTY_LOG(guest_st_preidx, with_af, guest_check_write_in_dirty_log), |
| 967 | + TEST_DIRTY_LOG(guest_read64, with_af, guest_check_no_write_in_dirty_log, |
| 968 | + guest_check_s1ptw_wr_in_dirty_log), |
| 969 | + TEST_DIRTY_LOG(guest_read64, no_af, guest_check_no_write_in_dirty_log, |
| 970 | + guest_check_no_s1ptw_wr_in_dirty_log), |
| 971 | + TEST_DIRTY_LOG(guest_ld_preidx, with_af, |
| 972 | + guest_check_no_write_in_dirty_log, |
| 973 | + guest_check_s1ptw_wr_in_dirty_log), |
| 974 | + TEST_DIRTY_LOG(guest_at, no_af, guest_check_no_write_in_dirty_log, |
| 975 | + guest_check_no_s1ptw_wr_in_dirty_log), |
| 976 | + TEST_DIRTY_LOG(guest_exec, with_af, guest_check_no_write_in_dirty_log, |
| 977 | + guest_check_s1ptw_wr_in_dirty_log), |
| 978 | + TEST_DIRTY_LOG(guest_write64, with_af, guest_check_write_in_dirty_log, |
| 979 | + guest_check_s1ptw_wr_in_dirty_log), |
| 980 | + TEST_DIRTY_LOG(guest_cas, with_af, guest_check_write_in_dirty_log, |
| 981 | + guest_check_s1ptw_wr_in_dirty_log), |
| 982 | + TEST_DIRTY_LOG(guest_dc_zva, with_af, guest_check_write_in_dirty_log, |
| 983 | + guest_check_s1ptw_wr_in_dirty_log), |
| 984 | + TEST_DIRTY_LOG(guest_st_preidx, with_af, guest_check_write_in_dirty_log, |
| 985 | + guest_check_s1ptw_wr_in_dirty_log), |
| 974 | 986 | |
| 975 | 987 | /* |
| 976 | 988 | * Access when the data and PT memory regions are both marked for |
| @@ -980,29 +992,43 @@ static struct test_desc tests[] = { · 3 unmodified lines |
| 980 | 992 | * fault, and nothing in the dirty log. Any S1PTW should result in |
| 981 | 993 | * a write in the dirty log and a userfaultfd write. |
| 982 | 994 | */ |
| 983 | | − TEST_UFFD_AND_DIRTY_LOG(guest_read64, with_af, uffd_data_read_handler, 2, |
| 984 | | − guest_check_no_write_in_dirty_log), |
| 985 | | − /* no_af should also lead to a PT write. */ |
| 986 | | − TEST_UFFD_AND_DIRTY_LOG(guest_read64, no_af, uffd_data_read_handler, 2, |
| 987 | | − guest_check_no_write_in_dirty_log), |
| 988 | | − TEST_UFFD_AND_DIRTY_LOG(guest_ld_preidx, with_af, uffd_data_read_handler, |
| 989 | | − 2, guest_check_no_write_in_dirty_log), |
| 990 | | − TEST_UFFD_AND_DIRTY_LOG(guest_at, with_af, 0, 1, |
| 991 | | − guest_check_no_write_in_dirty_log), |
| 992 | | − TEST_UFFD_AND_DIRTY_LOG(guest_exec, with_af, uffd_data_read_handler, 2, |
| 993 | | − guest_check_no_write_in_dirty_log), |
| 994 | | − TEST_UFFD_AND_DIRTY_LOG(guest_write64, with_af, uffd_data_write_handler, |
| 995 | | − 2, guest_check_write_in_dirty_log), |
| 996 | | − TEST_UFFD_AND_DIRTY_LOG(guest_cas, with_af, uffd_data_read_handler, 2, |
| 997 | | − guest_check_write_in_dirty_log), |
| 998 | | − TEST_UFFD_AND_DIRTY_LOG(guest_dc_zva, with_af, uffd_data_write_handler, |
| 999 | | − 2, guest_check_write_in_dirty_log), |
| 995 | + TEST_UFFD_AND_DIRTY_LOG(guest_read64, with_af, |
| 996 | + uffd_data_handler, 2, |
| 997 | + guest_check_no_write_in_dirty_log, |
| 998 | + guest_check_s1ptw_wr_in_dirty_log), |
| 999 | + TEST_UFFD_AND_DIRTY_LOG(guest_read64, no_af, |
| 1000 | + uffd_data_handler, 2, |
| 1001 | + guest_check_no_write_in_dirty_log, |
| 1002 | + guest_check_no_s1ptw_wr_in_dirty_log), |
| 1003 | + TEST_UFFD_AND_DIRTY_LOG(guest_ld_preidx, with_af, |
| 1004 | + uffd_data_handler, |
| 1005 | + 2, guest_check_no_write_in_dirty_log, |
| 1006 | + guest_check_s1ptw_wr_in_dirty_log), |
| 1007 | + TEST_UFFD_AND_DIRTY_LOG(guest_at, with_af, uffd_no_handler, 1, |
| 1008 | + guest_check_no_write_in_dirty_log, |
| 1009 | + guest_check_s1ptw_wr_in_dirty_log), |
| 1010 | + TEST_UFFD_AND_DIRTY_LOG(guest_exec, with_af, |
| 1011 | + uffd_data_handler, 2, |
| 1012 | + guest_check_no_write_in_dirty_log, |
| 1013 | + guest_check_s1ptw_wr_in_dirty_log), |
| 1014 | + TEST_UFFD_AND_DIRTY_LOG(guest_write64, with_af, |
| 1015 | + uffd_data_handler, |
| 1016 | + 2, guest_check_write_in_dirty_log, |
| 1017 | + guest_check_s1ptw_wr_in_dirty_log), |
| 1018 | + TEST_UFFD_AND_DIRTY_LOG(guest_cas, with_af, |
| 1019 | + uffd_data_handler, 2, |
| 1020 | + guest_check_write_in_dirty_log, |
| 1021 | + guest_check_s1ptw_wr_in_dirty_log), |
| 1022 | + TEST_UFFD_AND_DIRTY_LOG(guest_dc_zva, with_af, |
| 1023 | + uffd_data_handler, |
| 1024 | + 2, guest_check_write_in_dirty_log, |
| 1025 | + guest_check_s1ptw_wr_in_dirty_log), |
| 1000 | 1026 | TEST_UFFD_AND_DIRTY_LOG(guest_st_preidx, with_af, |
| 1001 | | − uffd_data_write_handler, 2, |
| 1002 | | − guest_check_write_in_dirty_log), |
| 1003 | | − |
| 1027 | + uffd_data_handler, 2, |
| 1028 | + guest_check_write_in_dirty_log, |
| 1029 | + guest_check_s1ptw_wr_in_dirty_log), |
| 1004 | 1030 | /* |
| 1005 | | − * Try accesses when the data memory region is marked read-only |
| 1031 | + * Access when both the PT and data regions are marked read-only |
| 1006 | 1032 | * (with KVM_MEM_READONLY). Writes with a syndrome result in an |
| 1007 | 1033 | * MMIO exit, writes with no syndrome (e.g., CAS) result in a |
| 1008 | 1034 | * failed vcpu run, and reads/execs with and without syndroms do |
| @@ -1018,7 +1044,7 @@ static struct test_desc tests[] = { · 9 unmodified lines |
| 1018 | 1044 | TEST_RO_MEMSLOT_NO_SYNDROME(guest_st_preidx), |
| 1019 | 1045 | |
| 1020 | 1046 | /* |
| 1021 | | − * Access when both the data region is both read-only and marked |
| 1047 | + * The PT and data regions are both read-only and marked |
| 1022 | 1048 | * for dirty logging at the same time. The expected result is that |
| 1023 | 1049 | * for writes there should be no write in the dirty log. The |
| 1024 | 1050 | * readonly handling is the same as if the memslot was not marked |
| @@ -1043,7 +1069,7 @@ static struct test_desc tests[] = { · 18 unmodified lines |
| 1043 | 1069 | guest_check_no_write_in_dirty_log), |
| 1044 | 1070 | |
| 1045 | 1071 | /* |
| 1046 | | − * Access when the data region is both read-only and punched with |
| 1072 | + * The PT and data regions are both read-only and punched with |
| 1047 | 1073 | * holes tracked with userfaultfd. The expected result is the |
| 1048 | 1074 | * union of both userfaultfd and read-only behaviors. For example, |
| 1049 | 1075 | * write accesses result in a userfaultfd write fault and an MMIO |
| @@ -1051,22 +1077,15 @@ static struct test_desc tests[] = { · 1 unmodified line |
| 1051 | 1077 | * no userfaultfd write fault. Reads result in userfaultfd getting |
| 1052 | 1078 | * triggered. |
| 1053 | 1079 | */ |
| 1054 | | − TEST_RO_MEMSLOT_AND_UFFD(guest_read64, 0, 0, |
| 1055 | | − uffd_data_read_handler, 2), |
| 1056 | | − TEST_RO_MEMSLOT_AND_UFFD(guest_ld_preidx, 0, 0, |
| 1057 | | − uffd_data_read_handler, 2), |
| 1058 | | − TEST_RO_MEMSLOT_AND_UFFD(guest_at, 0, 0, |
| 1059 | | − uffd_no_handler, 1), |
| 1060 | | − TEST_RO_MEMSLOT_AND_UFFD(guest_exec, 0, 0, |
| 1061 | | − uffd_data_read_handler, 2), |
| 1080 | + TEST_RO_MEMSLOT_AND_UFFD(guest_read64, 0, 0, uffd_data_handler, 2), |
| 1081 | + TEST_RO_MEMSLOT_AND_UFFD(guest_ld_preidx, 0, 0, uffd_data_handler, 2), |
| 1082 | + TEST_RO_MEMSLOT_AND_UFFD(guest_at, 0, 0, uffd_no_handler, 1), |
| 1083 | + TEST_RO_MEMSLOT_AND_UFFD(guest_exec, 0, 0, uffd_data_handler, 2), |
| 1062 | 1084 | TEST_RO_MEMSLOT_AND_UFFD(guest_write64, mmio_on_test_gpa_handler, 1, |
| 1063 | | − uffd_data_write_handler, 2), |
| 1064 | | − TEST_RO_MEMSLOT_NO_SYNDROME_AND_UFFD(guest_cas, |
| 1065 | | − uffd_data_read_handler, 2), |
| 1066 | | − TEST_RO_MEMSLOT_NO_SYNDROME_AND_UFFD(guest_dc_zva, |
| 1067 | | − uffd_no_handler, 1), |
| 1068 | | − TEST_RO_MEMSLOT_NO_SYNDROME_AND_UFFD(guest_st_preidx, |
| 1069 | | − uffd_no_handler, 1), |
| 1085 | + uffd_data_handler, 2), |
| 1086 | + TEST_RO_MEMSLOT_NO_SYNDROME_AND_UFFD(guest_cas, uffd_data_handler, 2), |
| 1087 | + TEST_RO_MEMSLOT_NO_SYNDROME_AND_UFFD(guest_dc_zva, uffd_no_handler, 1), |
| 1088 | + TEST_RO_MEMSLOT_NO_SYNDROME_AND_UFFD(guest_st_preidx, uffd_no_handler, 1), |
| 1070 | 1089 | |
| 1071 | 1090 | { 0 } |
| 1072 | 1091 | }; |