History

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini: "ARM64: - Yet another fix for non-CPU accesses to the memory backing the VGICv3 subsystem - A set of fixes for the setlftest checking for the S1PTW behaviour after the fix that went in ealier in the cycle" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: selftests: aarch64: Test read-only PT memory regions KVM: selftests: aarch64: Fix check of dirty log PT write KVM: selftests: aarch64: Do not default to dirty PTE pages on all S1PTWs KVM: selftests: aarch64: Relax userfaultfd read vs. write checks KVM: arm64: Allow no running vcpu on saving vgic3 pending table KVM: arm64: Allow no running vcpu on restoring vgic3 LPI pending status KVM: arm64: Add helper vgic_write_guest_lock()

Linus Torvalds committed 3 years ago

Commit c00f4dd2 parents 2ab2ba4 25b72cf6 files · +132 −98Browse files

Unified · Split

6 files
  1. Documentation/virt/kvm/api.rst +7 −3
  2. arch/arm64/kvm/vgic/vgic-its.c +5 −8
  3. arch/arm64/kvm/vgic/vgic-v3.c +2 −2
  4. arch/arm64/kvm/vgic/vgic.h +14 −0
  5. include/kvm/arm_vgic.h +1 −1
  6. tools/testing/selftests/kvm/aarch64/page_fault_test.c +103 −84
