aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h17
-rw-r--r--drivers/kvm/kvm_main.c74
-rw-r--r--drivers/kvm/svm.c3
-rw-r--r--drivers/kvm/vmx.c19
4 files changed, 25 insertions, 88 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 1072c8322d4..030b93bcdf1 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -561,15 +561,14 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu);
561void kvm_put_guest_fpu(struct kvm_vcpu *vcpu); 561void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
562void kvm_flush_remote_tlbs(struct kvm *kvm); 562void kvm_flush_remote_tlbs(struct kvm *kvm);
563 563
564int kvm_read_guest(struct kvm_vcpu *vcpu, 564int emulator_read_std(unsigned long addr,
565 gva_t addr, 565 void *val,
566 unsigned long size, 566 unsigned int bytes,
567 void *dest); 567 struct kvm_vcpu *vcpu);
568 568int emulator_write_emulated(unsigned long addr,
569int kvm_write_guest(struct kvm_vcpu *vcpu, 569 const void *val,
570 gva_t addr, 570 unsigned int bytes,
571 unsigned long size, 571 struct kvm_vcpu *vcpu);
572 void *data);
573 572
574unsigned long segment_base(u16 selector); 573unsigned long segment_base(u16 selector);
575 574
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a65a145f305..4bbd89e0332 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -146,74 +146,6 @@ static inline int valid_vcpu(int n)
146 return likely(n >= 0 && n < KVM_MAX_VCPUS); 146 return likely(n >= 0 && n < KVM_MAX_VCPUS);
147} 147}
148 148
149int kvm_read_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
150 void *dest)
151{
152 unsigned char *host_buf = dest;
153 unsigned long req_size = size;
154
155 while (size) {
156 hpa_t paddr;
157 unsigned now;
158 unsigned offset;
159 hva_t guest_buf;
160
161 paddr = gva_to_hpa(vcpu, addr);
162
163 if (is_error_hpa(paddr))
164 break;
165
166 guest_buf = (hva_t)kmap_atomic(
167 pfn_to_page(paddr >> PAGE_SHIFT),
168 KM_USER0);
169 offset = addr & ~PAGE_MASK;
170 guest_buf |= offset;
171 now = min(size, PAGE_SIZE - offset);
172 memcpy(host_buf, (void*)guest_buf, now);
173 host_buf += now;
174 addr += now;
175 size -= now;
176 kunmap_atomic((void *)(guest_buf & PAGE_MASK), KM_USER0);
177 }
178 return req_size - size;
179}
180EXPORT_SYMBOL_GPL(kvm_read_guest);
181
182int kvm_write_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
183 void *data)
184{
185 unsigned char *host_buf = data;
186 unsigned long req_size = size;
187
188 while (size) {
189 hpa_t paddr;
190 unsigned now;
191 unsigned offset;
192 hva_t guest_buf;
193 gfn_t gfn;
194
195 paddr = gva_to_hpa(vcpu, addr);
196
197 if (is_error_hpa(paddr))
198 break;
199
200 gfn = vcpu->mmu.gva_to_gpa(vcpu, addr) >> PAGE_SHIFT;
201 mark_page_dirty(vcpu->kvm, gfn);
202 guest_buf = (hva_t)kmap_atomic(
203 pfn_to_page(paddr >> PAGE_SHIFT), KM_USER0);
204 offset = addr & ~PAGE_MASK;
205 guest_buf |= offset;
206 now = min(size, PAGE_SIZE - offset);
207 memcpy((void*)guest_buf, host_buf, now);
208 host_buf += now;
209 addr += now;
210 size -= now;
211 kunmap_atomic((void *)(guest_buf & PAGE_MASK), KM_USER0);
212 }
213 return req_size - size;
214}
215EXPORT_SYMBOL_GPL(kvm_write_guest);
216
217void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) 149void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
218{ 150{
219 if (!vcpu->fpu_active || vcpu->guest_fpu_loaded) 151 if (!vcpu->fpu_active || vcpu->guest_fpu_loaded)
@@ -1017,7 +949,7 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
1017 } 949 }
1018} 950}
1019 951
1020static int emulator_read_std(unsigned long addr, 952int emulator_read_std(unsigned long addr,
1021 void *val, 953 void *val,
1022 unsigned int bytes, 954 unsigned int bytes,
1023 struct kvm_vcpu *vcpu) 955 struct kvm_vcpu *vcpu)
@@ -1051,6 +983,7 @@ static int emulator_read_std(unsigned long addr,
1051 983
1052 return X86EMUL_CONTINUE; 984 return X86EMUL_CONTINUE;
1053} 985}
986EXPORT_SYMBOL_GPL(emulator_read_std);
1054 987
1055static int emulator_write_std(unsigned long addr, 988static int emulator_write_std(unsigned long addr,
1056 const void *val, 989 const void *val,
@@ -1169,7 +1102,7 @@ static int emulator_write_emulated_onepage(unsigned long addr,
1169 return X86EMUL_CONTINUE; 1102 return X86EMUL_CONTINUE;
1170} 1103}
1171 1104
1172static int emulator_write_emulated(unsigned long addr, 1105int emulator_write_emulated(unsigned long addr,
1173 const void *val, 1106 const void *val,
1174 unsigned int bytes, 1107 unsigned int bytes,
1175 struct kvm_vcpu *vcpu) 1108 struct kvm_vcpu *vcpu)
@@ -1188,6 +1121,7 @@ static int emulator_write_emulated(unsigned long addr,
1188 } 1121 }
1189 return emulator_write_emulated_onepage(addr, val, bytes, vcpu); 1122 return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
1190} 1123}
1124EXPORT_SYMBOL_GPL(emulator_write_emulated);
1191 1125
1192static int emulator_cmpxchg_emulated(unsigned long addr, 1126static int emulator_cmpxchg_emulated(unsigned long addr,
1193 const void *old, 1127 const void *old,
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index cd966739970..b25f4e117e7 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1019,7 +1019,8 @@ static int io_get_override(struct vcpu_svm *svm,
1019 svm->vmcb->control.exit_info_2, 1019 svm->vmcb->control.exit_info_2,
1020 ins_length); 1020 ins_length);
1021 1021
1022 if (kvm_read_guest(&svm->vcpu, rip, ins_length, inst) != ins_length) 1022 if (emulator_read_std(rip, inst, ins_length, &svm->vcpu)
1023 != X86EMUL_CONTINUE)
1023 /* #PF */ 1024 /* #PF */
1024 return 0; 1025 return 0;
1025 1026
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index cc7ee3d484f..f770f55d46c 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include "kvm.h" 18#include "kvm.h"
19#include "x86_emulate.h"
19#include "vmx.h" 20#include "vmx.h"
20#include "segment_descriptor.h" 21#include "segment_descriptor.h"
21 22
@@ -1553,8 +1554,8 @@ static void inject_rmode_irq(struct kvm_vcpu *vcpu, int irq)
1553 return; 1554 return;
1554 } 1555 }
1555 1556
1556 if (kvm_read_guest(vcpu, irq * sizeof(ent), sizeof(ent), &ent) != 1557 if (emulator_read_std(irq * sizeof(ent), &ent, sizeof(ent), vcpu) !=
1557 sizeof(ent)) { 1558 X86EMUL_CONTINUE) {
1558 vcpu_printf(vcpu, "%s: read guest err\n", __FUNCTION__); 1559 vcpu_printf(vcpu, "%s: read guest err\n", __FUNCTION__);
1559 return; 1560 return;
1560 } 1561 }
@@ -1564,9 +1565,9 @@ static void inject_rmode_irq(struct kvm_vcpu *vcpu, int irq)
1564 ip = vmcs_readl(GUEST_RIP); 1565 ip = vmcs_readl(GUEST_RIP);
1565 1566
1566 1567
1567 if (kvm_write_guest(vcpu, ss_base + sp - 2, 2, &flags) != 2 || 1568 if (emulator_write_emulated(ss_base + sp - 2, &flags, 2, vcpu) != X86EMUL_CONTINUE ||
1568 kvm_write_guest(vcpu, ss_base + sp - 4, 2, &cs) != 2 || 1569 emulator_write_emulated(ss_base + sp - 4, &cs, 2, vcpu) != X86EMUL_CONTINUE ||
1569 kvm_write_guest(vcpu, ss_base + sp - 6, 2, &ip) != 2) { 1570 emulator_write_emulated(ss_base + sp - 6, &ip, 2, vcpu) != X86EMUL_CONTINUE) {
1570 vcpu_printf(vcpu, "%s: write guest err\n", __FUNCTION__); 1571 vcpu_printf(vcpu, "%s: write guest err\n", __FUNCTION__);
1571 return; 1572 return;
1572 } 1573 }
@@ -1767,7 +1768,7 @@ static int get_io_count(struct kvm_vcpu *vcpu, unsigned long *count)
1767 u64 inst; 1768 u64 inst;
1768 gva_t rip; 1769 gva_t rip;
1769 int countr_size; 1770 int countr_size;
1770 int i, n; 1771 int i;
1771 1772
1772 if ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_VM)) { 1773 if ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_VM)) {
1773 countr_size = 2; 1774 countr_size = 2;
@@ -1782,9 +1783,11 @@ static int get_io_count(struct kvm_vcpu *vcpu, unsigned long *count)
1782 if (countr_size != 8) 1783 if (countr_size != 8)
1783 rip += vmcs_readl(GUEST_CS_BASE); 1784 rip += vmcs_readl(GUEST_CS_BASE);
1784 1785
1785 n = kvm_read_guest(vcpu, rip, sizeof(inst), &inst); 1786 if (emulator_read_std(rip, &inst, sizeof(inst), vcpu) !=
1787 X86EMUL_CONTINUE)
1788 return 0;
1786 1789
1787 for (i = 0; i < n; i++) { 1790 for (i = 0; i < sizeof(inst); i++) {
1788 switch (((u8*)&inst)[i]) { 1791 switch (((u8*)&inst)[i]) {
1789 case 0xf0: 1792 case 0xf0:
1790 case 0xf2: 1793 case 0xf2: