aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-11-02 15:31:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-11-02 15:31:02 -0500
commit7501a5332932b8758a28028ce2ed063aec912c87 (patch)
tree0029d2a7c5b77cea6c5be64accaadd3267c5d8c9 /arch
parent7e05b807b93cc553bc2aa5ae8fac620cece34720 (diff)
parenta73896cb5bbdce672945745db8224352a689f580 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "A small set of x86 fixes. The most serious is an SRCU lockdep fix. A bit late - needed some time to test the SRCU fix, which only came in on Friday" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: vmx: defer load of APIC access page address during reset KVM: nVMX: Disable preemption while reading from shadow VMCS KVM: x86: Fix far-jump to non-canonical check KVM: emulator: fix execution close to the segment limit KVM: emulator: fix error code for __linearize
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c55
-rw-r--r--arch/x86/kvm/vmx.c6
2 files changed, 45 insertions, 16 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 749f9fa38254..5edf088ca51e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -574,12 +574,14 @@ static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
574 case 4: 574 case 4:
575 ctxt->_eip = (u32)dst; 575 ctxt->_eip = (u32)dst;
576 break; 576 break;
577#ifdef CONFIG_X86_64
577 case 8: 578 case 8:
578 if ((cs_l && is_noncanonical_address(dst)) || 579 if ((cs_l && is_noncanonical_address(dst)) ||
579 (!cs_l && (dst & ~(u32)-1))) 580 (!cs_l && (dst >> 32) != 0))
580 return emulate_gp(ctxt, 0); 581 return emulate_gp(ctxt, 0);
581 ctxt->_eip = dst; 582 ctxt->_eip = dst;
582 break; 583 break;
584#endif
583 default: 585 default:
584 WARN(1, "unsupported eip assignment size\n"); 586 WARN(1, "unsupported eip assignment size\n");
585 } 587 }
@@ -641,7 +643,8 @@ static bool insn_aligned(struct x86_emulate_ctxt *ctxt, unsigned size)
641 643
642static int __linearize(struct x86_emulate_ctxt *ctxt, 644static int __linearize(struct x86_emulate_ctxt *ctxt,
643 struct segmented_address addr, 645 struct segmented_address addr,
644 unsigned size, bool write, bool fetch, 646 unsigned *max_size, unsigned size,
647 bool write, bool fetch,
645 ulong *linear) 648 ulong *linear)
646{ 649{
647 struct desc_struct desc; 650 struct desc_struct desc;
@@ -652,10 +655,15 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
652 unsigned cpl; 655 unsigned cpl;
653 656
654 la = seg_base(ctxt, addr.seg) + addr.ea; 657 la = seg_base(ctxt, addr.seg) + addr.ea;
658 *max_size = 0;
655 switch (ctxt->mode) { 659 switch (ctxt->mode) {
656 case X86EMUL_MODE_PROT64: 660 case X86EMUL_MODE_PROT64:
657 if (((signed long)la << 16) >> 16 != la) 661 if (((signed long)la << 16) >> 16 != la)
658 return emulate_gp(ctxt, 0); 662 return emulate_gp(ctxt, 0);
663
664 *max_size = min_t(u64, ~0u, (1ull << 48) - la);
665 if (size > *max_size)
666 goto bad;
659 break; 667 break;
660 default: 668 default:
661 usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL, 669 usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL,
@@ -673,20 +681,25 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
673 if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch && 681 if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch &&
674 (ctxt->d & NoBigReal)) { 682 (ctxt->d & NoBigReal)) {
675 /* la is between zero and 0xffff */ 683 /* la is between zero and 0xffff */
676 if (la > 0xffff || (u32)(la + size - 1) > 0xffff) 684 if (la > 0xffff)
677 goto bad; 685 goto bad;
686 *max_size = 0x10000 - la;
678 } else if ((desc.type & 8) || !(desc.type & 4)) { 687 } else if ((desc.type & 8) || !(desc.type & 4)) {
679 /* expand-up segment */ 688 /* expand-up segment */
680 if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim) 689 if (addr.ea > lim)
681 goto bad; 690 goto bad;
691 *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea);
682 } else { 692 } else {
683 /* expand-down segment */ 693 /* expand-down segment */
684 if (addr.ea <= lim || (u32)(addr.ea + size - 1) <= lim) 694 if (addr.ea <= lim)
685 goto bad; 695 goto bad;
686 lim = desc.d ? 0xffffffff : 0xffff; 696 lim = desc.d ? 0xffffffff : 0xffff;
687 if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim) 697 if (addr.ea > lim)
688 goto bad; 698 goto bad;
699 *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea);
689 } 700 }
701 if (size > *max_size)
702 goto bad;
690 cpl = ctxt->ops->cpl(ctxt); 703 cpl = ctxt->ops->cpl(ctxt);
691 if (!(desc.type & 8)) { 704 if (!(desc.type & 8)) {
692 /* data segment */ 705 /* data segment */
@@ -711,9 +724,9 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
711 return X86EMUL_CONTINUE; 724 return X86EMUL_CONTINUE;
712bad: 725bad:
713 if (addr.seg == VCPU_SREG_SS) 726 if (addr.seg == VCPU_SREG_SS)
714 return emulate_ss(ctxt, sel); 727 return emulate_ss(ctxt, 0);
715 else 728 else
716 return emulate_gp(ctxt, sel); 729 return emulate_gp(ctxt, 0);
717} 730}
718 731
719static int linearize(struct x86_emulate_ctxt *ctxt, 732static int linearize(struct x86_emulate_ctxt *ctxt,
@@ -721,7 +734,8 @@ static int linearize(struct x86_emulate_ctxt *ctxt,
721 unsigned size, bool write, 734 unsigned size, bool write,
722 ulong *linear) 735 ulong *linear)
723{ 736{
724 return __linearize(ctxt, addr, size, write, false, linear); 737 unsigned max_size;
738 return __linearize(ctxt, addr, &max_size, size, write, false, linear);
725} 739}
726 740
727 741
@@ -746,17 +760,27 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
746static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size) 760static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size)
747{ 761{
748 int rc; 762 int rc;
749 unsigned size; 763 unsigned size, max_size;
750 unsigned long linear; 764 unsigned long linear;
751 int cur_size = ctxt->fetch.end - ctxt->fetch.data; 765 int cur_size = ctxt->fetch.end - ctxt->fetch.data;
752 struct segmented_address addr = { .seg = VCPU_SREG_CS, 766 struct segmented_address addr = { .seg = VCPU_SREG_CS,
753 .ea = ctxt->eip + cur_size }; 767 .ea = ctxt->eip + cur_size };
754 768
755 size = 15UL ^ cur_size; 769 /*
756 rc = __linearize(ctxt, addr, size, false, true, &linear); 770 * We do not know exactly how many bytes will be needed, and
771 * __linearize is expensive, so fetch as much as possible. We
772 * just have to avoid going beyond the 15 byte limit, the end
773 * of the segment, or the end of the page.
774 *
775 * __linearize is called with size 0 so that it does not do any
776 * boundary check itself. Instead, we use max_size to check
777 * against op_size.
778 */
779 rc = __linearize(ctxt, addr, &max_size, 0, false, true, &linear);
757 if (unlikely(rc != X86EMUL_CONTINUE)) 780 if (unlikely(rc != X86EMUL_CONTINUE))
758 return rc; 781 return rc;
759 782
783 size = min_t(unsigned, 15UL ^ cur_size, max_size);
760 size = min_t(unsigned, size, PAGE_SIZE - offset_in_page(linear)); 784 size = min_t(unsigned, size, PAGE_SIZE - offset_in_page(linear));
761 785
762 /* 786 /*
@@ -766,7 +790,8 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size)
766 * still, we must have hit the 15-byte boundary. 790 * still, we must have hit the 15-byte boundary.
767 */ 791 */
768 if (unlikely(size < op_size)) 792 if (unlikely(size < op_size))
769 return X86EMUL_UNHANDLEABLE; 793 return emulate_gp(ctxt, 0);
794
770 rc = ctxt->ops->fetch(ctxt, linear, ctxt->fetch.end, 795 rc = ctxt->ops->fetch(ctxt, linear, ctxt->fetch.end,
771 size, &ctxt->exception); 796 size, &ctxt->exception);
772 if (unlikely(rc != X86EMUL_CONTINUE)) 797 if (unlikely(rc != X86EMUL_CONTINUE))
@@ -2012,7 +2037,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
2012 2037
2013 rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); 2038 rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
2014 if (rc != X86EMUL_CONTINUE) { 2039 if (rc != X86EMUL_CONTINUE) {
2015 WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); 2040 WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
2016 /* assigning eip failed; restore the old cs */ 2041 /* assigning eip failed; restore the old cs */
2017 ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); 2042 ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS);
2018 return rc; 2043 return rc;
@@ -2109,7 +2134,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
2109 return rc; 2134 return rc;
2110 rc = assign_eip_far(ctxt, eip, new_desc.l); 2135 rc = assign_eip_far(ctxt, eip, new_desc.l);
2111 if (rc != X86EMUL_CONTINUE) { 2136 if (rc != X86EMUL_CONTINUE) {
2112 WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); 2137 WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
2113 ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); 2138 ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
2114 } 2139 }
2115 return rc; 2140 return rc;
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index a8b76c4c95e2..3e556c68351b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4579,7 +4579,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu)
4579 vmcs_write32(TPR_THRESHOLD, 0); 4579 vmcs_write32(TPR_THRESHOLD, 0);
4580 } 4580 }
4581 4581
4582 kvm_vcpu_reload_apic_access_page(vcpu); 4582 kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
4583 4583
4584 if (vmx_vm_has_apicv(vcpu->kvm)) 4584 if (vmx_vm_has_apicv(vcpu->kvm))
4585 memset(&vmx->pi_desc, 0, sizeof(struct pi_desc)); 4585 memset(&vmx->pi_desc, 0, sizeof(struct pi_desc));
@@ -6426,6 +6426,8 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx)
6426 const unsigned long *fields = shadow_read_write_fields; 6426 const unsigned long *fields = shadow_read_write_fields;
6427 const int num_fields = max_shadow_read_write_fields; 6427 const int num_fields = max_shadow_read_write_fields;
6428 6428
6429 preempt_disable();
6430
6429 vmcs_load(shadow_vmcs); 6431 vmcs_load(shadow_vmcs);
6430 6432
6431 for (i = 0; i < num_fields; i++) { 6433 for (i = 0; i < num_fields; i++) {
@@ -6449,6 +6451,8 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx)
6449 6451
6450 vmcs_clear(shadow_vmcs); 6452 vmcs_clear(shadow_vmcs);
6451 vmcs_load(vmx->loaded_vmcs->vmcs); 6453 vmcs_load(vmx->loaded_vmcs->vmcs);
6454
6455 preempt_enable();
6452} 6456}
6453 6457
6454static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) 6458static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx)