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