@@ -86,7 +86,7 @@ static void vcpu_run_expect_sync(struct kvm_vcpu *vcpu)
8686
8787extern char test_mmio_abort_insn ;
8888
89- static void test_mmio_abort_guest (void )
89+ static noinline void test_mmio_abort_guest (void )
9090{
9191 WRITE_ONCE (expected_abort_pc , (u64 )& test_mmio_abort_insn );
9292
@@ -251,6 +251,45 @@ static void test_serror_emulated(void)
251251 kvm_vm_free (vm );
252252}
253253
254+ static void test_mmio_ease_guest (void )
255+ {
256+ sysreg_clear_set_s (SYS_SCTLR2_EL1 , 0 , SCTLR2_EL1_EASE );
257+ isb ();
258+
259+ test_mmio_abort_guest ();
260+ }
261+
262+ /*
263+ * Test that KVM doesn't complete MMIO emulation when userspace has made an
264+ * external abort pending for the instruction.
265+ */
266+ static void test_mmio_ease (void )
267+ {
268+ struct kvm_vcpu * vcpu ;
269+ struct kvm_vm * vm = vm_create_with_dabt_handler (& vcpu , test_mmio_ease_guest ,
270+ unexpected_dabt_handler );
271+ struct kvm_run * run = vcpu -> run ;
272+ u64 pfr1 ;
273+
274+ pfr1 = vcpu_get_reg (vcpu , KVM_ARM64_SYS_REG (SYS_ID_AA64PFR1_EL1 ));
275+ if (!SYS_FIELD_GET (ID_AA64PFR1_EL1 , DF2 , pfr1 )) {
276+ pr_debug ("Skipping %s\n" , __func__ );
277+ return ;
278+ }
279+
280+ vm_install_exception_handler (vm , VECTOR_ERROR_CURRENT , expect_serror_handler );
281+
282+ vcpu_run (vcpu );
283+ TEST_ASSERT_KVM_EXIT_REASON (vcpu , KVM_EXIT_MMIO );
284+ TEST_ASSERT_EQ (run -> mmio .phys_addr , MMIO_ADDR );
285+ TEST_ASSERT_EQ (run -> mmio .len , sizeof (unsigned long ));
286+ TEST_ASSERT (!run -> mmio .is_write , "Expected MMIO read" );
287+
288+ vcpu_inject_sea (vcpu );
289+ vcpu_run_expect_done (vcpu );
290+ kvm_vm_free (vm );
291+ }
292+
254293int main (void )
255294{
256295 test_mmio_abort ();
@@ -259,4 +298,5 @@ int main(void)
259298 test_serror ();
260299 test_serror_masked ();
261300 test_serror_emulated ();
301+ test_mmio_ease ();
262302}
0 commit comments