summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2015-03-14 02:32:08 +0000
committerneel <neel@FreeBSD.org>2015-03-14 02:32:08 +0000
commite16d18eeb88f1763ac45bd42e37e7244970d4722 (patch)
tree3315483c52723327945a90b486ede6f81b26e39c /sys/amd64
parent771dc2cc82487fde44a71d30533ccde7bf753a8a (diff)
downloadFreeBSD-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.S31
-rw-r--r--sys/amd64/include/smp.h1
-rw-r--r--sys/amd64/vmm/intel/ept.c1
-rw-r--r--sys/amd64/vmm/intel/vmx.c11
-rw-r--r--sys/amd64/vmm/io/vlapic.c1
-rw-r--r--sys/amd64/vmm/vmm.c7
-rw-r--r--sys/amd64/vmm/vmm_ipi.c93
-rw-r--r--sys/amd64/vmm/vmm_ipi.h35
-rw-r--r--sys/amd64/vmm/vmm_lapic.c1
-rw-r--r--sys/amd64/vmm/vmm_support.S43
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
OpenPOWER on IntegriCloud