Documentation/virt/kvm/api.rst+7−3
@@ -8070,9 +8070,13 @@ considering the state as complete. VMM needs to ensure that the dirty · 8069 unmodified lines
80708070 state is final and avoid missing dirty pages from another ioctl ordered
80718071 after the bitmap collection.
80728072
8073−NOTE: One example of using the backup bitmap is saving arm64 vgic/its
8074−tables through KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_SAVE_TABLES} command on
8075−KVM device "kvm-arm-vgic-its" when dirty ring is enabled.
8073+NOTE: Multiple examples of using the backup bitmap: (1) save vgic/its
8074+tables through command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_SAVE_TABLES} on
8075+KVM device "kvm-arm-vgic-its". (2) restore vgic/its tables through
8076+command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_RESTORE_TABLES} on KVM device
8077+"kvm-arm-vgic-its". VGICv3 LPI pending status is restored. (3) save
8078+vgic3 pending table through KVM_DEV_ARM_VGIC_{GRP_CTRL, SAVE_PENDING_TABLES}
8079+command on KVM device "kvm-arm-vgic-v3".
80768080
80778081 8.30 KVM_CAP_XEN_HVM
80788082 --------------------
arch/arm64/kvm/vgic/vgic-its.c+5−8
@@ -2187,7 +2187,7 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev, · 2186 unmodified lines
21872187 ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) |
21882188 ite->collection->collection_id;
21892189 val = cpu_to_le64(val);
2190− return kvm_write_guest_lock(kvm, gpa, &val, ite_esz);
2190+ return vgic_write_guest_lock(kvm, gpa, &val, ite_esz);
21912191 }
21922192
21932193 /**
@@ -2339,7 +2339,7 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev, · 145 unmodified lines
23392339 (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
23402340 (dev->num_eventid_bits - 1));
23412341 val = cpu_to_le64(val);
2342− return kvm_write_guest_lock(kvm, ptr, &val, dte_esz);
2342+ return vgic_write_guest_lock(kvm, ptr, &val, dte_esz);
23432343 }
23442344
23452345 /**
@@ -2526,7 +2526,7 @@ static int vgic_its_save_cte(struct vgic_its *its, · 180 unmodified lines
25262526 ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) |
25272527 collection->collection_id);
25282528 val = cpu_to_le64(val);
2529− return kvm_write_guest_lock(its->dev->kvm, gpa, &val, esz);
2529+ return vgic_write_guest_lock(its->dev->kvm, gpa, &val, esz);
25302530 }
25312531
25322532 /*
@@ -2607,7 +2607,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its) · 74 unmodified lines
26072607 */
26082608 val = 0;
26092609 BUG_ON(cte_esz > sizeof(val));
2610− ret = kvm_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz);
2610+ ret = vgic_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz);
26112611 return ret;
26122612 }
26132613
@@ -2743,7 +2743,6 @@ static int vgic_its_has_attr(struct kvm_device *dev, · 129 unmodified lines
27432743 static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
27442744 {
27452745 const struct vgic_its_abi *abi = vgic_its_get_abi(its);
2746− struct vgic_dist *dist = &kvm->arch.vgic;
27472746 int ret = 0;
27482747
27492748 if (attr == KVM_DEV_ARM_VGIC_CTRL_INIT) /* Nothing to do */
@@ -2763,9 +2762,7 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr) · 13 unmodified lines
27632762 vgic_its_reset(kvm, its);
27642763 break;
27652764 case KVM_DEV_ARM_ITS_SAVE_TABLES:
2766− dist->save_its_tables_in_progress = true;
27672765 ret = abi->save_tables(its);
2768− dist->save_its_tables_in_progress = false;
27692766 break;
27702767 case KVM_DEV_ARM_ITS_RESTORE_TABLES:
27712768 ret = abi->restore_tables(its);
@@ -2792,7 +2789,7 @@ bool kvm_arch_allow_write_without_running_vcpu(struct kvm *kvm) · 20 unmodified lines
27922789 {
27932790 struct vgic_dist *dist = &kvm->arch.vgic;
27942791
2795− return dist->save_its_tables_in_progress;
2792+ return dist->table_write_in_progress;
27962793 }
27972794
27982795 static int vgic_its_set_attr(struct kvm_device *dev,
arch/arm64/kvm/vgic/vgic-v3.c+2−2
@@ -339,7 +339,7 @@ retry: · 338 unmodified lines
339339 if (status) {
340340 /* clear consumed data */
341341 val &= ~(1 << bit_nr);
342− ret = kvm_write_guest_lock(kvm, ptr, &val, 1);
342+ ret = vgic_write_guest_lock(kvm, ptr, &val, 1);
343343 if (ret)
344344 return ret;
345345 }
@@ -434,7 +434,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) · 88 unmodified lines
434434 else
435435 val &= ~(1 << bit_nr);
436436
437− ret = kvm_write_guest_lock(kvm, ptr, &val, 1);
437+ ret = vgic_write_guest_lock(kvm, ptr, &val, 1);
438438 if (ret)
439439 goto out;
440440 }
arch/arm64/kvm/vgic/vgic.h+14−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #define __KVM_ARM_VGIC_NEW_H__
77
88 #include <linux/irqchip/arm-gic-common.h>
9+#include <asm/kvm_mmu.h>
910
1011 #define PRODUCT_ID_KVM 0x4b /* ASCII code K */
1112 #define IMPLEMENTER_ARM 0x43b
@@ -131,6 +132,19 @@ static inline bool vgic_irq_is_multi_sgi(struct vgic_irq *irq) · 119 unmodified lines
131132 return vgic_irq_get_lr_count(irq) > 1;
132133 }
133134
135+static inline int vgic_write_guest_lock(struct kvm *kvm, gpa_t gpa,
136+ const void *data, unsigned long len)
137+{
138+ struct vgic_dist *dist = &kvm->arch.vgic;
139+ int ret;
140+
141+ dist->table_write_in_progress = true;
142+ ret = kvm_write_guest_lock(kvm, gpa, data, len);
143+ dist->table_write_in_progress = false;
144+
145+ return ret;
146+}
147+
134148 /*
135149 * This struct provides an intermediate representation of the fields contained
136150 * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC
include/kvm/arm_vgic.h+1−1
@@ -263,7 +263,7 @@ struct vgic_dist { · 262 unmodified lines
263263 struct vgic_io_device dist_iodev;
264264
265265 bool has_its;
266− bool save_its_tables_in_progress;
266+ bool table_write_in_progress;
267267
268268 /*
269269 * Contains the attributes and gpa of the LPI configuration table.
tools/testing/selftests/kvm/aarch64/page_fault_test.c+103−84
@@ -237,6 +237,11 @@ static void guest_check_s1ptw_wr_in_dirty_log(void) · 236 unmodified lines
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;
@@ -304,7 +309,7 @@ static struct uffd_args { · 61 unmodified lines
304309
305310 /* Returns true to continue the test, and false if it should be skipped. */
306311 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)
308313 {
309314 uint64_t addr = msg->arg.pagefault.address;
310315 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
313318
314319 TEST_ASSERT(uffd_mode == UFFDIO_REGISTER_MODE_MISSING,
315320 "The only expected UFFD mode is MISSING");
316− ASSERT_EQ(!!(flags & UFFD_PAGEFAULT_FLAG_WRITE), expect_write);
317321 ASSERT_EQ(addr, (uint64_t)args->hva);
318322
319323 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
337341 return 0;
338342 }
339343
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)
346345 {
347− return uffd_generic_handler(mode, uffd, msg, &data_args, true);
346+ return uffd_generic_handler(mode, uffd, msg, &pt_args);
348347 }
349348
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)
351350 {
352− return uffd_generic_handler(mode, uffd, msg, &data_args, false);
351+ return uffd_generic_handler(mode, uffd, msg, &data_args);
353352 }
354353
355354 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
471470 {
472471 struct userspace_mem_region *data_region, *pt_region;
473472 bool continue_test = true;
473+ uint64_t pte_gpa, pte_pg;
474474
475475 data_region = vm_get_mem_region(vm, MEM_REGION_TEST_DATA);
476476 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();
477479
478480 if (cmd == CMD_SKIP_TEST)
479481 continue_test = false;
@@ -486,13 +488,13 @@ static bool handle_cmd(struct kvm_vm *vm, int cmd) · 6 unmodified lines
486488 TEST_ASSERT(check_write_in_dirty_log(vm, data_region, 0),
487489 "Missing write in dirty log");
488490 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),
490492 "Missing s1ptw write in dirty log");
491493 if (cmd & CMD_CHECK_NO_WRITE_IN_DIRTY_LOG)
492494 TEST_ASSERT(!check_write_in_dirty_log(vm, data_region, 0),
493495 "Unexpected write in dirty log");
494496 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),
496498 "Unexpected s1ptw write in dirty log");
497499
498500 return continue_test;
@@ -797,7 +799,7 @@ static void help(char *name) · 298 unmodified lines
797799 .expected_events = { .uffd_faults = _uffd_faults, }, \
798800 }
799801
800−#define TEST_DIRTY_LOG(_access, _with_af, _test_check) \
802+#define TEST_DIRTY_LOG(_access, _with_af, _test_check, _pt_check) \
801803 { \
802804 .name = SCAT3(dirty_log, _access, _with_af), \
803805 .data_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \
@@ -805,13 +807,12 @@ static void help(char *name) · 1 unmodified line
805807 .guest_prepare = { _PREPARE(_with_af), \
806808 _PREPARE(_access) }, \
807809 .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 }, \
810811 .expected_events = { 0 }, \
811812 }
812813
813814 #define TEST_UFFD_AND_DIRTY_LOG(_access, _with_af, _uffd_data_handler, \
814− _uffd_faults, _test_check) \
815+ _uffd_faults, _test_check, _pt_check) \
815816 { \
816817 .name = SCAT3(uffd_and_dirty_log, _access, _with_af), \
817818 .data_memslot_flags = KVM_MEM_LOG_DIRTY_PAGES, \
@@ -820,16 +821,17 @@ static void help(char *name) · 2 unmodified lines
820821 _PREPARE(_access) }, \
821822 .guest_test = _access, \
822823 .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 }, \
824825 .uffd_data_handler = _uffd_data_handler, \
825− .uffd_pt_handler = uffd_pt_write_handler, \
826+ .uffd_pt_handler = uffd_pt_handler, \
826827 .expected_events = { .uffd_faults = _uffd_faults, }, \
827828 }
828829
829830 #define TEST_RO_MEMSLOT(_access, _mmio_handler, _mmio_exits) \
830831 { \
831− .name = SCAT3(ro_memslot, _access, _with_af), \
832+ .name = SCAT2(ro_memslot, _access), \
832833 .data_memslot_flags = KVM_MEM_READONLY, \
834+ .pt_memslot_flags = KVM_MEM_READONLY, \
833835 .guest_prepare = { _PREPARE(_access) }, \
834836 .guest_test = _access, \
835837 .mmio_handler = _mmio_handler, \
@@ -840,6 +842,7 @@ static void help(char *name) · 4 unmodified lines
840842 { \
841843 .name = SCAT2(ro_memslot_no_syndrome, _access), \
842844 .data_memslot_flags = KVM_MEM_READONLY, \
845+ .pt_memslot_flags = KVM_MEM_READONLY, \
843846 .guest_test = _access, \
844847 .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \
845848 .expected_events = { .fail_vcpu_runs = 1 }, \
@@ -848,9 +851,9 @@ static void help(char *name) · 2 unmodified lines
848851 #define TEST_RO_MEMSLOT_AND_DIRTY_LOG(_access, _mmio_handler, _mmio_exits, \
849852 _test_check) \
850853 { \
851− .name = SCAT3(ro_memslot, _access, _with_af), \
854+ .name = SCAT2(ro_memslot, _access), \
852855 .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, \
854857 .guest_prepare = { _PREPARE(_access) }, \
855858 .guest_test = _access, \
856859 .guest_test_check = { _test_check }, \
@@ -862,7 +865,7 @@ static void help(char *name) · 5 unmodified lines
862865 { \
863866 .name = SCAT2(ro_memslot_no_syn_and_dlog, _access), \
864867 .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, \
866869 .guest_test = _access, \
867870 .guest_test_check = { _test_check }, \
868871 .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \
@@ -874,11 +877,12 @@ static void help(char *name) · 5 unmodified lines
874877 { \
875878 .name = SCAT2(ro_memslot_uffd, _access), \
876879 .data_memslot_flags = KVM_MEM_READONLY, \
880+ .pt_memslot_flags = KVM_MEM_READONLY, \
877881 .mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \
878882 .guest_prepare = { _PREPARE(_access) }, \
879883 .guest_test = _access, \
880884 .uffd_data_handler = _uffd_data_handler, \
881− .uffd_pt_handler = uffd_pt_write_handler, \
885+ .uffd_pt_handler = uffd_pt_handler, \
882886 .mmio_handler = _mmio_handler, \
883887 .expected_events = { .mmio_exits = _mmio_exits, \
884888 .uffd_faults = _uffd_faults }, \
@@ -889,10 +893,11 @@ static void help(char *name) · 4 unmodified lines
889893 { \
890894 .name = SCAT2(ro_memslot_no_syndrome, _access), \
891895 .data_memslot_flags = KVM_MEM_READONLY, \
896+ .pt_memslot_flags = KVM_MEM_READONLY, \
892897 .mem_mark_cmd = CMD_HOLE_DATA | CMD_HOLE_PT, \
893898 .guest_test = _access, \
894899 .uffd_data_handler = _uffd_data_handler, \
895− .uffd_pt_handler = uffd_pt_write_handler, \
900+ .uffd_pt_handler = uffd_pt_handler, \
896901 .fail_vcpu_run_handler = fail_vcpu_run_mmio_no_syndrome_handler, \
897902 .expected_events = { .fail_vcpu_runs = 1, \
898903 .uffd_faults = _uffd_faults }, \
@@ -933,44 +938,51 @@ static struct test_desc tests[] = { · 34 unmodified lines
933938 * (S1PTW).
934939 */
935940 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),
938942 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),
941944 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),
943946 /*
944947 * Can't test guest_at with_af as it's IMPDEF whether the AF is set.
945948 * The S1PTW fault should still be marked as a write.
946949 */
947950 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),
949952 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),
951954 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),
953956 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),
955958 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),
957960 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),
959962
960963 /*
961964 * Try accesses when the data and PT memory regions are both
962965 * tracked for dirty logging.
963966 */
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),
974986
975987 /*
976988 * Access when the data and PT memory regions are both marked for
@@ -980,29 +992,43 @@ static struct test_desc tests[] = { · 3 unmodified lines
980992 * fault, and nothing in the dirty log. Any S1PTW should result in
981993 * a write in the dirty log and a userfaultfd write.
982994 */
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),
10001026 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),
10041030 /*
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
10061032 * (with KVM_MEM_READONLY). Writes with a syndrome result in an
10071033 * MMIO exit, writes with no syndrome (e.g., CAS) result in a
10081034 * failed vcpu run, and reads/execs with and without syndroms do
@@ -1018,7 +1044,7 @@ static struct test_desc tests[] = { · 9 unmodified lines
10181044 TEST_RO_MEMSLOT_NO_SYNDROME(guest_st_preidx),
10191045
10201046 /*
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
10221048 * for dirty logging at the same time. The expected result is that
10231049 * for writes there should be no write in the dirty log. The
10241050 * readonly handling is the same as if the memslot was not marked
@@ -1043,7 +1069,7 @@ static struct test_desc tests[] = { · 18 unmodified lines
10431069 guest_check_no_write_in_dirty_log),
10441070
10451071 /*
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
10471073 * holes tracked with userfaultfd. The expected result is the
10481074 * union of both userfaultfd and read-only behaviors. For example,
10491075 * write accesses result in a userfaultfd write fault and an MMIO
@@ -1051,22 +1077,15 @@ static struct test_desc tests[] = { · 1 unmodified line
10511077 * no userfaultfd write fault. Reads result in userfaultfd getting
10521078 * triggered.
10531079 */
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),
10621084 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),
10701089
10711090 { 0 }
10721091 };