diff options
author | neel <neel@FreeBSD.org> | 2015-03-14 02:32:08 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2015-03-14 02:32:08 +0000 |
commit | e16d18eeb88f1763ac45bd42e37e7244970d4722 (patch) | |
tree | 3315483c52723327945a90b486ede6f81b26e39c /sys/amd64 | |
parent | 771dc2cc82487fde44a71d30533ccde7bf753a8a (diff) | |
download | FreeBSD-src-e16d18eeb88f1763ac45bd42e37e7244970d4722.zip FreeBSD-src-e16d18eeb88f1763ac45bd42e37e7244970d4722.tar.gz |
Use lapic_ipi_alloc() to dynamically allocate IPI slots needed by bhyve when
vmm.ko is loaded.
Also relocate the 'justreturn' IPI handler to be alongside all other handlers.
Requested by: kib
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/apic_vector.S | 31 | ||||
-rw-r--r-- | sys/amd64/include/smp.h | 1 | ||||
-rw-r--r-- | sys/amd64/vmm/intel/ept.c | 1 | ||||
-rw-r--r-- | sys/amd64/vmm/intel/vmx.c | 11 | ||||
-rw-r--r-- | sys/amd64/vmm/io/vlapic.c | 1 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm.c | 7 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm_ipi.c | 93 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm_ipi.h | 35 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm_lapic.c | 1 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm_support.S | 43 |
10 files changed, 40 insertions, 184 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index d9f2724..c3aac33 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -301,4 +301,35 @@ IDTVEC(rendezvous) call smp_rendezvous_action call as_lapic_eoi jmp doreti + +/* + * IPI handler whose purpose is to interrupt the CPU with minimum overhead. + * This is used by bhyve to force a host cpu executing in guest context to + * trap into the hypervisor. + * + * This handler is different from other IPI handlers in the following aspects: + * + * 1. It doesn't push a trapframe on the stack. + * + * This implies that a DDB backtrace involving 'justreturn' will skip the + * function that was interrupted by this handler. + * + * 2. It doesn't 'swapgs' when userspace is interrupted. + * + * The 'justreturn' handler does not access any pcpu data so it is not an + * issue. Moreover the 'justreturn' handler can only be interrupted by an NMI + * whose handler already doesn't trust GS.base when kernel code is interrupted. + */ + .text + SUPERALIGN_TEXT +IDTVEC(justreturn) + pushq %rax + pushq %rcx + pushq %rdx + call as_lapic_eoi + popq %rdx + popq %rcx + popq %rax + jmp doreti_iret + #endif /* SMP */ diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 99bf1e4..3a4b6b3 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -54,6 +54,7 @@ inthand_t IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */ IDTVEC(cpustop), /* CPU stops & waits to be restarted */ IDTVEC(cpususpend), /* CPU suspends & waits to be resumed */ + IDTVEC(justreturn), /* interrupt CPU with minimum overhead */ IDTVEC(rendezvous); /* handle CPU rendezvous */ struct pmap; diff --git a/sys/amd64/vmm/intel/ept.c b/sys/amd64/vmm/intel/ept.c index 13c9788..54320cb 100644 --- a/sys/amd64/vmm/intel/ept.c +++ b/sys/amd64/vmm/intel/ept.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include <machine/vmm.h> #include "vmx_cpufunc.h" -#include "vmm_ipi.h" #include "ept.h" #define EPT_SUPPORTS_EXEC_ONLY(cap) ((cap) & (1UL << 0)) diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index b81e48b..6dbf38a 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); #include "vmm_lapic.h" #include "vmm_host.h" #include "vmm_ioport.h" -#include "vmm_ipi.h" #include "vmm_ktr.h" #include "vmm_stat.h" #include "vatpic.h" @@ -175,7 +174,7 @@ static int posted_interrupts; SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, posted_interrupts, CTLFLAG_RD, &posted_interrupts, 0, "APICv posted interrupt support"); -static int pirvec; +static int pirvec = -1; SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupt_vector, CTLFLAG_RD, &pirvec, 0, "APICv posted interrupt vector"); @@ -485,8 +484,8 @@ static int vmx_cleanup(void) { - if (pirvec != 0) - vmm_ipi_free(pirvec); + if (pirvec >= 0) + lapic_ipi_free(pirvec); if (vpid_unr != NULL) { delete_unrhdr(vpid_unr); @@ -694,8 +693,8 @@ vmx_init(int ipinum) MSR_VMX_TRUE_PINBASED_CTLS, PINBASED_POSTED_INTERRUPT, 0, &tmp); if (error == 0) { - pirvec = vmm_ipi_alloc(); - if (pirvec == 0) { + pirvec = lapic_ipi_alloc(&IDTVEC(justreturn)); + if (pirvec < 0) { if (bootverbose) { printf("vmx_init: unable to allocate " "posted interrupt vector\n"); diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c index b192735..7097248 100644 --- a/sys/amd64/vmm/io/vlapic.c +++ b/sys/amd64/vmm/io/vlapic.c @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include <machine/vmm.h> -#include "vmm_ipi.h" #include "vmm_lapic.h" #include "vmm_ktr.h" #include "vmm_stat.h" diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 9e44549..7e72b02 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -76,7 +76,6 @@ __FBSDID("$FreeBSD$"); #include "vlapic.h" #include "vpmtmr.h" #include "vrtc.h" -#include "vmm_ipi.h" #include "vmm_stat.h" #include "vmm_lapic.h" @@ -298,8 +297,8 @@ vmm_init(void) vmm_host_state_init(); - vmm_ipinum = vmm_ipi_alloc(); - if (vmm_ipinum == 0) + vmm_ipinum = lapic_ipi_alloc(&IDTVEC(justreturn)); + if (vmm_ipinum < 0) vmm_ipinum = IPI_AST; error = vmm_mem_init(); @@ -338,7 +337,7 @@ vmm_handler(module_t mod, int what, void *arg) vmm_resume_p = NULL; iommu_cleanup(); if (vmm_ipinum != IPI_AST) - vmm_ipi_free(vmm_ipinum); + lapic_ipi_free(vmm_ipinum); error = VMM_CLEANUP(); /* * Something bad happened - prevent new diff --git a/sys/amd64/vmm/vmm_ipi.c b/sys/amd64/vmm/vmm_ipi.c deleted file mode 100644 index aefa3ba..0000000 --- a/sys/amd64/vmm/vmm_ipi.c +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * 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$ - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/bus.h> - -#include <machine/intr_machdep.h> -#include <x86/apicvar.h> -#include <machine/segments.h> -#include <machine/md_var.h> - -#include <machine/vmm.h> -#include "vmm_ipi.h" - -extern inthand_t IDTVEC(rsvd), IDTVEC(justreturn); - -CTASSERT(APIC_SPURIOUS_INT == 255); - -int -vmm_ipi_alloc(void) -{ - int idx; - uintptr_t func; - struct gate_descriptor *ip; - - /* - * Search backwards from the highest IDT vector available for use - * as our IPI vector. We install the 'justreturn' handler at that - * vector and use it to interrupt the vcpus. - * - * We do this because the IPI_AST is heavyweight and saves all - * registers in the trapframe. This is overkill for our use case - * which is simply to EOI the interrupt and return. - */ - idx = APIC_SPURIOUS_INT; - while (--idx >= APIC_IPI_INTS) { - ip = &idt[idx]; - func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset); - if (func == (uintptr_t)&IDTVEC(rsvd)) { - setidt(idx , IDTVEC(justreturn), SDT_SYSIGT, - SEL_KPL, 0); - return (idx); - } - } - return (0); -} - -void -vmm_ipi_free(int ipinum) -{ - uintptr_t func; - struct gate_descriptor *ip; - - KASSERT(ipinum >= APIC_IPI_INTS && ipinum < APIC_SPURIOUS_INT, - ("invalid ipi %d", ipinum)); - - ip = &idt[ipinum]; - func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset); - KASSERT(func == (uintptr_t)&IDTVEC(justreturn), - ("invalid ipi %d", ipinum)); - - setidt(ipinum, IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0); -} diff --git a/sys/amd64/vmm/vmm_ipi.h b/sys/amd64/vmm/vmm_ipi.h deleted file mode 100644 index 679d183..0000000 --- a/sys/amd64/vmm/vmm_ipi.h +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * 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$ - */ - -#ifndef _VMM_IPI_H_ -#define _VMM_IPI_H_ - -int vmm_ipi_alloc(void); -void vmm_ipi_free(int num); - -#endif diff --git a/sys/amd64/vmm/vmm_lapic.c b/sys/amd64/vmm/vmm_lapic.c index fa9832e..15a995e 100644 --- a/sys/amd64/vmm/vmm_lapic.c +++ b/sys/amd64/vmm/vmm_lapic.c @@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$"); #include <x86/apicreg.h> #include <machine/vmm.h> -#include "vmm_ipi.h" #include "vmm_ktr.h" #include "vmm_lapic.h" #include "vlapic.h" diff --git a/sys/amd64/vmm/vmm_support.S b/sys/amd64/vmm/vmm_support.S deleted file mode 100644 index 7919511..0000000 --- a/sys/amd64/vmm/vmm_support.S +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * 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$ - */ - -#define LOCORE - -#include <machine/asmacros.h> - - .text - SUPERALIGN_TEXT -IDTVEC(justreturn) - pushq %rdx - pushq %rax - pushq %rcx - call as_lapic_eoi - popq %rcx - popq %rax - popq %rdx - jmp doreti_iret |