@@ -216,6 +216,48 @@ 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 p;
+
+ BUILD_BUG_ON(sizeof(p.vmx_basic.u) !=
+ sizeof(p.vmx_basic.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_pinbased_ctls.u) !=
+ sizeof(p.vmx_pinbased_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_procbased_ctls.u) !=
+ sizeof(p.vmx_procbased_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_exit_ctls.u) !=
+ sizeof(p.vmx_exit_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_entry_ctls.u) !=
+ sizeof(p.vmx_entry_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_misc.u) !=
+ sizeof(p.vmx_misc.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_cr0_fixed0.u) !=
+ sizeof(p.vmx_cr0_fixed0.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_cr0_fixed1.u) !=
+ sizeof(p.vmx_cr0_fixed1.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_cr4_fixed0.u) !=
+ sizeof(p.vmx_cr4_fixed0.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_cr4_fixed1.u) !=
+ sizeof(p.vmx_cr4_fixed1.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_vmcs_enum.u) !=
+ sizeof(p.vmx_vmcs_enum.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_procbased_ctls2.u) !=
+ sizeof(p.vmx_procbased_ctls2.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_ept_vpid_cap.u) !=
+ sizeof(p.vmx_ept_vpid_cap.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_true_pinbased_ctls.u) !=
+ sizeof(p.vmx_true_pinbased_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_true_procbased_ctls.u) !=
+ sizeof(p.vmx_true_procbased_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_true_exit_ctls.u) !=
+ sizeof(p.vmx_true_exit_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_true_entry_ctls.u) !=
+ sizeof(p.vmx_true_entry_ctls.u.raw));
+ BUILD_BUG_ON(sizeof(p.vmx_vmfunc.u) !=
+ sizeof(p.vmx_vmfunc.u.raw));
+}
+
/*
* Local variables:
* mode: C
@@ -202,6 +202,171 @@ void write_efer(u64 val);
DECLARE_PER_CPU(u32, ler_msr);
+union vmx_pin_based_exec_control_bits {
+ uint32_t raw;
+ struct {
+ bool ext_intr_exiting:1;
+ uint32_t :2; /* 1:2 reserved */
+ bool nmi_exiting:1;
+ uint32_t :1; /* 4 reserved */
+ bool virtual_nmis:1;
+ 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;
+ 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;
+ bool mov_dr_exiting:1;
+ bool uncond_io_exiting:1;
+ bool activate_io_bitmap:1;
+ uint32_t :1; /* 26 reserved */
+ bool monitor_trap_flag:1;
+ bool activate_msr_bitmap:1;
+ bool monitor_exiting:1;
+ bool pause_exiting:1;
+ bool activate_secondary_controls:1;
+ };
+};
+
+union vmx_vmexit_control_bits {
+ uint32_t raw;
+ struct {
+ uint32_t :2; /* 0:1 reserved */
+ bool save_debug_cntrls:1;
+ uint32_t :6; /* 3:8 reserved */
+ bool ia32e_mode:1;
+ uint32_t :2; /* 10:11 reserved */
+ bool load_perf_global_ctrl:1;
+ uint32_t :2; /* 13:14 reserved */
+ bool ack_intr_on_exit:1;
+ 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;
+ 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;
+ 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;
+ bool enable_ept:1;
+ bool descriptor_table_exiting:1;
+ bool enable_rdtscp:1;
+ bool virtualize_x2apic_mode:1;
+ bool enable_vpid:1;
+ bool wbinvd_exiting:1;
+ bool unrestricted_guest:1;
+ bool apic_register_virt:1;
+ bool virtual_intr_delivery:1;
+ bool pause_loop_exiting:1;
+ bool rdrand_exiting:1;
+ bool enable_invpcid:1;
+ bool enable_vm_functions:1;
+ bool enable_vmcs_shadowing:1;
+ bool encls_exiting:1;
+ bool rdseed_exiting:1;
+ bool enable_pml:1;
+ bool enable_virt_exceptions:1;
+ 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 */
+ };
+};
+
+struct cr0_bits {
+ 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;
+};
+
+struct cr4_bits {
+ 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 */
+};
+
/* MSR policy object for shared per-domain MSRs */
struct msr_domain_policy
{
@@ -210,6 +375,255 @@ struct msr_domain_policy
bool available; /* This MSR is non-architectural */
bool cpuid_faulting;
} plaform_info;
+
+ /* 0x00000480 MSR_IA32_VMX_BASIC */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ uint32_t vmcs_revision_id:31;
+ bool mbz:1; /* 31 always zero */
+ 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 */
+ };
+ } u;
+ } vmx_basic;
+
+ /* 0x00000481 MSR_IA32_VMX_PINBASED_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_pin_based_exec_control_bits allowed_0;
+ union vmx_pin_based_exec_control_bits allowed_1;
+ };
+ } u;
+ } vmx_pinbased_ctls;
+
+ /* 0x00000482 MSR_IA32_VMX_PROCBASED_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_cpu_based_exec_control_bits allowed_0;
+ union vmx_cpu_based_exec_control_bits allowed_1;
+ };
+ } u;
+ } vmx_procbased_ctls;
+
+ /* 0x00000483 MSR_IA32_VMX_EXIT_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_vmexit_control_bits allowed_0;
+ union vmx_vmexit_control_bits allowed_1;
+ };
+ } u;
+ } vmx_exit_ctls;
+
+ /* 0x00000484 MSR_IA32_VMX_ENTRY_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_vmentry_control_bits allowed_0;
+ union vmx_vmentry_control_bits allowed_1;
+ };
+ } u;
+ } vmx_entry_ctls;
+
+ /* 0x00000485 MSR_IA32_VMX_MISC */
+ struct {
+ bool available;
+ 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;
+ };
+ } u;
+ } vmx_misc;
+
+ /* 0x00000486 MSR_IA32_VMX_CR0_FIXED0 */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct cr0_bits allowed_0;
+ } u;
+ } vmx_cr0_fixed0;
+
+ /* 0x00000487 MSR_IA32_VMX_CR0_FIXED1 */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct cr0_bits allowed_1;
+ } u;
+ } vmx_cr0_fixed1;
+
+ /* 0x00000488 MSR_IA32_VMX_CR4_FIXED0 */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct cr4_bits allowed_0;
+ } u;
+ } vmx_cr4_fixed0;
+
+ /* 0x00000489 MSR_IA32_VMX_CR4_FIXED1 */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct cr4_bits allowed_1;
+ } u;
+ } vmx_cr4_fixed1;
+
+ /* 0x0000048A MSR_IA32_VMX_VMCS_ENUM */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ uint32_t :1; /* 0 reserved */
+ uint32_t vmcs_encoding_max_idx:9;
+ uint64_t :54; /* 10:63 reserved */
+ };
+ } u;
+ } vmx_vmcs_enum;
+
+ /* 0x0000048B MSR_IA32_VMX_PROCBASED_CTLS2 */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_secondary_exec_control_bits allowed_0;
+ union vmx_secondary_exec_control_bits allowed_1;
+ };
+ } u;
+ } vmx_procbased_ctls2;
+
+ /* 0x0000048C MSR_IA32_VMX_EPT_VPID_CAP */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ bool exec_only_supported:1;
+ uint32_t :5; /* 1:5 reserved */
+ bool walk_length_4_supported:1;
+ uint32_t :1; /* 7 reserved */
+ bool memory_type_uc:1;
+ uint32_t :5; /* 9:13 reserved */
+ bool memory_type_wb:1;
+ uint32_t :1; /* 15 reserved */
+ bool superpage_2mb:1;
+ bool superpage_1gb:1;
+ uint32_t :2; /* 18:19 reserved */
+ bool invept_instruction:1;
+ 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;
+ 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;
+ uint32_t :20; /* 44:63 reserved */
+ };
+ } u;
+ } vmx_ept_vpid_cap;
+
+ /* 0x0000048D MSR_IA32_VMX_TRUE_PINBASED_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_pin_based_exec_control_bits allowed_0;
+ union vmx_pin_based_exec_control_bits allowed_1;
+ };
+ } u;
+ } vmx_true_pinbased_ctls;
+
+ /* 0x0000048E MSR_IA32_VMX_TRUE_PROCBASED_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_cpu_based_exec_control_bits allowed_0;
+ union vmx_cpu_based_exec_control_bits allowed_1;
+ };
+ } u;
+ } vmx_true_procbased_ctls;
+
+ /* 0x0000048F MSR_IA32_VMX_TRUE_EXIT_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_vmexit_control_bits allowed_0;
+ union vmx_vmexit_control_bits allowed_1;
+ };
+ } u;
+ } vmx_true_exit_ctls;
+
+ /* 0x00000490 MSR_IA32_VMX_TRUE_ENTRY_CTLS */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ union vmx_vmentry_control_bits allowed_0;
+ union vmx_vmentry_control_bits allowed_1;
+ };
+ } u;
+ } vmx_true_entry_ctls;
+
+ /* 0x00000491 MSR_IA32_VMX_VMFUNC */
+ struct {
+ bool available;
+ union {
+ uint64_t raw;
+ struct {
+ bool eptp_switching:1;
+ uint64_t :63; /* 1:63 reserved */
+ };
+ } u;
+ } vmx_vmfunc;
};
/* MSR policy object for per-vCPU MSRs */
New definitions provide a convenient way of accessing contents of VMX MSRs: every bit value is accessible by its name and there is a "raw" 64-bit msr value. Bit names match existing Xen's definitions as close as possible. Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com> --- xen/arch/x86/msr.c | 42 +++++ xen/include/asm-x86/msr.h | 414 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 456 insertions(+)