diff options
author | Robert Mustacchi <rm@joyent.com> | 2011-06-21 16:01:29 -0700 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2011-06-22 09:52:57 -0700 |
commit | 08ed7f46587d750834588d85f66c5c2bbf88d337 (patch) | |
tree | 8b8c3ab2c0fc3d2395ee412652c64455d3fa9c40 | |
parent | 04c526fb6415a9258468248ff15128674676eddb (diff) | |
download | illumos-kvm-08ed7f46587d750834588d85f66c5c2bbf88d337.tar.gz |
HVM-389 Need support for KVM_NMI ioctl
HVM-390 kvm_x86.h should be symlinked in our sys proto area
HVM-391 userland expects qemu_dirty_log to have anonymous unions
-rw-r--r-- | kvm.c | 90 | ||||
-rw-r--r-- | kvm.h | 7 | ||||
-rw-r--r-- | kvm_host.h | 1 | ||||
-rw-r--r-- | kvm_x86.c | 12 | ||||
l--------- | sys/kvm_x86.h | 1 |
5 files changed, 70 insertions, 41 deletions
@@ -15,7 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * GPL HEADER END + * GPL HEADER END * * Originally implemented on Linux: * Copyright (C) 2006 Qumranet, Inc. @@ -76,10 +76,10 @@ * | | | | guest | * | | | |---------| * | | | | - * | | | | + * | | | | * | | | | * | | | | Stop execution of - * | | | | guest + * | | | | guest * | | | |------------| * | | |---------| | * | | | Handle | | @@ -91,7 +91,7 @@ * | exit | | Yes \ the exit / * |---------| | \ reason? / * ^ | \ / - * | | \ / + * | | \ / * | | | * | | | No * |--------------|------------------------------| @@ -104,7 +104,7 @@ * All the memory for the guest is handled in the userspace of the guest. This * includes mapping in the BIOS, the program text for the guest, and providing * devices. To communicate about this information, get and set kernel device - * state, and interact in various ways, + * state, and interact in various ways, * * Kernel Emulated and Assisted Hardware * ------------------------------------- @@ -117,18 +117,19 @@ * + Protected Mode - 80286 style 32-bit operands and addressing and Virtual * Memory * + Protected Mode with PAE - Physical Address Extensions to allow 36-bits of - * addressing for physical memory. Only 32-bits of - * addressing for virtual memory are available. + * addressing for physical memory. Only 32-bits of + * addressing for virtual memory are available. * * + Long Mode - amd64 style 64-bit operands and 64-bit virtual addressing. - * Currently only 48 bits of physical memory can be addressed. + * Currently only 48 bits of physical memory can be addressed. + * * + System Management mode is unsupported and untested. It may work. It may * cause a panic. * * Other Hardware * - * The kernel emulates various pieces of additional hardware that are necessary for an x86 - * system to function. These include: + * The kernel emulates various pieces of additional hardware that are necessary + * for an x86 system to function. These include: * * + i8254 PIT - Intel Programmable Interval Timer * + i8259 PIC - Intel Programmable Interrupt Controller @@ -143,7 +144,7 @@ * contained within the object. * * Up to KVM_MAX_VCPUS (64) cpus - * + * * |---------| |-------| * |-------------| | Virtual | | Local | Per * | |-------------->| CPU #n | | APIC |<-- VCPU @@ -156,18 +157,18 @@ * | | | | | | CR0,CR4,ETC | * | | | | | | CPUID,ETC | * | | | | | |-------------| - * | | | | | - * | | | | | - * | | | | | - * | | | | | - * |-------| | | | | | |---------------------------| - * | i8254 |<---| | | | | | | - * | PIT | | | | | | Memory Management | - * |-------| | | | |-------------------------->| Unit | - * | | | | | && | - * | | | | |--------------| | Shadow Page Table | - * |-------| | | | |->| Input/Output | | | - * | i8259 |<-----| | | APIC | |---------------------------| + * | | | | | + * | | | | | + * | | | | | + * | | | | | + * |-------| | | | | | |-------------------------| + * | i8254 |<---| | | | | | | + * | PIT | | | | | | Memory Management | + * |-------| | | | |-------------------------->| Unit | + * | | | | | && | + * | | | | |--------------| | Shadow Page Table | + * |-------| | | | |->| Input/Output | | | + * | i8259 |<-----| | | APIC | |-------------------------| * | PIC | \|/ |--------------| * |-------| |---------| * | IRQ | @@ -181,14 +182,14 @@ * * The KVM code can be broken down into the following broad sections: * - * + Device driver entry points + * + Device driver entry points * + Generic code and driver entry points * + x86 and architecture specific code * + Hardware emulation specific code * + Host CPU specific code * * Host CPU Specific Code - * + * * Both Intel and AMD provide a means for accelerating guest operation, VT-X * (VMX) and SVM (AMD-V) respectively. However, the instructions, design, and * means of interacting with each are different. To get around this there is a @@ -196,44 +197,44 @@ * rest of the code base references these operations via the vector. As a part * of attach(9E), the system dynamically determines whether the system * should use the VMX or SVM operations. - * + * * The operations vector is entitled kvm_x86_ops. It's functions are: * TODO Functions and descriptions, though there may be too many * * * Hardware Emulation Specific Code - * + * * Various pieces of hardware are emulated by the kernel in the KVM module as * described previously. These are accessed in several ways: - * + * * + Userland performs ioctl(2)s to get and set state * + Guests perform PIO to devices * + Guests write to memory locations that correspond to devices - * + * * To handle memory mapped devices in the guest there is an internal notion of * an I/O device. There is an internal notion of an I/O bus. Devices can be * registered onto the bus. Currently two buses exist. One for programmed I/O * devices and another for memory mapped devices. - * + * * Code related to IRQs is primairly contained within kvm_irq.c and * kvm_irq_conn.c. To facilitate and provide a more generic IRQ system there are * two useful sets of notifiers. The notifiers fire a callback when the * specified event occurs. Currently there are two notifiers: - * + * * * + IRQ Mask Notifier: This fires its callback when an IRQ has been masked - * by an operation. + * by an operation. * + IRQ Ack Notifier: This fires its callback when an IRQ has been - * acknowledged. + * acknowledged. * * The hardware emulation code is broken down across the following files: - * + * * + i8254 PIT implementation: kvm_i8254.c and kvm_i8254.h - * + i8259 PIC implementation: kvm_i8259.c + * + i8259 PIC implementation: kvm_i8259.c * + I/O APIC Implementation: kvm_ioapic.c and kvm_ioapic.h * + Local APIC Implementation: kvm_lapic.c and kvm_lapic.h * + Memory Management Unit: kvm_mmu.c, kvm_mmu.h, and kvm_paging_tmpl.h - * + * * x86 and Architecture Specific Code * * The code specific to x86 that is not device specific is broken across two @@ -274,7 +275,7 @@ * ----------------- * * -Current memory model / assumptions (i.e. can't be paged) - * -Use of kpm + * -Use of kpm */ #include <sys/types.h> @@ -2832,6 +2833,21 @@ kvm_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) rval = kvm_vm_ioctl_get_dirty_log(kvmp, &log); break; } + case KVM_NMI: { + + if (ksp->kds_kvmp == NULL) { + rval = EINVAL; + break; + } + + if (ksp->kds_vcpu == NULL) { + rval = EINVAL; + break; + } + + rval = kvm_vcpu_ioctl_nmi(ksp->kds_vcpu); + break; + } case KVM_NET_QUEUE: { struct vnode *vn; file_t *fp; @@ -15,6 +15,7 @@ #include <sys/types.h> #include <sys/param.h> +#include <sys/ioccom.h> #include "kvm_x86.h" #define KVM_API_VERSION 12 /* same as linux (for qemu compatability...) */ @@ -211,7 +212,7 @@ typedef struct kvm_dirty_log { union { void *dirty_bitmap; /* one bit per page */ uint64_t padding2; - }v; + }; } kvm_dirty_log_t; /* for KVM_SET_SIGNAL_MASK */ @@ -312,9 +313,7 @@ typedef struct kvm_guest_debug { /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 -#ifdef __KVM_HAVE_USER_NMI #define KVM_CAP_USER_NMI 22 -#endif #ifdef __KVM_HAVE_GUEST_DEBUG #define KVM_CAP_SET_GUEST_DEBUG 23 @@ -473,6 +472,8 @@ typedef struct kvm_clock_data { #define KVM_SET_VAPIC_ADDR _IOW(KVMIO, 0x93, struct kvm_vapic_addr) #define KVM_GET_MP_STATE _IOR(KVMIO, 0x98, struct kvm_mp_state) #define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state) +/* Available with KVM_CAP_NMI */ +#define KVM_NMI _IO(KVMIO, 0x9a) /* MCE for x86 */ #define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, uint64_t) #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, uint64_t) @@ -367,6 +367,7 @@ int kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, struct kvm_vcpu_events *events); int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); +int kvm_vcpu_ioctl_nmi(struct kvm_vcpu *vcpu); int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps); int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps); int kvm_vm_ioctl_set_identity_map_addr(struct kvm *kvm, uint64_t ident_addr); @@ -1964,6 +1964,16 @@ kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) } int +kvm_vcpu_ioctl_nmi(struct kvm_vcpu *vcpu) +{ + vcpu_load(vcpu); + kvm_inject_nmi(vcpu); + vcpu_put(vcpu); + + return (0); +} + +int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, uint64_t *mcg_capp) { int rval; @@ -2317,7 +2327,7 @@ kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) } r = 0; - if (copyout(dirty_bitmap, log->v.dirty_bitmap, n) != 0) + if (copyout(dirty_bitmap, log->dirty_bitmap, n) != 0) r = EFAULT; out_free: kmem_free(dirty_bitmap, n); diff --git a/sys/kvm_x86.h b/sys/kvm_x86.h new file mode 120000 index 0000000..faeb913 --- /dev/null +++ b/sys/kvm_x86.h @@ -0,0 +1 @@ +../kvm_x86.h
\ No newline at end of file |