aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/vmm/vmm.c
diff options
context:
space:
mode:
authorNeel Natu <neel@FreeBSD.org>2013-11-12 22:51:03 +0000
committerNeel Natu <neel@FreeBSD.org>2013-11-12 22:51:03 +0000
commit565bbb86983d390d4d83f49eaad81c46ea65f188 (patch)
treec5c556e061b1f182036d3b8ffc028cc9c7a83e2d /sys/amd64/vmm/vmm.c
parent4a14f9dadc3a6e09b45dcad14944694d83336a81 (diff)
downloadsrc-565bbb86983d390d4d83f49eaad81c46ea65f188.tar.gz
src-565bbb86983d390d4d83f49eaad81c46ea65f188.zip
Move the ioapic device model from userspace into vmm.ko. This is needed for
upcoming in-kernel device emulations like the HPET. The ioctls VM_IOAPIC_ASSERT_IRQ and VM_IOAPIC_DEASSERT_IRQ are used to manipulate the ioapic pin state. Discussed with: grehan@ Submitted by: Tycho Nightingale (tycho.nightingale@pluribusnetworks.com)
Notes
Notes: svn path=/head/; revision=258075
Diffstat (limited to 'sys/amd64/vmm/vmm.c')
-rw-r--r--sys/amd64/vmm/vmm.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index b3f56b181fad..40254c66ec04 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -59,11 +59,13 @@ __FBSDID("$FreeBSD$");
#include <machine/vmparam.h>
#include <machine/vmm.h>
+#include <machine/vmm_dev.h>
+
#include "vmm_ktr.h"
#include "vmm_host.h"
#include "vmm_mem.h"
#include "vmm_util.h"
-#include <machine/vmm_dev.h>
+#include "vioapic.h"
#include "vlapic.h"
#include "vmm_msr.h"
#include "vmm_ipi.h"
@@ -106,6 +108,7 @@ struct mem_seg {
struct vm {
void *cookie; /* processor-specific data */
void *iommu; /* iommu-specific data */
+ struct vioapic *vioapic; /* virtual ioapic */
struct vmspace *vmspace; /* guest's address space */
struct vcpu vcpu[VM_MAXCPU];
int num_mem_segs;
@@ -300,6 +303,7 @@ vm_create(const char *name, struct vm **retvm)
vm = malloc(sizeof(struct vm), M_VM, M_WAITOK | M_ZERO);
strcpy(vm->name, name);
vm->cookie = VMINIT(vm, vmspace_pmap(vmspace));
+ vm->vioapic = vioapic_init(vm);
for (i = 0; i < VM_MAXCPU; i++) {
vcpu_init(vm, i);
@@ -341,6 +345,8 @@ vm_destroy(struct vm *vm)
for (i = 0; i < VM_MAXCPU; i++)
vcpu_cleanup(&vm->vcpu[i]);
+ vioapic_cleanup(vm->vioapic);
+
VMSPACE_FREE(vm->vmspace);
VMCLEANUP(vm->cookie);
@@ -938,6 +944,8 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, boolean_t *retu)
struct vm_exit *vme;
int error, inst_length;
uint64_t rip, gla, gpa, cr3;
+ mem_region_read_t mread;
+ mem_region_write_t mwrite;
vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
@@ -960,13 +968,18 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, boolean_t *retu)
return (EFAULT);
/* return to userland unless this is a local apic access */
- if (gpa < DEFAULT_APIC_BASE || gpa >= DEFAULT_APIC_BASE + PAGE_SIZE) {
+ if (gpa >= DEFAULT_APIC_BASE && gpa < DEFAULT_APIC_BASE + PAGE_SIZE) {
+ mread = lapic_mmio_read;
+ mwrite = lapic_mmio_write;
+ } else if (gpa >= VIOAPIC_BASE && gpa < VIOAPIC_BASE + VIOAPIC_SIZE) {
+ mread = vioapic_mmio_read;
+ mwrite = vioapic_mmio_write;
+ } else {
*retu = TRUE;
return (0);
}
- error = vmm_emulate_instruction(vm, vcpuid, gpa, vie,
- lapic_mmio_read, lapic_mmio_write, 0);
+ error = vmm_emulate_instruction(vm, vcpuid, gpa, vie, mread, mwrite, 0);
/* return to userland to spin up the AP */
if (error == 0 && vme->exitcode == VM_EXITCODE_SPINUP_AP)
@@ -1149,6 +1162,13 @@ vm_lapic(struct vm *vm, int cpu)
return (vm->vcpu[cpu].vlapic);
}
+struct vioapic *
+vm_ioapic(struct vm *vm)
+{
+
+ return (vm->vioapic);
+}
+
boolean_t
vmm_is_pptdev(int bus, int slot, int func)
{
@@ -1313,3 +1333,12 @@ vm_get_vmspace(struct vm *vm)
return (vm->vmspace);
}
+
+int
+vm_apicid2vcpuid(struct vm *vm, int apicid)
+{
+ /*
+ * XXX apic id is assumed to be numerically identical to vcpu id
+ */
+ return (apicid);
+}