KVM: selftests: Introduce rdmsr_from_l2() and use it for MSR-Bitmap tests

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 <vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20221101145426.251680-46-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Vitaly Kuznetsov 2022-11-01 15:54:23 +01:00 committed by Paolo Bonzini
parent 8fda37cf3d
commit 75ee7505fe
2 changed files with 23 additions and 21 deletions

View file

@ -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);
@ -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();

View file

@ -23,6 +23,15 @@
#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);
@ -30,11 +39,11 @@ void l2_guest_code(void)
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);