Re: [kvm-unit-tests PATCH] x86/emulator: Test POP-SS blocking

Michal Luczaj
2022-08-24T21:49:26Z

On 8/24/22 20:32, Sean Christopherson wrote:
> Eh, let's completely skip usermode for code #DBs and not tweak __run_single_step_db_test().
> It's easier to just have a standalone function.

Something like this?

static void test_pop_ss_code_db(bool fep_available)
{
write_ss(KERNEL_DS);

write_dr7(DR7_FIXED_1 |
DR7_ENABLE_DRx(0) |
DR7_EXECUTE_DRx(0) |
DR7_LEN_1_DRx(0));

#define POPSS_DB(desc, fep1, fep2) \
({ \
unsigned int r; \
\
n = 0; \
asm volatile(/* jump to 32-bit code segment */ \
"ljmp *1f\n\t" \
"1:\n\t" \
" .long 2f\n\t" \
" .word " xstr(KERNEL_CS32) "\n\t" \
/* exercise POP SS blocking */ \
".code32\n\t" \
"2: lea 3f, %0\n\t" \
"mov %0, %%dr0\n\t" \
"push %%ss\n\t" \
fep1 "pop %%ss\n\t" \
fep2 "3: xor %0, %0\n\t" \
/* back to long mode */ \
"ljmp %[cs64], $4f\n\t" \
".code64\n\t" \
"4:" \
: "=R" (r) \
: [cs64] "i" (KERNEL_CS64) \
: "memory"); \
\
report(!n && !r, desc ": #DB suppressed after POP SS"); \
})

POPSS_DB("no fep", "", "");
if (fep_available) {
POPSS_DB("fep POP-SS", KVM_FEP, "");
POPSS_DB("fep XOR", "", KVM_FEP);
POPSS_DB("fep POP-SS/fep XOR", KVM_FEP, KVM_FEP);
}

write_dr7(DR7_FIXED_1);
}

Results:

em_pop_sreg unpatched
PASS: no fep: #DB suppressed after POP SS
FAIL: fep POP-SS: #DB suppressed after POP SS
PASS: fep XOR: #DB suppressed after POP SS
PASS: fep POP-SS/fep XOR: #DB suppressed after POP SS

em_pop_sreg patched
PASS: no fep: #DB suppressed after POP SS
PASS: fep POP-SS: #DB suppressed after POP SS
PASS: fep XOR: #DB suppressed after POP SS
PASS: fep POP-SS/fep XOR: #DB suppressed after POP SS

thanks,
Michal