Extend the non-canonical memory access tests to verify CR2 stays unchanged. There's currently a bug in QEMU/TCG that breaks that assumption. Link: https://gitlab.com/qemu-project/qemu/-/issues/928 Signed-off-by: Mathias Krause <minipli@xxxxxxxxxxxxxx> --- x86/emulator64.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/x86/emulator64.c b/x86/emulator64.c index 5d1bb0f06d4f..abef2bda29f1 100644 --- a/x86/emulator64.c +++ b/x86/emulator64.c @@ -325,16 +325,39 @@ static void test_mmx_movq_mf(uint64_t *mem) report(exception_vector() == MF_VECTOR, "movq mmx generates #MF"); } +#define CR2_REF_VALUE 0xdecafbadUL + +static void setup_cr2(void) +{ + write_cr2(CR2_REF_VALUE); +} + +static void check_cr2(void) +{ + unsigned long cr2 = read_cr2(); + + if (cr2 == CR2_REF_VALUE) { + report(true, "CR2 unchanged"); + } else { + report(false, "CR2 changed from %#lx to %#lx", CR2_REF_VALUE, cr2); + setup_cr2(); + } +} + static void test_jmp_noncanonical(uint64_t *mem) { + setup_cr2(); *mem = NONCANONICAL; asm volatile (ASM_TRY("1f") "jmp *%0; 1:" : : "m"(*mem)); report(exception_vector() == GP_VECTOR, "jump to non-canonical address"); + check_cr2(); } static void test_reg_noncanonical(void) { + setup_cr2(); + /* RAX based, should #GP(0) */ asm volatile(ASM_TRY("1f") "orq $0, (%[noncanonical]); 1:" : : [noncanonical]"a"(NONCANONICAL)); @@ -342,6 +365,7 @@ static void test_reg_noncanonical(void) "non-canonical memory access, should %s(0), got %s(%u)", exception_mnemonic(GP_VECTOR), exception_mnemonic(exception_vector()), exception_error_code()); + check_cr2(); /* RSP based, should #SS(0) */ asm volatile(ASM_TRY("1f") "orq $0, (%%rsp,%[noncanonical],1); 1:" @@ -350,6 +374,7 @@ static void test_reg_noncanonical(void) "non-canonical rsp-based access, should %s(0), got %s(%u)", exception_mnemonic(SS_VECTOR), exception_mnemonic(exception_vector()), exception_error_code()); + check_cr2(); /* RBP based, should #SS(0) */ asm volatile(ASM_TRY("1f") "orq $0, (%%rbp,%[noncanonical],1); 1:" @@ -358,6 +383,7 @@ static void test_reg_noncanonical(void) "non-canonical rbp-based access, should %s(0), got %s(%u)", exception_mnemonic(SS_VECTOR), exception_mnemonic(exception_vector()), exception_error_code()); + check_cr2(); } static void test_movabs(uint64_t *mem) -- 2.30.2