Loading arch/x86/kvm/x86.c +34 −26 Original line number Diff line number Diff line Loading @@ -3779,7 +3779,7 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, { struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; memcpy(vcpu->run->mmio.data, frag->data, frag->len); memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); return X86EMUL_CONTINUE; } Loading Loading @@ -3832,18 +3832,11 @@ static int emulator_read_write_onepage(unsigned long addr, void *val, bytes -= handled; val += handled; while (bytes) { unsigned now = min(bytes, 8U); WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; frag->gpa = gpa; frag->data = val; frag->len = now; gpa += now; val += now; bytes -= now; } frag->len = bytes; return X86EMUL_CONTINUE; } Loading Loading @@ -3890,7 +3883,7 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, vcpu->mmio_needed = 1; vcpu->mmio_cur_fragment = 0; vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = gpa; Loading Loading @@ -5522,6 +5515,7 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) * * read: * for each fragment * for each mmio piece in the fragment * write gpa, len * exit * copy data Loading @@ -5529,6 +5523,7 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) * * write: * for each fragment * for each mmio piece in the fragment * write gpa, len * copy data * exit Loading @@ -5537,13 +5532,27 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu->run; struct kvm_mmio_fragment *frag; unsigned len; BUG_ON(!vcpu->mmio_needed); /* Complete previous fragment */ frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; len = min(8u, frag->len); if (!vcpu->mmio_is_write) memcpy(frag->data, run->mmio.data, frag->len); memcpy(frag->data, run->mmio.data, len); if (frag->len <= 8) { /* Switch to the next fragment. */ frag++; vcpu->mmio_cur_fragment++; } else { /* Go forward to the next mmio piece. */ frag->data += len; frag->gpa += len; frag->len -= len; } if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; if (vcpu->mmio_is_write) Loading @@ -5551,13 +5560,12 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) vcpu->mmio_read_completed = 1; return complete_emulated_io(vcpu); } /* Initiate next fragment */ ++frag; run->exit_reason = KVM_EXIT_MMIO; run->mmio.phys_addr = frag->gpa; if (vcpu->mmio_is_write) memcpy(run->mmio.data, frag->data, frag->len); run->mmio.len = frag->len; memcpy(run->mmio.data, frag->data, min(8u, frag->len)); run->mmio.len = min(8u, frag->len); run->mmio.is_write = vcpu->mmio_is_write; vcpu->arch.complete_userspace_io = complete_emulated_mmio; return 0; Loading include/linux/kvm_host.h +2 −13 Original line number Diff line number Diff line Loading @@ -42,19 +42,8 @@ */ #define KVM_MEMSLOT_INVALID (1UL << 16) /* * If we support unaligned MMIO, at most one fragment will be split into two: */ #ifdef KVM_UNALIGNED_MMIO # define KVM_EXTRA_MMIO_FRAGMENTS 1 #else # define KVM_EXTRA_MMIO_FRAGMENTS 0 #endif #define KVM_USER_MMIO_SIZE 8 #define KVM_MAX_MMIO_FRAGMENTS \ (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS) /* Two fragments for cross MMIO pages. */ #define KVM_MAX_MMIO_FRAGMENTS 2 /* * For the normal pfn, the highest 12 bits should be zero, Loading Loading
arch/x86/kvm/x86.c +34 −26 Original line number Diff line number Diff line Loading @@ -3779,7 +3779,7 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, { struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; memcpy(vcpu->run->mmio.data, frag->data, frag->len); memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); return X86EMUL_CONTINUE; } Loading Loading @@ -3832,18 +3832,11 @@ static int emulator_read_write_onepage(unsigned long addr, void *val, bytes -= handled; val += handled; while (bytes) { unsigned now = min(bytes, 8U); WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; frag->gpa = gpa; frag->data = val; frag->len = now; gpa += now; val += now; bytes -= now; } frag->len = bytes; return X86EMUL_CONTINUE; } Loading Loading @@ -3890,7 +3883,7 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, vcpu->mmio_needed = 1; vcpu->mmio_cur_fragment = 0; vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = gpa; Loading Loading @@ -5522,6 +5515,7 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) * * read: * for each fragment * for each mmio piece in the fragment * write gpa, len * exit * copy data Loading @@ -5529,6 +5523,7 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) * * write: * for each fragment * for each mmio piece in the fragment * write gpa, len * copy data * exit Loading @@ -5537,13 +5532,27 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu->run; struct kvm_mmio_fragment *frag; unsigned len; BUG_ON(!vcpu->mmio_needed); /* Complete previous fragment */ frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; len = min(8u, frag->len); if (!vcpu->mmio_is_write) memcpy(frag->data, run->mmio.data, frag->len); memcpy(frag->data, run->mmio.data, len); if (frag->len <= 8) { /* Switch to the next fragment. */ frag++; vcpu->mmio_cur_fragment++; } else { /* Go forward to the next mmio piece. */ frag->data += len; frag->gpa += len; frag->len -= len; } if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; if (vcpu->mmio_is_write) Loading @@ -5551,13 +5560,12 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) vcpu->mmio_read_completed = 1; return complete_emulated_io(vcpu); } /* Initiate next fragment */ ++frag; run->exit_reason = KVM_EXIT_MMIO; run->mmio.phys_addr = frag->gpa; if (vcpu->mmio_is_write) memcpy(run->mmio.data, frag->data, frag->len); run->mmio.len = frag->len; memcpy(run->mmio.data, frag->data, min(8u, frag->len)); run->mmio.len = min(8u, frag->len); run->mmio.is_write = vcpu->mmio_is_write; vcpu->arch.complete_userspace_io = complete_emulated_mmio; return 0; Loading
include/linux/kvm_host.h +2 −13 Original line number Diff line number Diff line Loading @@ -42,19 +42,8 @@ */ #define KVM_MEMSLOT_INVALID (1UL << 16) /* * If we support unaligned MMIO, at most one fragment will be split into two: */ #ifdef KVM_UNALIGNED_MMIO # define KVM_EXTRA_MMIO_FRAGMENTS 1 #else # define KVM_EXTRA_MMIO_FRAGMENTS 0 #endif #define KVM_USER_MMIO_SIZE 8 #define KVM_MAX_MMIO_FRAGMENTS \ (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS) /* Two fragments for cross MMIO pages. */ #define KVM_MAX_MMIO_FRAGMENTS 2 /* * For the normal pfn, the highest 12 bits should be zero, Loading