L1 intercepts L2's SMI and the SMI is still pending at L0. When L1 re-enables GIF via stgi(), L0 delivers the SMI to L1. Without an SMI handler, L1 enters SMM and aborts. Install a trivial RSM handler at the default SMBASE entry point so L1 can return from SMM. Signed-off-by: Ryosuke Yasuoka --- x86/svm_tests.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/x86/svm_tests.c b/x86/svm_tests.c index ccbab1d0..11770854 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -3543,8 +3543,28 @@ static void svm_intr_intercept_mix_smi_guest(struct svm_test *test) report(0, "must not reach here"); } +#define SMBASE 0x30000 +#define SMBASE_ENTRY (SMBASE + 0x8000) +#define RSM_OPCODE 0xaa0f + +/* + * Install a trivial SMI handler that executes RSM at the default SMBASE + * entry point. Without this, entering SMM causes an abort. + */ +static void install_smi_handler(void) +{ + WRITE_ONCE(*(u16 *)SMBASE_ENTRY, RSM_OPCODE); +} + static void svm_intr_intercept_mix_smi(void) { + /* + * L1 intercepts L2's SMI. It makes L0 deliver the SMI to L1 + * when L1 re-enables GIF via stgi(), so L1 needs an SMI handler + * to avoid aborting. + */ + install_smi_handler(); + vmcb_set_intercept(INTERCEPT_SMI); vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; test_set_guest(svm_intr_intercept_mix_smi_guest); -- 2.55.0