summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-02-23 00:46:05 +0000
committerjhb <jhb@FreeBSD.org>2014-02-23 00:46:05 +0000
commit69d17427cae2b573203a13c2fe8cac0865c3cfdc (patch)
tree74c089432fac1660f52a522e3e53195374381e38 /lib
parent04e37d68ee180962d9cdaef4ffd90789f36548ab (diff)
downloadFreeBSD-src-69d17427cae2b573203a13c2fe8cac0865c3cfdc.zip
FreeBSD-src-69d17427cae2b573203a13c2fe8cac0865c3cfdc.tar.gz
MFC 258859,259081,259085,259205,259213,259275,259482,259537,259702,259779:
Several changes to the local APIC support in bhyve: - Rename 'vm_interrupt_hostcpu()' to 'vcpu_notify_event()'. - If a vcpu disables its local apic and then executes a 'HLT' then spin down the vcpu and destroy its thread context. Also modify the 'HLT' processing to ignore pending interrupts in the IRR if interrupts have been disabled by the guest. The interrupt cannot be injected into the guest in any case so resuming it is futile. - Use callout(9) to drive the vlapic timer instead of clocking it on each VM exit. - When the guest is bringing up the APs in the x2APIC mode a write to the ICR register will now trigger a return to userspace with an exitcode of VM_EXITCODE_SPINUP_AP. - Change the vlapic timer lock to be a spinlock because the vlapic can be accessed from within a critical section (vm run loop) when guest is using x2apic mode. - Fix the vlapic version register. - Add a command to bhyvectl to inject an NMI on a specific vcpu. - Add an API to deliver message signalled interrupts to vcpus. This allows callers to treat the MSI 'addr' and 'data' fields as opaque and also lets bhyve implement multiple destination modes: physical, flat and clustered. - Rename the ambiguously named 'vm_setup_msi()' and 'vm_setup_msix()' to 'vm_setup_pptdev_msi()' and 'vm_setup_pptdev_msix()' respectively. - Consolidate the virtual apic initialization in a single function: vlapic_reset() - Add a generic routine to trigger an LVT interrupt that supports both fixed and NMI delivery modes. - Add an ioctl and bhyvectl command to trigger local interrupts inside a guest. In particular, a global NMI similar to that raised by SERR# or PERR# can be simulated by asserting LINT1 on all vCPUs. - Extend the LVT table in the vCPU local APIC to support CMCI. - Flesh out the local APIC error reporting a bit to cache errors and report them via ESR when ESR is written to. Add support for asserting the error LVT when an error occurs. Raise illegal vector errors when attempting to signal an invalid vector for an interrupt or when sending an IPI. - Export table entries in the MADT and MP Table advertising the stock x86 config of LINT0 set to ExtInt and LINT1 wired to NMI.
Diffstat (limited to 'lib')
-rw-r--r--lib/libvmmapi/vmmapi.c36
-rw-r--r--lib/libvmmapi/vmmapi.h11
2 files changed, 37 insertions, 10 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
index c2851a4..6fec469 100644
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -397,6 +397,30 @@ vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector)
}
int
+vm_lapic_local_irq(struct vmctx *ctx, int vcpu, int vector)
+{
+ struct vm_lapic_irq vmirq;
+
+ bzero(&vmirq, sizeof(vmirq));
+ vmirq.cpuid = vcpu;
+ vmirq.vector = vector;
+
+ return (ioctl(ctx->fd, VM_LAPIC_LOCAL_IRQ, &vmirq));
+}
+
+int
+vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg)
+{
+ struct vm_lapic_msi vmmsi;
+
+ bzero(&vmmsi, sizeof(vmmsi));
+ vmmsi.addr = addr;
+ vmmsi.msg = msg;
+
+ return (ioctl(ctx->fd, VM_LAPIC_MSI, &vmmsi));
+}
+
+int
vm_ioapic_assert_irq(struct vmctx *ctx, int irq)
{
struct vm_ioapic_irq ioapic_irq;
@@ -551,8 +575,8 @@ vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func,
}
int
-vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
- int destcpu, int vector, int numvec)
+vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
+ uint64_t addr, uint64_t msg, int numvec)
{
struct vm_pptdev_msi pptmsi;
@@ -561,16 +585,16 @@ vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
pptmsi.bus = bus;
pptmsi.slot = slot;
pptmsi.func = func;
- pptmsi.destcpu = destcpu;
- pptmsi.vector = vector;
+ pptmsi.msg = msg;
+ pptmsi.addr = addr;
pptmsi.numvec = numvec;
return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi));
}
int
-vm_setup_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
- int idx, uint32_t msg, uint32_t vector_control, uint64_t addr)
+vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
+ int idx, uint64_t addr, uint64_t msg, uint32_t vector_control)
{
struct vm_pptdev_msix pptmsix;
diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h
index 293c431..69762c7 100644
--- a/lib/libvmmapi/vmmapi.h
+++ b/lib/libvmmapi/vmmapi.h
@@ -67,6 +67,8 @@ int vm_inject_event(struct vmctx *ctx, int vcpu, enum vm_event_type type,
int vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type,
int vector, int error_code);
int vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector);
+int vm_lapic_local_irq(struct vmctx *ctx, int vcpu, int vector);
+int vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg);
int vm_ioapic_assert_irq(struct vmctx *ctx, int irq);
int vm_ioapic_deassert_irq(struct vmctx *ctx, int irq);
int vm_ioapic_pulse_irq(struct vmctx *ctx, int irq);
@@ -81,10 +83,11 @@ int vm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func);
int vm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func);
int vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func,
vm_paddr_t gpa, size_t len, vm_paddr_t hpa);
-int vm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
- int dest, int vector, int numvec);
-int vm_setup_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
- int idx, uint32_t msg, uint32_t vector_control, uint64_t addr);
+int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot,
+ int func, uint64_t addr, uint64_t msg, int numvec);
+int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot,
+ int func, int idx, uint64_t addr, uint64_t msg,
+ uint32_t vector_control);
/*
* Return a pointer to the statistics buffer. Note that this is not MT-safe.
OpenPOWER on IntegriCloud