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

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



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>
---
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 {
+    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 */
+    };
+};
+
 /* 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;
+                    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 */
+                };
+            } 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;
+            } 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;
+                    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;
+            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 */
+        };
+    } 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__ */
-- 
2.14.1


_______________________________________________
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®.