From: Anthony Liguori <aligu...@amazon.com>

We split initialization of Vixen into two parts.  The first part
just detects the presence of an HVM hypervisor so that we can
figure out whether to modify the e820 table.

The later initialization is used to actually map the shared_info
structure from the parent hypervisor into Xen.

Signed-off-by: Anthony Liguori <aligu...@amazon.com>
---
v1 -> v2
 - allow disabling vixen by specifying vixen_domid=-1 on command line
 - use hvm_info_table for reserved region if still valid
 - use reserved region for shared_info instead of BSS
---
 xen/arch/x86/guest/vixen.c        | 76 +++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/setup.c              |  5 +++
 xen/include/asm-x86/guest/vixen.h |  4 +++
 3 files changed, 85 insertions(+)

diff --git a/xen/arch/x86/guest/vixen.c b/xen/arch/x86/guest/vixen.c
index cacbe69..1ad5bd7 100644
--- a/xen/arch/x86/guest/vixen.c
+++ b/xen/arch/x86/guest/vixen.c
@@ -20,13 +20,89 @@
  */
 
 #include <asm/guest/vixen.h>
+#include <public/version.h>
+#include <public/hvm/hvm_info_table.h>
+
+#define X86_HVM_END_SPECIAL_REGION  0xff000u
+
+#define SHARED_INFO_PFN                (X86_HVM_END_SPECIAL_REGION + 0)
 
 static int in_vixen;
 static int vixen_domid = 1;
 static uint32_t vixen_reserved_mem_pgstart = 0xfeff0000;
+static shared_info_t *global_si;
 
 integer_param("vixen_domid", vixen_domid);
 
+void __init init_vixen(void)
+{
+    int major, minor, version;
+    struct hvm_info_table *hvm_info;
+
+    if ( !xen_guest )
+    {
+        printk("Disabling Vixen because we are not running under Xen\n");
+        in_vixen = -1;
+        return;
+    }
+
+    if ( vixen_domid < 0 )
+    {
+        printk("Disabling Vixen due to user request\n");
+        in_vixen = -1;
+        return;
+    }
+
+    version = HYPERVISOR_xen_version(XENVER_version, NULL);
+    major = version >> 16;
+    minor = version & 0xffff;
+
+    printk("Vixen running under Xen %d.%d\n", major, minor);
+
+    hvm_info = maddr_to_virt(HVM_INFO_PADDR);
+    if ( strncmp(hvm_info->signature, "HVM INFO", 8) == 0 &&
+        hvm_info->length >= sizeof(struct hvm_info_table) &&
+        hvm_info->length < (PAGE_SIZE - HVM_INFO_OFFSET) )
+    {
+       uint8_t sum;
+       uint32_t i;
+
+       for ( i = 0, sum = 0; i < hvm_info->length; i++ )
+           sum += ((uint8_t *)hvm_info)[i];
+
+       if ( sum == 0 )
+       {
+           vixen_reserved_mem_pgstart = hvm_info->reserved_mem_pgstart << 
XEN_PAGE_SHIFT;
+       }
+    }
+
+    in_vixen = 1;
+}
+
+void __init early_vixen_init(void)
+{
+    struct xen_add_to_physmap xatp;
+    long rc;
+
+    if ( !is_vixen() )
+       return;
+
+    global_si = mfn_to_virt(SHARED_INFO_PFN);
+
+    /* Setup our own shared info area */
+    xatp.domid = DOMID_SELF;
+    xatp.idx = 0;
+    xatp.space = XENMAPSPACE_shared_info;
+    xatp.gpfn = virt_to_mfn(global_si);
+
+    rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
+    if ( rc < 0 )
+        printk("Setting shared info page failed: %ld\n", rc);
+
+    memset(&global_si->native.evtchn_mask[0], 0x00,
+           sizeof(global_si->native.evtchn_mask));
+}
+
 bool is_vixen(void)
 {
     return in_vixen > 0;
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index f9d087e..07239c0 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -869,6 +869,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     else
         panic("Bootloader provided no memory information.");
 
+    /* Vixen must be initialized before init_e820() */
+    init_vixen();
+
     /* Sanitise the raw E820 map to produce a final clean version. */
     max_page = raw_max_page = init_e820(memmap_type, &e820_raw);
 
@@ -1516,6 +1519,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     rcu_init();
 
+    early_vixen_init();
+
     early_time_init();
 
     arch_init_memory();
diff --git a/xen/include/asm-x86/guest/vixen.h 
b/xen/include/asm-x86/guest/vixen.h
index fb8e871..0c040ee 100644
--- a/xen/include/asm-x86/guest/vixen.h
+++ b/xen/include/asm-x86/guest/vixen.h
@@ -74,4 +74,8 @@ int vixen_get_domid(void);
 
 void vixen_get_reserved_mem(unsigned long *start_pfn, unsigned long *end_pfn);
 
+void __init init_vixen(void);
+
+void __init early_vixen_init(void);
+
 #endif
-- 
1.9.1


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

Reply via email to