Date: Sat, 14 May 2011 20:35:02 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r221914 - in projects/bhyve/sys: amd64/amd64 amd64/conf amd64/include amd64/vmm amd64/vmm/io conf dev/blackhole dev/bvm kern modules modules/blackhole modules/vmm x86/include x86/x86 Message-ID: <201105142035.p4EKZ2lm014664@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Sat May 14 20:35:01 2011 New Revision: 221914 URL: http://svn.freebsd.org/changeset/base/221914 Log: First cut at porting the kernel portions of 221828 and 221905 from the BHyVe reference branch to HEAD. Added: projects/bhyve/sys/amd64/include/vmm.h - copied unchanged from r221828, projects/bhyve_ref/sys/amd64/include/vmm.h projects/bhyve/sys/amd64/include/vmm_dev.h - copied unchanged from r221828, projects/bhyve_ref/sys/amd64/include/vmm_dev.h projects/bhyve/sys/amd64/vmm/ - copied from r221828, projects/bhyve_ref/sys/amd64/vmm/ projects/bhyve/sys/dev/blackhole/ - copied from r221905, projects/bhyve_ref/sys/dev/blackhole/ projects/bhyve/sys/dev/bvm/ - copied from r221905, projects/bhyve_ref/sys/dev/bvm/ projects/bhyve/sys/modules/blackhole/ - copied from r221905, projects/bhyve_ref/sys/modules/blackhole/ projects/bhyve/sys/modules/vmm/ - copied from r221828, projects/bhyve_ref/sys/modules/vmm/ Modified: projects/bhyve/sys/amd64/amd64/apic_vector.S projects/bhyve/sys/amd64/amd64/intr_machdep.c projects/bhyve/sys/amd64/amd64/minidump_machdep.c projects/bhyve/sys/amd64/amd64/mp_machdep.c projects/bhyve/sys/amd64/amd64/vm_machdep.c projects/bhyve/sys/amd64/conf/GENERIC projects/bhyve/sys/amd64/include/specialreg.h projects/bhyve/sys/amd64/vmm/io/ppt.c projects/bhyve/sys/amd64/vmm/io/vlapic.c projects/bhyve/sys/amd64/vmm/vmm.c projects/bhyve/sys/amd64/vmm/vmm_dev.c projects/bhyve/sys/amd64/vmm/vmm_ipi.c projects/bhyve/sys/amd64/vmm/vmm_msr.c projects/bhyve/sys/conf/files.amd64 projects/bhyve/sys/conf/options.amd64 projects/bhyve/sys/kern/subr_bus.c projects/bhyve/sys/modules/Makefile projects/bhyve/sys/modules/vmm/Makefile projects/bhyve/sys/x86/include/bus.h projects/bhyve/sys/x86/x86/local_apic.c Modified: projects/bhyve/sys/amd64/amd64/apic_vector.S ============================================================================== --- projects/bhyve/sys/amd64/amd64/apic_vector.S Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/amd64/amd64/apic_vector.S Sat May 14 20:35:01 2011 (r221914) @@ -57,8 +57,15 @@ IDTVEC(vec_name) ; \ PUSH_FRAME ; \ FAKE_MCOUNT(TF_RIP(%rsp)) ; \ movq lapic, %rdx ; /* pointer to local APIC */ \ + testq %rdx, %rdx; \ + jnz 3f; \ + movl $MSR_APIC_ISR ## index, %ecx; \ + rdmsr; \ + jmp 4f; \ +3: ; \ movl LA_ISR + 16 * (index)(%rdx), %eax ; /* load ISR */ \ - bsrl %eax, %eax ; /* index of highest set bit in ISR */ \ +4: ; \ + bsrl %eax, %eax ; /* index of highset set bit in ISR */ \ jz 1f ; \ addl $(32 * index),%eax ; \ movq %rsp, %rsi ; \ @@ -129,6 +136,26 @@ IDTVEC(errorint) jmp doreti #ifdef SMP + +/* + * We assume that %rax is being saved/restored outside of this macro + */ +#define DO_EOI \ + movq lapic, %rax; \ + testq %rax, %rax; \ + jz 8f; \ + movl $0, LA_EOI(%rax); \ + jmp 9f; \ +8:; \ + pushq %rcx; \ + pushq %rdx; \ + xorl %edx, %edx; /* eax is already zero */ \ + movl $MSR_APIC_EOI, %ecx; \ + wrmsr; \ + popq %rdx; \ + popq %rcx; \ +9: + /* * Global address space TLB shootdown. */ @@ -153,8 +180,7 @@ IDTVEC(invltlb) movq %cr3, %rax /* invalidate the TLB */ movq %rax, %cr3 - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -186,8 +212,7 @@ IDTVEC(invlpg) movq smp_tlb_addr1, %rax invlpg (%rax) /* invalidate single page */ - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -224,8 +249,7 @@ IDTVEC(invlrng) cmpq %rax, %rdx jb 1b - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -252,8 +276,7 @@ IDTVEC(invlcache) wbinvd - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI lock incl smp_tlb_wait @@ -269,9 +292,8 @@ IDTVEC(invlcache) IDTVEC(ipi_intr_bitmap_handler) PUSH_FRAME - movq lapic, %rdx - movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */ - + DO_EOI + FAKE_MCOUNT(TF_RIP(%rsp)) call ipi_bitmap_handler @@ -286,8 +308,7 @@ IDTVEC(ipi_intr_bitmap_handler) IDTVEC(cpustop) PUSH_FRAME - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI call cpustop_handler jmp doreti @@ -300,8 +321,7 @@ IDTVEC(cpustop) IDTVEC(cpususpend) PUSH_FRAME - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI call cpususpend_handler @@ -323,7 +343,6 @@ IDTVEC(rendezvous) incq (%rax) #endif call smp_rendezvous_action - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ + DO_EOI jmp doreti #endif /* SMP */ Modified: projects/bhyve/sys/amd64/amd64/intr_machdep.c ============================================================================== --- projects/bhyve/sys/amd64/amd64/intr_machdep.c Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/amd64/amd64/intr_machdep.c Sat May 14 20:35:01 2011 (r221914) @@ -78,6 +78,8 @@ static STAILQ_HEAD(, pic) pics; #ifdef SMP static int assign_cpu; +static int round_robin_interrupts = 1; +TUNABLE_INT("round_robin_interrupts", &round_robin_interrupts); #endif static int intr_assign_cpu(void *arg, u_char cpu); @@ -460,6 +462,10 @@ intr_next_cpu(void) if (!assign_cpu) return (PCPU_GET(apic_id)); + /* All interrupts go to the BSP if not allowed to round robin */ + if (!round_robin_interrupts) + return (cpu_apic_ids[0]); + mtx_lock_spin(&icu_lock); apic_id = cpu_apic_ids[current_cpu]; do { Modified: projects/bhyve/sys/amd64/amd64/minidump_machdep.c ============================================================================== --- projects/bhyve/sys/amd64/amd64/minidump_machdep.c Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/amd64/amd64/minidump_machdep.c Sat May 14 20:35:01 2011 (r221914) @@ -27,6 +27,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_pmap.h" #include "opt_watchdog.h" #include <sys/param.h> Modified: projects/bhyve/sys/amd64/amd64/mp_machdep.c ============================================================================== --- projects/bhyve/sys/amd64/amd64/mp_machdep.c Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/amd64/amd64/mp_machdep.c Sat May 14 20:35:01 2011 (r221914) @@ -146,6 +146,26 @@ struct cpu_info { int cpu_apic_ids[MAXCPU]; int apic_cpuids[MAX_APIC_ID + 1]; +/* + * Trampoline for hypervisor direct 64-bit jump. + * + * 0 - signature for guest->host verification + * 8 - virtual address of this page + * 16 - instruction virtual address + * 24 - stack pointer virtual address + * 32 - CR3, physical address of kernel page table + * 40 - 24-byte area for null/code/data GDT entries + */ +#define MP_V64T_SIG 0xcafebabecafebabeULL +struct mp_v64tramp { + uint64_t mt_sig; + uint64_t mt_virt; + uint64_t mt_eip; + uint64_t mt_rsp; + uint64_t mt_cr3; + uint64_t mt_gdtr[3]; +}; + /* Holds pending bitmap based IPIs per CPU */ static volatile u_int cpu_ipi_pending[MAXCPU]; @@ -948,6 +968,29 @@ start_all_aps(void) bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8; bootAP = cpu; + /* + * If running in a VM that doesn't support the unrestricted + * guest 16-bit mode, forget most of the above and create + * the data block that allows the hypervisor to direct-jump + * into 64-bit mode. Copy this over the top of the 16-bit + * bootstrap. The startup-IPI informs the hypervisor which + * physical page this data block lies in. The hypervisor + * will then use the block to initialise register state of + * the AP in an almost identical fashion to how it builds + * the BSP initial register state. + */ + if (testenv("hw.use_bvm_mptramp")) { + struct mp_v64tramp mv; + + bzero(&mv, sizeof(mv)); + mv.mt_sig = MP_V64T_SIG; + mv.mt_virt = (uint64_t) va; + mv.mt_eip = (uint64_t) init_secondary; + mv.mt_rsp = (uint64_t) bootSTK; + mv.mt_cr3 = KPML4phys; + bcopy(&mv, (void *) va, sizeof(mv)); + } + /* attempt to start the Application Processor */ if (!start_ap(apic_id)) { /* restore the warmstart vector */ Modified: projects/bhyve/sys/amd64/amd64/vm_machdep.c ============================================================================== --- projects/bhyve/sys/amd64/amd64/vm_machdep.c Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/amd64/amd64/vm_machdep.c Sat May 14 20:35:01 2011 (r221914) @@ -514,8 +514,10 @@ cpu_reset_proxy() { cpu_reset_proxy_active = 1; - while (cpu_reset_proxy_active == 1) + while (cpu_reset_proxy_active == 1) { + ia32_pause(); ; /* Wait for other cpu to see that we've started */ + } stop_cpus((1<<cpu_reset_proxyid)); printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid); DELAY(1000000); @@ -547,14 +549,17 @@ cpu_reset() atomic_store_rel_int(&started_cpus, 1 << 0); cnt = 0; - while (cpu_reset_proxy_active == 0 && cnt < 10000000) + while (cpu_reset_proxy_active == 0 && cnt < 10000000) { + ia32_pause(); cnt++; /* Wait for BSP to announce restart */ + } if (cpu_reset_proxy_active == 0) printf("cpu_reset: Failed to restart BSP\n"); enable_intr(); cpu_reset_proxy_active = 2; - while (1); + while (1) + ia32_pause(); /* NOTREACHED */ } Modified: projects/bhyve/sys/amd64/conf/GENERIC ============================================================================== --- projects/bhyve/sys/amd64/conf/GENERIC Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/amd64/conf/GENERIC Sat May 14 20:35:01 2011 (r221914) @@ -67,6 +67,7 @@ options INCLUDE_CONFIG_FILE # Inclu # Debugging for use in -current options KDB # Enable kernel debugger support. +options KDB_TRACE options DDB # Support DDB. options GDB # Support remote GDB. options DEADLKRES # Enable the deadlock resolver @@ -337,3 +338,8 @@ device fwe # Ethernet over FireWire (n device fwip # IP over FireWire (RFC 2734,3146) device dcons # Dumb console driver device dcons_crom # Configuration ROM for dcons + +# bhyve options +device bvmconsole # brain dead simple bvm console +device bvmdebug # brain dead simple bvm gdb pipe +device mptable Modified: projects/bhyve/sys/amd64/include/specialreg.h ============================================================================== --- projects/bhyve/sys/amd64/include/specialreg.h Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/amd64/include/specialreg.h Sat May 14 20:35:01 2011 (r221914) @@ -315,11 +315,42 @@ #define MSR_MC4_ADDR 0x412 #define MSR_MC4_MISC 0x413 +/* X2APIC MSRs */ +#define MSR_APIC_ID 0x802 +#define MSR_APIC_VERSION 0x803 +#define MSR_APIC_TPR 0x808 +#define MSR_APIC_EOI 0x80b +#define MSR_APIC_LDR 0x80d +#define MSR_APIC_SVR 0x80f +#define MSR_APIC_ISR0 0x810 +#define MSR_APIC_ISR1 0x811 +#define MSR_APIC_ISR2 0x812 +#define MSR_APIC_ISR3 0x813 +#define MSR_APIC_ISR4 0x814 +#define MSR_APIC_ISR5 0x815 +#define MSR_APIC_ISR6 0x816 +#define MSR_APIC_ISR7 0x817 +#define MSR_APIC_TMR0 0x818 +#define MSR_APIC_IRR0 0x820 +#define MSR_APIC_ESR 0x828 +#define MSR_APIC_LVT_CMCI 0x82F +#define MSR_APIC_ICR 0x830 +#define MSR_APIC_LVT_TIMER 0x832 +#define MSR_APIC_LVT_THERMAL 0x833 +#define MSR_APIC_LVT_PCINT 0x834 +#define MSR_APIC_LVT_LINT0 0x835 +#define MSR_APIC_LVT_LINT1 0x836 +#define MSR_APIC_LVT_ERROR 0x837 +#define MSR_APIC_ICR_TIMER 0x838 +#define MSR_APIC_CCR_TIMER 0x839 +#define MSR_APIC_DCR_TIMER 0x83e + /* * Constants related to MSR's. */ -#define APICBASE_RESERVED 0x000006ff +#define APICBASE_RESERVED 0x000002ff #define APICBASE_BSP 0x00000100 +#define APICBASE_X2APIC 0x00000400 #define APICBASE_ENABLED 0x00000800 #define APICBASE_ADDRESS 0xfffff000 Copied: projects/bhyve/sys/amd64/include/vmm.h (from r221828, projects/bhyve_ref/sys/amd64/include/vmm.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/bhyve/sys/amd64/include/vmm.h Sat May 14 20:35:01 2011 (r221914, copy of r221828, projects/bhyve_ref/sys/amd64/include/vmm.h) @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``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 NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: vmm.h 482 2011-05-09 21:22:43Z grehan $ + */ + +#ifndef _VMM_H_ +#define _VMM_H_ + +#ifdef _KERNEL + +#define VM_MAX_NAMELEN 32 + +struct vm; +struct vm_memory_segment; +struct seg_desc; +struct vm_exit; +struct vm_run; +struct vlapic; + +typedef int (*vmm_init_func_t)(void); +typedef int (*vmm_cleanup_func_t)(void); +typedef void * (*vmi_init_func_t)(struct vm *vm); /* instance specific apis */ +typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip, + struct vm_exit *vmexit); +typedef void (*vmi_cleanup_func_t)(void *vmi); +typedef int (*vmi_mmap_func_t)(void *vmi, vm_paddr_t gpa, vm_paddr_t hpa, + size_t length, vm_memattr_t attr, + int prot, boolean_t superpages_ok); +typedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num, + uint64_t *retval); +typedef int (*vmi_set_register_t)(void *vmi, int vcpu, int num, + uint64_t val); +typedef int (*vmi_get_desc_t)(void *vmi, int vcpu, int num, + struct seg_desc *desc); +typedef int (*vmi_set_desc_t)(void *vmi, int vcpu, int num, + struct seg_desc *desc); +typedef int (*vmi_inject_event_t)(void *vmi, int vcpu, + int type, int vector, + uint32_t code, int code_valid); +typedef int (*vmi_inject_nmi_t)(void *vmi, int vcpu); +typedef int (*vmi_get_cap_t)(void *vmi, int vcpu, int num, int *retval); +typedef int (*vmi_set_cap_t)(void *vmi, int vcpu, int num, int val); + +struct vmm_ops { + vmm_init_func_t init; /* module wide initialization */ + vmm_cleanup_func_t cleanup; + + vmi_init_func_t vminit; /* vm-specific initialization */ + vmi_run_func_t vmrun; + vmi_cleanup_func_t vmcleanup; + vmi_mmap_func_t vmmmap; + vmi_get_register_t vmgetreg; + vmi_set_register_t vmsetreg; + vmi_get_desc_t vmgetdesc; + vmi_set_desc_t vmsetdesc; + vmi_inject_event_t vminject; + vmi_inject_nmi_t vmnmi; + vmi_get_cap_t vmgetcap; + vmi_set_cap_t vmsetcap; +}; + +extern struct vmm_ops vmm_ops_intel; +extern struct vmm_ops vmm_ops_amd; + +struct vm *vm_create(const char *name); +void vm_destroy(struct vm *vm); +const char *vm_name(struct vm *vm); +int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t *ret_hpa); +int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); +vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); +int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, + struct vm_memory_segment *seg); +int vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval); +int vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val); +int vm_get_seg_desc(struct vm *vm, int vcpu, int reg, + struct seg_desc *ret_desc); +int vm_set_seg_desc(struct vm *vm, int vcpu, int reg, + struct seg_desc *desc); +int vm_get_pinning(struct vm *vm, int vcpu, int *cpuid); +int vm_set_pinning(struct vm *vm, int vcpu, int cpuid); +int vm_run(struct vm *vm, struct vm_run *vmrun); +int vm_inject_event(struct vm *vm, int vcpu, int type, + int vector, uint32_t error_code, int error_code_valid); +int vm_inject_nmi(struct vm *vm, int vcpu); +uint64_t *vm_guest_msrs(struct vm *vm, int cpu); +struct vlapic *vm_lapic(struct vm *vm, int cpu); +int vm_get_capability(struct vm *vm, int vcpu, int type, int *val); +int vm_set_capability(struct vm *vm, int vcpu, int type, int val); +void vm_activate_cpu(struct vm *vm, int vcpu); +cpumask_t vm_active_cpus(struct vm *vm); + +/* + * Return 1 if device indicated by bus/slot/func is supposed to be a + * pci passthrough device. + * + * Return 0 otherwise. + */ +int vmm_is_pptdev(int bus, int slot, int func); + +void *vm_iommu_domain(struct vm *vm); + +#define VCPU_STOPPED 0 +#define VCPU_RUNNING 1 +void vm_set_run_state(struct vm *vm, int vcpu, int running); +int vm_get_run_state(struct vm *vm, int vcpu, int *hostcpu); + +void *vcpu_stats(struct vm *vm, int vcpu); + +static int __inline +vcpu_is_running(struct vm *vm, int vcpu, int *hostcpu) +{ + return (vm_get_run_state(vm, vcpu, hostcpu) == VCPU_RUNNING); +} + +static cpumask_t __inline +vcpu_mask(int vcpuid) +{ + return ((cpumask_t)1 << vcpuid); +} + +#endif /* KERNEL */ + +#define VM_MAXCPU 8 /* maximum virtual cpus */ + +/* + * Identifiers for events that can be injected into the VM + */ +enum vm_event_type { + VM_EVENT_NONE, + VM_HW_INTR, + VM_NMI, + VM_HW_EXCEPTION, + VM_SW_INTR, + VM_PRIV_SW_EXCEPTION, + VM_SW_EXCEPTION, + VM_EVENT_MAX +}; + +/* + * Identifiers for architecturally defined registers. + */ +enum vm_reg_name { + VM_REG_GUEST_RAX, + VM_REG_GUEST_RBX, + VM_REG_GUEST_RCX, + VM_REG_GUEST_RDX, + VM_REG_GUEST_RSI, + VM_REG_GUEST_RDI, + VM_REG_GUEST_RBP, + VM_REG_GUEST_R8, + VM_REG_GUEST_R9, + VM_REG_GUEST_R10, + VM_REG_GUEST_R11, + VM_REG_GUEST_R12, + VM_REG_GUEST_R13, + VM_REG_GUEST_R14, + VM_REG_GUEST_R15, + VM_REG_GUEST_CR0, + VM_REG_GUEST_CR3, + VM_REG_GUEST_CR4, + VM_REG_GUEST_DR7, + VM_REG_GUEST_RSP, + VM_REG_GUEST_RIP, + VM_REG_GUEST_RFLAGS, + VM_REG_GUEST_ES, + VM_REG_GUEST_CS, + VM_REG_GUEST_SS, + VM_REG_GUEST_DS, + VM_REG_GUEST_FS, + VM_REG_GUEST_GS, + VM_REG_GUEST_LDTR, + VM_REG_GUEST_TR, + VM_REG_GUEST_IDTR, + VM_REG_GUEST_GDTR, + VM_REG_GUEST_EFER, + VM_REG_LAST +}; + +/* + * Identifiers for optional vmm capabilities + */ +enum vm_cap_type { + VM_CAP_HALT_EXIT, + VM_CAP_MTRAP_EXIT, + VM_CAP_PAUSE_EXIT, + VM_CAP_UNRESTRICTED_GUEST, + VM_CAP_MAX +}; + +/* + * The 'access' field has the format specified in Table 21-2 of the Intel + * Architecture Manual vol 3b. + * + * XXX The contents of the 'access' field are architecturally defined except + * bit 16 - Segment Unusable. + */ +struct seg_desc { + uint64_t base; + uint32_t limit; + uint32_t access; +}; + +enum vm_exitcode { + VM_EXITCODE_INOUT, + VM_EXITCODE_VMX, + VM_EXITCODE_BOGUS, + VM_EXITCODE_RDMSR, + VM_EXITCODE_WRMSR, + VM_EXITCODE_HLT, + VM_EXITCODE_MTRAP, + VM_EXITCODE_PAUSE, + VM_EXITCODE_MAX, +}; + +struct vm_exit { + enum vm_exitcode exitcode; + int inst_length; /* 0 means unknown */ + uint64_t rip; + union { + struct { + uint16_t bytes:3; /* 1 or 2 or 4 */ + uint16_t in:1; /* out is 0, in is 1 */ + uint16_t string:1; + uint16_t rep:1; + uint16_t port; + uint32_t eax; /* valid for out */ + } inout; + /* + * VMX specific payload. Used when there is no "better" + * exitcode to represent the VM-exit. + */ + struct { + int error; /* vmx inst error */ + uint32_t exit_reason; + uint64_t exit_qualification; + } vmx; + struct { + uint32_t code; /* ecx value */ + uint64_t wval; + } msr; + } u; +}; + +#endif /* _VMM_H_ */ Copied: projects/bhyve/sys/amd64/include/vmm_dev.h (from r221828, projects/bhyve_ref/sys/amd64/include/vmm_dev.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/bhyve/sys/amd64/include/vmm_dev.h Sat May 14 20:35:01 2011 (r221914, copy of r221828, projects/bhyve_ref/sys/amd64/include/vmm_dev.h) @@ -0,0 +1,191 @@ +/*- + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``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 NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: vmm_dev.h 482 2011-05-09 21:22:43Z grehan $ + */ + +#ifndef _VMM_DEV_H_ +#define _VMM_DEV_H_ + +#ifdef _KERNEL +void vmmdev_init(void); +void vmmdev_cleanup(void); +#endif + +struct vm_memory_segment { + vm_paddr_t hpa; /* out */ + vm_paddr_t gpa; /* in */ + size_t len; /* in */ +}; + +struct vm_register { + int cpuid; + int regnum; /* enum vm_reg_name */ + uint64_t regval; +}; + +struct vm_seg_desc { /* data or code segment */ + int cpuid; + int regnum; /* enum vm_reg_name */ + struct seg_desc desc; +}; + +struct vm_pin { + int vm_cpuid; + int host_cpuid; /* -1 to unpin */ +}; + +struct vm_run { + int cpuid; + uint64_t rip; /* start running here */ + struct vm_exit vm_exit; +}; + +struct vm_event { + int cpuid; + enum vm_event_type type; + int vector; + uint32_t error_code; + int error_code_valid; +}; + +struct vm_lapic_irq { + int cpuid; + int vector; +}; + +struct vm_capability { + int cpuid; + enum vm_cap_type captype; + int capval; + int allcpus; +}; + +struct vm_pptdev { + int bus; + int slot; + int func; +}; + +struct vm_pptdev_mmio { + int bus; + int slot; + int func; + vm_paddr_t gpa; + vm_paddr_t hpa; + size_t len; +}; + +struct vm_pptdev_msi { + int vcpu; + int bus; + int slot; + int func; + int numvec; /* 0 means disabled */ + int vector; + int destcpu; +}; + +struct vm_nmi { + int cpuid; +}; + +#define MAX_VM_STATS 64 +struct vm_stats { + int cpuid; /* in */ + int num_entries; /* out */ + struct timeval tv; + uint64_t statbuf[MAX_VM_STATS]; +}; + +struct vm_stat_desc { + int index; /* in */ + char desc[128]; /* out */ +}; + +enum { + IOCNUM_RUN, + IOCNUM_SET_PINNING, + IOCNUM_GET_PINNING, + IOCNUM_MAP_MEMORY, + IOCNUM_GET_MEMORY_SEG, + IOCNUM_SET_REGISTER, + IOCNUM_GET_REGISTER, + IOCNUM_SET_SEGMENT_DESCRIPTOR, + IOCNUM_GET_SEGMENT_DESCRIPTOR, + IOCNUM_INJECT_EVENT, + IOCNUM_LAPIC_IRQ, + IOCNUM_SET_CAPABILITY, + IOCNUM_GET_CAPABILITY, + IOCNUM_BIND_PPTDEV, + IOCNUM_UNBIND_PPTDEV, + IOCNUM_MAP_PPTDEV_MMIO, + IOCNUM_PPTDEV_MSI, + IOCNUM_INJECT_NMI, + IOCNUM_VM_STATS, + IOCNUM_VM_STAT_DESC, +}; + +#define VM_RUN \ + _IOWR('v', IOCNUM_RUN, struct vm_run) +#define VM_SET_PINNING \ + _IOW('v', IOCNUM_SET_PINNING, struct vm_pin) +#define VM_GET_PINNING \ + _IOWR('v', IOCNUM_GET_PINNING, struct vm_pin) +#define VM_MAP_MEMORY \ + _IOWR('v', IOCNUM_MAP_MEMORY, struct vm_memory_segment) +#define VM_GET_MEMORY_SEG \ + _IOWR('v', IOCNUM_GET_MEMORY_SEG, struct vm_memory_segment) +#define VM_SET_REGISTER \ + _IOW('v', IOCNUM_SET_REGISTER, struct vm_register) +#define VM_GET_REGISTER \ + _IOWR('v', IOCNUM_GET_REGISTER, struct vm_register) +#define VM_SET_SEGMENT_DESCRIPTOR \ + _IOW('v', IOCNUM_SET_SEGMENT_DESCRIPTOR, struct vm_seg_desc) +#define VM_GET_SEGMENT_DESCRIPTOR \ + _IOWR('v', IOCNUM_GET_SEGMENT_DESCRIPTOR, struct vm_seg_desc) +#define VM_INJECT_EVENT \ + _IOW('v', IOCNUM_INJECT_EVENT, struct vm_event) +#define VM_LAPIC_IRQ \ + _IOW('v', IOCNUM_LAPIC_IRQ, struct vm_lapic_irq) +#define VM_SET_CAPABILITY \ + _IOW('v', IOCNUM_SET_CAPABILITY, struct vm_capability) +#define VM_GET_CAPABILITY \ + _IOWR('v', IOCNUM_GET_CAPABILITY, struct vm_capability) +#define VM_BIND_PPTDEV \ + _IOW('v', IOCNUM_BIND_PPTDEV, struct vm_pptdev) +#define VM_UNBIND_PPTDEV \ + _IOW('v', IOCNUM_UNBIND_PPTDEV, struct vm_pptdev) +#define VM_MAP_PPTDEV_MMIO \ + _IOW('v', IOCNUM_MAP_PPTDEV_MMIO, struct vm_pptdev_mmio) +#define VM_PPTDEV_MSI \ + _IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi) +#define VM_INJECT_NMI \ + _IOW('v', IOCNUM_INJECT_NMI, struct vm_nmi) +#define VM_STATS \ + _IOWR('v', IOCNUM_VM_STATS, struct vm_stats) +#define VM_STAT_DESC \ + _IOWR('v', IOCNUM_VM_STAT_DESC, struct vm_stat_desc) +#endif Modified: projects/bhyve/sys/amd64/vmm/io/ppt.c ============================================================================== --- projects/bhyve_ref/sys/amd64/vmm/io/ppt.c Fri May 13 04:54:01 2011 (r221828) +++ projects/bhyve/sys/amd64/vmm/io/ppt.c Sat May 14 20:35:01 2011 (r221914) @@ -433,7 +433,7 @@ ppt_setup_msi(struct vm *vm, int vcpu, i ppt->msi.arg[i].msg = i; error = bus_setup_intr(ppt->dev, ppt->msi.res[i], - INTR_TYPE_NET | INTR_MPSAFE | INTR_FAST, + INTR_TYPE_NET | INTR_MPSAFE, pptintr, NULL, &ppt->msi.arg[i], &ppt->msi.cookie[i]); if (error != 0) Modified: projects/bhyve/sys/amd64/vmm/io/vlapic.c ============================================================================== --- projects/bhyve_ref/sys/amd64/vmm/io/vlapic.c Fri May 13 04:54:01 2011 (r221828) +++ projects/bhyve/sys/amd64/vmm/io/vlapic.c Sat May 14 20:35:01 2011 (r221914) @@ -63,7 +63,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <machine/clock.h> -#include <machine/apicreg.h> +#include <x86/apicreg.h> #include <machine/vmm.h> Modified: projects/bhyve/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_ref/sys/amd64/vmm/vmm.c Fri May 13 04:54:01 2011 (r221828) +++ projects/bhyve/sys/amd64/vmm/vmm.c Sat May 14 20:35:01 2011 (r221914) @@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$"); #include <machine/vm.h> #include <machine/pcb.h> -#include <machine/apicreg.h> +#include <x86/apicreg.h> #include <machine/vmm.h> #include "vmm_mem.h" @@ -160,7 +160,8 @@ vcpu_init(struct vm *vm, uint32_t vcpu_i vcpu->hostcpu = -1; vcpu->vcpuid = vcpu_id; vcpu->vlapic = vlapic_init(vm, vcpu_id); - fpugetregs(curthread, &vcpu->savefpu); + fpugetregs(curthread); + vcpu->savefpu = curthread->td_pcb->pcb_user_save; vcpu->stats = vmm_stat_alloc(); } @@ -545,7 +546,7 @@ vm_run(struct vm *vm, struct vm_run *vmr tscval = rdtsc(); pcb = PCPU_GET(curpcb); - pcb->pcb_full_iret = 1; + set_pcb_flags(pcb, PCB_FULL_IRET); vcpu->hostcpu = curcpu; Modified: projects/bhyve/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/bhyve_ref/sys/amd64/vmm/vmm_dev.c Fri May 13 04:54:01 2011 (r221828) +++ projects/bhyve/sys/amd64/vmm/vmm_dev.c Sat May 14 20:35:01 2011 (r221914) @@ -336,7 +336,8 @@ done: } static int -vmmdev_mmap(struct cdev *cdev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) +vmmdev_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr, + int nprot, vm_memattr_t *memattr) { int error; struct vmmdev_softc *sc; Modified: projects/bhyve/sys/amd64/vmm/vmm_ipi.c ============================================================================== --- projects/bhyve_ref/sys/amd64/vmm/vmm_ipi.c Fri May 13 04:54:01 2011 (r221828) +++ projects/bhyve/sys/amd64/vmm/vmm_ipi.c Sat May 14 20:35:01 2011 (r221914) @@ -99,5 +99,5 @@ vm_interrupt_hostcpu(struct vm *vm, int int hostcpu; if (vcpu_is_running(vm, vcpu, &hostcpu) && hostcpu != curcpu) - ipi_selected((cpumask_t)1 << hostcpu, ipinum); + ipi_cpu(hostcpu, ipinum); } Modified: projects/bhyve/sys/amd64/vmm/vmm_msr.c ============================================================================== --- projects/bhyve_ref/sys/amd64/vmm/vmm_msr.c Fri May 13 04:54:01 2011 (r221828) +++ projects/bhyve/sys/amd64/vmm/vmm_msr.c Sat May 14 20:35:01 2011 (r221914) @@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <machine/specialreg.h> -#include <machine/apicreg.h> +#include <x86/apicreg.h> #include <machine/vmm.h> #include "vmm_lapic.h" Modified: projects/bhyve/sys/conf/files.amd64 ============================================================================== --- projects/bhyve/sys/conf/files.amd64 Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/conf/files.amd64 Sat May 14 20:35:01 2011 (r221914) @@ -295,6 +295,11 @@ libkern/memset.c standard compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | vesa contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa # +# bvm console +# +dev/bvm/bvm_console.c optional bvmconsole +dev/bvm/bvm_dbg.c optional bvmdebug +# # x86 shared code between IA32, AMD64 and PC98 architectures # x86/acpica/OsdEnvironment.c optional acpi Modified: projects/bhyve/sys/conf/options.amd64 ============================================================================== --- projects/bhyve/sys/conf/options.amd64 Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/conf/options.amd64 Sat May 14 20:35:01 2011 (r221914) @@ -10,6 +10,7 @@ PERFMON PMAP_SHPGPERPROC opt_pmap.h MPTABLE_FORCE_HTT MP_WATCHDOG +NKPT opt_pmap.h # Options for emulators. These should only be used at config time, so # they are handled like options for static filesystems Modified: projects/bhyve/sys/kern/subr_bus.c ============================================================================== --- projects/bhyve/sys/kern/subr_bus.c Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/kern/subr_bus.c Sat May 14 20:35:01 2011 (r221914) @@ -2683,7 +2683,7 @@ device_attach(device_t dev) printf("device_attach: %s%d attach returned %d\n", dev->driver->name, dev->unit, error); /* Unset the class; set in device_probe_child */ - if (dev->devclass == NULL) + if ((dev->flags & DF_FIXEDCLASS) == 0) device_set_devclass(dev, NULL); device_set_driver(dev, NULL); device_sysctl_fini(dev); Modified: projects/bhyve/sys/modules/Makefile ============================================================================== --- projects/bhyve/sys/modules/Makefile Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/modules/Makefile Sat May 14 20:35:01 2011 (r221914) @@ -43,6 +43,7 @@ SUBDIR= ${_3dfx} \ ${_bxe} \ ${_bios} \ ${_bktr} \ + ${_blackhole} \ ${_bm} \ bridgestp \ bwi \ @@ -311,6 +312,7 @@ SUBDIR= ${_3dfx} \ ${_vesa} \ vge \ vkbd \ + ${_vmm} \ ${_vpo} \ vr \ vte \ @@ -541,6 +543,7 @@ _amdsbwd= amdsbwd _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc +_blackhole= blackhole _bxe= bxe _cardbus= cardbus _cbb= cbb @@ -617,6 +620,7 @@ _sppp= sppp _tpm= tpm _twa= twa _vesa= vesa +_vmm= vmm _x86bios= x86bios _wi= wi _wpi= wpi Modified: projects/bhyve/sys/modules/vmm/Makefile ============================================================================== --- projects/bhyve_ref/sys/modules/vmm/Makefile Fri May 13 04:54:01 2011 (r221828) +++ projects/bhyve/sys/modules/vmm/Makefile Sat May 14 20:35:01 2011 (r221914) @@ -9,7 +9,7 @@ KMOD= vmm SRCS= device_if.h bus_if.h pci_if.h -CFLAGS+= -DVMM_KEEP_STATS +CFLAGS+= -DVMM_KEEP_STATS -DSMP CFLAGS+= -DOLD_BINUTILS CFLAGS+= -I${.CURDIR}/../../amd64/vmm CFLAGS+= -I${.CURDIR}/../../amd64/vmm/io @@ -60,7 +60,7 @@ vmx_support.o: vmx_support.S vmx_assym.s ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ ${.IMPSRC} -o ${.TARGET} -vmx_genassym.o: vmx_genassym.c @ machine +vmx_genassym.o: vmx_genassym.c @ machine x86 ${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC} .include <bsd.kmod.mk> Modified: projects/bhyve/sys/x86/include/bus.h ============================================================================== --- projects/bhyve/sys/x86/include/bus.h Sat May 14 20:31:04 2011 (r221913) +++ projects/bhyve/sys/x86/include/bus.h Sat May 14 20:35:01 2011 (r221914) @@ -279,9 +279,13 @@ bus_space_read_multi_1(bus_space_tag_t t bus_size_t offset, u_int8_t *addr, size_t count) { - if (tag == X86_BUS_SPACE_IO) - insb(bsh + offset, addr, count); - else { + if (tag == X86_BUS_SPACE_IO) { + while (count > 0) { + *addr = inb(bsh + offset); + count--; + addr++; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ @@ -300,9 +304,13 @@ bus_space_read_multi_2(bus_space_tag_t t bus_size_t offset, u_int16_t *addr, size_t count) { - if (tag == X86_BUS_SPACE_IO) - insw(bsh + offset, addr, count); - else { + if (tag == X86_BUS_SPACE_IO) { + while (count > 0) { + *addr = inw(bsh + offset); + count--; + addr++; + } + } else { #ifdef __GNUCLIKE_ASM __asm __volatile(" \n\ cld \n\ @@ -321,9 +329,13 @@ bus_space_read_multi_4(bus_space_tag_t t bus_size_t offset, u_int32_t *addr, size_t count) { - if (tag == X86_BUS_SPACE_IO) - insl(bsh + offset, addr, count); - else { + if (tag == X86_BUS_SPACE_IO) { + while (count > 0) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105142035.p4EKZ2lm014664>