Message ID | 20210609182945.36849-5-nadav.amit@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | x86: non-KVM improvements | expand |
On Wed, Jun 9, 2021 at 11:32 AM Nadav Amit <nadav.amit@gmail.com> wrote: > > From: Nadav Amit <nadav.amit@gmail.com> > > KVM knows to emulate both vmcall and vmmcall regardless of the > actual architecture. Native hardware does not behave this way. Based on > the availability of test-device, figure out that the test is run on > non-KVM environment, and if so, run vmcall/vmmcall based on the actual > architecture. > > Signed-off-by: Nadav Amit <nadav.amit@gmail.com> > --- > lib/x86/processor.h | 8 ++++++++ > x86/hypercall.c | 31 +++++++++++++++++++++++-------- > 2 files changed, 31 insertions(+), 8 deletions(-) > > diff --git a/lib/x86/processor.h b/lib/x86/processor.h > index abc04b0..517ee70 100644 > --- a/lib/x86/processor.h > +++ b/lib/x86/processor.h > @@ -118,6 +118,14 @@ static inline u8 cpuid_maxphyaddr(void) > return raw_cpuid(0x80000008, 0).a & 0xff; > } > > +static inline bool is_intel(void) > +{ > + struct cpuid c = cpuid(0); > + u32 name[4] = {c.b, c.d, c.c }; > + > + return strcmp((char *)name, "GenuineIntel") == 0; > +} > + Don't VIA CPUs also require vmcall, since they implement VMX rather than SVM?
> On Jun 9, 2021, at 11:37 AM, Jim Mattson <jmattson@google.com> wrote: > > On Wed, Jun 9, 2021 at 11:32 AM Nadav Amit <nadav.amit@gmail.com> wrote: >> >> From: Nadav Amit <nadav.amit@gmail.com> >> >> KVM knows to emulate both vmcall and vmmcall regardless of the >> actual architecture. Native hardware does not behave this way. Based on >> the availability of test-device, figure out that the test is run on >> non-KVM environment, and if so, run vmcall/vmmcall based on the actual >> architecture. >> >> Signed-off-by: Nadav Amit <nadav.amit@gmail.com> >> --- >> lib/x86/processor.h | 8 ++++++++ >> x86/hypercall.c | 31 +++++++++++++++++++++++-------- >> 2 files changed, 31 insertions(+), 8 deletions(-) >> >> diff --git a/lib/x86/processor.h b/lib/x86/processor.h >> index abc04b0..517ee70 100644 >> --- a/lib/x86/processor.h >> +++ b/lib/x86/processor.h >> @@ -118,6 +118,14 @@ static inline u8 cpuid_maxphyaddr(void) >> return raw_cpuid(0x80000008, 0).a & 0xff; >> } >> >> +static inline bool is_intel(void) >> +{ >> + struct cpuid c = cpuid(0); >> + u32 name[4] = {c.b, c.d, c.c }; >> + >> + return strcmp((char *)name, "GenuineIntel") == 0; >> +} >> + > Don't VIA CPUs also require vmcall, since they implement VMX rather than SVM? I would add VIA for the sake of correctness, although I presume it does not really matter in real-life.
diff --git a/lib/x86/processor.h b/lib/x86/processor.h index abc04b0..517ee70 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -118,6 +118,14 @@ static inline u8 cpuid_maxphyaddr(void) return raw_cpuid(0x80000008, 0).a & 0xff; } +static inline bool is_intel(void) +{ + struct cpuid c = cpuid(0); + u32 name[4] = {c.b, c.d, c.c }; + + return strcmp((char *)name, "GenuineIntel") == 0; +} + #define CPUID(a, b, c, d) ((((unsigned long long) a) << 32) | (b << 16) | \ (c << 8) | d) diff --git a/x86/hypercall.c b/x86/hypercall.c index 28760e3..a02ee33 100644 --- a/x86/hypercall.c +++ b/x86/hypercall.c @@ -2,6 +2,7 @@ #include "vm.h" #include "desc.h" #include "alloc_page.h" +#include "fwcfg.h" #define KVM_HYPERCALL_INTEL ".byte 0x0f,0x01,0xc1" #define KVM_HYPERCALL_AMD ".byte 0x0f,0x01,0xd9" @@ -51,10 +52,18 @@ test_edge(void) int main(int ac, char **av) { - kvm_hypercall0_intel(-1u); - printf("Hypercall via VMCALL: OK\n"); - kvm_hypercall0_amd(-1u); - printf("Hypercall via VMMCALL: OK\n"); + bool test_vmcall = !no_test_device || is_intel(); + bool test_vmmcall = !no_test_device || !is_intel(); + + if (test_vmcall) { + kvm_hypercall0_intel(-1u); + printf("Hypercall via VMCALL: OK\n"); + } + + if (test_vmmcall) { + kvm_hypercall0_amd(-1u); + printf("Hypercall via VMMCALL: OK\n"); + } #ifdef __x86_64__ setup_vm(); @@ -70,12 +79,18 @@ int main(int ac, char **av) topmost[4093] = 0x0f; topmost[4094] = 0x01; topmost[4095] = 0xc1; - report(test_edge(), - "VMCALL on edge of canonical address space (intel)"); + + if (test_vmcall) { + report(test_edge(), + "VMCALL on edge of canonical address space (intel)"); + } topmost[4095] = 0xd9; - report(test_edge(), - "VMMCALL on edge of canonical address space (AMD)"); + + if (test_vmmcall) { + report(test_edge(), + "VMMCALL on edge of canonical address space (AMD)"); + } #endif return report_summary();