diff options
-rw-r--r-- | arch/x86/kvm/x86.c | 60 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 15 |
2 files changed, 36 insertions, 39 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1eefebe5d727..224a7e78cb6c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3779,7 +3779,7 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
3779 | { | 3779 | { |
3780 | struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; | 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 | return X86EMUL_CONTINUE; | 3783 | return X86EMUL_CONTINUE; |
3784 | } | 3784 | } |
3785 | 3785 | ||
@@ -3832,18 +3832,11 @@ mmio: | |||
3832 | bytes -= handled; | 3832 | bytes -= handled; |
3833 | val += handled; | 3833 | val += handled; |
3834 | 3834 | ||
3835 | while (bytes) { | 3835 | WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); |
3836 | unsigned now = min(bytes, 8U); | 3836 | frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; |
3837 | 3837 | frag->gpa = gpa; | |
3838 | frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; | 3838 | frag->data = val; |
3839 | frag->gpa = gpa; | 3839 | frag->len = bytes; |
3840 | frag->data = val; | ||
3841 | frag->len = now; | ||
3842 | |||
3843 | gpa += now; | ||
3844 | val += now; | ||
3845 | bytes -= now; | ||
3846 | } | ||
3847 | return X86EMUL_CONTINUE; | 3840 | return X86EMUL_CONTINUE; |
3848 | } | 3841 | } |
3849 | 3842 | ||
@@ -3890,7 +3883,7 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, | |||
3890 | vcpu->mmio_needed = 1; | 3883 | vcpu->mmio_needed = 1; |
3891 | vcpu->mmio_cur_fragment = 0; | 3884 | vcpu->mmio_cur_fragment = 0; |
3892 | 3885 | ||
3893 | vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; | 3886 | vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); |
3894 | vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; | 3887 | vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; |
3895 | vcpu->run->exit_reason = KVM_EXIT_MMIO; | 3888 | vcpu->run->exit_reason = KVM_EXIT_MMIO; |
3896 | vcpu->run->mmio.phys_addr = gpa; | 3889 | vcpu->run->mmio.phys_addr = gpa; |
@@ -5522,28 +5515,44 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) | |||
5522 | * | 5515 | * |
5523 | * read: | 5516 | * read: |
5524 | * for each fragment | 5517 | * for each fragment |
5525 | * write gpa, len | 5518 | * for each mmio piece in the fragment |
5526 | * exit | 5519 | * write gpa, len |
5527 | * copy data | 5520 | * exit |
5521 | * copy data | ||
5528 | * execute insn | 5522 | * execute insn |
5529 | * | 5523 | * |
5530 | * write: | 5524 | * write: |
5531 | * for each fragment | 5525 | * for each fragment |
5532 | * write gpa, len | 5526 | * for each mmio piece in the fragment |
5533 | * copy data | 5527 | * write gpa, len |
5534 | * exit | 5528 | * copy data |
5529 | * exit | ||
5535 | */ | 5530 | */ |
5536 | static int complete_emulated_mmio(struct kvm_vcpu *vcpu) | 5531 | static int complete_emulated_mmio(struct kvm_vcpu *vcpu) |
5537 | { | 5532 | { |
5538 | struct kvm_run *run = vcpu->run; | 5533 | struct kvm_run *run = vcpu->run; |
5539 | struct kvm_mmio_fragment *frag; | 5534 | struct kvm_mmio_fragment *frag; |
5535 | unsigned len; | ||
5540 | 5536 | ||
5541 | BUG_ON(!vcpu->mmio_needed); | 5537 | BUG_ON(!vcpu->mmio_needed); |
5542 | 5538 | ||
5543 | /* Complete previous fragment */ | 5539 | /* Complete previous fragment */ |
5544 | frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; | 5540 | frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; |
5541 | len = min(8u, frag->len); | ||
5545 | if (!vcpu->mmio_is_write) | 5542 | if (!vcpu->mmio_is_write) |
5546 | memcpy(frag->data, run->mmio.data, frag->len); | 5543 | memcpy(frag->data, run->mmio.data, len); |
5544 | |||
5545 | if (frag->len <= 8) { | ||
5546 | /* Switch to the next fragment. */ | ||
5547 | frag++; | ||
5548 | vcpu->mmio_cur_fragment++; | ||
5549 | } else { | ||
5550 | /* Go forward to the next mmio piece. */ | ||
5551 | frag->data += len; | ||
5552 | frag->gpa += len; | ||
5553 | frag->len -= len; | ||
5554 | } | ||
5555 | |||
5547 | if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { | 5556 | if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { |
5548 | vcpu->mmio_needed = 0; | 5557 | vcpu->mmio_needed = 0; |
5549 | if (vcpu->mmio_is_write) | 5558 | if (vcpu->mmio_is_write) |
@@ -5551,13 +5560,12 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) | |||
5551 | vcpu->mmio_read_completed = 1; | 5560 | vcpu->mmio_read_completed = 1; |
5552 | return complete_emulated_io(vcpu); | 5561 | return complete_emulated_io(vcpu); |
5553 | } | 5562 | } |
5554 | /* Initiate next fragment */ | 5563 | |
5555 | ++frag; | ||
5556 | run->exit_reason = KVM_EXIT_MMIO; | 5564 | run->exit_reason = KVM_EXIT_MMIO; |
5557 | run->mmio.phys_addr = frag->gpa; | 5565 | run->mmio.phys_addr = frag->gpa; |
5558 | if (vcpu->mmio_is_write) | 5566 | if (vcpu->mmio_is_write) |
5559 | memcpy(run->mmio.data, frag->data, frag->len); | 5567 | memcpy(run->mmio.data, frag->data, min(8u, frag->len)); |
5560 | run->mmio.len = frag->len; | 5568 | run->mmio.len = min(8u, frag->len); |
5561 | run->mmio.is_write = vcpu->mmio_is_write; | 5569 | run->mmio.is_write = vcpu->mmio_is_write; |
5562 | vcpu->arch.complete_userspace_io = complete_emulated_mmio; | 5570 | vcpu->arch.complete_userspace_io = complete_emulated_mmio; |
5563 | return 0; | 5571 | return 0; |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 93bfc9f9815c..ecc554374e44 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -42,19 +42,8 @@ | |||
42 | */ | 42 | */ |
43 | #define KVM_MEMSLOT_INVALID (1UL << 16) | 43 | #define KVM_MEMSLOT_INVALID (1UL << 16) |
44 | 44 | ||
45 | /* | 45 | /* Two fragments for cross MMIO pages. */ |
46 | * If we support unaligned MMIO, at most one fragment will be split into two: | 46 | #define KVM_MAX_MMIO_FRAGMENTS 2 |
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) | ||
58 | 47 | ||
59 | /* | 48 | /* |
60 | * For the normal pfn, the highest 12 bits should be zero, | 49 | * For the normal pfn, the highest 12 bits should be zero, |