Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177387853
D44451.1794269229.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
D44451.1794269229.diff
View Options
diff --git a/sys/amd64/amd64/xen-locore.S b/sys/amd64/amd64/xen-locore.S
--- a/sys/amd64/amd64/xen-locore.S
+++ b/sys/amd64/amd64/xen-locore.S
@@ -61,7 +61,7 @@
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))
+ ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, xen_start32)
.text
.p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */
@@ -71,12 +71,13 @@
/* PVH entry point. */
.code32
+ .pushsection .text.init32
ENTRY(xen_start32)
/* Load flat GDT */
- movl $VTOP(gdtdesc32), %eax
+ movl $gdt32desc, %eax
lgdt (%eax)
- jmp $GDT_CODE, $VTOP(reload_cs)
+ jmp $GDT_CODE, $reload_cs
reload_cs:
movw $GDT_DATA, %ax
@@ -90,38 +91,6 @@
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
@@ -134,7 +103,7 @@
movl %eax, %cr4
/* Set %cr3 for PT4 */
- movl $VTOP(PT4), %eax
+ call xen_start_pgtable
movl %eax, %cr3
/* Turn on paging (implicitly sets EFER.LMA) */
@@ -143,9 +112,9 @@
movl %eax, %cr0
/* Now we're in compatibility mode. Set %cs for long mode */
- movl $VTOP(gdtdesc), %eax
+ movl $gdt64desc, %eax
lgdt (%eax)
- ljmp $GDT_CODE, $VTOP(longmode)
+ ljmp $GDT_CODE, $longmode
.code64
longmode:
@@ -155,6 +124,7 @@
pushq %rax
ret
+ .popsection
start_kernel:
/*
* Pass %ebx as the argument to hammer_time_xen, it contains
@@ -168,41 +138,3 @@
/* 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 - 1
- .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 - 1
- .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/amd64/amd64/xen-start.c b/sys/amd64/amd64/xen-start.c
new file mode 100644
--- /dev/null
+++ b/sys/amd64/amd64/xen-start.c
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+#include <machine/_inttypes.h>
+
+#include <x86/segments.h>
+
+/*
+ * This code is compiled in 32bit mode, so it can be called from the PVH entry
+ * point as part of the bootstrap sequence to transition to long mode. Care
+ * should be taken to avoid calling any external functions, as that will not
+ * work. Also only the .text, .data, .rodata and .bss sections are handled
+ * specially so that VMA == LMA.
+ */
+
+/* GDT descriptors for the PVH entry point trampoline. */
+const static struct segment_descriptor gdt64[] = {
+ { }, /* NULL descriptor */
+ {
+ .sd_type = SDT_MEMERA,
+ .sd_p = 1,
+ .sd_xx = 0x2 /* Longmode bit. */
+ }, /* %cs */
+ { .sd_p = 1 }, /* %ds */
+};
+const struct {
+ uint64_t limit:16;
+ const struct segment_descriptor *base;
+ uint32_t pad;
+} __packed gdt64desc = {
+ .limit = sizeof(gdt64) - 1,
+ .base = gdt64,
+};
+
+const static struct segment_descriptor gdt32[] = {
+ { }, /* NULL descriptor */
+ {
+ .sd_lolimit = 0xffff,
+ .sd_type = SDT_MEMERA,
+ .sd_p = 1,
+ .sd_hilimit = 0xf,
+ .sd_def32 = 1,
+ .sd_gran = 1,
+ }, /* %cs */
+ {
+ .sd_lolimit = 0xffff,
+ .sd_type = SDT_MEMRWA,
+ .sd_p = 1,
+ .sd_hilimit = 0xf,
+ .sd_def32 = 1,
+ .sd_gran = 1,
+ }, /* %ds, %es, %ss */
+};
+const struct {
+ unsigned int limit:16;
+ const struct segment_descriptor *base;
+} __packed gdt32desc = {
+ .limit = sizeof(gdt32) - 1,
+ .base = gdt32,
+};
+
+/* Called from assembly only. */
+uint32_t xen_start_pgtable(void);
+
+#define PG_V 0x001
+#define PG_RW 0x002
+#define PG_PS 0x080
+
+uint32_t xen_start_pgtable(void)
+{
+ static uint64_t PT4[PAGE_SIZE/sizeof(uint64_t)] __aligned(PAGE_SIZE);
+ static uint64_t PT3[PAGE_SIZE/sizeof(uint64_t)] __aligned(PAGE_SIZE);
+ static uint64_t PT2[PAGE_SIZE/sizeof(uint64_t)] __aligned(PAGE_SIZE);
+ unsigned int i;
+
+ for (i = 0; i < nitems(PT4); i++) {
+ /* Each slot of the level 4 pages points to the same level 3 page */
+ PT4[i] = (uint64_t)&PT3[0];
+ PT4[i] |= PG_V | PG_RW;
+
+ /* Each slot of the level 3 pages points to the same level 2 page */
+ PT3[i] = (uint64_t)&PT2[0];
+ PT3[i] |= PG_V | PG_RW;
+
+ /* 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;
+ }
+
+ return (uint32_t)&PT4[0];
+}
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -78,6 +78,8 @@
amd64/amd64/initcpu.c standard
amd64/amd64/io.c optional io
amd64/amd64/locore.S standard no-obj
+amd64/amd64/xen-start.c optional xenhvm \
+ compile-with "${NORMAL_C} -m32 -g0 && ${OBJCOPY} -I elf32-i386 -O elf64-x86-64 --rename-section .text=.text.init32 --rename-section .data=.data.init32 --rename-section .rodata=.rodata.init32 --rename-section .bss=.bss.init32 ${.TARGET} ${.TARGET}"
amd64/amd64/xen-locore.S optional xenhvm \
compile-with "${NORMAL_S} -g0" \
no-ctfconvert
diff --git a/sys/conf/ldscript.amd64 b/sys/conf/ldscript.amd64
--- a/sys/conf/ldscript.amd64
+++ b/sys/conf/ldscript.amd64
@@ -4,14 +4,26 @@
SEARCH_DIR("/usr/lib");
SECTIONS
{
+ /* PVH 32bit protected mode init code.
+ *
+ * Force VMA == LMA, as that code runs with paging disabled or with identity
+ * page tables.
+ */
+ . = kernload + SIZEOF_HEADERS;
+ /*
+ * Merge all sections into a single .text section, either we run with paging
+ * disabled and flat segments, or with identity page tables with all entries
+ * having AWX permissions. Trying to keep sections separated is useless.
+ */
+ .text.init32 : AT (.) { *(.text.init32 .data.init32 .rodata.init32 .bss.init32) }
/* Read-only sections, merged into text segment: */
- . = kernbase + kernload + SIZEOF_HEADERS;
+ . = . + kernbase;
/*
* Use the AT keyword in order to set the right LMA that contains
* the physical address where the section should be loaded. This is
* needed for the Xen loader which honours the LMA.
*/
- .interp : AT (kernload + SIZEOF_HEADERS) { *(.interp) }
+ .interp : AT (. - kernbase) { *(.interp) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 10, 12:07 AM (2 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41622281
Default Alt Text
D44451.1794269229.diff (7 KB)
Attached To
Mode
D44451: amd64/xen: move early PVH entry point code from assembly to C
Attached
Detach File
Event Timeline