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

[Xen-devel] [PATCH v7 01/19] xen: add PV/PVH kernel entry point



Add the PV/PVH entry point and the low level functions for PVH
initialization.
---
 sys/amd64/amd64/locore.S     |   53 +++++++++++++++++++++++++++++++
 sys/amd64/amd64/machdep.c    |   72 ++++++++++++++++++++++++++++++++++++++++++
 sys/amd64/include/asmacros.h |   26 +++++++++++++++
 sys/i386/xen/xen_machdep.c   |    2 +
 sys/x86/xen/hvm.c            |    1 +
 sys/xen/xen-os.h             |    4 ++
 6 files changed, 158 insertions(+), 0 deletions(-)

diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S
index 55cda3a..e04cc48 100644
--- a/sys/amd64/amd64/locore.S
+++ b/sys/amd64/amd64/locore.S
@@ -31,6 +31,12 @@
 #include <machine/pmap.h>
 #include <machine/specialreg.h>
 
+#ifdef XENHVM
+#include <xen/xen-os.h>
+#define __ASSEMBLY__
+#include <xen/interface/elfnote.h>
+#endif
+
 #include "assym.s"
 
 /*
@@ -86,3 +92,50 @@ NON_GPROF_ENTRY(btext)
        ALIGN_DATA                      /* just to be sure */
        .space  0x1000                  /* space for bootstack - temporary 
stack */
 bootstack:
+
+#ifdef XENHVM
+/* Xen */
+.section __xen_guest
+       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "FreeBSD")
+       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "HEAD")
+       ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
+       ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .quad,  KERNBASE)
+       ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  KERNBASE) /* Xen 
honours elf->p_paddr; compensate for this */
+       ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  xen_start)
+       ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,  hypercall_page)
+       ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .quad,  HYPERVISOR_VIRT_START)
+       ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, 
"writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector")
+       ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
+       ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PG_V, PG_V)
+       ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
+       ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long,  0)
+       ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB,     .asciz, "yes")
+
+       .text
+.p2align PAGE_SHIFT, 0x90      /* Hypercall_page needs to be PAGE aligned */
+
+NON_GPROF_ENTRY(hypercall_page)
+       .skip   0x1000, 0x90    /* Fill with "nop"s */
+
+NON_GPROF_ENTRY(xen_start)
+       /* Don't trust what the loader gives for rflags. */
+       pushq   $PSL_KERNEL
+       popfq
+
+       /* Parameters for the xen init function */
+       movq    %rsi, %rdi              /* shared_info (arg 1) */
+       movq    %rsp, %rsi              /* xenstack    (arg 2) */
+
+       /* Use our own stack */
+       movq    $bootstack,%rsp
+       xorl    %ebp, %ebp
+
+       /* u_int64_t hammer_time_xen(start_info_t *si, u_int64_t xenstack); */
+       call    hammer_time_xen
+       movq    %rax, %rsp              /* set up kstack for mi_startup() */
+       call    mi_startup              /* autoconfiguration, mountroot etc */
+
+       /* NOTREACHED */
+0:     hlt
+       jmp     0b
+#endif
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index eae657b..a73e33e 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -146,10 +146,17 @@ __FBSDID("$FreeBSD$");
 #include <isa/isareg.h>
 #include <isa/rtc.h>
 
+#ifdef XENHVM
+#include <xen/xen-os.h>
+#endif
+
 /* Sanity check for __curthread() */
 CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
 
 extern u_int64_t hammer_time(u_int64_t, u_int64_t);
+#ifdef XENHVM
+extern u_int64_t hammer_time_xen(start_info_t *, u_int64_t);
+#endif
 
 extern void printcpuinfo(void);        /* XXX header file */
 extern void identify_cpu(void);
@@ -1683,6 +1690,71 @@ do_next:
        msgbufp = (struct msgbuf *)PHYS_TO_DMAP(phys_avail[pa_indx]);
 }
 
