diff options
author | Laurent Vivier <Laurent.Vivier@bull.net> | 2007-07-30 06:35:24 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 04:18:21 -0400 |
commit | cebff02b11b02a81d21b6cc8390938dc9bdf0a12 (patch) | |
tree | 99641f1b444835fca8218a5f5b10d2d1bd6ad429 /drivers | |
parent | 0e5017d4ae981b0311a3ec1ca04806a4ae7d7446 (diff) |
KVM: Change the emulator_{read,write,cmpxchg}_* functions to take a vcpu
... instead of a x86_emulate_ctxt, so that other callers can use it easily.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/kvm/kvm_main.c | 25 | ||||
-rw-r--r-- | drivers/kvm/x86_emulate.c | 35 | ||||
-rw-r--r-- | drivers/kvm/x86_emulate.h | 10 |
3 files changed, 36 insertions, 34 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 6ad1b04f3099..a65a145f3050 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -1020,9 +1020,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn) | |||
1020 | static int emulator_read_std(unsigned long addr, | 1020 | static int emulator_read_std(unsigned long addr, |
1021 | void *val, | 1021 | void *val, |
1022 | unsigned int bytes, | 1022 | unsigned int bytes, |
1023 | struct x86_emulate_ctxt *ctxt) | 1023 | struct kvm_vcpu *vcpu) |
1024 | { | 1024 | { |
1025 | struct kvm_vcpu *vcpu = ctxt->vcpu; | ||
1026 | void *data = val; | 1025 | void *data = val; |
1027 | 1026 | ||
1028 | while (bytes) { | 1027 | while (bytes) { |
@@ -1056,7 +1055,7 @@ static int emulator_read_std(unsigned long addr, | |||
1056 | static int emulator_write_std(unsigned long addr, | 1055 | static int emulator_write_std(unsigned long addr, |
1057 | const void *val, | 1056 | const void *val, |
1058 | unsigned int bytes, | 1057 | unsigned int bytes, |
1059 | struct x86_emulate_ctxt *ctxt) | 1058 | struct kvm_vcpu *vcpu) |
1060 | { | 1059 | { |
1061 | printk(KERN_ERR "emulator_write_std: addr %lx n %d\n", | 1060 | printk(KERN_ERR "emulator_write_std: addr %lx n %d\n", |
1062 | addr, bytes); | 1061 | addr, bytes); |
@@ -1083,9 +1082,8 @@ static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, | |||
1083 | static int emulator_read_emulated(unsigned long addr, | 1082 | static int emulator_read_emulated(unsigned long addr, |
1084 | void *val, | 1083 | void *val, |
1085 | unsigned int bytes, | 1084 | unsigned int bytes, |
1086 | struct x86_emulate_ctxt *ctxt) | 1085 | struct kvm_vcpu *vcpu) |
1087 | { | 1086 | { |
1088 | struct kvm_vcpu *vcpu = ctxt->vcpu; | ||
1089 | struct kvm_io_device *mmio_dev; | 1087 | struct kvm_io_device *mmio_dev; |
1090 | gpa_t gpa; | 1088 | gpa_t gpa; |
1091 | 1089 | ||
@@ -1093,7 +1091,7 @@ static int emulator_read_emulated(unsigned long addr, | |||
1093 | memcpy(val, vcpu->mmio_data, bytes); | 1091 | memcpy(val, vcpu->mmio_data, bytes); |
1094 | vcpu->mmio_read_completed = 0; | 1092 | vcpu->mmio_read_completed = 0; |
1095 | return X86EMUL_CONTINUE; | 1093 | return X86EMUL_CONTINUE; |
1096 | } else if (emulator_read_std(addr, val, bytes, ctxt) | 1094 | } else if (emulator_read_std(addr, val, bytes, vcpu) |
1097 | == X86EMUL_CONTINUE) | 1095 | == X86EMUL_CONTINUE) |
1098 | return X86EMUL_CONTINUE; | 1096 | return X86EMUL_CONTINUE; |
1099 | 1097 | ||
@@ -1140,9 +1138,8 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
1140 | static int emulator_write_emulated_onepage(unsigned long addr, | 1138 | static int emulator_write_emulated_onepage(unsigned long addr, |
1141 | const void *val, | 1139 | const void *val, |
1142 | unsigned int bytes, | 1140 | unsigned int bytes, |
1143 | struct x86_emulate_ctxt *ctxt) | 1141 | struct kvm_vcpu *vcpu) |
1144 | { | 1142 | { |
1145 | struct kvm_vcpu *vcpu = ctxt->vcpu; | ||
1146 | struct kvm_io_device *mmio_dev; | 1143 | struct kvm_io_device *mmio_dev; |
1147 | gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr); | 1144 | gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr); |
1148 | 1145 | ||
@@ -1175,28 +1172,28 @@ static int emulator_write_emulated_onepage(unsigned long addr, | |||
1175 | static int emulator_write_emulated(unsigned long addr, | 1172 | static int emulator_write_emulated(unsigned long addr, |
1176 | const void *val, | 1173 | const void *val, |
1177 | unsigned int bytes, | 1174 | unsigned int bytes, |
1178 | struct x86_emulate_ctxt *ctxt) | 1175 | struct kvm_vcpu *vcpu) |
1179 | { | 1176 | { |
1180 | /* Crossing a page boundary? */ | 1177 | /* Crossing a page boundary? */ |
1181 | if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { | 1178 | if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { |
1182 | int rc, now; | 1179 | int rc, now; |
1183 | 1180 | ||
1184 | now = -addr & ~PAGE_MASK; | 1181 | now = -addr & ~PAGE_MASK; |
1185 | rc = emulator_write_emulated_onepage(addr, val, now, ctxt); | 1182 | rc = emulator_write_emulated_onepage(addr, val, now, vcpu); |
1186 | if (rc != X86EMUL_CONTINUE) | 1183 | if (rc != X86EMUL_CONTINUE) |
1187 | return rc; | 1184 | return rc; |
1188 | addr += now; | 1185 | addr += now; |
1189 | val += now; | 1186 | val += now; |
1190 | bytes -= now; | 1187 | bytes -= now; |
1191 | } | 1188 | } |
1192 | return emulator_write_emulated_onepage(addr, val, bytes, ctxt); | 1189 | return emulator_write_emulated_onepage(addr, val, bytes, vcpu); |
1193 | } | 1190 | } |
1194 | 1191 | ||
1195 | static int emulator_cmpxchg_emulated(unsigned long addr, | 1192 | static int emulator_cmpxchg_emulated(unsigned long addr, |
1196 | const void *old, | 1193 | const void *old, |
1197 | const void *new, | 1194 | const void *new, |
1198 | unsigned int bytes, | 1195 | unsigned int bytes, |
1199 | struct x86_emulate_ctxt *ctxt) | 1196 | struct kvm_vcpu *vcpu) |
1200 | { | 1197 | { |
1201 | static int reported; | 1198 | static int reported; |
1202 | 1199 | ||
@@ -1204,7 +1201,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr, | |||
1204 | reported = 1; | 1201 | reported = 1; |
1205 | printk(KERN_WARNING "kvm: emulating exchange as write\n"); | 1202 | printk(KERN_WARNING "kvm: emulating exchange as write\n"); |
1206 | } | 1203 | } |
1207 | return emulator_write_emulated(addr, new, bytes, ctxt); | 1204 | return emulator_write_emulated(addr, new, bytes, vcpu); |
1208 | } | 1205 | } |
1209 | 1206 | ||
1210 | static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) | 1207 | static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) |
@@ -1266,7 +1263,7 @@ static void report_emulation_failure(struct x86_emulate_ctxt *ctxt) | |||
1266 | if (reported) | 1263 | if (reported) |
1267 | return; | 1264 | return; |
1268 | 1265 | ||
1269 | emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt); | 1266 | emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt->vcpu); |
1270 | 1267 | ||
1271 | printk(KERN_ERR "emulation failed but !mmio_needed?" | 1268 | printk(KERN_ERR "emulation failed but !mmio_needed?" |
1272 | " rip %lx %02x %02x %02x %02x\n", | 1269 | " rip %lx %02x %02x %02x %02x\n", |
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index 2136da5d6976..44eb28d31499 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -420,7 +420,7 @@ struct operand { | |||
420 | #define insn_fetch(_type, _size, _eip) \ | 420 | #define insn_fetch(_type, _size, _eip) \ |
421 | ({ unsigned long _x; \ | 421 | ({ unsigned long _x; \ |
422 | rc = ops->read_std((unsigned long)(_eip) + ctxt->cs_base, &_x, \ | 422 | rc = ops->read_std((unsigned long)(_eip) + ctxt->cs_base, &_x, \ |
423 | (_size), ctxt); \ | 423 | (_size), ctxt->vcpu); \ |
424 | if ( rc != 0 ) \ | 424 | if ( rc != 0 ) \ |
425 | goto done; \ | 425 | goto done; \ |
426 | (_eip) += (_size); \ | 426 | (_eip) += (_size); \ |
@@ -469,10 +469,12 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, | |||
469 | if (op_bytes == 2) | 469 | if (op_bytes == 2) |
470 | op_bytes = 3; | 470 | op_bytes = 3; |
471 | *address = 0; | 471 | *address = 0; |
472 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, ctxt); | 472 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, |
473 | ctxt->vcpu); | ||
473 | if (rc) | 474 | if (rc) |
474 | return rc; | 475 | return rc; |
475 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, ctxt); | 476 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, |
477 | ctxt->vcpu); | ||
476 | return rc; | 478 | return rc; |
477 | } | 479 | } |
478 | 480 | ||
@@ -780,7 +782,7 @@ done_prefixes: | |||
780 | src.type = OP_MEM; | 782 | src.type = OP_MEM; |
781 | src.ptr = (unsigned long *)cr2; | 783 | src.ptr = (unsigned long *)cr2; |
782 | if ((rc = ops->read_emulated((unsigned long)src.ptr, | 784 | if ((rc = ops->read_emulated((unsigned long)src.ptr, |
783 | &src.val, src.bytes, ctxt)) != 0) | 785 | &src.val, src.bytes, ctxt->vcpu)) != 0) |
784 | goto done; | 786 | goto done; |
785 | src.orig_val = src.val; | 787 | src.orig_val = src.val; |
786 | break; | 788 | break; |
@@ -850,7 +852,7 @@ done_prefixes: | |||
850 | } | 852 | } |
851 | if (!(d & Mov) && /* optimisation - avoid slow emulated read */ | 853 | if (!(d & Mov) && /* optimisation - avoid slow emulated read */ |
852 | ((rc = ops->read_emulated((unsigned long)dst.ptr, | 854 | ((rc = ops->read_emulated((unsigned long)dst.ptr, |
853 | &dst.val, dst.bytes, ctxt)) != 0)) | 855 | &dst.val, dst.bytes, ctxt->vcpu)) != 0)) |
854 | goto done; | 856 | goto done; |
855 | break; | 857 | break; |
856 | } | 858 | } |
@@ -963,7 +965,7 @@ done_prefixes: | |||
963 | dst.bytes = 8; | 965 | dst.bytes = 8; |
964 | if ((rc = ops->read_std(register_address(ctxt->ss_base, | 966 | if ((rc = ops->read_std(register_address(ctxt->ss_base, |
965 | _regs[VCPU_REGS_RSP]), | 967 | _regs[VCPU_REGS_RSP]), |
966 | &dst.val, dst.bytes, ctxt)) != 0) | 968 | &dst.val, dst.bytes, ctxt->vcpu)) != 0) |
967 | goto done; | 969 | goto done; |
968 | register_address_increment(_regs[VCPU_REGS_RSP], dst.bytes); | 970 | register_address_increment(_regs[VCPU_REGS_RSP], dst.bytes); |
969 | break; | 971 | break; |
@@ -1048,7 +1050,7 @@ done_prefixes: | |||
1048 | dst.bytes = 8; | 1050 | dst.bytes = 8; |
1049 | if ((rc = ops->read_std((unsigned long)dst.ptr, | 1051 | if ((rc = ops->read_std((unsigned long)dst.ptr, |
1050 | &dst.val, 8, | 1052 | &dst.val, 8, |
1051 | ctxt)) != 0) | 1053 | ctxt->vcpu)) != 0) |
1052 | goto done; | 1054 | goto done; |
1053 | } | 1055 | } |
1054 | register_address_increment(_regs[VCPU_REGS_RSP], | 1056 | register_address_increment(_regs[VCPU_REGS_RSP], |
@@ -1056,7 +1058,7 @@ done_prefixes: | |||
1056 | if ((rc = ops->write_std( | 1058 | if ((rc = ops->write_std( |
1057 | register_address(ctxt->ss_base, | 1059 | register_address(ctxt->ss_base, |
1058 | _regs[VCPU_REGS_RSP]), | 1060 | _regs[VCPU_REGS_RSP]), |
1059 | &dst.val, dst.bytes, ctxt)) != 0) | 1061 | &dst.val, dst.bytes, ctxt->vcpu)) != 0) |
1060 | goto done; | 1062 | goto done; |
1061 | no_wb = 1; | 1063 | no_wb = 1; |
1062 | break; | 1064 | break; |
@@ -1091,11 +1093,11 @@ writeback: | |||
1091 | rc = ops->cmpxchg_emulated((unsigned long)dst. | 1093 | rc = ops->cmpxchg_emulated((unsigned long)dst. |
1092 | ptr, &dst.orig_val, | 1094 | ptr, &dst.orig_val, |
1093 | &dst.val, dst.bytes, | 1095 | &dst.val, dst.bytes, |
1094 | ctxt); | 1096 | ctxt->vcpu); |
1095 | else | 1097 | else |
1096 | rc = ops->write_emulated((unsigned long)dst.ptr, | 1098 | rc = ops->write_emulated((unsigned long)dst.ptr, |
1097 | &dst.val, dst.bytes, | 1099 | &dst.val, dst.bytes, |
1098 | ctxt); | 1100 | ctxt->vcpu); |
1099 | if (rc != 0) | 1101 | if (rc != 0) |
1100 | goto done; | 1102 | goto done; |
1101 | default: | 1103 | default: |
@@ -1130,7 +1132,7 @@ special_insn: | |||
1130 | _regs[VCPU_REGS_RDI]); | 1132 | _regs[VCPU_REGS_RDI]); |
1131 | if ((rc = ops->read_emulated(register_address( | 1133 | if ((rc = ops->read_emulated(register_address( |
1132 | override_base ? *override_base : ctxt->ds_base, | 1134 | override_base ? *override_base : ctxt->ds_base, |
1133 | _regs[VCPU_REGS_RSI]), &dst.val, dst.bytes, ctxt)) != 0) | 1135 | _regs[VCPU_REGS_RSI]), &dst.val, dst.bytes, ctxt->vcpu)) != 0) |
1134 | goto done; | 1136 | goto done; |
1135 | register_address_increment(_regs[VCPU_REGS_RSI], | 1137 | register_address_increment(_regs[VCPU_REGS_RSI], |
1136 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); | 1138 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
@@ -1152,7 +1154,8 @@ special_insn: | |||
1152 | dst.type = OP_REG; | 1154 | dst.type = OP_REG; |
1153 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; | 1155 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; |
1154 | dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX]; | 1156 | dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX]; |
1155 | if ((rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0) | 1157 | if ((rc = ops->read_emulated(cr2, &dst.val, dst.bytes, |
1158 | ctxt->vcpu)) != 0) | ||
1156 | goto done; | 1159 | goto done; |
1157 | register_address_increment(_regs[VCPU_REGS_RSI], | 1160 | register_address_increment(_regs[VCPU_REGS_RSI], |
1158 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); | 1161 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
@@ -1171,7 +1174,8 @@ special_insn: | |||
1171 | 1174 | ||
1172 | pop_instruction: | 1175 | pop_instruction: |
1173 | if ((rc = ops->read_std(register_address(ctxt->ss_base, | 1176 | if ((rc = ops->read_std(register_address(ctxt->ss_base, |
1174 | _regs[VCPU_REGS_RSP]), dst.ptr, op_bytes, ctxt)) != 0) | 1177 | _regs[VCPU_REGS_RSP]), dst.ptr, op_bytes, ctxt->vcpu)) |
1178 | != 0) | ||
1175 | goto done; | 1179 | goto done; |
1176 | 1180 | ||
1177 | register_address_increment(_regs[VCPU_REGS_RSP], op_bytes); | 1181 | register_address_increment(_regs[VCPU_REGS_RSP], op_bytes); |
@@ -1378,7 +1382,8 @@ twobyte_special_insn: | |||
1378 | case 0xc7: /* Grp9 (cmpxchg8b) */ | 1382 | case 0xc7: /* Grp9 (cmpxchg8b) */ |
1379 | { | 1383 | { |
1380 | u64 old, new; | 1384 | u64 old, new; |
1381 | if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0) | 1385 | if ((rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu)) |
1386 | != 0) | ||
1382 | goto done; | 1387 | goto done; |
1383 | if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || | 1388 | if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || |
1384 | ((u32) (old >> 32) != (u32) _regs[VCPU_REGS_RDX])) { | 1389 | ((u32) (old >> 32) != (u32) _regs[VCPU_REGS_RDX])) { |
@@ -1389,7 +1394,7 @@ twobyte_special_insn: | |||
1389 | new = ((u64)_regs[VCPU_REGS_RCX] << 32) | 1394 | new = ((u64)_regs[VCPU_REGS_RCX] << 32) |
1390 | | (u32) _regs[VCPU_REGS_RBX]; | 1395 | | (u32) _regs[VCPU_REGS_RBX]; |
1391 | if ((rc = ops->cmpxchg_emulated(cr2, &old, | 1396 | if ((rc = ops->cmpxchg_emulated(cr2, &old, |
1392 | &new, 8, ctxt)) != 0) | 1397 | &new, 8, ctxt->vcpu)) != 0) |
1393 | goto done; | 1398 | goto done; |
1394 | _eflags |= EFLG_ZF; | 1399 | _eflags |= EFLG_ZF; |
1395 | } | 1400 | } |
diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h index 574cca70b22e..92c73aa7f9ac 100644 --- a/drivers/kvm/x86_emulate.h +++ b/drivers/kvm/x86_emulate.h | |||
@@ -60,7 +60,7 @@ struct x86_emulate_ops { | |||
60 | * @bytes: [IN ] Number of bytes to read from memory. | 60 | * @bytes: [IN ] Number of bytes to read from memory. |
61 | */ | 61 | */ |
62 | int (*read_std)(unsigned long addr, void *val, | 62 | int (*read_std)(unsigned long addr, void *val, |
63 | unsigned int bytes, struct x86_emulate_ctxt * ctxt); | 63 | unsigned int bytes, struct kvm_vcpu *vcpu); |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * write_std: Write bytes of standard (non-emulated/special) memory. | 66 | * write_std: Write bytes of standard (non-emulated/special) memory. |
@@ -71,7 +71,7 @@ struct x86_emulate_ops { | |||
71 | * @bytes: [IN ] Number of bytes to write to memory. | 71 | * @bytes: [IN ] Number of bytes to write to memory. |
72 | */ | 72 | */ |
73 | int (*write_std)(unsigned long addr, const void *val, | 73 | int (*write_std)(unsigned long addr, const void *val, |
74 | unsigned int bytes, struct x86_emulate_ctxt * ctxt); | 74 | unsigned int bytes, struct kvm_vcpu *vcpu); |
75 | 75 | ||
76 | /* | 76 | /* |
77 | * read_emulated: Read bytes from emulated/special memory area. | 77 | * read_emulated: Read bytes from emulated/special memory area. |
@@ -82,7 +82,7 @@ struct x86_emulate_ops { | |||
82 | int (*read_emulated) (unsigned long addr, | 82 | int (*read_emulated) (unsigned long addr, |
83 | void *val, | 83 | void *val, |
84 | unsigned int bytes, | 84 | unsigned int bytes, |
85 | struct x86_emulate_ctxt * ctxt); | 85 | struct kvm_vcpu *vcpu); |
86 | 86 | ||
87 | /* | 87 | /* |
88 | * write_emulated: Read bytes from emulated/special memory area. | 88 | * write_emulated: Read bytes from emulated/special memory area. |
@@ -94,7 +94,7 @@ struct x86_emulate_ops { | |||
94 | int (*write_emulated) (unsigned long addr, | 94 | int (*write_emulated) (unsigned long addr, |
95 | const void *val, | 95 | const void *val, |
96 | unsigned int bytes, | 96 | unsigned int bytes, |
97 | struct x86_emulate_ctxt * ctxt); | 97 | struct kvm_vcpu *vcpu); |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an | 100 | * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an |
@@ -108,7 +108,7 @@ struct x86_emulate_ops { | |||
108 | const void *old, | 108 | const void *old, |
109 | const void *new, | 109 | const void *new, |
110 | unsigned int bytes, | 110 | unsigned int bytes, |
111 | struct x86_emulate_ctxt * ctxt); | 111 | struct kvm_vcpu *vcpu); |
112 | 112 | ||
113 | }; | 113 | }; |
114 | 114 | ||