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; +}