Module Name: src
Committed By: bouyer
Date: Sat May 2 16:44:36 UTC 2020
Modified Files:
src/sys/arch/amd64/amd64: autoconf.c genassym.cf locore.S machdep.c
src/sys/arch/amd64/conf: GENERIC
src/sys/arch/i386/i386: autoconf.c genassym.cf locore.S machdep.c
src/sys/arch/x86/acpi: acpi_machdep.c
src/sys/arch/x86/include: cpu.h
src/sys/arch/x86/isa: clock.c isa_machdep.c
src/sys/arch/x86/x86: consinit.c cpu.c lapic.c pmap.c x86_autoconf.c
x86_machdep.c
src/sys/arch/xen/conf: Makefile.xen files.xen
src/sys/arch/xen/include: hypervisor.h xen.h
src/sys/arch/xen/x86: autoconf.c hypervisor_machdep.c x86_xpmap.c
xen_mainbus.c
src/sys/arch/xen/xen: hypervisor.c xen_clock.c xen_machdep.c
Added Files:
src/sys/arch/xen/x86: pvh_consinit.c
Log Message:
Introduce Xen PVH support in GENERIC.
This is compiled in with
options XENPVHVM
x86 changes:
- add Xen section and xen pvh entry points to locore.S. Set vm_guest
to VM_GUEST_XENPVH in this entry point.
Most of the boot procedure (especially page table setup and switch to
paged mode) is shared with native.
- change some x86_delay() to delay_func(), which points to x86_delay() for
native/HVM, and xen_delay() for PVH
Xen changes:
- remove Xen bits from init_x86_64_ksyms() and init386_ksyms()
and move to xen_init_ksyms(), used for both PV and PVH
- set ISA no-legacy-devices property for PVH
- factor out code from Xen's cpu_bootconf() to xen_bootconf()
in xen_machdep.c
- set up a specific pvh_consinit() which starts with printk()
(which uses a simple hypercall that is available early) and switch to
xencons when we can use pmap_kenter_pa().
To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/amd64/amd64/autoconf.c
cvs rdiff -u -r1.83 -r1.84 src/sys/arch/amd64/amd64/genassym.cf
cvs rdiff -u -r1.205 -r1.206 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.351 -r1.352 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.566 -r1.567 src/sys/arch/amd64/conf/GENERIC
cvs rdiff -u -r1.106 -r1.107 src/sys/arch/i386/i386/autoconf.c
cvs rdiff -u -r1.121 -r1.122 src/sys/arch/i386/i386/genassym.cf
cvs rdiff -u -r1.181 -r1.182 src/sys/arch/i386/i386/locore.S
cvs rdiff -u -r1.828 -r1.829 src/sys/arch/i386/i386/machdep.c
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/x86/acpi/acpi_machdep.c
cvs rdiff -u -r1.124 -r1.125 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/x86/isa/clock.c
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/x86/isa/isa_machdep.c
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/x86/x86/consinit.c
cvs rdiff -u -r1.188 -r1.189 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.77 -r1.78 src/sys/arch/x86/x86/lapic.c
cvs rdiff -u -r1.386 -r1.387 src/sys/arch/x86/x86/pmap.c
cvs rdiff -u -r1.81 -r1.82 src/sys/arch/x86/x86/x86_autoconf.c
cvs rdiff -u -r1.140 -r1.141 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/xen/conf/Makefile.xen
cvs rdiff -u -r1.182 -r1.183 src/sys/arch/xen/conf/files.xen
cvs rdiff -u -r1.51 -r1.52 src/sys/arch/xen/include/hypervisor.h
cvs rdiff -u -r1.46 -r1.47 src/sys/arch/xen/include/xen.h
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/xen/x86/autoconf.c
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/xen/x86/hypervisor_machdep.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/xen/x86/pvh_consinit.c
cvs rdiff -u -r1.85 -r1.86 src/sys/arch/xen/x86/x86_xpmap.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/xen/x86/xen_mainbus.c
cvs rdiff -u -r1.78 -r1.79 src/sys/arch/xen/xen/hypervisor.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/xen/xen/xen_clock.c
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/xen/xen/xen_machdep.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amd64/amd64/autoconf.c
diff -u src/sys/arch/amd64/amd64/autoconf.c:1.29 src/sys/arch/amd64/amd64/autoconf.c:1.30
--- src/sys/arch/amd64/amd64/autoconf.c:1.29 Fri Dec 27 12:51:56 2019
+++ src/sys/arch/amd64/amd64/autoconf.c Sat May 2 16:44:34 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.29 2019/12/27 12:51:56 ad Exp $ */
+/* $NetBSD: autoconf.c,v 1.30 2020/05/02 16:44:34 bouyer Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.29 2019/12/27 12:51:56 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.30 2020/05/02 16:44:34 bouyer Exp $");
#include "opt_multiprocessor.h"
#include "opt_intrdebug.h"
@@ -92,7 +92,14 @@ extern void platform_init(void);
void
cpu_configure(void)
{
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH)
+ xen_startrtclock();
+ else
+ startrtclock();
+#else
startrtclock();
+#endif
#if NBIOS32 > 0
efi_init();
Index: src/sys/arch/amd64/amd64/genassym.cf
diff -u src/sys/arch/amd64/amd64/genassym.cf:1.83 src/sys/arch/amd64/amd64/genassym.cf:1.84
--- src/sys/arch/amd64/amd64/genassym.cf:1.83 Sat Apr 25 15:26:16 2020
+++ src/sys/arch/amd64/amd64/genassym.cf Sat May 2 16:44:34 2020
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.83 2020/04/25 15:26:16 bouyer Exp $
+# $NetBSD: genassym.cf,v 1.84 2020/05/02 16:44:34 bouyer Exp $
#
# Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -120,6 +120,7 @@ endif
ifdef XEN
include <xen/include/public/xen.h>
+include <xen/include/public/arch-x86/hvm/start_info.h>
endif
include <sys/bus.h>
@@ -361,6 +362,7 @@ define X86_BUS_SPACE_IO X86_BUS_SPACE_IO
define BST_TYPE offsetof(struct bus_space_tag, bst_type)
define VM_GUEST_XENPV VM_GUEST_XENPV
+define VM_GUEST_XENPVH VM_GUEST_XENPVH
ifdef XEN
define CPU_INFO_VCPU offsetof(struct cpu_info, ci_vcpu)
@@ -373,7 +375,7 @@ define XEN_PT_BASE offsetof(struct star
define XEN_NR_PT_FRAMES offsetof(struct start_info, nr_pt_frames)
define __HYPERVISOR_iret __HYPERVISOR_iret
endif /* XENPV */
-endif
+endif /* XEN */
define NKL4_KIMG_ENTRIES NKL4_KIMG_ENTRIES
define NKL3_KIMG_ENTRIES NKL3_KIMG_ENTRIES
Index: src/sys/arch/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.205 src/sys/arch/amd64/amd64/locore.S:1.206
--- src/sys/arch/amd64/amd64/locore.S:1.205 Sat May 2 16:28:37 2020
+++ src/sys/arch/amd64/amd64/locore.S Sat May 2 16:44:34 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.205 2020/05/02 16:28:37 maxv Exp $ */
+/* $NetBSD: locore.S,v 1.206 2020/05/02 16:44:34 bouyer Exp $ */
/*
* Copyright-o-rama!
@@ -279,9 +279,7 @@
#define __ASSEMBLY__
#include <xen/include/public/elfnote.h>
#include <xen/include/public/xen.h>
-#endif /* XEN */
-#ifdef XENPV
#define ELFNOTE(name, type, desctype, descdata...) \
.pushsection .note.name ; \
.align 4 ; \
@@ -302,11 +300,16 @@
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "4.99")
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0")
ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .quad, KERNBASE)
+#ifdef XENPV
ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, KERNBASE)
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .quad, start)
+#else
+ ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, 0)
+ ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, RELOC(start_xen32))
+#endif /* XENPV */
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, "")
+ 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, PTE_P, PTE_P)\
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
@@ -314,7 +317,7 @@
#if NKSYMS > 0 || defined(DDB) || defined(MODULAR)
ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes")
#endif
-#endif /* XENPV */
+#endif /* XEN */
/*
* Initialization
@@ -418,6 +421,21 @@ _C_LABEL(farjmp64):
.word GSEL(GCODE_SEL, SEL_KPL)
END(farjmp64)
+#ifdef XEN
+/* 32bit GDT */
+gdtdesc32:
+ .word gdt32end - gdt32
+ .long RELOC(gdt32)
+ .long 0
+gdt32:
+ .long 0 # null descriptor
+ .long 0
+ .long 0x0000ffff # %cs
+ .long 0x00cf9a00
+ .long 0x0000ffff # %ds, %es, %ss
+ .long 0x00cf9200
+gdt32end:
+#endif /* XEN */
#endif /* !XENPV */
/* Space for the temporary stack */
@@ -973,6 +991,9 @@ longmode_hi:
#endif /* XENPV */
pushq %rdi
+#if defined(XEN) && !defined(XENPV)
+ call _C_LABEL(init_xen_early)
+#endif
call _C_LABEL(init_bootspace)
#ifdef KASAN
movq _C_LABEL(lwp0uarea)(%rip),%rdi
@@ -984,6 +1005,64 @@ longmode_hi:
call _C_LABEL(main)
END(start)
+#ifndef XENPV
+/* entry point for Xen PVH */
+ .code32
+ENTRY(start_xen32)
+ /* Xen doesn't start us with a valid gdt */
+ movl $RELOC(gdtdesc32), %eax
+ lgdt (%eax)
+ jmp $GSEL(GCODE_SEL, SEL_KPL), $RELOC(.Lreload_cs)
+
+.Lreload_cs:
+ movw $GSEL(GDATA_SEL, SEL_KPL), %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss
+
+ /* we need a valid stack */
+ movl $RELOC(tmpstk),%esp
+
+ /* clear BSS */
+ xorl %eax,%eax
+ movl $RELOC(__bss_start),%edi
+ movl $RELOC(_end),%ecx
+ subl %edi,%ecx
+ rep
+ stosb
+
+ /*
+ * save addr of the hvm_start_info structure. This is also the end
+ * of the symbol table
+ */
+ movl %ebx, RELOC(hvm_start_paddr)
+ movl %ebx, %eax
+ addl $KERNBASE_LO,%eax
+ movl $RELOC(esym),%ebp
+ movl %eax,(%ebp)
+ movl $KERNBASE_HI,4(%ebp)
+ /* get a page for HYPERVISOR_shared_info */
+ addl $PAGE_SIZE, %ebx
+ addl $PGOFSET,%ebx
+ andl $~PGOFSET,%ebx
+ movl $RELOC(HYPERVISOR_shared_info_pa),%ebp
+ movl %ebx,(%ebp)
+ movl $0,4(%ebp)
+ /* XXX assume hvm_start_info+dependant struture fits in a single page */
+ addl $PAGE_SIZE, %ebx
+ addl $PGOFSET,%ebx
+ andl $~PGOFSET,%ebx
+ addl $KERNBASE_LO,%ebx
+ movl $RELOC(eblob),%ebp
+ movl %ebx,(%ebp)
+ movl $KERNBASE_HI,4(%ebp)
+
+ /* annouce ourself */
+ movl $VM_GUEST_XENPVH, RELOC(vm_guest)
+ jmp .Lbiosbasemem_finished
+END(start_xen32)
+ .code64
+#endif /* XENPV */
#if defined(XEN)
/* space for the hypercall call page */
#define HYPERCALL_PAGE_OFFSET 0x1000
Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.351 src/sys/arch/amd64/amd64/machdep.c:1.352
--- src/sys/arch/amd64/amd64/machdep.c:1.351 Sat May 2 16:28:37 2020
+++ src/sys/arch/amd64/amd64/machdep.c Sat May 2 16:44:34 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.351 2020/05/02 16:28:37 maxv Exp $ */
+/* $NetBSD: machdep.c,v 1.352 2020/05/02 16:44:34 bouyer Exp $ */
/*
* Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.351 2020/05/02 16:28:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.352 2020/05/02 16:44:34 bouyer Exp $");
#include "opt_modular.h"
#include "opt_user_ldt.h"
@@ -1483,22 +1483,20 @@ extern vector IDTVEC(syscall32);
extern vector IDTVEC(osyscall);
extern vector *x86_exceptions[];
+#ifndef XENPV
static void
init_x86_64_ksyms(void)
{
#if NKSYMS || defined(DDB) || defined(MODULAR)
extern int end;
extern int *esym;
-#ifndef XENPV
struct btinfo_symtab *symtab;
vaddr_t tssym, tesym;
-#endif
#ifdef DDB
db_machine_init();
#endif
-#ifndef XENPV
symtab = lookup_bootinfo(BTINFO_SYMTAB);
if (symtab) {
#ifdef KASLR
@@ -1512,15 +1510,9 @@ init_x86_64_ksyms(void)
} else
ksyms_addsyms_elf(*(long *)(void *)&end,
((long *)(void *)&end) + 1, esym);
-#else /* XENPV */
- esym = xen_start_info.mod_start ?
- (void *)xen_start_info.mod_start :
- (void *)xen_start_info.mfn_list;
- ksyms_addsyms_elf(*(int *)(void *)&end,
- ((int *)(void *)&end) + 1, esym);
-#endif /* XENPV */
#endif
}
+#endif /* XENPV */
void __noasan
init_bootspace(void)
@@ -1676,6 +1668,10 @@ init_x86_64(paddr_t first_avail)
cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
#endif
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH)
+ xen_parse_cmdline(XEN_PARSE_BOOTFLAGS, NULL);
+#endif
init_pte();
uvm_lwp_setuarea(&lwp0, lwp0uarea);
@@ -1903,7 +1899,16 @@ init_x86_64(paddr_t first_avail)
cpu_init_idt();
- init_x86_64_ksyms();
+#ifdef XENPV
+ xen_init_ksyms();
+#else /* XENPV */
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH)
+ xen_init_ksyms();
+ else
+#endif /* XEN */
+ init_x86_64_ksyms();
+#endif /* XENPV */
#ifndef XENPV
intr_default_setup();
Index: src/sys/arch/amd64/conf/GENERIC
diff -u src/sys/arch/amd64/conf/GENERIC:1.566 src/sys/arch/amd64/conf/GENERIC:1.567
--- src/sys/arch/amd64/conf/GENERIC:1.566 Sat Apr 25 15:26:16 2020
+++ src/sys/arch/amd64/conf/GENERIC Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.566 2020/04/25 15:26:16 bouyer Exp $
+# $NetBSD: GENERIC,v 1.567 2020/05/02 16:44:35 bouyer Exp $
#
# GENERIC machine description file
#
@@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "GENERIC-$Revision: 1.566 $"
+#ident "GENERIC-$Revision: 1.567 $"
maxusers 64 # estimated number of users
@@ -121,6 +121,7 @@ options DDB_HISTORY_SIZE=512 # enable h
#options KGDB # remote debugger
#options KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600
makeoptions DEBUG="-g" # compile full symbol table for CTF
+options DDB_COMMANDONENTER="trace;show registers"
#options KUBSAN # Kernel Undefined Behavior Sanitizer (kUBSan)
#options UBSAN_ALWAYS_FATAL # (optional) Panic on all kUBSan reports
#options SYSCALL_STATS # per syscall counts
Index: src/sys/arch/i386/i386/autoconf.c
diff -u src/sys/arch/i386/i386/autoconf.c:1.106 src/sys/arch/i386/i386/autoconf.c:1.107
--- src/sys/arch/i386/i386/autoconf.c:1.106 Fri Dec 27 12:51:56 2019
+++ src/sys/arch/i386/i386/autoconf.c Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.106 2019/12/27 12:51:56 ad Exp $ */
+/* $NetBSD: autoconf.c,v 1.107 2020/05/02 16:44:35 bouyer Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.106 2019/12/27 12:51:56 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.107 2020/05/02 16:44:35 bouyer Exp $");
#include "opt_intrdebug.h"
#include "opt_multiprocessor.h"
@@ -105,7 +105,14 @@ cpu_configure(void)
{
struct pcb *pcb;
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH)
+ xen_startrtclock();
+ else
+ startrtclock();
+#else
startrtclock();
+#endif
#if NBIOS32 > 0
efi_init();
Index: src/sys/arch/i386/i386/genassym.cf
diff -u src/sys/arch/i386/i386/genassym.cf:1.121 src/sys/arch/i386/i386/genassym.cf:1.122
--- src/sys/arch/i386/i386/genassym.cf:1.121 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/i386/i386/genassym.cf Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.121 2020/04/25 15:26:17 bouyer Exp $
+# $NetBSD: genassym.cf,v 1.122 2020/05/02 16:44:35 bouyer Exp $
#
# Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -99,6 +99,7 @@ include <machine/segments.h>
ifdef XEN
include <xen/include/public/sched.h>
+include <xen/include/public/arch-x86/hvm/start_info.h>
endif
if defined(_KERNEL) && defined(_KERNEL_OPT)
@@ -372,6 +373,7 @@ define PGOFSET PGOFSET
define PGSHIFT PGSHIFT
define VM_GUEST_XENPV VM_GUEST_XENPV
+define VM_GUEST_XENPVH VM_GUEST_XENPVH
ifdef XEN
define CPU_INFO_VCPU offsetof(struct cpu_info, ci_vcpu)
@@ -388,4 +390,4 @@ define EVTCHN_UPCALL_MASK offsetof(struc
define HYPERVISOR_sched_op __HYPERVISOR_sched_op
define SCHEDOP_yield SCHEDOP_yield
-endif
+endif /* XEN */
Index: src/sys/arch/i386/i386/locore.S
diff -u src/sys/arch/i386/i386/locore.S:1.181 src/sys/arch/i386/i386/locore.S:1.182
--- src/sys/arch/i386/i386/locore.S:1.181 Thu Apr 30 17:17:33 2020
+++ src/sys/arch/i386/i386/locore.S Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.181 2020/04/30 17:17:33 maxv Exp $ */
+/* $NetBSD: locore.S,v 1.182 2020/05/02 16:44:35 bouyer Exp $ */
/*
* Copyright-o-rama!
@@ -128,7 +128,7 @@
*/
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.181 2020/04/30 17:17:33 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.182 2020/05/02 16:44:35 bouyer Exp $");
#include "opt_copy_symtab.h"
#include "opt_ddb.h"
@@ -243,37 +243,48 @@ __KERNEL_RCSID(0, "$NetBSD: locore.S,v 1
#ifdef XEN
-/*
- * Unfortunately, the Xen codebase uses nonstandard preprocessing tools.
- * See: https://xenbits.xen.org/gitweb/?p=xen.git&a=search&h=HEAD&st=grep&s=__UnDeF__
- * for a fine selection of examples.
- *
- * What this means for us here is that we can't include the standard
- * xen.h header in assembler code.
- *
- * So we have to manually define, and keep track of the values we need, ourselves.
- */
-#define __HYPERVISOR_xen_version 17
-#endif /* XEN */
+#define __ASSEMBLY__
+#include <xen/include/public/elfnote.h>
+#include <xen/include/public/xen.h>
+
+#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
-#ifdef XENPV
/*
* Xen guest identifier and loader selection
*/
.section __xen_guest
- .ascii "GUEST_OS=netbsd,GUEST_VER=3.0,XEN_VER=xen-3.0"
- .ascii ",VIRT_BASE=0xc0000000" /* KERNBASE */
- .ascii ",ELF_PADDR_OFFSET=0xc0000000" /* KERNBASE */
- .ascii ",VIRT_ENTRY=0xc0100000" /* KERNTEXTOFF */
- .ascii ",HYPERCALL_PAGE=0x00000101"
- /* (???+HYPERCALL_PAGE_OFFSET)/PAGE_SIZE) */
- .ascii ",PAE=yes[extended-cr3]"
- .ascii ",LOADER=generic"
-#if (NKSYMS || defined(DDB) || defined(MODULAR)) && !defined(makeoptions_COPY_SYMTAB)
- .ascii ",BSD_SYMTAB=yes"
+ ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "NetBSD")
+ ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "4.99")
+ ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0")
+ ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, KERNBASE)
+#ifdef XENPV
+ ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, KERNBASE)
+ ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, start)
+#else
+ ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, 0)
+ ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, RELOC(start_xenpvh))
+#endif /* XENPV */
+ ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
+ ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long, 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, .quad, PTE_P, PTE_P)\
+ ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
+ ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 0)
+#if NKSYMS > 0 || defined(DDB) || defined(MODULAR)
+ ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes")
#endif
- .byte 0
-#endif /* XENPV */
+#endif /* XEN */
/*
* Initialization
@@ -580,7 +591,7 @@ multiboot2_loader:
pushl %ebx /* Address of Multiboot information */
call _C_LABEL(multiboot2_pre_reloc)
addl $4,%esp
- jmp 2f
+ jmp .Lstart_common
#endif /* MULTIBOOT */
1:
@@ -597,7 +608,7 @@ multiboot2_loader:
call _C_LABEL(native_loader)
addl $24,%esp
-2:
+.Lstart_common:
/* First, reset the PSL. */
pushl $PSL_MBO
popfl
@@ -1071,6 +1082,9 @@ begin:
pushl $0 /* init386() expects a 64 bits paddr_t with PAE */
#endif
pushl %eax
+#if defined(XEN) && !defined(XENPV)
+ call _C_LABEL(init_xen_early)
+#endif
call _C_LABEL(init_bootspace)
call _C_LABEL(init386)
addl $PDE_SIZE,%esp /* pop paddr_t */
@@ -1150,6 +1164,74 @@ begin:
#endif /* XENPV */
END(start)
+#ifndef XENPV
+/* entry point for Xen PVH */
+ENTRY(start_xenpvh)
+ /* Xen doesn't start us with a valid gdt */
+ movl $RELOC(gdtdesc_xenpvh), %eax
+ lgdt (%eax)
+ jmp $GSEL(GCODE_SEL, SEL_KPL), $RELOC(.Lreload_cs)
+
+.Lreload_cs:
+ movw $GSEL(GDATA_SEL, SEL_KPL), %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss
+
+ /* we need a valid stack */
+ movl $RELOC(tmpstk),%esp
+
+ /* clear BSS */
+ xorl %eax,%eax
+ movl $RELOC(__bss_start),%edi
+ movl $RELOC(_end),%ecx
+ subl %edi,%ecx
+ rep
+ stosb
+
+ /*
+ * save addr of the hvm_start_info structure. This is also the end
+ * of the symbol table
+ */
+ movl %ebx, RELOC(hvm_start_paddr)
+ movl %ebx, %eax
+ addl $KERNBASE,%eax
+ movl $RELOC(esym),%ebp
+ movl %eax,(%ebp)
+ /* get a page for HYPERVISOR_shared_info */
+ addl $PAGE_SIZE, %ebx
+ addl $PGOFSET,%ebx
+ andl $~PGOFSET,%ebx
+ movl $RELOC(HYPERVISOR_shared_info_pa),%ebp
+ movl %ebx,(%ebp)
+ /* XXX assume hvm_start_info+dependant struture fits in a single page */
+ addl $PAGE_SIZE, %ebx
+ addl $PGOFSET,%ebx
+ andl $~PGOFSET,%ebx
+ addl $KERNBASE,%ebx
+ movl $RELOC(eblob),%ebp
+ movl %ebx,(%ebp)
+ /* annouce ourself */
+ movl $VM_GUEST_XENPVH, RELOC(vm_guest)
+ jmp .Lstart_common
+END(start_xenpvh)
+ .align 8
+gdtdesc_xenpvh:
+ .word gdt_xenpvhend - gdt_xenpvh
+ .long RELOC(gdt_xenpvh)
+ .word 0
+gdt_xenpvh:
+ .long 0 # null descriptor
+ .long 0
+ .long 0x0000ffff # %cs
+ .long 0x00cf9a00
+ .long 0x0000ffff # %ds, %es, %ss
+ .long 0x00cf9200
+gdt_xenpvhend:
+ .align 4
+#endif /* XENPV */
+
+
#if defined(XEN)
/* space for the hypercall call page */
#define HYPERCALL_PAGE_OFFSET 0x1000
Index: src/sys/arch/i386/i386/machdep.c
diff -u src/sys/arch/i386/i386/machdep.c:1.828 src/sys/arch/i386/i386/machdep.c:1.829
--- src/sys/arch/i386/i386/machdep.c:1.828 Thu Apr 30 03:29:19 2020
+++ src/sys/arch/i386/i386/machdep.c Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.828 2020/04/30 03:29:19 riastradh Exp $ */
+/* $NetBSD: machdep.c,v 1.829 2020/05/02 16:44:35 bouyer Exp $ */
/*
* Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009, 2017
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.828 2020/04/30 03:29:19 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.829 2020/05/02 16:44:35 bouyer Exp $");
#include "opt_beep.h"
#include "opt_compat_freebsd.h"
@@ -1044,8 +1044,9 @@ init386_pte0(void)
/* make sure it is clean before using */
memset((void *)vaddr, 0, PAGE_SIZE);
}
-#endif /* !XENPV */
+#endif /* !XENPV && NBIOSCALL > 0 */
+#ifndef XENPV
static void
init386_ksyms(void)
{
@@ -1075,6 +1076,7 @@ init386_ksyms(void)
ksyms_addsyms_elf(symtab->nsym, (int *)symtab->ssym, (int *)symtab->esym);
#endif
}
+#endif /* XENPV */
void
init_bootspace(void)
@@ -1140,12 +1142,17 @@ init386(paddr_t first_avail)
cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
#endif
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH)
+ xen_parse_cmdline(XEN_PARSE_BOOTFLAGS, NULL);
+#endif
+
uvm_lwp_setuarea(&lwp0, lwp0uarea);
cpu_probe(&cpu_info_primary);
cpu_rng_init();
cpu_init_msrs(&cpu_info_primary, true);
-#ifndef XEN
+#ifndef XENPV
cpu_speculation_init(&cpu_info_primary);
#endif
@@ -1366,7 +1373,16 @@ init386(paddr_t first_avail)
lldt(GSEL(GLDT_SEL, SEL_KPL));
cpu_init_idt();
- init386_ksyms();
+#ifdef XENPV
+ xen_init_ksyms();
+#else /* XENPV */
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH)
+ xen_init_ksyms();
+ else
+#endif /* XEN */
+ init386_ksyms();
+#endif /* XENPV */
#if NMCA > 0
/*
@@ -1376,7 +1392,7 @@ init386(paddr_t first_avail)
* And we do not search for MCA using bioscall() on EFI systems
* that lacks it (they lack MCA too, anyway).
*/
- if (lookup_bootinfo(BTINFO_EFI) == NULL)
+ if (lookup_bootinfo(BTINFO_EFI) == NULL && vm_guest != VM_GUEST_XENPVH)
mca_busprobe();
#endif
Index: src/sys/arch/x86/acpi/acpi_machdep.c
diff -u src/sys/arch/x86/acpi/acpi_machdep.c:1.29 src/sys/arch/x86/acpi/acpi_machdep.c:1.30
--- src/sys/arch/x86/acpi/acpi_machdep.c:1.29 Sun Dec 22 15:57:07 2019
+++ src/sys/arch/x86/acpi/acpi_machdep.c Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_machdep.c,v 1.29 2019/12/22 15:57:07 thorpej Exp $ */
+/* $NetBSD: acpi_machdep.c,v 1.30 2020/05/02 16:44:35 bouyer Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.29 2019/12/22 15:57:07 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.30 2020/05/02 16:44:35 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -79,6 +79,10 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_machdep
#include "opt_acpi.h"
#include "opt_vga.h"
+#ifdef XEN
+#include <xen/hypervisor.h>
+#endif
+
/*
* Default VBIOS reset method for non-HW accelerated VGA drivers.
*/
@@ -151,6 +155,13 @@ out:
return PhysicalAddress;
}
#else
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH) {
+ PhysicalAddress = hvm_start_info->rsdp_paddr;
+ if (PhysicalAddress)
+ return PhysicalAddress;
+ }
+#endif
/*
* Get the ACPI RSDP from EFI SystemTable. This works when the
* kernel was loaded from EFI bootloader.
Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.124 src/sys/arch/x86/include/cpu.h:1.125
--- src/sys/arch/x86/include/cpu.h:1.124 Thu Apr 30 22:05:17 2020
+++ src/sys/arch/x86/include/cpu.h Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.124 2020/04/30 22:05:17 bouyer Exp $ */
+/* $NetBSD: cpu.h,v 1.125 2020/05/02 16:44:35 bouyer Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
@@ -516,6 +516,18 @@ vm_guest_is_xenpv(void)
}
}
+static __inline bool __unused
+vm_guest_is_xenpvh_or_pvhvm(void)
+{
+ switch(vm_guest) {
+ case VM_GUEST_XENPVH:
+ case VM_GUEST_XENPVHVM:
+ return true;
+ default:
+ return false;
+ }
+}
+
/* cpu_topology.c */
void x86_cpu_topology(struct cpu_info *);
Index: src/sys/arch/x86/isa/clock.c
diff -u src/sys/arch/x86/isa/clock.c:1.37 src/sys/arch/x86/isa/clock.c:1.38
--- src/sys/arch/x86/isa/clock.c:1.37 Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/isa/clock.c Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: clock.c,v 1.37 2020/04/25 15:26:18 bouyer Exp $ */
+/* $NetBSD: clock.c,v 1.38 2020/05/02 16:44:35 bouyer Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -121,7 +121,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.37 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.38 2020/05/02 16:44:35 bouyer Exp $");
/* #define CLOCKDEBUG */
/* #define CLOCK_PARANOIA */
@@ -304,6 +304,9 @@ initrtclock(u_long freq)
{
u_long tval;
+ if (vm_guest == VM_GUEST_XENPVH)
+ return;
+
/*
* Compute timer_count, the count-down count the timer will be
* set to. Also, correctly round
@@ -512,6 +515,8 @@ i8254_delay(unsigned int n)
int
sysbeepmatch(device_t parent, cfdata_t match, void *aux)
{
+ if (vm_guest == VM_GUEST_XENPVH)
+ return 0;
return (!ppi_attached);
}
Index: src/sys/arch/x86/isa/isa_machdep.c
diff -u src/sys/arch/x86/isa/isa_machdep.c:1.45 src/sys/arch/x86/isa/isa_machdep.c:1.46
--- src/sys/arch/x86/isa/isa_machdep.c:1.45 Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/isa/isa_machdep.c Sat May 2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: isa_machdep.c,v 1.45 2020/04/25 15:26:18 bouyer Exp $ */
+/* $NetBSD: isa_machdep.c,v 1.46 2020/05/02 16:44:35 bouyer Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: isa_machdep.c,v 1.45 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: isa_machdep.c,v 1.46 2020/05/02 16:44:35 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -365,6 +365,9 @@ device_isa_register(device_t dev, void *
return dev;
}
}
+ if (vm_guest == VM_GUEST_XENPVH)
+ prop_dictionary_set_bool(device_properties(dev),
+ "no-legacy-devices", true);
#if NACPICA > 0
#if notyet
if (device_is_a(dev, "isa") && acpi_active) {
Index: src/sys/arch/x86/x86/consinit.c
diff -u src/sys/arch/x86/x86/consinit.c:1.32 src/sys/arch/x86/x86/consinit.c:1.33
--- src/sys/arch/x86/x86/consinit.c:1.32 Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/x86/consinit.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: consinit.c,v 1.32 2020/04/25 15:26:18 bouyer Exp $ */
+/* $NetBSD: consinit.c,v 1.33 2020/05/02 16:44:36 bouyer Exp $ */
/*
* Copyright (c) 1998
@@ -27,10 +27,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.32 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.33 2020/05/02 16:44:36 bouyer Exp $");
#include "opt_kgdb.h"
#include "opt_puc.h"
+#include "opt_xen.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -98,6 +99,10 @@ __KERNEL_RCSID(0, "$NetBSD: consinit.c,v
#endif
#endif
+#ifdef XENPVHVM
+#include <xen/xen.h>
+#endif
+
#ifndef CONSDEVNAME
#define CONSDEVNAME "pc"
#endif
@@ -166,6 +171,12 @@ consinit(void)
int rv;
#endif
+#ifdef XENPVHVM
+ if (vm_guest == VM_GUEST_XENPVH) {
+ xen_pvh_consinit();
+ return;
+ }
+#endif
if (initted)
return;
initted = 1;
Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.188 src/sys/arch/x86/x86/cpu.c:1.189
--- src/sys/arch/x86/x86/cpu.c:1.188 Wed Apr 29 22:03:09 2020
+++ src/sys/arch/x86/x86/cpu.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.188 2020/04/29 22:03:09 ad Exp $ */
+/* $NetBSD: cpu.c,v 1.189 2020/05/02 16:44:36 bouyer Exp $ */
/*
* Copyright (c) 2000-2012 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.188 2020/04/29 22:03:09 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.189 2020/05/02 16:44:36 bouyer Exp $");
#include "opt_ddb.h"
#include "opt_mpbios.h" /* for MPDEBUG */
@@ -447,7 +447,7 @@ cpu_attach(device_t parent, device_t sel
/* Enable lapic. */
lapic_enable();
lapic_set_lvt();
- if (vm_guest != VM_GUEST_XENPVHVM)
+ if (!vm_guest_is_xenpvh_or_pvhvm())
lapic_calibrate_timer(ci);
}
#endif
@@ -824,7 +824,7 @@ cpu_start_secondary(struct cpu_info *ci)
KASSERT(cpu_starting == NULL);
cpu_starting = ci;
for (i = 100000; (!(ci->ci_flags & CPUF_PRESENT)) && i > 0; i--) {
- x86_delay(10);
+ delay_func(10);
}
if ((ci->ci_flags & CPUF_PRESENT) == 0) {
@@ -860,7 +860,7 @@ cpu_boot_secondary(struct cpu_info *ci)
atomic_or_32(&ci->ci_flags, CPUF_GO);
for (i = 100000; (!(ci->ci_flags & CPUF_RUNNING)) && i > 0; i--) {
- x86_delay(10);
+ delay_func(10);
}
if ((ci->ci_flags & CPUF_RUNNING) == 0) {
aprint_error_dev(ci->ci_dev, "failed to start\n");
@@ -1143,7 +1143,7 @@ mp_cpu_start(struct cpu_info *ci, paddr_
__func__);
return error;
}
- x86_delay(10000);
+ delay_func(10000);
error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE);
if (error != 0) {
@@ -1151,7 +1151,7 @@ mp_cpu_start(struct cpu_info *ci, paddr_
__func__);
return error;
}
- x86_delay(200);
+ delay_func(200);
error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE);
if (error != 0) {
@@ -1159,7 +1159,7 @@ mp_cpu_start(struct cpu_info *ci, paddr_
__func__);
return error;
}
- x86_delay(200);
+ delay_func(200);
}
return 0;
@@ -1321,7 +1321,7 @@ cpu_get_tsc_freq(struct cpu_info *ci)
} else {
/* Calibrate TSC frequency. */
last_tsc = cpu_counter_serializing();
- x86_delay(100000);
+ delay_func(100000);
ci->ci_data.cpu_cc_freq =
(cpu_counter_serializing() - last_tsc) * 10;
}
Index: src/sys/arch/x86/x86/lapic.c
diff -u src/sys/arch/x86/x86/lapic.c:1.77 src/sys/arch/x86/x86/lapic.c:1.78
--- src/sys/arch/x86/x86/lapic.c:1.77 Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/x86/lapic.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: lapic.c,v 1.77 2020/04/25 15:26:18 bouyer Exp $ */
+/* $NetBSD: lapic.c,v 1.78 2020/05/02 16:44:36 bouyer Exp $ */
/*-
* Copyright (c) 2000, 2008 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.77 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.78 2020/05/02 16:44:36 bouyer Exp $");
#include "acpica.h"
#include "ioapic.h"
@@ -789,7 +789,7 @@ i82489_ipi_init(int target)
i82489_writereg(LAPIC_ICRLO, LAPIC_DLMODE_INIT | LAPIC_LEVEL_ASSERT);
i82489_icr_wait();
- x86_delay(10000);
+ delay_func(10000);
i82489_writereg(LAPIC_ICRLO,
LAPIC_DLMODE_INIT | LAPIC_TRIGMODE_LEVEL | LAPIC_LEVEL_DEASSERT);
i82489_icr_wait();
@@ -861,7 +861,7 @@ x2apic_ipi_init(int target)
x2apic_write_icr(target, LAPIC_DLMODE_INIT | LAPIC_LEVEL_ASSERT);
- x86_delay(10000);
+ delay_func(10000);
x2apic_write_icr(0,
LAPIC_DLMODE_INIT | LAPIC_TRIGMODE_LEVEL | LAPIC_LEVEL_DEASSERT);
Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.386 src/sys/arch/x86/x86/pmap.c:1.387
--- src/sys/arch/x86/x86/pmap.c:1.386 Sat May 2 16:28:37 2020
+++ src/sys/arch/x86/x86/pmap.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.386 2020/05/02 16:28:37 maxv Exp $ */
+/* $NetBSD: pmap.c,v 1.387 2020/05/02 16:44:36 bouyer Exp $ */
/*
* Copyright (c) 2008, 2010, 2016, 2017, 2019, 2020 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.386 2020/05/02 16:28:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.387 2020/05/02 16:44:36 bouyer Exp $");
#include "opt_user_ldt.h"
#include "opt_lockdebug.h"
@@ -1335,8 +1335,10 @@ pmap_bootstrap(vaddr_t kva_start)
extern volatile struct xencons_interface *xencons_interface; /* XXX */
extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
- HYPERVISOR_shared_info = (void *) pmap_bootstrap_valloc(1);
- HYPERVISOR_shared_info_pa = pmap_bootstrap_palloc(1);
+ if (vm_guest != VM_GUEST_XENPVH) {
+ HYPERVISOR_shared_info = (void *) pmap_bootstrap_valloc(1);
+ HYPERVISOR_shared_info_pa = pmap_bootstrap_palloc(1);
+ }
xencons_interface = (void *) pmap_bootstrap_valloc(1);
xenstore_interface = (void *) pmap_bootstrap_valloc(1);
#endif
Index: src/sys/arch/x86/x86/x86_autoconf.c
diff -u src/sys/arch/x86/x86/x86_autoconf.c:1.81 src/sys/arch/x86/x86/x86_autoconf.c:1.82
--- src/sys/arch/x86/x86/x86_autoconf.c:1.81 Tue Apr 28 15:43:34 2020
+++ src/sys/arch/x86/x86/x86_autoconf.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_autoconf.c,v 1.81 2020/04/28 15:43:34 bouyer Exp $ */
+/* $NetBSD: x86_autoconf.c,v 1.82 2020/05/02 16:44:36 bouyer Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.81 2020/04/28 15:43:34 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.82 2020/05/02 16:44:36 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -54,6 +54,8 @@ __KERNEL_RCSID(0, "$NetBSD: x86_autoconf
#include <machine/bootinfo.h>
#include <machine/pio.h>
+#include <xen/xen.h>
+
#include <dev/i2c/i2cvar.h>
#include "acpica.h"
@@ -535,6 +537,12 @@ findroot(void)
void
cpu_bootconf(void)
{
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH) {
+ xen_bootconf();
+ return;
+ }
+#endif
findroot();
matchbiosdisks();
}
Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.140 src/sys/arch/x86/x86/x86_machdep.c:1.141
--- src/sys/arch/x86/x86/x86_machdep.c:1.140 Fri May 1 14:16:15 2020
+++ src/sys/arch/x86/x86/x86_machdep.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_machdep.c,v 1.140 2020/05/01 14:16:15 hannken Exp $ */
+/* $NetBSD: x86_machdep.c,v 1.141 2020/05/02 16:44:36 bouyer Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.140 2020/05/01 14:16:15 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.141 2020/05/02 16:44:36 bouyer Exp $");
#include "opt_modular.h"
#include "opt_physmem.h"
@@ -95,6 +95,11 @@ void (*x86_cpu_idle)(void);
static bool x86_cpu_idle_ipi;
static char x86_cpu_idle_text[16];
+#ifdef XEN
+
+#include <xen/xen.h>
+#include <xen/hypervisor.h>
+#endif
#ifdef XENPV
char module_machine_amd64_xen[] = "amd64-xen";
char module_machine_i386pae_xen[] = "i386pae-xen";
@@ -855,6 +860,27 @@ init_x86_clusters(void)
* Check to see if we have a memory map from the BIOS (passed to us by
* the boot program).
*/
+#ifdef XEN
+ if (vm_guest == VM_GUEST_XENPVH) {
+ struct hvm_memmap_table_entry *map_entry;
+ map_entry = (void *)((uintptr_t)hvm_start_info->memmap_paddr + KERNBASE);
+ for (int i = 0; i < hvm_start_info->memmap_entries; i++) {
+ if (map_entry[i].size < PAGE_SIZE)
+ continue;
+ switch(map_entry[i].type) {
+ case XEN_HVM_MEMMAP_TYPE_RAM:
+ x86_add_cluster(map_entry[i].addr,
+ map_entry[i].size, BIM_Memory);
+ break;
+ case XEN_HVM_MEMMAP_TYPE_ACPI:
+ x86_add_cluster(map_entry[i].addr,
+ map_entry[i].size, BIM_ACPI);
+ break;
+ }
+ }
+ }
+#endif /* XEN */
+
#ifdef i386
extern int biosmem_implicit;
biem = lookup_bootinfo(BTINFO_EFIMEMMAP);
Index: src/sys/arch/xen/conf/Makefile.xen
diff -u src/sys/arch/xen/conf/Makefile.xen:1.49 src/sys/arch/xen/conf/Makefile.xen:1.50
--- src/sys/arch/xen/conf/Makefile.xen:1.49 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/conf/Makefile.xen Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.xen,v 1.49 2020/04/25 15:26:17 bouyer Exp $
+# $NetBSD: Makefile.xen,v 1.50 2020/05/02 16:44:36 bouyer Exp $
# NetBSD: Makefile.i386,v 1.132 2003/07/05 16:56:10 simonb Exp
# Makefile for NetBSD
@@ -41,7 +41,7 @@ ARCH_INC= $S/arch/xen/include/${XEN_BUIL
## (2) compile settings
##
CPPFLAGS+= -D${XEN_BUILD}
-AFLAGS+= -x assembler-with-cpp ${DBG} -D__XEN__
+AFLAGS+= -x assembler-with-cpp ${DBG}
EXTRA_INCLUDES= -I${.CURDIR}/xen-ma -I$S/external/mit/xen-include-public/dist/
.if ${XEN_BUILD} == "amd64"
Index: src/sys/arch/xen/conf/files.xen
diff -u src/sys/arch/xen/conf/files.xen:1.182 src/sys/arch/xen/conf/files.xen:1.183
--- src/sys/arch/xen/conf/files.xen:1.182 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/conf/files.xen Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.xen,v 1.182 2020/04/25 15:26:17 bouyer Exp $
+# $NetBSD: files.xen,v 1.183 2020/05/02 16:44:36 bouyer Exp $
defflag opt_xen.h XEN XENPVH XENPVHVM PAE
@@ -11,6 +11,8 @@ file arch/xen/x86/xen_mainbus.c xen
file arch/xen/xen/xen_clock.c xen
file arch/xen/x86/xen_bus_dma.c xen
+file arch/xen/x86/hvm_consinit.c xenpvhvm
+
define hypervisorbus {}
define xendevbus {}
Index: src/sys/arch/xen/include/hypervisor.h
diff -u src/sys/arch/xen/include/hypervisor.h:1.51 src/sys/arch/xen/include/hypervisor.h:1.52
--- src/sys/arch/xen/include/hypervisor.h:1.51 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/include/hypervisor.h Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: hypervisor.h,v 1.51 2020/04/25 15:26:17 bouyer Exp $ */
+/* $NetBSD: hypervisor.h,v 1.52 2020/05/02 16:44:36 bouyer Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -99,6 +99,7 @@ struct xen_npx_attach_args {
#include <xen/include/public/memory.h>
#include <xen/include/public/io/netif.h>
#include <xen/include/public/io/blkif.h>
+#include <xen/include/public/arch-x86/hvm/start_info.h>
#if __XEN_INTERFACE_VERSION < 0x00030208
/* Undo namespace damage from xen/include/public/io/ring.h
@@ -138,9 +139,14 @@ union start_info_union
extern union start_info_union start_info_union;
#define xen_start_info (start_info_union.start_info)
+extern struct hvm_start_info *hvm_start_info;
+
/* For use in guest OSes. */
extern volatile shared_info_t *HYPERVISOR_shared_info;
+/* console */
+extern volatile struct xencons_interface *xencons_interface;
+
/* Structural guest handles introduced in 0x00030201. */
#if __XEN_INTERFACE_VERSION__ >= 0x00030201
@@ -197,4 +203,6 @@ hypervisor_notify_via_evtchn(unsigned in
(void)HYPERVISOR_event_channel_op(&op);
}
+void xen_init_ksyms(void);
+
#endif /* _XEN_HYPERVISOR_H_ */
Index: src/sys/arch/xen/include/xen.h
diff -u src/sys/arch/xen/include/xen.h:1.46 src/sys/arch/xen/include/xen.h:1.47
--- src/sys/arch/xen/include/xen.h:1.46 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/include/xen.h Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xen.h,v 1.46 2020/04/25 15:26:17 bouyer Exp $ */
+/* $NetBSD: xen.h,v 1.47 2020/05/02 16:44:36 bouyer Exp $ */
/*
*
@@ -60,6 +60,8 @@ void xen_parse_cmdline(int, union xen_cm
void xenconscn_attach(void);
+void xen_pvh_consinit(void);
+
void xenprivcmd_init(void);
void xbdback_init(void);
@@ -294,6 +296,8 @@ xen_feature(int f)
return xen_feature_tables[f];
}
+void xen_bootconf(void);
+
#endif /* !__ASSEMBLY__ */
#endif /* _OS_H_ */
Index: src/sys/arch/xen/x86/autoconf.c
diff -u src/sys/arch/xen/x86/autoconf.c:1.24 src/sys/arch/xen/x86/autoconf.c:1.25
--- src/sys/arch/xen/x86/autoconf.c:1.24 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/x86/autoconf.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.24 2020/04/25 15:26:17 bouyer Exp $ */
+/* $NetBSD: autoconf.c,v 1.25 2020/05/02 16:44:36 bouyer Exp $ */
/* NetBSD: autoconf.c,v 1.75 2003/12/30 12:33:22 pk Exp */
/*-
@@ -45,7 +45,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.24 2020/04/25 15:26:17 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.25 2020/05/02 16:44:36 bouyer Exp $");
#include "opt_xen.h"
#include "opt_multiprocessor.h"
@@ -82,8 +82,6 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v
#include <machine/pcb.h>
#include <machine/bootinfo.h>
-static int is_valid_disk(device_t);
-
struct disklist *x86_alldisks;
int x86_ndisks;
int x86_found_console;
@@ -116,7 +114,7 @@ cpu_configure(void)
{
struct pcb *pcb;
- startrtclock();
+ xen_startrtclock();
#if defined(DOM0OPS)
if (xendomain_is_dom0()) {
@@ -171,69 +169,8 @@ cpu_rootconf(void)
void
cpu_bootconf(void)
{
- device_t dv;
- deviter_t di;
- union xen_cmdline_parseinfo xcp;
- static char bootspecbuf[sizeof(xcp.xcp_bootdev)];
-
- if (booted_device) {
- DPRINTF(("%s: preset booted_device: %s\n", __func__, device_xname(booted_device)));
- return;
- }
-
- xen_parse_cmdline(XEN_PARSE_BOOTDEV, &xcp);
-
- for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
- dv != NULL;
- dv = deviter_next(&di)) {
- bool is_ifnet, is_disk;
- const char *devname;
-
- is_ifnet = (device_class(dv) == DV_IFNET);
- is_disk = is_valid_disk(dv);
- devname = device_xname(dv);
-
- if (!is_ifnet && !is_disk)
- continue;
-
- if (is_disk && xcp.xcp_bootdev[0] == 0) {
- booted_device = dv;
- break;
- }
-
- if (strncmp(xcp.xcp_bootdev, devname, strlen(devname)))
- continue;
-
- if (is_disk && strlen(xcp.xcp_bootdev) > strlen(devname)) {
- /* XXX check device_cfdata as in x86_autoconf.c? */
- booted_partition = toupper(
- xcp.xcp_bootdev[strlen(devname)]) - 'A';
- DPRINTF(("%s: booted_partition: %d\n", __func__, booted_partition));
- }
-
- booted_device = dv;
- booted_method = "bootinfo/bootdev";
- break;
- }
- deviter_release(&di);
-
- if (booted_device) {
- DPRINTF(("%s: booted_device: %s\n", __func__, device_xname(booted_device)));
- return;
- }
-
- /*
- * not a boot device name, pass through to MI code
- */
- if (xcp.xcp_bootdev[0] != '\0') {
- strlcpy(bootspecbuf, xcp.xcp_bootdev, sizeof(bootspecbuf));
- bootspec = bootspecbuf;
- booted_method = "bootinfo/bootspec";
- DPRINTF(("%s: bootspec: %s\n", __func__, bootspec));
- return;
- }
+ xen_bootconf();
}
-
#include "pci.h"
#include <dev/isa/isavar.h>
@@ -370,17 +307,3 @@ found:
}
booted_device = dev;
}
-
-static int
-is_valid_disk(device_t dv)
-{
- if (device_class(dv) != DV_DISK)
- return (0);
-
- return (device_is_a(dv, "dk") ||
- device_is_a(dv, "sd") ||
- device_is_a(dv, "wd") ||
- device_is_a(dv, "ld") ||
- device_is_a(dv, "ed") ||
- device_is_a(dv, "xbd"));
-}
Index: src/sys/arch/xen/x86/hypervisor_machdep.c
diff -u src/sys/arch/xen/x86/hypervisor_machdep.c:1.38 src/sys/arch/xen/x86/hypervisor_machdep.c:1.39
--- src/sys/arch/xen/x86/hypervisor_machdep.c:1.38 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/x86/hypervisor_machdep.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: hypervisor_machdep.c,v 1.38 2020/04/25 15:26:17 bouyer Exp $ */
+/* $NetBSD: hypervisor_machdep.c,v 1.39 2020/05/02 16:44:36 bouyer Exp $ */
/*
*
@@ -54,12 +54,13 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.38 2020/04/25 15:26:17 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.39 2020/05/02 16:44:36 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kmem.h>
#include <sys/cpu.h>
+#include <sys/ksyms.h>
#include <uvm/uvm_extern.h>
@@ -76,8 +77,18 @@ __KERNEL_RCSID(0, "$NetBSD: hypervisor_m
#include <xen/xenpmap.h>
#include "opt_xen.h"
+#include "opt_modular.h"
+#include "opt_ddb.h"
#include "isa.h"
#include "pci.h"
+#include "ksyms.h"
+
+#ifdef DDB
+#include <machine/db_machdep.h>
+#include <ddb/db_extern.h>
+#include <ddb/db_output.h>
+#include <ddb/db_interface.h>
+#endif
#ifdef XENPV
/*
@@ -569,3 +580,24 @@ update_p2m_frame_list_list(void)
}
#endif /* XENPV */
+
+void
+xen_init_ksyms(void)
+{
+#if NKSYMS || defined(DDB) || defined(MODULAR)
+ extern int end;
+ extern int *esym;
+#ifdef DDB
+ db_machine_init();
+#endif
+
+#ifdef XENPV
+ esym = xen_start_info.mod_start ?
+ (void *)xen_start_info.mod_start :
+ (void *)xen_start_info.mfn_list;
+#endif /* XENPV */
+ /* for PVH, esym is set in locore.S */
+ ksyms_addsyms_elf(*(int *)(void *)&end,
+ ((int *)(void *)&end) + 1, esym);
+#endif
+}
Index: src/sys/arch/xen/x86/x86_xpmap.c
diff -u src/sys/arch/xen/x86/x86_xpmap.c:1.85 src/sys/arch/xen/x86/x86_xpmap.c:1.86
--- src/sys/arch/xen/x86/x86_xpmap.c:1.85 Wed Oct 30 07:40:06 2019
+++ src/sys/arch/xen/x86/x86_xpmap.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_xpmap.c,v 1.85 2019/10/30 07:40:06 maxv Exp $ */
+/* $NetBSD: x86_xpmap.c,v 1.86 2020/05/02 16:44:36 bouyer Exp $ */
/*
* Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -95,7 +95,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.85 2019/10/30 07:40:06 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.86 2020/05/02 16:44:36 bouyer Exp $");
#include "opt_xen.h"
#include "opt_ddb.h"
@@ -135,7 +135,6 @@ static mmu_update_t xpq_queue_array[MAXC
void xen_failsafe_handler(void);
-extern volatile struct xencons_interface *xencons_interface; /* XXX */
extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
static void xen_bt_set_readonly(vaddr_t);
Index: src/sys/arch/xen/x86/xen_mainbus.c
diff -u src/sys/arch/xen/x86/xen_mainbus.c:1.7 src/sys/arch/xen/x86/xen_mainbus.c:1.8
--- src/sys/arch/xen/x86/xen_mainbus.c:1.7 Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/x86/xen_mainbus.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_mainbus.c,v 1.7 2020/04/25 15:26:17 bouyer Exp $ */
+/* $NetBSD: xen_mainbus.c,v 1.8 2020/05/02 16:44:36 bouyer Exp $ */
/* NetBSD: mainbus.c,v 1.19 2017/05/23 08:54:39 nonaka Exp */
/* NetBSD: mainbus.c,v 1.53 2003/10/27 14:11:47 junyoung Exp */
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_mainbus.c,v 1.7 2020/04/25 15:26:17 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_mainbus.c,v 1.8 2020/05/02 16:44:36 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -131,6 +131,7 @@ xen_mainbus_attach(device_t parent, devi
config_found_ia(self, "ipmibus", &mba.mba_ipmi, 0);
#endif
/* FALLTHROUGH */
+ case VM_GUEST_XENPVH:
case VM_GUEST_XENPVHVM:
mba.mba_haa.haa_busname = "hypervisor";
config_found_ia(self, "hypervisorbus",
Index: src/sys/arch/xen/xen/hypervisor.c
diff -u src/sys/arch/xen/xen/hypervisor.c:1.78 src/sys/arch/xen/xen/hypervisor.c:1.79
--- src/sys/arch/xen/xen/hypervisor.c:1.78 Tue Apr 28 15:43:34 2020
+++ src/sys/arch/xen/xen/hypervisor.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: hypervisor.c,v 1.78 2020/04/28 15:43:34 bouyer Exp $ */
+/* $NetBSD: hypervisor.c,v 1.79 2020/05/02 16:44:36 bouyer Exp $ */
/*
* Copyright (c) 2005 Manuel Bouyer.
@@ -53,7 +53,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.78 2020/04/28 15:43:34 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.79 2020/05/02 16:44:36 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -163,8 +163,9 @@ struct x86_isa_chipset x86_isa_chipset;
#endif
#endif
-#if defined(XENPVHVM)
+#if defined(XENPVHVM) || defined(XENPVH)
#include <xen/include/public/arch-x86/cpuid.h>
+#include <xen/include/public/arch-x86/hvm/start_info.h>
#include <xen/include/public/hvm/hvm_op.h>
#include <xen/include/public/hvm/params.h>
#include <xen/include/public/vcpu.h>
@@ -179,12 +180,12 @@ extern vector IDTVEC(osyscall);
extern vector *x86_exceptions[];
extern vector IDTVEC(hypervisor_pvhvm_callback);
-extern volatile struct xencons_interface *xencons_interface; /* XXX */
extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
volatile shared_info_t *HYPERVISOR_shared_info __read_mostly;
paddr_t HYPERVISOR_shared_info_pa;
union start_info_union start_info_union __aligned(PAGE_SIZE);
+struct hvm_start_info *hvm_start_info;
static int xen_hvm_vec = 0;
#endif
@@ -209,6 +210,64 @@ enum {
bool xenhvm_use_percpu_callback = 0;
+static void
+xen_init_hypercall_page(void)
+{
+ extern vaddr_t hypercall_page;
+ u_int descs[4];
+
+ x86_cpuid(XEN_CPUID_LEAF(2), descs);
+
+ /*
+ * Given 32 bytes per hypercall stub, and an optimistic number
+ * of 100 hypercalls ( the current max is 55), there shouldn't
+ * be any reason to spill over the arbitrary number of 1
+ * hypercall page. This is what we allocate in locore.S
+ * anyway. Make sure the allocation matches the registration.
+ */
+
+ KASSERT(descs[0] == 1);
+
+ /* XXX: vtophys(&hypercall_page) */
+ wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
+}
+
+uint32_t hvm_start_paddr;
+
+void init_xen_early(void);
+void
+init_xen_early(void)
+{
+ const char *cmd_line;
+ if (vm_guest != VM_GUEST_XENPVH)
+ return;
+ xen_init_hypercall_page();
+ hvm_start_info = (void *)((uintptr_t)hvm_start_paddr + KERNBASE);
+
+ HYPERVISOR_shared_info = (void *)(HYPERVISOR_shared_info_pa + KERNBASE);
+ struct xen_add_to_physmap xmap = {
+ .domid = DOMID_SELF,
+ .space = XENMAPSPACE_shared_info,
+ .idx = 0, /* Important - XEN checks for this */
+ .gpfn = atop(HYPERVISOR_shared_info_pa)
+ };
+
+ int err;
+
+ if ((err = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap)) < 0) {
+ printk(
+ "Xen HVM: Unable to register HYPERVISOR_shared_info %d\n", err);
+ }
+ delay_func = xen_delay;
+ x86_initclock_func = xen_initclocks;
+ x86_cpu_initclock_func = xen_cpu_initclocks;
+ cmd_line =
+ (void *)((uintptr_t)hvm_start_info->cmdline_paddr + KERNBASE);
+ strlcpy(xen_start_info.cmd_line, cmd_line,
+ sizeof(xen_start_info.cmd_line));
+}
+
+
static bool
xen_check_hypervisordev(void)
{
@@ -227,51 +286,17 @@ xen_check_hypervisordev(void)
}
return 0;
}
-int
-xen_hvm_init(void)
-{
- extern vaddr_t hypercall_page;
- u_int descs[4];
-
- /*
- * We need to setup the HVM interfaces early, so that we can
- * properly setup the CPUs later (especially, all CPUs needs to
- * run x86_cpuid() locally to get their vcpuid.
- *
- * if everything goes fine, we switch vm_guest to VM_GUEST_XENPVHVM
- */
- if (vm_guest != VM_GUEST_XENHVM)
- return 0;
-
- /* check if hypervisor was disabled with userconf */
- if (!xen_check_hypervisordev())
+static int
+xen_hvm_init_late(void)
+{
+ if (HYPERVISOR_xen_version(XENVER_version, NULL) < 0) {
+ aprint_error("Xen HVM: hypercall page not working\n");
return 0;
-
- aprint_normal("Identified Guest XEN in HVM mode.\n");
-
- x86_cpuid(XEN_CPUID_LEAF(2), descs);
-
- /*
- * Given 32 bytes per hypercall stub, and an optimistic number
- * of 100 hypercalls ( the current max is 55), there shouldn't
- * be any reason to spill over the arbitrary number of 1
- * hypercall page. This is what we allocate in locore.S
- * anyway. Make sure the allocation matches the registration.
- */
-
- KASSERT(descs[0] == 1);
-
- /* XXX: vtophys(&hypercall_page) */
- wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
-
- if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) {
- printf("Xen HVM: detected functional hypercall page.\n");
- xen_init_features();
}
+ xen_init_features();
/* Init various preset boot time data structures */
-
/* XEN xenstore shared page address, event channel */
struct xen_hvm_param xen_hvm_param;
@@ -301,31 +326,59 @@ xen_hvm_init(void)
xen_start_info.store_evtchn = xen_hvm_param.value;
- xen_hvm_param.domid = DOMID_SELF;
- xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
-
- if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
- aprint_error(
- "Xen HVM: Unable to obtain xencons page address\n");
+ /*
+ * First register callback: here's why
+ * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
+ */
+
+ /*
+ * Check for XENFEAT_hvm_callback_vector. Can't proceed
+ * without it.
+ */
+ if (!xen_feature(XENFEAT_hvm_callback_vector)) {
+ aprint_error("Xen HVM: XENFEAT_hvm_callback_vector"
+ "not available, cannot proceed");
return 0;
}
- /* Re-use PV field */
- xen_start_info.console.domU.mfn = xen_hvm_param.value;
+ /*
+ * prepare vector.
+ * We don't really care where it is, as long as it's free
+ */
+ xen_hvm_vec = idt_vec_alloc(129, 255);
+ idt_vec_set(xen_hvm_vec, &IDTVEC(hypervisor_pvhvm_callback));
- pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn),
- VM_PROT_READ|VM_PROT_WRITE, 0);
+ events_default_setup();
+ return 1;
+}
- xen_hvm_param.domid = DOMID_SELF;
- xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
+int
+xen_hvm_init(void)
+{
+ /*
+ * We need to setup the HVM interfaces early, so that we can
+ * properly setup the CPUs later (especially, all CPUs needs to
+ * run x86_cpuid() locally to get their vcpuid.
+ *
+ * For PVH, part of it has already been done.
+ */
+ if (vm_guest == VM_GUEST_XENPVH) {
+ if (xen_hvm_init_late() == 0) {
+ panic("hvm_init failed");
+ }
+ return 1;
+ }
- if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
- aprint_error(
- "Xen HVM: Unable to obtain xencons event channel\n");
+ if (vm_guest != VM_GUEST_XENHVM)
return 0;
- }
- xen_start_info.console.domU.evtchn = xen_hvm_param.value;
+ /* check if hypervisor was disabled with userconf */
+ if (!xen_check_hypervisordev())
+ return 0;
+
+ aprint_normal("Identified Guest XEN in HVM mode.\n");
+
+ xen_init_hypercall_page();
/* HYPERVISOR_shared_info */
struct xen_add_to_physmap xmap = {
@@ -345,33 +398,41 @@ xen_hvm_init(void)
pmap_kenter_pa((vaddr_t) HYPERVISOR_shared_info,
HYPERVISOR_shared_info_pa, VM_PROT_READ|VM_PROT_WRITE, 0);
- /*
- * First register callback: here's why
- * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
- */
+ if (xen_hvm_init_late() == 0)
+ return 0;
- /*
- * Check for XENFEAT_hvm_callback_vector. Can't proceed
- * without it.
- */
- if (!xen_feature(XENFEAT_hvm_callback_vector)) {
- aprint_error("Xen HVM: XENFEAT_hvm_callback_vector"
- "not available, cannot proceed");
+ struct xen_hvm_param xen_hvm_param;
+ xen_hvm_param.domid = DOMID_SELF;
+ xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
+
+ if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
+ aprint_error(
+ "Xen HVM: Unable to obtain xencons page address\n");
return 0;
}
- /*
- * prepare vector.
- * We don't really care where it is, as long as it's free
- */
- xen_hvm_vec = idt_vec_alloc(129, 255);
- idt_vec_set(xen_hvm_vec, &IDTVEC(hypervisor_pvhvm_callback));
+ /* Re-use PV field */
+ xen_start_info.console.domU.mfn = xen_hvm_param.value;
+
+ pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn),
+ VM_PROT_READ|VM_PROT_WRITE, 0);
+
+ xen_hvm_param.domid = DOMID_SELF;
+ xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
+
+ if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
+ aprint_error(
+ "Xen HVM: Unable to obtain xencons event channel\n");
+ return 0;
+ }
+
+ xen_start_info.console.domU.evtchn = xen_hvm_param.value;
- events_default_setup();
delay_func = xen_delay;
x86_initclock_func = xen_initclocks;
x86_cpu_initclock_func = xen_cpu_initclocks;
+
vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */
return 1;
}
@@ -384,7 +445,7 @@ xen_hvm_init_cpu(struct cpu_info *ci)
int error;
static bool again = 0;
- if (vm_guest != VM_GUEST_XENPVHVM)
+ if (!vm_guest_is_xenpvh_or_pvhvm())
return 0;
KASSERT(ci == curcpu());
@@ -464,7 +525,7 @@ hypervisor_match(device_t parent, cfdata
#ifdef XENPVHVM
- if (vm_guest != VM_GUEST_XENPVHVM)
+ if (!vm_guest_is_xenpvh_or_pvhvm())
return 0;
#endif
/* If we got here, it must mean we matched */
@@ -499,11 +560,15 @@ hypervisor_attach(device_t parent, devic
const struct sysctlnode *node = NULL;
#ifdef XENPVHVM
- /* disable emulated devices */
- if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) {
- outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS);
- } else {
- aprint_error_dev(self, "Unable to disable emulated devices\n");
+ if (vm_guest == VM_GUEST_XENPVHVM) {
+ /* disable emulated devices */
+ if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) {
+ outw(XEN_MAGIC_IOPORT,
+ XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS);
+ } else {
+ aprint_error_dev(self,
+ "Unable to disable emulated devices\n");
+ }
}
#endif /* XENPVHVM */
xenkernfs_init();
Index: src/sys/arch/xen/xen/xen_clock.c
diff -u src/sys/arch/xen/xen/xen_clock.c:1.3 src/sys/arch/xen/xen/xen_clock.c:1.4
--- src/sys/arch/xen/xen/xen_clock.c:1.3 Sun Apr 26 20:41:30 2020
+++ src/sys/arch/xen/xen/xen_clock.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_clock.c,v 1.3 2020/04/26 20:41:30 roy Exp $ */
+/* $NetBSD: xen_clock.c,v 1.4 2020/05/02 16:44:36 bouyer Exp $ */
/*-
* Copyright (c) 2017, 2018 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_clock.c,v 1.3 2020/04/26 20:41:30 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_clock.c,v 1.4 2020/05/02 16:44:36 bouyer Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -382,7 +382,6 @@ xen_vcputime_raw_systime_ns(void)
return raw_systime_ns;
}
-#ifdef XENPV
/*
* struct xen_wallclock_ticket
*
@@ -437,7 +436,6 @@ xen_wallclock_exit(struct xen_wallclock_
return tp->version == HYPERVISOR_shared_info->wc_version;
}
-#endif
/*
* xen_global_systime_ns()
@@ -892,7 +890,6 @@ sysctl_xen_timepush(SYSCTLFN_ARGS)
#endif /* DOM0OPS */
-#ifdef XENPV
static int xen_rtc_get(struct todr_chip_handle *, struct timeval *);
static int xen_rtc_set(struct todr_chip_handle *, struct timeval *);
static void xen_wallclock_time(struct timespec *);
@@ -907,31 +904,18 @@ static struct todr_chip_handle xen_todr_
};
/*
- * startrtclock()
+ * xen_startrtclock()
*
* Initialize the real-time clock from x86 machdep autoconf.
*/
void
-startrtclock(void)
+xen_startrtclock(void)
{
todr_attach(&xen_todr_chip);
}
/*
- * setstatclockrate(rate)
- *
- * Set the statclock to run at rate, in units of ticks per second.
- *
- * Currently Xen does not have a separate statclock, so this is a
- * noop; instad the statclock runs in hardclock.
- */
-void
-setstatclockrate(int rate)
-{
-}
-
-/*
* xen_rtc_get(todr, tv)
*
* Get the current real-time clock from the Xen wall clock time
@@ -1012,4 +996,17 @@ xen_wallclock_time(struct timespec *tsp)
tsp->tv_nsec = systime_ns % 1000000000ull;
}
+#ifdef XENPV
+/*
+ * setstatclockrate(rate)
+ *
+ * Set the statclock to run at rate, in units of ticks per second.
+ *
+ * Currently Xen does not have a separate statclock, so this is a
+ * noop; instad the statclock runs in hardclock.
+ */
+void
+setstatclockrate(int rate)
+{
+}
#endif /* XENPV */
Index: src/sys/arch/xen/xen/xen_machdep.c
diff -u src/sys/arch/xen/xen/xen_machdep.c:1.23 src/sys/arch/xen/xen/xen_machdep.c:1.24
--- src/sys/arch/xen/xen/xen_machdep.c:1.23 Sat Apr 25 15:26:18 2020
+++ src/sys/arch/xen/xen/xen_machdep.c Sat May 2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_machdep.c,v 1.23 2020/04/25 15:26:18 bouyer Exp $ */
+/* $NetBSD: xen_machdep.c,v 1.24 2020/05/02 16:44:36 bouyer Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -53,13 +53,16 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_machdep.c,v 1.23 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_machdep.c,v 1.24 2020/05/02 16:44:36 bouyer Exp $");
#include "opt_xen.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/boot_flag.h>
+#include <sys/conf.h>
+#include <sys/disk.h>
+#include <sys/device.h>
#include <sys/mount.h>
#include <sys/reboot.h>
#include <sys/timetc.h>
@@ -77,17 +80,16 @@ __KERNEL_RCSID(0, "$NetBSD: xen_machdep.
#define DPRINTK(x)
#endif
-u_int tsc_get_timecount(struct timecounter *);
+#ifdef DEBUG_GEOM
+#define DPRINTF(a) printf a
+#else
+#define DPRINTF(a)
+#endif
-bool xen_suspend_allow;
-#ifdef XENPV
-extern uint64_t tsc_freq; /* XXX */
+u_int tsc_get_timecount(struct timecounter *);
-static int sysctl_xen_suspend(SYSCTLFN_ARGS);
-static void xen_suspend_domain(void);
-static void xen_prepare_suspend(void);
-static void xen_prepare_resume(void);
+bool xen_suspend_allow;
void
xen_parse_cmdline(int what, union xen_cmdline_parseinfo *xcp)
@@ -217,6 +219,14 @@ xen_parse_cmdline(int what, union xen_cm
}
}
+#ifdef XENPV
+extern uint64_t tsc_freq; /* XXX */
+
+static int sysctl_xen_suspend(SYSCTLFN_ARGS);
+static void xen_suspend_domain(void);
+static void xen_prepare_suspend(void);
+static void xen_prepare_resume(void);
+
u_int
tsc_get_timecount(struct timecounter *tc)
{
@@ -455,3 +465,87 @@ xen_init_features(void)
}
}
}
+
+/*
+ * Attempt to find the device from which we were booted.
+ */
+
+static int
+is_valid_disk(device_t dv)
+{
+ if (device_class(dv) != DV_DISK)
+ return (0);
+
+ return (device_is_a(dv, "dk") ||
+ device_is_a(dv, "sd") ||
+ device_is_a(dv, "wd") ||
+ device_is_a(dv, "ld") ||
+ device_is_a(dv, "ed") ||
+ device_is_a(dv, "xbd"));
+}
+
+void
+xen_bootconf(void)
+{
+ device_t dv;
+ deviter_t di;
+ union xen_cmdline_parseinfo xcp;
+ static char bootspecbuf[sizeof(xcp.xcp_bootdev)];
+
+ if (booted_device) {
+ DPRINTF(("%s: preset booted_device: %s\n", __func__, device_xname(booted_device)));
+ return;
+ }
+
+ xen_parse_cmdline(XEN_PARSE_BOOTDEV, &xcp);
+
+ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
+ dv != NULL;
+ dv = deviter_next(&di)) {
+ bool is_ifnet, is_disk;
+ const char *devname;
+
+ is_ifnet = (device_class(dv) == DV_IFNET);
+ is_disk = is_valid_disk(dv);
+ devname = device_xname(dv);
+
+ if (!is_ifnet && !is_disk)
+ continue;
+
+ if (is_disk && xcp.xcp_bootdev[0] == 0) {
+ booted_device = dv;
+ break;
+ }
+
+ if (strncmp(xcp.xcp_bootdev, devname, strlen(devname)))
+ continue;
+
+ if (is_disk && strlen(xcp.xcp_bootdev) > strlen(devname)) {
+ /* XXX check device_cfdata as in x86_autoconf.c? */
+ booted_partition = toupper(
+ xcp.xcp_bootdev[strlen(devname)]) - 'A';
+ DPRINTF(("%s: booted_partition: %d\n", __func__, booted_partition));
+ }
+
+ booted_device = dv;
+ booted_method = "bootinfo/bootdev";
+ break;
+ }
+ deviter_release(&di);
+
+ if (booted_device) {
+ DPRINTF(("%s: booted_device: %s\n", __func__, device_xname(booted_device)));
+ return;
+ }
+
+ /*
+ * not a boot device name, pass through to MI code
+ */
+ if (xcp.xcp_bootdev[0] != '\0') {
+ strlcpy(bootspecbuf, xcp.xcp_bootdev, sizeof(bootspecbuf));
+ bootspec = bootspecbuf;
+ booted_method = "bootinfo/bootspec";
+ DPRINTF(("%s: bootspec: %s\n", __func__, bootspec));
+ return;
+ }
+}
Added files:
Index: src/sys/arch/xen/x86/pvh_consinit.c
diff -u /dev/null src/sys/arch/xen/x86/pvh_consinit.c:1.1
--- /dev/null Sat May 2 16:44:37 2020
+++ src/sys/arch/xen/x86/pvh_consinit.c Sat May 2 16:44:36 2020
@@ -0,0 +1,115 @@
+/* $NetBSD: pvh_consinit.c,v 1.1 2020/05/02 16:44:36 bouyer Exp $ */
+
+/*
+ * Copyright (c) 2020 Manuel Bouyer.
+ *
+ * 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 ``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 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>
+__KERNEL_RCSID(0, "$NetBSD: pvh_consinit.c,v 1.1 2020/05/02 16:44:36 bouyer Exp $");
+
+#include "xencons.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <uvm/uvm_extern.h>
+#include <uvm/uvm_prot.h>
+
+#include <dev/cons.h>
+#include <xen/xen.h>
+#include <xen/hypervisor.h>
+#include <xen/include/public/hvm/hvm_op.h>
+#include <xen/include/public/hvm/params.h>
+
+static int pvh_xenconscn_getc(dev_t);
+static void pvh_xenconscn_putc(dev_t, int);
+static void pvh_xenconscn_pollc(dev_t, int);
+
+static struct consdev pvh_xencons = {
+ NULL, NULL, pvh_xenconscn_getc, pvh_xenconscn_putc, pvh_xenconscn_pollc,
+ NULL, NULL, NULL, NODEV, CN_NORMAL
+};
+
+
+void
+xen_pvh_consinit(void)
+{
+ /*
+ * hugly hack because we're called multiple times at different
+ * boot stage.
+ */
+ static int initted = 0;
+ if (initted == 0) {
+ /* pmap not up yet, fall back to printk() */
+ cn_tab = &pvh_xencons;
+ initted++;
+ return;
+ } else if (initted > 1) {
+ return;
+ }
+ initted++;
+#if NXENCONS > 0
+ /* we can now map the xencons rings. */
+ struct xen_hvm_param xen_hvm_param;
+
+
+ xen_hvm_param.domid = DOMID_SELF;
+ xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
+
+ if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0)
+ panic("xen_pvh_consinit: can't get console PFN");
+
+ xen_start_info.console.domU.mfn = xen_hvm_param.value;
+ pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_hvm_param.value),
+ VM_PROT_READ|VM_PROT_WRITE, 0);
+
+ xen_hvm_param.domid = DOMID_SELF;
+ xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
+
+ if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0)
+ panic("xen_pvh_consinit: can't get console event");
+
+ xen_start_info.console.domU.evtchn = xen_hvm_param.value;
+ xenconscn_attach();
+#endif
+}
+
+static int
+pvh_xenconscn_getc(dev_t dev)
+{
+ while(1)
+ ;
+ return -1;
+}
+
+static void
+pvh_xenconscn_putc(dev_t dev, int c)
+{
+ printk("%c", c);
+}
+
+static void
+pvh_xenconscn_pollc(dev_t dev, int on)
+{
+ return;
+}