+#ifdef XENHVM
+/*
+ * First function called by the Xen PVH boot sequence.
+ *
+ * Set some Xen global variables and prepare the environment so it is
+ * as similar as possible to what native FreeBSD init function expects.
+ */
+u_int64_t
+hammer_time_xen(start_info_t *si, u_int64_t xenstack)
+{
+       u_int64_t physfree;
+       u_int64_t *PT4 = (u_int64_t *)xenstack;
+       u_int64_t *PT3 = (u_int64_t *)(xenstack + PAGE_SIZE);
+       u_int64_t *PT2 = (u_int64_t *)(xenstack + 2 * PAGE_SIZE);
+       int i;
+
+       KASSERT((si != NULL && xenstack != 0),
+               ("invalid start_info or xenstack"));
+
+       /* We use 3 pages of xen stack for the boot pagetables */
+       physfree = xenstack + 3 * PAGE_SIZE - KERNBASE;
+
+       /* Setup Xen global variables */
+       HYPERVISOR_start_info = si;
+       HYPERVISOR_shared_info =
+               (shared_info_t *)(si->shared_info + KERNBASE);
+
+       /*
+        * Setup some misc global variables for Xen devices
+        *
+        * XXX: devices that need this specific variables should
+        *      be rewritten to fetch this info by themselves from the
+        *      start_info page.
+        */
+       xen_store = (struct xenstore_domain_interface *)
+                   (ptoa(si->store_mfn) + KERNBASE);
+
+       xen_domain_type = XEN_PV_DOMAIN;
+       vm_guest = VM_GUEST_XEN;
+
+       /*
+        * Use the stack Xen gives us to build the page tables
+        * as native FreeBSD expects to find them (created
+        * by the boot trampoline).
+        */
+       for (i = 0; i < 512; i++) {
+               /* Each slot of the level 4 pages points to the same level 3 
page */
+               PT4[i] = ((u_int64_t)&PT3[0]) - KERNBASE;
+               PT4[i] |= PG_V | PG_RW | PG_U;
+
+               /* Each slot of the level 3 pages points to the same level 2 
page */
+               PT3[i] = ((u_int64_t)&PT2[0]) - KERNBASE;
+               PT3[i] |= PG_V | PG_RW | PG_U;
+
+               /* The level 2 page slots are mapped with 2MB pages for 1GB. */
+               PT2[i] = i * (2 * 1024 * 1024);
+               PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+       }
+       load_cr3(((u_int64_t)&PT4[0]) - KERNBASE);
+
+       /* Now we can jump into the native init function */
+       return (hammer_time(0, physfree));
+}
+#endif
+
 u_int64_t
 hammer_time(u_int64_t modulep, u_int64_t physfree)
 {
diff --git a/sys/amd64/include/asmacros.h b/sys/amd64/include/asmacros.h
index 1fb592a..ce8dce4 100644
--- a/sys/amd64/include/asmacros.h
+++ b/sys/amd64/include/asmacros.h
@@ -201,4 +201,30 @@
 
 #endif /* LOCORE */
 
+#ifdef __STDC__
+#define ELFNOTE(name, type, desctype, descdata...) \
+.pushsection .note.name                 ;       \
+  .align 4                              ;       \
+  .long 2f - 1f         /* namesz */    ;       \
+  .long 4f - 3f         /* descsz */    ;       \
+  .long type                            ;       \
+1:.asciz #name                          ;       \
+2:.align 4                              ;       \
+3:desctype descdata                     ;       \
+4:.align 4                              ;       \
+.popsection
+#else /* !__STDC__, i.e. -traditional */
+#define ELFNOTE(name, type, desctype, descdata) \
+.pushsection .note.name                 ;       \
+  .align 4                              ;       \
+  .long 2f - 1f         /* namesz */    ;       \
+  .long 4f - 3f         /* descsz */    ;       \
+  .long type                            ;       \
+1:.asciz "name"                         ;       \
+2:.align 4                              ;       \
+3:desctype descdata                     ;       \
+4:.align 4                              ;       \
+.popsection
+#endif /* __STDC__ */
+
 #endif /* !_MACHINE_ASMACROS_H_ */
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index 7049be6..fd575ee 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -89,6 +89,7 @@ IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), 
IDTVEC(ofl),
 
 int xendebug_flags; 
 start_info_t *xen_start_info;
+start_info_t *HYPERVISOR_start_info;
 shared_info_t *HYPERVISOR_shared_info;
 xen_pfn_t *xen_machine_phys = machine_to_phys_mapping;
 xen_pfn_t *xen_phys_machine;
@@ -927,6 +928,7 @@ initvalues(start_info_t *startinfo)
        HYPERVISOR_vm_assist(VMASST_CMD_enable, 
VMASST_TYPE_4gb_segments_notify);       
 #endif 
        xen_start_info = startinfo;
+       HYPERVISOR_start_info = startinfo;
        xen_phys_machine = (xen_pfn_t *)startinfo->mfn_list;
 
        IdlePTD = (pd_entry_t *)((uint8_t *)startinfo->pt_base + PAGE_SIZE);
diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index 72811dc..b397721 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -159,6 +159,7 @@ DPCPU_DEFINE(xen_intr_handle_t, 
ipi_handle[nitems(xen_ipis)]);
 /** Hypercall table accessed via HYPERVISOR_*_op() methods. */
 char *hypercall_stubs;
 shared_info_t *HYPERVISOR_shared_info;
+start_info_t *HYPERVISOR_start_info;
 
 #ifdef SMP
 /*---------------------------- XEN PV IPI Handlers 
---------------------------*/
diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h
index 87644e9..c7474d8 100644
--- a/sys/xen/xen-os.h
+++ b/sys/xen/xen-os.h
@@ -51,6 +51,10 @@
 void force_evtchn_callback(void);
 
 extern shared_info_t *HYPERVISOR_shared_info;
+extern start_info_t *HYPERVISOR_start_info;
+
+/* XXX: we need to get rid of this and use HYPERVISOR_start_info directly */
+extern struct xenstore_domain_interface *xen_store;
 
 enum xen_domain_type {
        XEN_NATIVE,             /* running on bare hardware    */
-- 
1.7.7.5 (Apple Git-26)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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