[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v5 1/5] x86/msr: add VMX MSRs definitions and populate Raw domain policy



On 28/02/18 16:09, Sergey Dyasli wrote:
> New definitions provide a convenient way of accessing contents of
> VMX MSRs. They are separated into 5 logical blocks based on the
> availability conditions of MSRs in the each block:
>
>     1. vmx: [VMX_BASIC, VMX_VMCS_ENUM]
>     2. VMX_PROCBASED_CTLS2
>     3. VMX_EPT_VPID_CAP
>     4. vmx_true_ctls: [VMX_TRUE_PINBASED_CTLS, VMX_TRUE_ENTRY_CTLS]
>     5. VMX_VMFUNC
>
> Every bit value is accessible by its name and bit names match existing
> Xen's definitions as close as possible. There is a "raw" 64-bit field
> for each MSR as well as "raw" arrays for vmx and vmx_true_ctls blocks.
>
> Add calculate_raw_vmx_policy() which fills Raw policy with H/W values
> of VMX MSRs. Host policy will contain a copy of these values (for now).
>
> Signed-off-by: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>

Overall, I think this is good.  However, I'd like to take this
opportunity to make the names shorter, because there is a huge quantity
of unnecessary code volume in these names.  Some suggestions inline.

> ---
> v4 --> v5:
> - Clarified the reason for splitting MSRs into 5 blocks
> - Added raw field into cr0/4_bits
> - Moved cr0/4_bits definitions into asm-x86/x86-defns.h
> - Added msr availability helpers
> ---
>  xen/arch/x86/msr.c              | 118 ++++++++++++++
>  xen/include/asm-x86/msr.h       | 330 
> ++++++++++++++++++++++++++++++++++++++++
>  xen/include/asm-x86/x86-defns.h |  54 +++++++
>  3 files changed, 502 insertions(+)
>
> diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
> index 8ae3b4e616..43607b5107 100644
> --- a/xen/arch/x86/msr.c
> +++ b/xen/arch/x86/msr.c
> @@ -34,10 +34,65 @@ struct msr_domain_policy __read_mostly     
> raw_msr_domain_policy,
>  struct msr_vcpu_policy __read_mostly hvm_max_msr_vcpu_policy,
>                         __read_mostly  pv_max_msr_vcpu_policy;
>  
> +static bool vmx_procbased_ctls2_available(const struct msr_domain_policy *dp)
> +{
> +    return dp->vmx.procbased_ctls.allowed_1.activate_secondary_controls;
> +}
> +
> +static bool vmx_ept_vpid_cap_available(const struct msr_domain_policy *dp)
> +{
> +    return dp->vmx_procbased_ctls2.allowed_1.enable_ept ||
> +           dp->vmx_procbased_ctls2.allowed_1.enable_vpid;
> +}
> +
> +static bool vmx_true_ctls_available(const struct msr_domain_policy *dp)
> +{
> +    return dp->vmx.basic.default1_zero;
> +}
> +
> +static bool vmx_vmfunc_available(const struct msr_domain_policy *dp)
> +{
> +    return dp->vmx_procbased_ctls2.allowed_1.enable_vm_functions;
> +}
> +
> +static void __init calculate_raw_vmx_policy(struct msr_domain_policy *dp)
> +{
> +    unsigned int i, start_msr, end_msr;
> +
> +    if ( !cpu_has_vmx )
> +        return;
> +
> +    start_msr = MSR_IA32_VMX_BASIC;
> +    end_msr = MSR_IA32_VMX_VMCS_ENUM;
> +    for ( i = start_msr; i <= end_msr; i++ )
> +        rdmsrl(i, dp->vmx.raw[i - start_msr]);
> +
> +    if ( vmx_procbased_ctls2_available(dp) )
> +        rdmsrl(MSR_IA32_VMX_PROCBASED_CTLS2, dp->vmx_procbased_ctls2.raw);
> +
> +    if ( vmx_ept_vpid_cap_available(dp) )
> +        rdmsrl(MSR_IA32_VMX_EPT_VPID_CAP, dp->vmx_ept_vpid_cap.raw);
> +
> +    if ( vmx_true_ctls_available(dp) )
> +    {
> +        start_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS;
> +        end_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS;
> +        for ( i = start_msr; i <= end_msr; i++ )
> +            rdmsrl(i, dp->vmx_true_ctls.raw[i - start_msr]);
> +    }
> +
> +    if ( vmx_vmfunc_available(dp) )
> +        rdmsrl(MSR_IA32_VMX_VMFUNC, dp->vmx_vmfunc.raw);
> +}
> +
>  static void __init calculate_raw_policy(void)
>  {
> +    struct msr_domain_policy *dp = &raw_msr_domain_policy;
> +
>      /* 0x000000ce  MSR_INTEL_PLATFORM_INFO */
>      /* Was already added by probe_cpuid_faulting() */
> +
> +    calculate_raw_vmx_policy(dp);
>  }
>  
>  static void __init calculate_host_policy(void)
> @@ -260,6 +315,69 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t 
> val)
>      return X86EMUL_EXCEPTION;
>  }
>  
> +static void __init __maybe_unused build_assertions(void)
> +{
> +    struct msr_domain_policy dp;
> +
> +    BUILD_BUG_ON(sizeof(dp.vmx.basic) !=
> +                 sizeof(dp.vmx.basic.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.pinbased_ctls) !=
> +                 sizeof(dp.vmx.pinbased_ctls.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.procbased_ctls) !=
> +                 sizeof(dp.vmx.procbased_ctls.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.exit_ctls) !=
> +                 sizeof(dp.vmx.exit_ctls.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.entry_ctls) !=
> +                 sizeof(dp.vmx.entry_ctls.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.misc) !=
> +                 sizeof(dp.vmx.misc.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.cr0_fixed0) !=
> +                 sizeof(dp.vmx.cr0_fixed0.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.cr0_fixed1) !=
> +                 sizeof(dp.vmx.cr0_fixed1.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.cr4_fixed0) !=
> +                 sizeof(dp.vmx.cr4_fixed0.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.cr4_fixed1) !=
> +                 sizeof(dp.vmx.cr4_fixed1.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.vmcs_enum) !=
> +                 sizeof(dp.vmx.vmcs_enum.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx.raw) !=
> +                     sizeof(dp.vmx.basic) +
> +                     sizeof(dp.vmx.pinbased_ctls) +
> +                     sizeof(dp.vmx.procbased_ctls) +
> +                     sizeof(dp.vmx.exit_ctls) +
> +                     sizeof(dp.vmx.entry_ctls) +
> +                     sizeof(dp.vmx.misc) +
> +                     sizeof(dp.vmx.cr0_fixed0) +
> +                     sizeof(dp.vmx.cr0_fixed1) +
> +                     sizeof(dp.vmx.cr4_fixed0) +
> +                     sizeof(dp.vmx.cr4_fixed1) +
> +                     sizeof(dp.vmx.vmcs_enum));
> +
> +    BUILD_BUG_ON(sizeof(dp.vmx_procbased_ctls2) !=
> +                 sizeof(dp.vmx_procbased_ctls2.raw));
> +
> +    BUILD_BUG_ON(sizeof(dp.vmx_ept_vpid_cap) !=
> +                 sizeof(dp.vmx_ept_vpid_cap.raw));
> +
> +    BUILD_BUG_ON(sizeof(dp.vmx_true_ctls.pinbased) !=
> +                 sizeof(dp.vmx_true_ctls.pinbased.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx_true_ctls.procbased) !=
> +                 sizeof(dp.vmx_true_ctls.procbased.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx_true_ctls.exit) !=
> +                 sizeof(dp.vmx_true_ctls.exit.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx_true_ctls.entry) !=
> +                 sizeof(dp.vmx_true_ctls.entry.raw));
> +    BUILD_BUG_ON(sizeof(dp.vmx_true_ctls.raw) !=
> +                     sizeof(dp.vmx_true_ctls.pinbased) +
> +                     sizeof(dp.vmx_true_ctls.procbased) +
> +                     sizeof(dp.vmx_true_ctls.exit) +
> +                     sizeof(dp.vmx_true_ctls.entry));
> +
> +    BUILD_BUG_ON(sizeof(dp.vmx_vmfunc) !=
> +                 sizeof(dp.vmx_vmfunc.raw));
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
> index a5072a2d5e..419ab6f8a7 100644
> --- a/xen/include/asm-x86/msr.h
> +++ b/xen/include/asm-x86/msr.h
> @@ -10,6 +10,7 @@
>  #include <xen/errno.h>
>  #include <asm/asm_defns.h>
>  #include <asm/cpufeature.h>
> +#include <asm/x86-defns.h>
>  
>  #define rdmsr(msr,val1,val2) \
>       __asm__ __volatile__("rdmsr" \
> @@ -222,6 +223,127 @@ static inline void wrmsr_tsc_aux(uint32_t val)
>      }
>  }
>  
> +union vmx_pin_based_exec_control_bits {

I don't think you need a _bits suffix on these union names, and I don't
think you need based in the middle of any of them.  I know that is how
the manual refers to them, but "pin controls" is equally as meaningful
as "pin based controls".

> +    uint32_t raw;
> +    struct {
> +        bool ext_intr_exiting:1;

I don't think we need any _exiting suffixes.  Enough context is
available from the control name.

> +        uint32_t             :2;  /* 1:2 reserved */
> +        bool      nmi_exiting:1;
> +        uint32_t             :1;  /* 4 reserved */
> +        bool     virtual_nmis:1;

vnmis ?

> +        bool    preempt_timer:1;
> +        bool posted_interrupt:1;
> +        uint32_t             :24; /* 8:31 reserved */
> +    };
> +};
> +
> +union vmx_cpu_based_exec_control_bits {
> +    uint32_t raw;
> +    struct {
> +        uint32_t                        :2;  /* 0:1 reserved */
> +        bool        virtual_intr_pending:1;
> +        bool           use_tsc_offseting:1;

tsc_offset ?

> +        uint32_t                        :3;  /* 4:6 reserved */
> +        bool                 hlt_exiting:1;
> +        uint32_t                        :1;  /* 8 reserved */
> +        bool              invlpg_exiting:1;
> +        bool               mwait_exiting:1;
> +        bool               rdpmc_exiting:1;
> +        bool               rdtsc_exiting:1;
> +        uint32_t                        :2;  /* 13:14 reserved */
> +        bool            cr3_load_exiting:1;
> +        bool           cr3_store_exiting:1;
> +        uint32_t                        :2;  /* 17:18 reserved */
> +        bool            cr8_load_exiting:1;
> +        bool           cr8_store_exiting:1;
> +        bool                  tpr_shadow:1;
> +        bool         virtual_nmi_pending:1;

vnmi_pending ?

> +        bool              mov_dr_exiting:1;
> +        bool           uncond_io_exiting:1;
> +        bool          activate_io_bitmap:1;

io_bitmap ?

> +        uint32_t                        :1;  /* 26 reserved */
> +        bool           monitor_trap_flag:1;

mtf is an abbreviation already used in the vm_event infrastructure.

> +        bool         activate_msr_bitmap:1;

msr_bitmap ?

> +        bool             monitor_exiting:1;
> +        bool               pause_exiting:1;
> +        bool activate_secondary_controls:1;

Simply just secondary?  It is the only name like this.

> +    };
> +};
> +
> +union vmx_vmexit_control_bits {
> +    uint32_t raw;
> +    struct {
> +        uint32_t                    :2;  /* 0:1 reserved */
> +        bool       save_debug_cntrls:1;

save_guest_debug ?  matches the later conventions.

> +        uint32_t                    :6;  /* 3:8 reserved */
> +        bool              ia32e_mode:1;
> +        uint32_t                    :2;  /* 10:11 reserved */
> +        bool   load_perf_global_ctrl:1;

the global in the middle is a bit redundant.

> +        uint32_t                    :2;  /* 13:14 reserved */
> +        bool        ack_intr_on_exit:1;

just ack_intr.  These are already the exit controls.

> +        uint32_t                    :2;  /* 16:17 reserved */
> +        bool          save_guest_pat:1;
> +        bool           load_host_pat:1;
> +        bool         save_guest_efer:1;
> +        bool          load_host_efer:1;
> +        bool      save_preempt_timer:1;
> +        bool           clear_bndcfgs:1;
> +        bool conceal_vmexits_from_pt:1;

conceal_from_pt?

> +        uint32_t                    :7;  /* 25:31 reserved */
> +    };
> +};
> +
> +union vmx_vmentry_control_bits {
> +    uint32_t raw;
> +    struct {
> +        uint32_t                        :2;  /* 0:1 reserved */
> +        bool           load_debug_cntrls:1;
> +        uint32_t                        :6;  /* 3:8 reserved */
> +        bool                  ia32e_mode:1;
> +        bool                         smm:1;
> +        bool          deact_dual_monitor:1;

deact isn't an obvious abbreviation.  Here, I'd actually go for the
longer "deactivate_dual_monitor".

OTOH, I wonder whether we should include any of the dual monitor
controls.  Xen isn't plausibly going to make use of them, although I
suppose we probably do need them to audit guest settings.

> +        uint32_t                        :1;  /* 12 reserved */
> +        bool       load_perf_global_ctrl:1;
> +        bool              load_guest_pat:1;
> +        bool             load_guest_efer:1;
> +        bool                load_bndcfgs:1;
> +        bool   conceal_vmentries_from_pt:1;
> +        uint32_t                        :14; /* 18:31 reserved */
> +    };
> +};
> +
> +union vmx_secondary_exec_control_bits {
> +    uint32_t raw;
> +    struct {
> +        bool    virtualize_apic_accesses:1;

This is annoying because I can't suggest an obviously better shorter
alternative.  We can probably drop the leading virtualise_ as these
fields are always in the context of the exec controls.

> +        bool                  enable_ept:1;

ept.

> +        bool    descriptor_table_exiting:1;

desc_table which again is an abbreviation already used by the monitor
subsystem.

> +        bool               enable_rdtscp:1;
> +        bool      virtualize_x2apic_mode:1;
> +        bool                 enable_vpid:1;
> +        bool              wbinvd_exiting:1;
> +        bool          unrestricted_guest:1;

Can probably get away with just unrestricted.  This particular field is
quite unique.

> +        bool          apic_register_virt:1;
> +        bool       virtual_intr_delivery:1;
> +        bool          pause_loop_exiting:1;

ple ?

> +        bool              rdrand_exiting:1;
> +        bool              enable_invpcid:1;
> +        bool         enable_vm_functions:1;

vmfunc.

> +        bool       enable_vmcs_shadowing:1;
> +        bool               encls_exiting:1;
> +        bool              rdseed_exiting:1;
> +        bool                  enable_pml:1;
> +        bool      enable_virt_exceptions:1;

ve.

> +        bool conceal_vmx_nonroot_from_pt:1;
> +        bool                      xsaves:1;
> +        uint32_t                        :1;  /* 21 reserved */
> +        bool   ept_mode_based_exec_cntrl:1;
> +        uint32_t                        :2;  /* 23:24 reserved */
> +        bool                 tsc_scaling:1;
> +        uint32_t                        :6;  /* 26:31 reserved */
> +    };
> +};
> +
>  /* MSR policy object for shared per-domain MSRs */
>  struct msr_domain_policy
>  {
> @@ -230,6 +352,214 @@ struct msr_domain_policy
>          bool available; /* This MSR is non-architectural */
>          bool cpuid_faulting;
>      } plaform_info;
> +
> +    union {
> +        uint64_t raw[MSR_IA32_VMX_VMCS_ENUM - MSR_IA32_VMX_BASIC + 1];
> +
> +        struct {
> +            /* 0x00000480  MSR_IA32_VMX_BASIC */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    uint32_t vmcs_revision_id:31;

vmcs_rev_id

> +                    bool                  mbz:1;  /* 31 always zero */

Is this really mbz?  Isn't this the shadow identifier bit for shadow vmcs's?

> +                    uint32_t vmcs_region_size:13;
> +                    uint32_t                 :3;  /* 45:47 reserved */
> +                    bool      addresses_32bit:1;
> +                    bool         dual_monitor:1;
> +                    uint32_t      memory_type:4;
> +                    bool         ins_out_info:1;
> +                    bool        default1_zero:1;
> +                    uint32_t                 :8;  /* 56:63 reserved */
> +                };
> +            } basic;
> +
> +            /* 0x00000481  MSR_IA32_VMX_PINBASED_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_pin_based_exec_control_bits allowed_0;
> +                    union vmx_pin_based_exec_control_bits allowed_1;
> +                };
> +            } pinbased_ctls;
> +
> +            /* 0x00000482  MSR_IA32_VMX_PROCBASED_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_cpu_based_exec_control_bits allowed_0;
> +                    union vmx_cpu_based_exec_control_bits allowed_1;
> +                };
> +            } procbased_ctls;
> +
> +            /* 0x00000483  MSR_IA32_VMX_EXIT_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_vmexit_control_bits allowed_0;
> +                    union vmx_vmexit_control_bits allowed_1;
> +                };
> +            } exit_ctls;
> +
> +            /* 0x00000484  MSR_IA32_VMX_ENTRY_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_vmentry_control_bits allowed_0;
> +                    union vmx_vmentry_control_bits allowed_1;
> +                };
> +            } entry_ctls;
> +
> +            /* 0x00000485  MSR_IA32_VMX_MISC */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    uint32_t      preempt_timer_scale:5;
> +                    bool            vmexit_stores_lma:1;
> +                    bool           hlt_activity_state:1;
> +                    bool      shutdown_activity_state:1;
> +                    bool wait_for_sipi_activity_state:1;
> +                    uint32_t                         :5;  /* 9:13 reserved */
> +                    bool                    pt_in_vmx:1;
> +                    bool          ia32_smbase_support:1;
> +                    uint32_t               cr3_target:9;
> +                    uint32_t       max_msr_load_count:3;
> +                    bool    ia32_smm_monitor_ctl_bit2:1;
> +                    bool                  vmwrite_all:1;
> +                    bool           inject_ilen0_event:1;
> +                    uint32_t                         :1;  /* 31 reserved */
> +                    uint32_t         mseg_revision_id;
> +                };
> +            } misc;
> +
> +            /* 0x00000486  MSR_IA32_VMX_CR0_FIXED0 */
> +            union {
> +                uint64_t raw;
> +                union cr0_bits allowed_0;

Hmm - it is rather unfortunate to have this allowed_0 infix, but I can't
think of a clean way of removing it.

The best I can think of is to have the contents of cr0_bits be a
define.  See CPUID_BITFIELD_ and DECL_BITFIELD(), although there is
probably no need to automatically generate the cr information.

> +            } cr0_fixed0;
> +
> +            /* 0x00000487  MSR_IA32_VMX_CR0_FIXED1 */
> +            union {
> +                uint64_t raw;
> +                union cr0_bits allowed_1;
> +            } cr0_fixed1;
> +
> +            /* 0x00000488  MSR_IA32_VMX_CR4_FIXED0 */
> +            union {
> +                uint64_t raw;
> +                union cr4_bits allowed_0;
> +            } cr4_fixed0;
> +
> +            /* 0x00000489  MSR_IA32_VMX_CR4_FIXED1 */
> +            union {
> +                uint64_t raw;
> +                union cr4_bits allowed_1;
> +            } cr4_fixed1;
> +
> +            /* 0x0000048A  MSR_IA32_VMX_VMCS_ENUM */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    uint32_t                      :1;  /* 0 reserved */
> +                    uint32_t vmcs_encoding_max_idx:9;

