diff --git a/sys/amd64/amd64/xen-locore.S b/sys/amd64/amd64/xen-locore.S index 06349fd90610..899499adda60 100644 --- a/sys/amd64/amd64/xen-locore.S +++ b/sys/amd64/amd64/xen-locore.S @@ -1,87 +1,234 @@ /*- * Copyright (c) 2003 Peter Wemm * Copyright (c) 2011-2012 Spectra Logic Corporation * Copyright (c) 2013 Roger Pau Monne * All rights reserved. * * This software was developed by Cherry G. Mathew * under sponsorship from Spectra Logic Corporation. * * 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 #include #include #include #include #define __ASSEMBLY__ #include #include "assym.inc" +#define VTOP(x) ((x) - KERNBASE) +#define ENTRY_SIZE 8 /* sizeof(uint64_t) */ + +#define GDT_CODE 0x08 +#define GDT_DATA 0x10 + .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, 0) 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") + /* For PVHv2 support. */ + ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, VTOP(xen_start32)) .text .p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */ NON_GPROF_ENTRY(hypercall_page) .skip 0x1000, 0x90 /* Fill with "nop"s */ +/* Legacy PVH entry point, to be removed. */ 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 + +/* PVH entry point. */ + .code32 +NON_GPROF_ENTRY(xen_start32) + + /* Load flat GDT */ + movl $VTOP(gdtdesc32), %eax + lgdt (%eax) + jmp $GDT_CODE, $VTOP(reload_cs) + +reload_cs: + movw $GDT_DATA, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + + movl $VTOP(bootstack), %esp + + /* Don't trust what the loader gives for eflags. */ + pushl $PSL_KERNEL + popfl + + /* + * Create the page tables. + * The first 1GB is mapped using 2MB entries. + */ + movl $0, %eax +pgbuild: + cmp $(PAGE_SIZE/ENTRY_SIZE), %eax + jae pgbuild_done + + /* PT4[i] = VTOP(&PT3[0]) | PG_V | PG_RW | PG_U */ + movl $VTOP(PT4), %ecx + movl $VTOP(PT3), %edx + orl $(PG_V | PG_RW | PG_U), %edx + movl %edx, (%ecx,%eax,ENTRY_SIZE) + + /* PT3[i] = VTOP(&PT2[0]) | PG_V | PG_RW | PG_U */ + movl $VTOP(PT3), %ecx + movl $VTOP(PT2), %edx + orl $(PG_V | PG_RW | PG_U), %edx + movl %edx, (%ecx,%eax,ENTRY_SIZE) + + /* PT2[i] = i * 2MiB | PG_V | PG_RW | PG_PS | PG_U */ + movl $VTOP(PT2), %ecx + movl %eax, %edx + shll $PDRSHIFT, %edx + orl $(PG_V | PG_RW | PG_PS | PG_U), %edx + movl %edx, (%ecx,%eax,ENTRY_SIZE) + + inc %eax + jmp pgbuild + +pgbuild_done: + /* Turn on EFER.LME */ + movl $MSR_EFER, %ecx + rdmsr + orl $EFER_LME, %eax + wrmsr + + /* Turn on PAE */ + movl %cr4, %eax + orl $CR4_PAE, %eax + movl %eax, %cr4 + + /* Set %cr3 for PT4 */ + movl $VTOP(PT4), %eax + movl %eax, %cr3 + + /* Turn on paging (implicitly sets EFER.LMA) */ + movl %cr0, %eax + orl $CR0_PG, %eax + movl %eax, %cr0 + + /* Now we're in compatibility mode. Set %cs for long mode */ + movl $VTOP(gdtdesc), %eax + lgdt (%eax) + ljmp $GDT_CODE, $VTOP(longmode) + + .code64 +longmode: + /* We're still running V=P, jump to entry point */ + movq $bootstack, %rsp + movq $start_kernel, %rax + pushq %rax + ret + +start_kernel: + /* + * Pass %ebx as the argument to hammer_time_xen, it contains + * the startup info. + */ + movq %rbx, %rdi + call hammer_time_xen + movq %rax, %rsp + call mi_startup + + /* NOTREACHED */ +0: hlt + jmp 0b + +/* Space for initial page tables */ + .data + .p2align 12,0x40 +PT4: + .space 0x1000 +PT3: + .space 0x1000 +PT2: + .space 0x1000 + +/* 64bit GDT */ +gdtdesc: + .word gdtend - gdt + .long VTOP(gdt) # low + .long 0 # high +gdt: + .long 0 # null descriptor + .long 0 + .long 0x00000000 # %cs + .long 0x00209800 + .long 0x00000000 # %ds + .long 0x00008000 +gdtend: + +/* 32bit GDT */ +gdtdesc32: + .word gdt32end - gdt32 + .long VTOP(gdt32) + .long 0 +gdt32: + .long 0 # null descriptor + .long 0 + .long 0x0000ffff # %cs + .long 0x00cf9a00 + .long 0x0000ffff # %ds, %es, %ss + .long 0x00cf9200 +gdt32end: diff --git a/sys/xen/interface/elfnote.h b/sys/xen/interface/elfnote.h index 3824a94572b5..353985fe58f3 100644 --- a/sys/xen/interface/elfnote.h +++ b/sys/xen/interface/elfnote.h @@ -1,271 +1,281 @@ /****************************************************************************** * elfnote.h * * Definitions used for the Xen ELF notes. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (c) 2006, Ian Campbell, XenSource Ltd. */ #ifndef __XEN_PUBLIC_ELFNOTE_H__ #define __XEN_PUBLIC_ELFNOTE_H__ /* * `incontents 200 elfnotes ELF notes * * The notes should live in a PT_NOTE segment and have "Xen" in the * name field. * * Numeric types are either 4 or 8 bytes depending on the content of * the desc field. * * LEGACY indicated the fields in the legacy __xen_guest string which * this a note type replaces. * * String values (for non-legacy) are NULL terminated ASCII, also known * as ASCIZ type. */ /* * NAME=VALUE pair (string). */ #define XEN_ELFNOTE_INFO 0 /* * The virtual address of the entry point (numeric). * * LEGACY: VIRT_ENTRY */ #define XEN_ELFNOTE_ENTRY 1 /* The virtual address of the hypercall transfer page (numeric). * * LEGACY: HYPERCALL_PAGE. (n.b. legacy value is a physical page * number not a virtual address) */ #define XEN_ELFNOTE_HYPERCALL_PAGE 2 /* The virtual address where the kernel image should be mapped (numeric). * * Defaults to 0. * * LEGACY: VIRT_BASE */ #define XEN_ELFNOTE_VIRT_BASE 3 /* * The offset of the ELF paddr field from the actual required * pseudo-physical address (numeric). * * This is used to maintain backwards compatibility with older kernels * which wrote __PAGE_OFFSET into that field. This field defaults to 0 * if not present. * * LEGACY: ELF_PADDR_OFFSET. (n.b. legacy default is VIRT_BASE) */ #define XEN_ELFNOTE_PADDR_OFFSET 4 /* * The version of Xen that we work with (string). * * LEGACY: XEN_VER */ #define XEN_ELFNOTE_XEN_VERSION 5 /* * The name of the guest operating system (string). * * LEGACY: GUEST_OS */ #define XEN_ELFNOTE_GUEST_OS 6 /* * The version of the guest operating system (string). * * LEGACY: GUEST_VER */ #define XEN_ELFNOTE_GUEST_VERSION 7 /* * The loader type (string). * * LEGACY: LOADER */ #define XEN_ELFNOTE_LOADER 8 /* * The kernel supports PAE (x86/32 only, string = "yes", "no" or * "bimodal"). * * For compatibility with Xen 3.0.3 and earlier the "bimodal" setting * may be given as "yes,bimodal" which will cause older Xen to treat * this kernel as PAE. * * LEGACY: PAE (n.b. The legacy interface included a provision to * indicate 'extended-cr3' support allowing L3 page tables to be * placed above 4G. It is assumed that any kernel new enough to use * these ELF notes will include this and therefore "yes" here is * equivalent to "yes[entended-cr3]" in the __xen_guest interface. */ #define XEN_ELFNOTE_PAE_MODE 9 /* * The features supported/required by this kernel (string). * * The string must consist of a list of feature names (as given in * features.h, without the "XENFEAT_" prefix) separated by '|' * characters. If a feature is required for the kernel to function * then the feature name must be preceded by a '!' character. * * LEGACY: FEATURES */ #define XEN_ELFNOTE_FEATURES 10 /* * The kernel requires the symbol table to be loaded (string = "yes" or "no") * LEGACY: BSD_SYMTAB (n.b. The legacy treated the presence or absence * of this string as a boolean flag rather than requiring "yes" or * "no". */ #define XEN_ELFNOTE_BSD_SYMTAB 11 /* * The lowest address the hypervisor hole can begin at (numeric). * * This must not be set higher than HYPERVISOR_VIRT_START. Its presence * also indicates to the hypervisor that the kernel can deal with the * hole starting at a higher address. */ #define XEN_ELFNOTE_HV_START_LOW 12 /* * List of maddr_t-sized mask/value pairs describing how to recognize * (non-present) L1 page table entries carrying valid MFNs (numeric). */ #define XEN_ELFNOTE_L1_MFN_VALID 13 /* * Whether or not the guest supports cooperative suspend cancellation. * This is a numeric value. * * Default is 0 */ #define XEN_ELFNOTE_SUSPEND_CANCEL 14 /* * The (non-default) location the initial phys-to-machine map should be * placed at by the hypervisor (Dom0) or the tools (DomU). * The kernel must be prepared for this mapping to be established using * large pages, despite such otherwise not being available to guests. * The kernel must also be able to handle the page table pages used for * this mapping not being accessible through the initial mapping. * (Only x86-64 supports this at present.) */ #define XEN_ELFNOTE_INIT_P2M 15 /* * Whether or not the guest can deal with being passed an initrd not * mapped through its initial page tables. */ #define XEN_ELFNOTE_MOD_START_PFN 16 /* * The features supported by this kernel (numeric). * * Other than XEN_ELFNOTE_FEATURES on pre-4.2 Xen, this note allows a * kernel to specify support for features that older hypervisors don't * know about. The set of features 4.2 and newer hypervisors will * consider supported by the kernel is the combination of the sets * specified through this and the string note. * * LEGACY: FEATURES */ #define XEN_ELFNOTE_SUPPORTED_FEATURES 17 +/* + * Physical entry point into the kernel. + * + * 32bit entry point into the kernel. When requested to launch the + * guest kernel in a HVM container, Xen will use this entry point to + * launch the guest in 32bit protected mode with paging disabled. + * Ignored otherwise. + */ +#define XEN_ELFNOTE_PHYS32_ENTRY 18 + /* * The number of the highest elfnote defined. */ -#define XEN_ELFNOTE_MAX XEN_ELFNOTE_SUPPORTED_FEATURES +#define XEN_ELFNOTE_MAX XEN_ELFNOTE_PHYS32_ENTRY /* * System information exported through crash notes. * * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO * note in case of a system crash. This note will contain various * information about the system, see xen/include/xen/elfcore.h. */ #define XEN_ELFNOTE_CRASH_INFO 0x1000001 /* * System registers exported through crash notes. * * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_REGS * note per cpu in case of a system crash. This note is architecture * specific and will contain registers not saved in the "CORE" note. * See xen/include/xen/elfcore.h for more information. */ #define XEN_ELFNOTE_CRASH_REGS 0x1000002 /* * xen dump-core none note. * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_NONE * in its dump file to indicate that the file is xen dump-core * file. This note doesn't have any other information. * See tools/libxc/xc_core.h for more information. */ #define XEN_ELFNOTE_DUMPCORE_NONE 0x2000000 /* * xen dump-core header note. * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_HEADER * in its dump file. * See tools/libxc/xc_core.h for more information. */ #define XEN_ELFNOTE_DUMPCORE_HEADER 0x2000001 /* * xen dump-core xen version note. * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_XEN_VERSION * in its dump file. It contains the xen version obtained via the * XENVER hypercall. * See tools/libxc/xc_core.h for more information. */ #define XEN_ELFNOTE_DUMPCORE_XEN_VERSION 0x2000002 /* * xen dump-core format version note. * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION * in its dump file. It contains a format version identifier. * See tools/libxc/xc_core.h for more information. */ #define XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION 0x2000003 #endif /* __XEN_PUBLIC_ELFNOTE_H__ */ /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */