Skip to content

Commit

Permalink
KVM: selftests: Introduce rdmsr_from_l2() and use it for MSR-Bitmap t…
Browse files Browse the repository at this point in the history
…ests

Hyper-V MSR-Bitmap tests do RDMSR from L2 to exit to L1. While 'evmcs_test'
correctly clobbers all GPRs (which are not preserved), 'hyperv_svm_test'
does not. Introduce a more generic rdmsr_from_l2() to avoid code
duplication and remove hardcoding of MSRs.  Do not put it in common code
because it is really just a selftests bug rather than a processor
feature that requires it.

Signed-off-by: Vitaly Kuznetsov <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
vittyvk authored and bonzini committed Nov 21, 2022
1 parent 8fda37c commit 75ee750
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
27 changes: 10 additions & 17 deletions tools/testing/selftests/kvm/x86_64/evmcs_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,15 @@ static void guest_nmi_handler(struct ex_regs *regs)
{
}

/* Exits to L1 destroy GRPs! */
static inline void rdmsr_fs_base(void)
static inline void rdmsr_from_l2(uint32_t msr)
{
__asm__ __volatile__ ("mov $0xc0000100, %%rcx; rdmsr" : : :
"rax", "rbx", "rcx", "rdx",
"rsi", "rdi", "r8", "r9", "r10", "r11", "r12",
"r13", "r14", "r15");
}
static inline void rdmsr_gs_base(void)
{
__asm__ __volatile__ ("mov $0xc0000101, %%rcx; rdmsr" : : :
"rax", "rbx", "rcx", "rdx",
"rsi", "rdi", "r8", "r9", "r10", "r11", "r12",
"r13", "r14", "r15");
/* Currently, L1 doesn't preserve GPRs during vmexits. */
__asm__ __volatile__ ("rdmsr" : : "c"(msr) :
"rax", "rbx", "rdx", "rsi", "rdi", "r8", "r9",
"r10", "r11", "r12", "r13", "r14", "r15");
}

/* Exit to L1 from L2 with RDMSR instruction */
void l2_guest_code(void)
{
GUEST_SYNC(7);
Expand All @@ -58,11 +51,11 @@ void l2_guest_code(void)
vmcall();

/* MSR-Bitmap tests */
rdmsr_fs_base(); /* intercepted */
rdmsr_fs_base(); /* intercepted */
rdmsr_gs_base(); /* not intercepted */
rdmsr_from_l2(MSR_FS_BASE); /* intercepted */
rdmsr_from_l2(MSR_FS_BASE); /* intercepted */
rdmsr_from_l2(MSR_GS_BASE); /* not intercepted */
vmcall();
rdmsr_gs_base(); /* intercepted */
rdmsr_from_l2(MSR_GS_BASE); /* intercepted */

/* Done, exit to L1 and never come back. */
vmcall();
Expand Down
17 changes: 13 additions & 4 deletions tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,27 @@

#define L2_GUEST_STACK_SIZE 256

/* Exit to L1 from L2 with RDMSR instruction */
static inline void rdmsr_from_l2(uint32_t msr)
{
/* Currently, L1 doesn't preserve GPRs during vmexits. */
__asm__ __volatile__ ("rdmsr" : : "c"(msr) :
"rax", "rbx", "rdx", "rsi", "rdi", "r8", "r9",
"r10", "r11", "r12", "r13", "r14", "r15");
}

void l2_guest_code(void)
{
GUEST_SYNC(3);
/* Exit to L1 */
vmmcall();

/* MSR-Bitmap tests */
rdmsr(MSR_FS_BASE); /* intercepted */
rdmsr(MSR_FS_BASE); /* intercepted */
rdmsr(MSR_GS_BASE); /* not intercepted */
rdmsr_from_l2(MSR_FS_BASE); /* intercepted */
rdmsr_from_l2(MSR_FS_BASE); /* intercepted */
rdmsr_from_l2(MSR_GS_BASE); /* not intercepted */
vmmcall();
rdmsr(MSR_GS_BASE); /* intercepted */
rdmsr_from_l2(MSR_GS_BASE); /* intercepted */

GUEST_SYNC(5);

Expand Down

0 comments on commit 75ee750

Please sign in to comment.