diff options
author | Izik Eidus <izike@qumranet.com> | 2007-10-24 18:29:55 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:52:56 -0500 |
commit | cbc9402297b9a233981f74587786364cda21c771 (patch) | |
tree | 35ba97693ffc506bb08f6bafa9e61a260bc8189f /drivers/kvm/vmx.c | |
parent | e0d62c7f48605119a7f9fa632e77561c89928963 (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.c | 27 |
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 | ||
1106 | static gva_t rmode_tss_base(struct kvm *kvm) | 1106 | static 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 | ||
1112 | static void fix_rmode_seg(int seg, struct kvm_save_segment *save) | 1116 | static 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 | ||
1742 | static 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 | |||
1738 | static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu) | 1759 | static 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 | ||
2548 | static int __init vmx_init(void) | 2571 | static int __init vmx_init(void) |