max_encoding ?

> +                    uint64_t                      :54; /* 10:63 reserved */
> +                };
> +            } vmcs_enum;
> +        };
> +    } vmx;
> +
> +    /* 0x0000048B  MSR_IA32_VMX_PROCBASED_CTLS2 */
> +    union {
> +        uint64_t raw;
> +        struct {
> +            union vmx_secondary_exec_control_bits allowed_0;
> +            union vmx_secondary_exec_control_bits allowed_1;
> +        };
> +    } vmx_procbased_ctls2;
> +
> +    /* 0x0000048C  MSR_IA32_VMX_EPT_VPID_CAP */
> +    union {
> +        uint64_t raw;
> +        struct {
> +            bool     exec_only_supported:1;

x_only ?

> +            uint32_t                    :5;  /* 1:5 reserved */
> +            bool walk_length_4_supported:1;

wl4 ?

> +            uint32_t                    :1;  /* 7 reserved */
> +            bool          memory_type_uc:1;

uc

> +            uint32_t                    :5;  /* 9:13 reserved */
> +            bool          memory_type_wb:1;

wb

> +            uint32_t                    :1;  /* 15 reserved */
> +            bool           superpage_2mb:1;
> +            bool           superpage_1gb:1;

_2mb and _1gb respectively.

> +            uint32_t                    :2;  /* 18:19 reserved */
> +            bool      invept_instruction:1;

the _instruction suffix doesn't add anything.

> +            bool                  ad_bit:1;
> +            bool advanced_ept_violations:1;
> +            uint32_t                    :2;  /* 23:24 reserved */
> +            bool   invept_single_context:1;
> +            bool      invept_all_context:1;

The _context suffixes probably aren't helpful here.

> +            uint32_t                    :5;  /* 27:31 reserved */
> +            bool     invvpid_instruction:1;
> +            uint32_t                    :7;  /* 33:39 reserved */
> +            bool invvpid_individual_addr:1;
> +            bool  invvpid_single_context:1;
> +            bool     invvpid_all_context:1;
> +            bool invvpid_single_context_retaining_global:1;

invvpid_single_nonglobal?

~Andrew

> +            uint32_t                    :20; /* 44:63 reserved */
> +        };
> +    } vmx_ept_vpid_cap;
> +
> +    union {
> +        uint64_t raw[MSR_IA32_VMX_TRUE_ENTRY_CTLS -
> +                     MSR_IA32_VMX_TRUE_PINBASED_CTLS + 1];
> +
> +        struct {
> +            /* 0x0000048D  MSR_IA32_VMX_TRUE_PINBASED_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_pin_based_exec_control_bits allowed_0;
> +                    union vmx_pin_based_exec_control_bits allowed_1;
> +                };
> +            } pinbased;
> +
> +            /* 0x0000048E  MSR_IA32_VMX_TRUE_PROCBASED_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_cpu_based_exec_control_bits allowed_0;
> +                    union vmx_cpu_based_exec_control_bits allowed_1;
> +                };
> +            } procbased;
> +
> +            /* 0x0000048F  MSR_IA32_VMX_TRUE_EXIT_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_vmexit_control_bits allowed_0;
> +                    union vmx_vmexit_control_bits allowed_1;
> +                };
> +            } exit;
> +
> +            /* 0x00000490  MSR_IA32_VMX_TRUE_ENTRY_CTLS */
> +            union {
> +                uint64_t raw;
> +                struct {
> +                    union vmx_vmentry_control_bits allowed_0;
> +                    union vmx_vmentry_control_bits allowed_1;
> +                };
> +            } entry;
> +        };
> +    } vmx_true_ctls;
> +
> +    /* 0x00000491  MSR_IA32_VMX_VMFUNC */
> +    union {
> +        uint64_t raw;
> +        struct {
> +            bool eptp_switching:1;
> +            uint64_t           :63; /* 1:63 reserved */
> +        };
> +    } vmx_vmfunc;
>  };
>  
>  /* RAW msr domain policy: contains the actual values from H/W MSRs */
> diff --git a/xen/include/asm-x86/x86-defns.h b/xen/include/asm-x86/x86-defns.h
> index 70453e8dfb..ff2f59e732 100644
> --- a/xen/include/asm-x86/x86-defns.h
> +++ b/xen/include/asm-x86/x86-defns.h
> @@ -42,6 +42,28 @@
>  #define X86_CR0_CD              0x40000000 /* Cache Disable            (RW) 
> */
>  #define X86_CR0_PG              0x80000000 /* Paging                   (RW) 
> */
>  
> +#ifndef __ASSEMBLY__
> +union cr0_bits {
> +    uint64_t raw;
> +    struct {
> +        bool     pe:1;
> +        bool     mp:1;
> +        bool     em:1;
> +        bool     ts:1;
> +        bool     et:1;
> +        bool     ne:1;
> +        uint32_t   :10; /* 6:15 reserved */
> +        bool     wp:1;
> +        uint32_t   :1;  /* 17 reserved */
> +        bool     am:1;
> +        uint32_t   :10; /* 19:28 reserved */
> +        bool     nw:1;
> +        bool     cd:1;
> +        bool     pg:1;
> +    };
> +};
> +#endif /* #ifndef __ASSEMBLY__ */
> +
>  /*
>   * Intel CPU features in CR4
>   */
> @@ -66,4 +88,36 @@
>  #define X86_CR4_SMAP       0x00200000 /* enable SMAP */
>  #define X86_CR4_PKE        0x00400000 /* enable PKE */
>  
> +#ifndef __ASSEMBLY__
> +union cr4_bits {
> +    uint64_t raw;
> +    struct {
> +        bool        vme:1;
> +        bool        pvi:1;
> +        bool        tsd:1;
> +        bool         de:1;
> +        bool        pse:1;
> +        bool        pae:1;
> +        bool        mce:1;
> +        bool        pge:1;
> +        bool        pce:1;
> +        bool     osfxsr:1;
> +        bool osxmmexcpt:1;
> +        bool       umip:1;
> +        uint32_t       :1;  /* 12 reserved */
> +        bool       vmxe:1;
> +        bool       smxe:1;
> +        uint32_t       :1;  /* 15 reserved */
> +        bool   fsgsbase:1;
> +        bool      pcide:1;
> +        bool    osxsave:1;
> +        uint32_t       :1;  /* 19 reserved */
> +        bool       smep:1;
> +        bool       smap:1;
> +        bool        pke:1;
> +        uint32_t       :9;  /* 23:31 reserved */
> +    };
> +};
> +#endif /* #ifndef __ASSEMBLY__ */
> +
>  #endif       /* __XEN_X86_DEFNS_H__ */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.