11// SPDX-License-Identifier: GPL-2.0-only
22/*
3- * mmio_abort - Tests for userspace MMIO abort injection
3+ * external_abort - Tests for userspace external abort injection
44 *
55 * Copyright (c) 2024 Google LLC
66 */
@@ -41,15 +41,23 @@ static struct kvm_vm *vm_create_with_dabt_handler(struct kvm_vcpu **vcpu, void *
4141 return vm ;
4242}
4343
44- static void vcpu_inject_extabt (struct kvm_vcpu * vcpu )
44+ static void vcpu_inject_sea (struct kvm_vcpu * vcpu )
4545{
4646 struct kvm_vcpu_events events = {};
4747
4848 events .exception .ext_dabt_pending = true;
4949 vcpu_events_set (vcpu , & events );
5050}
5151
52- static void vcpu_run_expect_done (struct kvm_vcpu * vcpu )
52+ static void vcpu_inject_serror (struct kvm_vcpu * vcpu )
53+ {
54+ struct kvm_vcpu_events events = {};
55+
56+ events .exception .serror_pending = true;
57+ vcpu_events_set (vcpu , & events );
58+ }
59+
60+ static void __vcpu_run_expect (struct kvm_vcpu * vcpu , unsigned int cmd )
5361{
5462 struct ucall uc ;
5563
@@ -58,13 +66,24 @@ static void vcpu_run_expect_done(struct kvm_vcpu *vcpu)
5866 case UCALL_ABORT :
5967 REPORT_GUEST_ASSERT (uc );
6068 break ;
61- case UCALL_DONE :
62- break ;
6369 default :
70+ if (uc .cmd == cmd )
71+ return ;
72+
6473 TEST_FAIL ("Unexpected ucall: %lu" , uc .cmd );
6574 }
6675}
6776
77+ static void vcpu_run_expect_done (struct kvm_vcpu * vcpu )
78+ {
79+ __vcpu_run_expect (vcpu , UCALL_DONE );
80+ }
81+
82+ static void vcpu_run_expect_sync (struct kvm_vcpu * vcpu )
83+ {
84+ __vcpu_run_expect (vcpu , UCALL_SYNC );
85+ }
86+
6887extern char test_mmio_abort_insn ;
6988
7089static void test_mmio_abort_guest (void )
@@ -95,7 +114,7 @@ static void test_mmio_abort(void)
95114 TEST_ASSERT_EQ (run -> mmio .len , sizeof (unsigned long ));
96115 TEST_ASSERT (!run -> mmio .is_write , "Expected MMIO read" );
97116
98- vcpu_inject_extabt (vcpu );
117+ vcpu_inject_sea (vcpu );
99118 vcpu_run_expect_done (vcpu );
100119 kvm_vm_free (vm );
101120}
@@ -146,7 +165,88 @@ static void test_mmio_nisv_abort(void)
146165 TEST_ASSERT_KVM_EXIT_REASON (vcpu , KVM_EXIT_ARM_NISV );
147166 TEST_ASSERT_EQ (run -> arm_nisv .fault_ipa , MMIO_ADDR );
148167
149- vcpu_inject_extabt (vcpu );
168+ vcpu_inject_sea (vcpu );
169+ vcpu_run_expect_done (vcpu );
170+ kvm_vm_free (vm );
171+ }
172+
173+ static void unexpected_serror_handler (struct ex_regs * regs )
174+ {
175+ GUEST_FAIL ("Took unexpected SError exception" );
176+ }
177+
178+ static void test_serror_masked_guest (void )
179+ {
180+ GUEST_ASSERT (read_sysreg (isr_el1 ) & ISR_EL1_A );
181+
182+ isb ();
183+
184+ GUEST_DONE ();
185+ }
186+
187+ static void test_serror_masked (void )
188+ {
189+ struct kvm_vcpu * vcpu ;
190+ struct kvm_vm * vm = vm_create_with_dabt_handler (& vcpu , test_serror_masked_guest ,
191+ unexpected_dabt_handler );
192+
193+ vm_install_exception_handler (vm , VECTOR_ERROR_CURRENT , unexpected_serror_handler );
194+
195+ vcpu_inject_serror (vcpu );
196+ vcpu_run_expect_done (vcpu );
197+ kvm_vm_free (vm );
198+ }
199+
200+ static void expect_serror_handler (struct ex_regs * regs )
201+ {
202+ GUEST_DONE ();
203+ }
204+
205+ static void test_serror_guest (void )
206+ {
207+ GUEST_ASSERT (read_sysreg (isr_el1 ) & ISR_EL1_A );
208+
209+ local_serror_enable ();
210+ isb ();
211+ local_serror_disable ();
212+
213+ GUEST_FAIL ("Should've taken pending SError exception" );
214+ }
215+
216+ static void test_serror (void )
217+ {
218+ struct kvm_vcpu * vcpu ;
219+ struct kvm_vm * vm = vm_create_with_dabt_handler (& vcpu , test_serror_guest ,
220+ unexpected_dabt_handler );
221+
222+ vm_install_exception_handler (vm , VECTOR_ERROR_CURRENT , expect_serror_handler );
223+
224+ vcpu_inject_serror (vcpu );
225+ vcpu_run_expect_done (vcpu );
226+ kvm_vm_free (vm );
227+ }
228+
229+ static void test_serror_emulated_guest (void )
230+ {
231+ GUEST_ASSERT (!(read_sysreg (isr_el1 ) & ISR_EL1_A ));
232+
233+ local_serror_enable ();
234+ GUEST_SYNC (0 );
235+ local_serror_disable ();
236+
237+ GUEST_FAIL ("Should've taken unmasked SError exception" );
238+ }
239+
240+ static void test_serror_emulated (void )
241+ {
242+ struct kvm_vcpu * vcpu ;
243+ struct kvm_vm * vm = vm_create_with_dabt_handler (& vcpu , test_serror_emulated_guest ,
244+ unexpected_dabt_handler );
245+
246+ vm_install_exception_handler (vm , VECTOR_ERROR_CURRENT , expect_serror_handler );
247+
248+ vcpu_run_expect_sync (vcpu );
249+ vcpu_inject_serror (vcpu );
150250 vcpu_run_expect_done (vcpu );
151251 kvm_vm_free (vm );
152252}
@@ -156,4 +256,7 @@ int main(void)
156256 test_mmio_abort ();
157257 test_mmio_nisv ();
158258 test_mmio_nisv_abort ();
259+ test_serror ();
260+ test_serror_masked ();
261+ test_serror_emulated ();
159262}
0 commit comments