Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull KVM fix from Marcelo Tosatti.

* git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: x86: fix vcpu->mmio_fragments overflow

+36 -39
+34 -26
arch/x86/kvm/x86.c
··· 3779 3779 { 3780 3780 struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; 3781 3781 3782 - memcpy(vcpu->run->mmio.data, frag->data, frag->len); 3782 + memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); 3783 3783 return X86EMUL_CONTINUE; 3784 3784 } 3785 3785 ··· 3832 3832 bytes -= handled; 3833 3833 val += handled; 3834 3834 3835 - while (bytes) { 3836 - unsigned now = min(bytes, 8U); 3837 - 3838 - frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; 3839 - frag->gpa = gpa; 3840 - frag->data = val; 3841 - frag->len = now; 3842 - 3843 - gpa += now; 3844 - val += now; 3845 - bytes -= now; 3846 - } 3835 + WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); 3836 + frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; 3837 + frag->gpa = gpa; 3838 + frag->data = val; 3839 + frag->len = bytes; 3847 3840 return X86EMUL_CONTINUE; 3848 3841 } 3849 3842 ··· 3883 3890 vcpu->mmio_needed = 1; 3884 3891 vcpu->mmio_cur_fragment = 0; 3885 3892 3886 - vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; 3893 + vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); 3887 3894 vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; 3888 3895 vcpu->run->exit_reason = KVM_EXIT_MMIO; 3889 3896 vcpu->run->mmio.phys_addr = gpa; ··· 5515 5522 * 5516 5523 * read: 5517 5524 * for each fragment 5518 - * write gpa, len 5519 - * exit 5520 - * copy data 5525 + * for each mmio piece in the fragment 5526 + * write gpa, len 5527 + * exit 5528 + * copy data 5521 5529 * execute insn 5522 5530 * 5523 5531 * write: 5524 5532 * for each fragment 5525 - * write gpa, len 5526 - * copy data 5527 - * exit 5533 + * for each mmio piece in the fragment 5534 + * write gpa, len 5535 + * copy data 5536 + * exit 5528 5537 */ 5529 5538 static int complete_emulated_mmio(struct kvm_vcpu *vcpu) 5530 5539 { 5531 5540 struct kvm_run *run = vcpu->run; 5532 5541 struct kvm_mmio_fragment *frag; 5542 + unsigned len; 5533 5543 5534 5544 BUG_ON(!vcpu->mmio_needed); 5535 5545 5536 5546 /* Complete previous fragment */ 5537 - frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; 5547 + frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; 5548 + len = min(8u, frag->len); 5538 5549 if (!vcpu->mmio_is_write) 5539 - memcpy(frag->data, run->mmio.data, frag->len); 5550 + memcpy(frag->data, run->mmio.data, len); 5551 + 5552 + if (frag->len <= 8) { 5553 + /* Switch to the next fragment. */ 5554 + frag++; 5555 + vcpu->mmio_cur_fragment++; 5556 + } else { 5557 + /* Go forward to the next mmio piece. */ 5558 + frag->data += len; 5559 + frag->gpa += len; 5560 + frag->len -= len; 5561 + } 5562 + 5540 5563 if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { 5541 5564 vcpu->mmio_needed = 0; 5542 5565 if (vcpu->mmio_is_write) ··· 5560 5551 vcpu->mmio_read_completed = 1; 5561 5552 return complete_emulated_io(vcpu); 5562 5553 } 5563 - /* Initiate next fragment */ 5564 - ++frag; 5554 + 5565 5555 run->exit_reason = KVM_EXIT_MMIO; 5566 5556 run->mmio.phys_addr = frag->gpa; 5567 5557 if (vcpu->mmio_is_write) 5568 - memcpy(run->mmio.data, frag->data, frag->len); 5569 - run->mmio.len = frag->len; 5558 + memcpy(run->mmio.data, frag->data, min(8u, frag->len)); 5559 + run->mmio.len = min(8u, frag->len); 5570 5560 run->mmio.is_write = vcpu->mmio_is_write; 5571 5561 vcpu->arch.complete_userspace_io = complete_emulated_mmio; 5572 5562 return 0;
+2 -13
include/linux/kvm_host.h
··· 42 42 */ 43 43 #define KVM_MEMSLOT_INVALID (1UL << 16) 44 44 45 - /* 46 - * If we support unaligned MMIO, at most one fragment will be split into two: 47 - */ 48 - #ifdef KVM_UNALIGNED_MMIO 49 - # define KVM_EXTRA_MMIO_FRAGMENTS 1 50 - #else 51 - # define KVM_EXTRA_MMIO_FRAGMENTS 0 52 - #endif 53 - 54 - #define KVM_USER_MMIO_SIZE 8 55 - 56 - #define KVM_MAX_MMIO_FRAGMENTS \ 57 - (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS) 45 + /* Two fragments for cross MMIO pages. */ 46 + #define KVM_MAX_MMIO_FRAGMENTS 2 58 47 59 48 /* 60 49 * For the normal pfn, the highest 12 bits should be zero,