[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |