aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h9
-rw-r--r--arch/x86/kvm/vmx.c37
-rw-r--r--arch/x86/kvm/x86.c30
3 files changed, 37 insertions, 39 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index e3167224d936..ec891a2ce86e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -644,8 +644,6 @@ int emulator_write_emulated(unsigned long addr,
644 unsigned int bytes, 644 unsigned int bytes,
645 struct kvm_vcpu *vcpu); 645 struct kvm_vcpu *vcpu);
646 646
647unsigned long segment_base(u16 selector);
648
649void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu); 647void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu);
650void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, 648void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
651 const u8 *new, int bytes, 649 const u8 *new, int bytes,
@@ -723,13 +721,6 @@ static inline void kvm_get_idt(struct desc_ptr *table)
723 asm("sidt %0" : "=m"(*table)); 721 asm("sidt %0" : "=m"(*table));
724} 722}
725 723
726static inline unsigned long kvm_read_tr_base(void)
727{
728 u16 tr;
729 asm("str %0" : "=g"(tr));
730 return segment_base(tr);
731}
732
733#ifdef CONFIG_X86_64 724#ifdef CONFIG_X86_64
734static inline unsigned long read_msr(unsigned long msr) 725static inline unsigned long read_msr(unsigned long msr)
735{ 726{
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 68712bdf0407..8e2a24693be9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -634,6 +634,43 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
634 return true; 634 return true;
635} 635}
636 636
637static unsigned long segment_base(u16 selector)
638{
639 struct desc_ptr gdt;
640 struct desc_struct *d;
641 unsigned long table_base;
642 unsigned long v;
643
644 if (!(selector & ~3))
645 return 0;
646
647 native_store_gdt(&gdt);
648 table_base = gdt.address;
649
650 if (selector & 4) { /* from ldt */
651 u16 ldt_selector = kvm_read_ldt();
652
653 if (!(ldt_selector & ~3))
654 return 0;
655
656 table_base = segment_base(ldt_selector);
657 }
658 d = (struct desc_struct *)(table_base + (selector & ~7));
659 v = get_desc_base(d);
660#ifdef CONFIG_X86_64
661 if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
662 v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
663#endif
664 return v;
665}
666
667static inline unsigned long kvm_read_tr_base(void)
668{
669 u16 tr;
670 asm("str %0" : "=g"(tr));
671 return segment_base(tr);
672}
673
637static void vmx_save_host_state(struct kvm_vcpu *vcpu) 674static void vmx_save_host_state(struct kvm_vcpu *vcpu)
638{ 675{
639 struct vcpu_vmx *vmx = to_vmx(vcpu); 676 struct vcpu_vmx *vmx = to_vmx(vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 814e72a02eff..2b34dc705cfb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -223,36 +223,6 @@ static void drop_user_return_notifiers(void *ignore)
223 kvm_on_user_return(&smsr->urn); 223 kvm_on_user_return(&smsr->urn);
224} 224}
225 225
226unsigned long segment_base(u16 selector)
227{
228 struct desc_ptr gdt;
229 struct desc_struct *d;
230 unsigned long table_base;
231 unsigned long v;
232
233 if (!(selector & ~3))
234 return 0;
235
236 native_store_gdt(&gdt);
237 table_base = gdt.address;
238
239 if (selector & 4) { /* from ldt */
240 u16 ldt_selector = kvm_read_ldt();
241
242 if (!(ldt_selector & ~3))
243 return 0;
244 table_base = segment_base(ldt_selector);
245 }
246 d = (struct desc_struct *)(table_base + (selector & ~7));
247 v = get_desc_base(d);
248#ifdef CONFIG_X86_64
249 if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
250 v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
251#endif
252 return v;
253}
254EXPORT_SYMBOL_GPL(segment_base);
255
256u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) 226u64 kvm_get_apic_base(struct kvm_vcpu *vcpu)
257{ 227{
258 if (irqchip_in_kernel(vcpu->kvm)) 228 if (irqchip_in_kernel(vcpu->kvm))