On 17/08/2017 21:52, Yu Zhang wrote:
> diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
> index ac15193..3e759cf 100644
> --- a/arch/x86/kvm/cpuid.h
> +++ b/arch/x86/kvm/cpuid.h
> @@ -21,7 +21,14 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
>  int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
>                             struct kvm_cpuid2 *cpuid,
>                             struct kvm_cpuid_entry2 __user *entries);
> -void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 
> *edx);
> +
> +enum {
> +     NO_CHECK_LIMIT = 0,
> +     CHECK_LIMIT = 1,
> +};

emulate.c should not include cpuid.h.  The argument can be simply a
bool, though.

> +bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
> +            u32 *ecx, u32 *edx, int check_limit);
>  
>  int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
>  
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index fb00559..46daa37 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -28,6 +28,7 @@
>  
>  #include "x86.h"
>  #include "tss.h"
> +#include "cpuid.h"
>  
>  /*
>   * Operand types
> @@ -2333,8 +2334,10 @@ static int emulator_has_longmode(struct 
> x86_emulate_ctxt *ctxt)
>  
>       eax = 0x80000001;
>       ecx = 0;
> -     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
> -     return edx & bit(X86_FEATURE_LM);
> +     if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, NO_CHECK_LIMIT))
> +             return edx & bit(X86_FEATURE_LM);
> +     else
> +             return 0;
>  }
>  
>  #define GET_SMSTATE(type, smbase, offset)                              \
> @@ -2636,7 +2639,7 @@ static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
>       u32 eax, ebx, ecx, edx;
>  
>       eax = ecx = 0;
> -     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
> +     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, NO_CHECK_LIMIT);
>       return ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx
>               && ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx
>               && edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx;
> @@ -2656,7 +2659,7 @@ static bool em_syscall_is_enabled(struct 
> x86_emulate_ctxt *ctxt)
>  
>       eax = 0x00000000;
>       ecx = 0x00000000;
> -     ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
> +     ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, NO_CHECK_LIMIT);
>       /*
>        * Intel ("GenuineIntel")
>        * remark: Intel CPUs only support "syscall" in 64bit
> @@ -3551,7 +3554,7 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
>       /*
>        * Check MOVBE is set in the guest-visible CPUID leaf.
>        */
> -     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
> +     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, CHECK_LIMIT);

This should be NO_CHECK_LIMIT.

Otherwise okay!

Paolo

>       if (!(ecx & FFL(MOVBE)))
>               return emulate_ud(ctxt);
>  
> @@ -3865,7 +3868,7 @@ static int em_cpuid(struct x86_emulate_ctxt *ctxt)
>  
>       eax = reg_read(ctxt, VCPU_REGS_RAX);
>       ecx = reg_read(ctxt, VCPU_REGS_RCX);
> -     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
> +     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, CHECK_LIMIT);
>       *reg_write(ctxt, VCPU_REGS_RAX) = eax;
>       *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
>       *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
> @@ -3924,7 +3927,7 @@ static int check_fxsr(struct x86_emulate_ctxt *ctxt)
>  {
>       u32 eax = 1, ebx, ecx = 0, edx;
>  
> -     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
> +     ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, CHECK_LIMIT);
>       if (!(edx & FFL(FXSR)))
>               return emulate_ud(ctxt);
>  
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 1fa9ee5..9def4a8 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -1580,7 +1580,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool 
> init_event)
>       }
>       init_vmcb(svm);
>  
> -     kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy);
> +     kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, CHECK_LIMIT);
>       kvm_register_write(vcpu, VCPU_REGS_RDX, eax);
>  
>       if (kvm_vcpu_apicv_active(vcpu) && !init_event)
> diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
> index 0a6cc67..8a202c4 100644
> --- a/arch/x86/kvm/trace.h
> +++ b/arch/x86/kvm/trace.h
> @@ -151,8 +151,8 @@ TRACE_EVENT(kvm_fast_mmio,
>   */
>  TRACE_EVENT(kvm_cpuid,
>       TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx,
> -              unsigned long rcx, unsigned long rdx),
> -     TP_ARGS(function, rax, rbx, rcx, rdx),
> +              unsigned long rcx, unsigned long rdx, bool found),
> +     TP_ARGS(function, rax, rbx, rcx, rdx, found),
>  
>       TP_STRUCT__entry(
>               __field(        unsigned int,   function        )
> @@ -160,6 +160,7 @@ TRACE_EVENT(kvm_cpuid,
>               __field(        unsigned long,  rbx             )
>               __field(        unsigned long,  rcx             )
>               __field(        unsigned long,  rdx             )
> +             __field(        bool,           found           )
>       ),
>  
>       TP_fast_assign(
> @@ -168,11 +169,13 @@ TRACE_EVENT(kvm_cpuid,
>               __entry->rbx            = rbx;
>               __entry->rcx            = rcx;
>               __entry->rdx            = rdx;
> +             __entry->found          = found;
>       ),
>  
> -     TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx",
> +     TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx, cpuid entry %s",
>                 __entry->function, __entry->rax,
> -               __entry->rbx, __entry->rcx, __entry->rdx)
> +               __entry->rbx, __entry->rcx, __entry->rdx,
> +               __entry->found ? "found" : "not found")
>  );
>  
>  #define AREG(x) { APIC_##x, "APIC_" #x }
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e40a779..ee99fc1 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -5213,10 +5213,10 @@ static int emulator_intercept(struct x86_emulate_ctxt 
> *ctxt,
>       return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
>  }
>  
> -static void emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
> -                            u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
> +static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
> +                     u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, int check_limit)
>  {
> -     kvm_cpuid(emul_to_vcpu(ctxt), eax, ebx, ecx, edx);
> +     return kvm_cpuid(emul_to_vcpu(ctxt), eax, ebx, ecx, edx, check_limit);
>  }
>  
>  static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
> 

Reply via email to