···37793779{37803780 struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0];3781378137823782- memcpy(vcpu->run->mmio.data, frag->data, frag->len);37823782+ memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len));37833783 return X86EMUL_CONTINUE;37843784}37853785···38323832 bytes -= handled;38333833 val += handled;3834383438353835- while (bytes) {38363836- unsigned now = min(bytes, 8U);38373837-38383838- frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++];38393839- frag->gpa = gpa;38403840- frag->data = val;38413841- frag->len = now;38423842-38433843- gpa += now;38443844- val += now;38453845- bytes -= now;38463846- }38353835+ WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS);38363836+ frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++];38373837+ frag->gpa = gpa;38383838+ frag->data = val;38393839+ frag->len = bytes;38473840 return X86EMUL_CONTINUE;38483841}38493842···38833890 vcpu->mmio_needed = 1;38843891 vcpu->mmio_cur_fragment = 0;3885389238863886- vcpu->run->mmio.len = vcpu->mmio_fragments[0].len;38933893+ vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len);38873894 vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write;38883895 vcpu->run->exit_reason = KVM_EXIT_MMIO;38893896 vcpu->run->mmio.phys_addr = gpa;···55155522 *55165523 * read:55175524 * for each fragment55185518- * write gpa, len55195519- * exit55205520- * copy data55255525+ * for each mmio piece in the fragment55265526+ * write gpa, len55275527+ * exit55285528+ * copy data55215529 * execute insn55225530 *55235531 * write:55245532 * for each fragment55255525- * write gpa, len55265526- * copy data55275527- * exit55335533+ * for each mmio piece in the fragment55345534+ * write gpa, len55355535+ * copy data55365536+ * exit55285537 */55295538static int complete_emulated_mmio(struct kvm_vcpu *vcpu)55305539{55315540 struct kvm_run *run = vcpu->run;55325541 struct kvm_mmio_fragment *frag;55425542+ unsigned len;5533554355345544 BUG_ON(!vcpu->mmio_needed);5535554555365546 /* Complete previous fragment */55375537- frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];55475547+ frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment];55485548+ len = min(8u, frag->len);55385549 if (!vcpu->mmio_is_write)55395539- memcpy(frag->data, run->mmio.data, frag->len);55505550+ memcpy(frag->data, run->mmio.data, len);55515551+55525552+ if (frag->len <= 8) {55535553+ /* Switch to the next fragment. */55545554+ frag++;55555555+ vcpu->mmio_cur_fragment++;55565556+ } else {55575557+ /* Go forward to the next mmio piece. */55585558+ frag->data += len;55595559+ frag->gpa += len;55605560+ frag->len -= len;55615561+ }55625562+55405563 if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {55415564 vcpu->mmio_needed = 0;55425565 if (vcpu->mmio_is_write)···55605551 vcpu->mmio_read_completed = 1;55615552 return complete_emulated_io(vcpu);55625553 }55635563- /* Initiate next fragment */55645564- ++frag;55545554+55655555 run->exit_reason = KVM_EXIT_MMIO;55665556 run->mmio.phys_addr = frag->gpa;55675557 if (vcpu->mmio_is_write)55685568- memcpy(run->mmio.data, frag->data, frag->len);55695569- run->mmio.len = frag->len;55585558+ memcpy(run->mmio.data, frag->data, min(8u, frag->len));55595559+ run->mmio.len = min(8u, frag->len);55705560 run->mmio.is_write = vcpu->mmio_is_write;55715561 vcpu->arch.complete_userspace_io = complete_emulated_mmio;55725562 return 0;
+2-13
include/linux/kvm_host.h
···4242 */4343#define KVM_MEMSLOT_INVALID (1UL << 16)44444545-/*4646- * If we support unaligned MMIO, at most one fragment will be split into two:4747- */4848-#ifdef KVM_UNALIGNED_MMIO4949-# define KVM_EXTRA_MMIO_FRAGMENTS 15050-#else5151-# define KVM_EXTRA_MMIO_FRAGMENTS 05252-#endif5353-5454-#define KVM_USER_MMIO_SIZE 85555-5656-#define KVM_MAX_MMIO_FRAGMENTS \5757- (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS)4545+/* Two fragments for cross MMIO pages. */4646+#define KVM_MAX_MMIO_FRAGMENTS 258475948/*6049 * For the normal pfn, the highest 12 bits should be zero,