aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/include/asm/kvm_host.h2
-rw-r--r--arch/ia64/kvm/kvm-ia64.c10
-rw-r--r--arch/x86/kvm/x86.c114
-rw-r--r--include/linux/kvm_host.h31
4 files changed, 115 insertions, 42 deletions
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index c4b4bac3d09e..6d6a5ac48d85 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -449,6 +449,8 @@ struct kvm_vcpu_arch {
449 char log_buf[VMM_LOG_LEN]; 449 char log_buf[VMM_LOG_LEN];
450 union context host; 450 union context host;
451 union context guest; 451 union context guest;
452
453 char mmio_data[8];
452}; 454};
453 455
454struct kvm_vm_stat { 456struct kvm_vm_stat {
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 9d80ff8d9eff..882ab21a8dcd 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -232,12 +232,12 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
232 if ((p->addr & PAGE_MASK) == IOAPIC_DEFAULT_BASE_ADDRESS) 232 if ((p->addr & PAGE_MASK) == IOAPIC_DEFAULT_BASE_ADDRESS)
233 goto mmio; 233 goto mmio;
234 vcpu->mmio_needed = 1; 234 vcpu->mmio_needed = 1;
235 vcpu->mmio_phys_addr = kvm_run->mmio.phys_addr = p->addr; 235 vcpu->mmio_fragments[0].gpa = kvm_run->mmio.phys_addr = p->addr;
236 vcpu->mmio_size = kvm_run->mmio.len = p->size; 236 vcpu->mmio_fragments[0].len = kvm_run->mmio.len = p->size;
237 vcpu->mmio_is_write = kvm_run->mmio.is_write = !p->dir; 237 vcpu->mmio_is_write = kvm_run->mmio.is_write = !p->dir;
238 238
239 if (vcpu->mmio_is_write) 239 if (vcpu->mmio_is_write)
240 memcpy(vcpu->mmio_data, &p->data, p->size); 240 memcpy(vcpu->arch.mmio_data, &p->data, p->size);
241 memcpy(kvm_run->mmio.data, &p->data, p->size); 241 memcpy(kvm_run->mmio.data, &p->data, p->size);
242 kvm_run->exit_reason = KVM_EXIT_MMIO; 242 kvm_run->exit_reason = KVM_EXIT_MMIO;
243 return 0; 243 return 0;
@@ -719,7 +719,7 @@ static void kvm_set_mmio_data(struct kvm_vcpu *vcpu)
719 struct kvm_mmio_req *p = kvm_get_vcpu_ioreq(vcpu); 719 struct kvm_mmio_req *p = kvm_get_vcpu_ioreq(vcpu);
720 720
721 if (!vcpu->mmio_is_write) 721 if (!vcpu->mmio_is_write)
722 memcpy(&p->data, vcpu->mmio_data, 8); 722 memcpy(&p->data, vcpu->arch.mmio_data, 8);
723 p->state = STATE_IORESP_READY; 723 p->state = STATE_IORESP_READY;
724} 724}
725 725
@@ -739,7 +739,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
739 } 739 }
740 740
741 if (vcpu->mmio_needed) { 741 if (vcpu->mmio_needed) {
742 memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); 742 memcpy(vcpu->arch.mmio_data, kvm_run->mmio.data, 8);
743 kvm_set_mmio_data(vcpu); 743 kvm_set_mmio_data(vcpu);
744 vcpu->mmio_read_completed = 1; 744 vcpu->mmio_read_completed = 1;
745 vcpu->mmio_needed = 0; 745 vcpu->mmio_needed = 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0d9a57875f0b..4de705cdcafd 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3718,9 +3718,8 @@ struct read_write_emulator_ops {
3718static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes) 3718static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes)
3719{ 3719{
3720 if (vcpu->mmio_read_completed) { 3720 if (vcpu->mmio_read_completed) {
3721 memcpy(val, vcpu->mmio_data, bytes);
3722 trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, 3721 trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
3723 vcpu->mmio_phys_addr, *(u64 *)val); 3722 vcpu->mmio_fragments[0].gpa, *(u64 *)val);
3724 vcpu->mmio_read_completed = 0; 3723 vcpu->mmio_read_completed = 0;
3725 return 1; 3724 return 1;
3726 } 3725 }
@@ -3756,8 +3755,9 @@ static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
3756static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, 3755static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
3757 void *val, int bytes) 3756 void *val, int bytes)
3758{ 3757{
3759 memcpy(vcpu->mmio_data, val, bytes); 3758 struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0];
3760 memcpy(vcpu->run->mmio.data, vcpu->mmio_data, 8); 3759
3760 memcpy(vcpu->run->mmio.data, frag->data, frag->len);
3761 return X86EMUL_CONTINUE; 3761 return X86EMUL_CONTINUE;
3762} 3762}
3763 3763
@@ -3784,10 +3784,7 @@ static int emulator_read_write_onepage(unsigned long addr, void *val,
3784 gpa_t gpa; 3784 gpa_t gpa;
3785 int handled, ret; 3785 int handled, ret;
3786 bool write = ops->write; 3786 bool write = ops->write;
3787 3787 struct kvm_mmio_fragment *frag;
3788 if (ops->read_write_prepare &&
3789 ops->read_write_prepare(vcpu, val, bytes))
3790 return X86EMUL_CONTINUE;
3791 3788
3792 ret = vcpu_mmio_gva_to_gpa(vcpu, addr, &gpa, exception, write); 3789 ret = vcpu_mmio_gva_to_gpa(vcpu, addr, &gpa, exception, write);
3793 3790
@@ -3813,15 +3810,19 @@ mmio:
3813 bytes -= handled; 3810 bytes -= handled;
3814 val += handled; 3811 val += handled;
3815 3812
3816 vcpu->mmio_needed = 1; 3813 while (bytes) {
3817 vcpu->run->exit_reason = KVM_EXIT_MMIO; 3814 unsigned now = min(bytes, 8U);
3818 vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa;
3819 vcpu->mmio_size = bytes;
3820 vcpu->run->mmio.len = min(vcpu->mmio_size, 8);
3821 vcpu->run->mmio.is_write = vcpu->mmio_is_write = write;
3822 vcpu->mmio_index = 0;
3823 3815
3824 return ops->read_write_exit_mmio(vcpu, gpa, val, bytes); 3816 frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++];
3817 frag->gpa = gpa;
3818 frag->data = val;
3819 frag->len = now;
3820
3821 gpa += now;
3822 val += now;
3823 bytes -= now;
3824 }
3825 return X86EMUL_CONTINUE;
3825} 3826}
3826 3827
3827int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, 3828int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
@@ -3830,10 +3831,18 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
3830 struct read_write_emulator_ops *ops) 3831 struct read_write_emulator_ops *ops)
3831{ 3832{
3832 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); 3833 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
3834 gpa_t gpa;
3835 int rc;
3836
3837 if (ops->read_write_prepare &&
3838 ops->read_write_prepare(vcpu, val, bytes))
3839 return X86EMUL_CONTINUE;
3840
3841 vcpu->mmio_nr_fragments = 0;
3833 3842
3834 /* Crossing a page boundary? */ 3843 /* Crossing a page boundary? */
3835 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { 3844 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
3836 int rc, now; 3845 int now;
3837 3846
3838 now = -addr & ~PAGE_MASK; 3847 now = -addr & ~PAGE_MASK;
3839 rc = emulator_read_write_onepage(addr, val, now, exception, 3848 rc = emulator_read_write_onepage(addr, val, now, exception,
@@ -3846,8 +3855,25 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
3846 bytes -= now; 3855 bytes -= now;
3847 } 3856 }
3848 3857
3849 return emulator_read_write_onepage(addr, val, bytes, exception, 3858 rc = emulator_read_write_onepage(addr, val, bytes, exception,
3850 vcpu, ops); 3859 vcpu, ops);
3860 if (rc != X86EMUL_CONTINUE)
3861 return rc;
3862
3863 if (!vcpu->mmio_nr_fragments)
3864 return rc;
3865
3866 gpa = vcpu->mmio_fragments[0].gpa;
3867
3868 vcpu->mmio_needed = 1;
3869 vcpu->mmio_cur_fragment = 0;
3870
3871 vcpu->run->mmio.len = vcpu->mmio_fragments[0].len;
3872 vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write;
3873 vcpu->run->exit_reason = KVM_EXIT_MMIO;
3874 vcpu->run->mmio.phys_addr = gpa;
3875
3876 return ops->read_write_exit_mmio(vcpu, gpa, val, bytes);
3851} 3877}
3852 3878
3853static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt, 3879static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
@@ -5446,33 +5472,55 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
5446 return r; 5472 return r;
5447} 5473}
5448 5474
5475/*
5476 * Implements the following, as a state machine:
5477 *
5478 * read:
5479 * for each fragment
5480 * write gpa, len
5481 * exit
5482 * copy data
5483 * execute insn
5484 *
5485 * write:
5486 * for each fragment
5487 * write gpa, len
5488 * copy data
5489 * exit
5490 */
5449static int complete_mmio(struct kvm_vcpu *vcpu) 5491static int complete_mmio(struct kvm_vcpu *vcpu)
5450{ 5492{
5451 struct kvm_run *run = vcpu->run; 5493 struct kvm_run *run = vcpu->run;
5494 struct kvm_mmio_fragment *frag;
5452 int r; 5495 int r;
5453 5496
5454 if (!(vcpu->arch.pio.count || vcpu->mmio_needed)) 5497 if (!(vcpu->arch.pio.count || vcpu->mmio_needed))
5455 return 1; 5498 return 1;
5456 5499
5457 if (vcpu->mmio_needed) { 5500 if (vcpu->mmio_needed) {
5458 vcpu->mmio_needed = 0; 5501 /* Complete previous fragment */
5502 frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];
5459 if (!vcpu->mmio_is_write) 5503 if (!vcpu->mmio_is_write)
5460 memcpy(vcpu->mmio_data + vcpu->mmio_index, 5504 memcpy(frag->data, run->mmio.data, frag->len);
5461 run->mmio.data, 8); 5505 if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {
5462 vcpu->mmio_index += 8; 5506 vcpu->mmio_needed = 0;
5463 if (vcpu->mmio_index < vcpu->mmio_size) { 5507 if (vcpu->mmio_is_write)
5464 run->exit_reason = KVM_EXIT_MMIO; 5508 return 1;
5465 run->mmio.phys_addr = vcpu->mmio_phys_addr + vcpu->mmio_index; 5509 vcpu->mmio_read_completed = 1;
5466 memcpy(run->mmio.data, vcpu->mmio_data + vcpu->mmio_index, 8); 5510 goto done;
5467 run->mmio.len = min(vcpu->mmio_size - vcpu->mmio_index, 8);
5468 run->mmio.is_write = vcpu->mmio_is_write;
5469 vcpu->mmio_needed = 1;
5470 return 0;
5471 } 5511 }
5512 /* Initiate next fragment */
5513 ++frag;
5514 run->exit_reason = KVM_EXIT_MMIO;
5515 run->mmio.phys_addr = frag->gpa;
5472 if (vcpu->mmio_is_write) 5516 if (vcpu->mmio_is_write)
5473 return 1; 5517 memcpy(run->mmio.data, frag->data, frag->len);
5474 vcpu->mmio_read_completed = 1; 5518 run->mmio.len = frag->len;
5519 run->mmio.is_write = vcpu->mmio_is_write;
5520 return 0;
5521
5475 } 5522 }
5523done:
5476 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 5524 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
5477 r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE); 5525 r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
5478 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); 5526 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index a2d00b1bbf54..186ffab0b9f0 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -35,6 +35,20 @@
35#endif 35#endif
36 36
37/* 37/*
38 * If we support unaligned MMIO, at most one fragment will be split into two:
39 */
40#ifdef KVM_UNALIGNED_MMIO
41# define KVM_EXTRA_MMIO_FRAGMENTS 1
42#else
43# define KVM_EXTRA_MMIO_FRAGMENTS 0
44#endif
45
46#define KVM_USER_MMIO_SIZE 8
47
48#define KVM_MAX_MMIO_FRAGMENTS \
49 (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS)
50
51/*
38 * vcpu->requests bit members 52 * vcpu->requests bit members
39 */ 53 */
40#define KVM_REQ_TLB_FLUSH 0 54#define KVM_REQ_TLB_FLUSH 0
@@ -117,6 +131,16 @@ enum {
117 EXITING_GUEST_MODE 131 EXITING_GUEST_MODE
118}; 132};
119 133
134/*
135 * Sometimes a large or cross-page mmio needs to be broken up into separate
136 * exits for userspace servicing.
137 */
138struct kvm_mmio_fragment {
139 gpa_t gpa;
140 void *data;
141 unsigned len;
142};
143
120struct kvm_vcpu { 144struct kvm_vcpu {
121 struct kvm *kvm; 145 struct kvm *kvm;
122#ifdef CONFIG_PREEMPT_NOTIFIERS 146#ifdef CONFIG_PREEMPT_NOTIFIERS
@@ -144,10 +168,9 @@ struct kvm_vcpu {
144 int mmio_needed; 168 int mmio_needed;
145 int mmio_read_completed; 169 int mmio_read_completed;
146 int mmio_is_write; 170 int mmio_is_write;
147 int mmio_size; 171 int mmio_cur_fragment;
148 int mmio_index; 172 int mmio_nr_fragments;
149 unsigned char mmio_data[KVM_MMIO_SIZE]; 173 struct kvm_mmio_fragment mmio_fragments[KVM_MAX_MMIO_FRAGMENTS];
150 gpa_t mmio_phys_addr;
151#endif 174#endif
152 175
153#ifdef CONFIG_KVM_ASYNC_PF 176#ifdef CONFIG_KVM_ASYNC_PF