xen: add PV/PVH kernel entry point
Add the PV/PVH entry point and the low level functions for PVH early initialization. Approved by: gibbs Sponsored by: Citrix Systems R&D amd64/amd64/genassym.c: - Add __FreeBSD_version define to assym.s so it can be used for the Xen notes. amd64/amd64/locore.S: - Make bootstack global so it can be used from Xen kernel entry point. amd64/amd64/xen-locore.S: - Add Xen notes to the kernel. - Add the Xen PV entry point, that is going to call hammer_time_xen. amd64/include/asmacros.h: - Add ELFNOTE macros. i386/xen/xen_machdep.c: - Define HYPERVISOR_start_info for the XEN i386 PV port, which is going to be used in some shared code between PV and PVH. x86/xen/hvm.c: - Define HYPERVISOR_start_info for the PVH port. x86/xen/pv.c: - Introduce hammer_time_xen which is going to perform early setup for Xen PVH: - Setup shared Xen variables start_info, shared_info and xen_store. - Set guest type. - Create initial page tables as FreeBSD expects to find them. - Call into native init function (hammer_time). xen/xen-os.h: - Declare HYPERVISOR_start_info. conf/files.amd64: - Add amd64/amd64/locore.S and x86/xen/pv.c to the list of files.
This commit is contained in:
parent
27026f4f2a
commit
5dd05db7ff
@ -248,6 +248,8 @@ ASSYM(TSSSEL, GSEL(GPROC0_SEL, SEL_KPL));
|
||||
ASSYM(LDTSEL, GSEL(GUSERLDT_SEL, SEL_KPL));
|
||||
ASSYM(SEL_RPL_MASK, SEL_RPL_MASK);
|
||||
|
||||
ASSYM(__FreeBSD_version, __FreeBSD_version);
|
||||
|
||||
#ifdef HWPMC_HOOKS
|
||||
ASSYM(PMC_FN_USER_CALLCHAIN, PMC_FN_USER_CALLCHAIN);
|
||||
#endif
|
||||
|
@ -84,5 +84,6 @@ NON_GPROF_ENTRY(btext)
|
||||
|
||||
.bss
|
||||
ALIGN_DATA /* just to be sure */
|
||||
.globl bootstack
|
||||
.space 0x1000 /* space for bootstack - temporary stack */
|
||||
bootstack:
|
||||
|
83
sys/amd64/amd64/xen-locore.S
Normal file
83
sys/amd64/amd64/xen-locore.S
Normal file
@ -0,0 +1,83 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
|
||||
* Copyright (c) 2013 Roger Pau Monne <royger@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <machine/asmacros.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/specialreg.h>
|
||||
|
||||
#include <xen/xen-os.h>
|
||||
#define __ASSEMBLY__
|
||||
#include <xen/interface/elfnote.h>
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
.section __xen_guest
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD")
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, __XSTRING(__FreeBSD_version))
|
||||
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
|
@ -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_ */
|
||||
|
@ -108,6 +108,7 @@ amd64/amd64/in_cksum.c optional inet | inet6
|
||||
amd64/amd64/initcpu.c standard
|
||||
amd64/amd64/io.c optional io
|
||||
amd64/amd64/locore.S standard no-obj
|
||||
amd64/amd64/xen-locore.S optional xenhvm
|
||||
amd64/amd64/machdep.c standard
|
||||
amd64/amd64/mem.c optional mem
|
||||
amd64/amd64/minidump_machdep.c standard
|
||||
@ -555,3 +556,4 @@ x86/x86/nexus.c standard
|
||||
x86/x86/tsc.c standard
|
||||
x86/xen/hvm.c optional xenhvm
|
||||
x86/xen/xen_intr.c optional xen | xenhvm
|
||||
x86/xen/pv.c optional xenhvm
|
||||
|
@ -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);
|
||||
|
@ -149,6 +149,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 ---------------------------*/
|
||||
|
119
sys/x86/xen/pv.c
Normal file
119
sys/x86/xen/pv.c
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Christian Limpach.
|
||||
* Copyright (c) 2004-2006,2008 Kip Macy
|
||||
* Copyright (c) 2013 Roger Pau Monné <roger.pau@citrix.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/rwlock.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_object.h>
|
||||
#include <vm/vm_pager.h>
|
||||
#include <vm/vm_param.h>
|
||||
|
||||
#include <xen/xen-os.h>
|
||||
#include <xen/hypervisor.h>
|
||||
|
||||
/* Native initial function */
|
||||
extern u_int64_t hammer_time(u_int64_t, u_int64_t);
|
||||
/* Xen initial function */
|
||||
uint64_t hammer_time_xen(start_info_t *, uint64_t);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
uint64_t
|
||||
hammer_time_xen(start_info_t *si, uint64_t xenstack)
|
||||
{
|
||||
uint64_t physfree;
|
||||
uint64_t *PT4 = (u_int64_t *)xenstack;
|
||||
uint64_t *PT3 = (u_int64_t *)(xenstack + PAGE_SIZE);
|
||||
uint64_t *PT2 = (u_int64_t *)(xenstack + 2 * PAGE_SIZE);
|
||||
int i;
|
||||
|
||||
xen_domain_type = XEN_PV_DOMAIN;
|
||||
vm_guest = VM_GUEST_XEN;
|
||||
|
||||
if ((si == NULL) || (xenstack == 0)) {
|
||||
HYPERVISOR_shutdown(SHUTDOWN_crash);
|
||||
}
|
||||
|
||||
/* 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 these 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);
|
||||
|
||||
/*
|
||||
* 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 < (PAGE_SIZE / sizeof(uint64_t)); i++) {
|
||||
/* Each slot of the level 4 pages points to the same level 3 page */
|
||||
PT4[i] = ((uint64_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] = ((uint64_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(((uint64_t)&PT4[0]) - KERNBASE);
|
||||
|
||||
/* Now we can jump into the native init function */
|
||||
return (hammer_time(0, physfree));
|
||||
}
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user