diff options
author | Neel Natu <neel@FreeBSD.org> | 2013-11-12 22:51:03 +0000 |
---|---|---|
committer | Neel Natu <neel@FreeBSD.org> | 2013-11-12 22:51:03 +0000 |
commit | 565bbb86983d390d4d83f49eaad81c46ea65f188 (patch) | |
tree | c5c556e061b1f182036d3b8ffc028cc9c7a83e2d /sys/amd64/vmm/vmm.c | |
parent | 4a14f9dadc3a6e09b45dcad14944694d83336a81 (diff) | |
download | src-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.c | 37 |
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); +} |