aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/vmx.c
diff options
context:
space:
mode:
authorIzik Eidus <izike@qumranet.com>2007-10-24 18:29:55 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:56 -0500
commitcbc9402297b9a233981f74587786364cda21c771 (patch)
tree35ba97693ffc506bb08f6bafa9e61a260bc8189f /drivers/kvm/vmx.c
parente0d62c7f48605119a7f9fa632e77561c89928963 (diff)
KVM: Add ioctl to tss address from userspace,
Currently kvm has a wart in that it requires three extra pages for use as a tss when emulating real mode on Intel. This patch moves the allocation internally, only requiring userspace to tell us where in the physical address space we can place the tss. Signed-off-by: Izik Eidus <izike@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r--drivers/kvm/vmx.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 768ea88beb45..46b29184a4d8 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1105,8 +1105,12 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
1105 1105
1106static gva_t rmode_tss_base(struct kvm *kvm) 1106static gva_t rmode_tss_base(struct kvm *kvm)
1107{ 1107{
1108 gfn_t base_gfn = kvm->memslots[0].base_gfn + kvm->memslots[0].npages - 3; 1108 if (!kvm->tss_addr) {
1109 return base_gfn << PAGE_SHIFT; 1109 gfn_t base_gfn = kvm->memslots[0].base_gfn +
1110 kvm->memslots[0].npages - 3;
1111 return base_gfn << PAGE_SHIFT;
1112 }
1113 return kvm->tss_addr;
1110} 1114}
1111 1115
1112static void fix_rmode_seg(int seg, struct kvm_save_segment *save) 1116static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
@@ -1735,6 +1739,23 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
1735 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); 1739 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
1736} 1740}
1737 1741
1742static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
1743{
1744 int ret;
1745 struct kvm_userspace_memory_region tss_mem = {
1746 .slot = 8,
1747 .guest_phys_addr = addr,
1748 .memory_size = PAGE_SIZE * 3,
1749 .flags = 0,
1750 };
1751
1752 ret = kvm_set_memory_region(kvm, &tss_mem, 0);
1753 if (ret)
1754 return ret;
1755 kvm->tss_addr = addr;
1756 return 0;
1757}
1758
1738static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu) 1759static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu)
1739{ 1760{
1740 struct kvm_guest_debug *dbg = &vcpu->guest_debug; 1761 struct kvm_guest_debug *dbg = &vcpu->guest_debug;
@@ -2543,6 +2564,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
2543 .set_irq = vmx_inject_irq, 2564 .set_irq = vmx_inject_irq,
2544 .inject_pending_irq = vmx_intr_assist, 2565 .inject_pending_irq = vmx_intr_assist,
2545 .inject_pending_vectors = do_interrupt_requests, 2566 .inject_pending_vectors = do_interrupt_requests,
2567
2568 .set_tss_addr = vmx_set_tss_addr,
2546}; 2569};
2547 2570
2548static int __init vmx_init(void) 2571static int __init vmx_init(void)