A stack based memory access should generate a #SS(0) exception but QEMU/TCG as of now (7.2) makes all exceptions based on a non-canonical address generate a #GP(0) instead (issue linked below). Add a test that will succeed when run under KVM but fail when using TCG. Link: https://gitlab.com/qemu-project/qemu/-/issues/928 Signed-off-by: Mathias Krause <minipli@xxxxxxxxxxxxxx> --- v2: use ASM_TRY() as suggested by Sean The non-canonical jump test is, apparently, broken under TCG as well. It "succeeds," as in changing RIP and thereby creating a #GP loop. I therefore put the new test in front of it to allow it to run. x86/emulator64.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/x86/emulator64.c b/x86/emulator64.c index f8ff99fc39cc..e1a0968f5236 100644 --- a/x86/emulator64.c +++ b/x86/emulator64.c @@ -333,6 +333,33 @@ static void test_jmp_noncanonical(uint64_t *mem) "jump to non-canonical address"); } +static void test_reg_noncanonical(void) +{ + /* RAX based, should #GP(0) */ + asm volatile(ASM_TRY("1f") "orq $0, (%[noncanonical]); 1:" + : : [noncanonical]"a"(NONCANONICAL)); + report(exception_vector() == GP_VECTOR && exception_error_code() == 0, + "non-canonical memory access, should %s(0), got %s(%u)", + exception_mnemonic(GP_VECTOR), + exception_mnemonic(exception_vector()), exception_error_code()); + + /* RSP based, should #SS(0) */ + asm volatile(ASM_TRY("1f") "orq $0, (%%rsp,%[noncanonical],1); 1:" + : : [noncanonical]"r"(NONCANONICAL)); + report(exception_vector() == SS_VECTOR && exception_error_code() == 0, + "non-canonical rsp-based access, should %s(0), got %s(%u)", + exception_mnemonic(SS_VECTOR), + exception_mnemonic(exception_vector()), exception_error_code()); + + /* RBP based, should #SS(0) */ + asm volatile(ASM_TRY("1f") "orq $0, (%%rbp,%[noncanonical],1); 1:" + : : [noncanonical]"r"(NONCANONICAL)); + report(exception_vector() == SS_VECTOR && exception_error_code() == 0, + "non-canonical rbp-based access, should %s(0), got %s(%u)", + exception_mnemonic(SS_VECTOR), + exception_mnemonic(exception_vector()), exception_error_code()); +} + static void test_movabs(uint64_t *mem) { /* mov $0x9090909090909090, %rcx */ @@ -459,5 +486,6 @@ static void test_emulator_64(void *mem) test_push16(mem); + test_reg_noncanonical(); test_jmp_noncanonical(mem); } -- 2.39.2