aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorCarsten Otte <cotte@de.ibm.com>2007-10-30 13:44:21 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:58 -0500
commitbbd9b64e37aff5aa715ec5e168425790f5983bf1 (patch)
treead69fb6e400801430e7a69019bd8fc40599ff20d /drivers
parent15c4a6406f6c40632260861e1db7c539e79dcf1a (diff)
KVM: Portability: Move x86 emulation and mmio device hook to x86.c
This patch moves the following functions to from kvm_main.c to x86.c: emulator_read/write_std, vcpu_find_pervcpu_dev, vcpu_find_mmio_dev, emulator_read/write_emulated, emulator_write_phys, emulator_write_emulated_onepage, emulator_cmpxchg_emulated, get_setment_base, emulate_invlpg, emulate_clts, emulator_get/set_dr, kvm_report_emulation_failure, emulate_instruction The following data type is moved to x86.c: struct x86_emulate_ops emulate_ops Signed-off-by: Carsten Otte <cotte@de.ibm.com> Acked-by: Hollis Blanchard <hollisb@us.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/kvm/kvm_main.c357
-rw-r--r--drivers/kvm/x86.c358
2 files changed, 358 insertions, 357 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 7acf4cb07793..1a56d76560de 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -827,369 +827,12 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
827 } 827 }
828} 828}
829 829
830int emulator_read_std(unsigned long addr,
831 void *val,
832 unsigned int bytes,
833 struct kvm_vcpu *vcpu)
834{
835 void *data = val;
836
837 while (bytes) {
838 gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
839 unsigned offset = addr & (PAGE_SIZE-1);
840 unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
841 int ret;
842
843 if (gpa == UNMAPPED_GVA)
844 return X86EMUL_PROPAGATE_FAULT;
845 ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy);
846 if (ret < 0)
847 return X86EMUL_UNHANDLEABLE;
848
849 bytes -= tocopy;
850 data += tocopy;
851 addr += tocopy;
852 }
853
854 return X86EMUL_CONTINUE;
855}
856EXPORT_SYMBOL_GPL(emulator_read_std);
857
858static int emulator_write_std(unsigned long addr,
859 const void *val,
860 unsigned int bytes,
861 struct kvm_vcpu *vcpu)
862{
863 pr_unimpl(vcpu, "emulator_write_std: addr %lx n %d\n", addr, bytes);
864 return X86EMUL_UNHANDLEABLE;
865}
866
867/*
868 * Only apic need an MMIO device hook, so shortcut now..
869 */
870static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
871 gpa_t addr)
872{
873 struct kvm_io_device *dev;
874
875 if (vcpu->apic) {
876 dev = &vcpu->apic->dev;
877 if (dev->in_range(dev, addr))
878 return dev;
879 }
880 return NULL;
881}
882
883static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
884 gpa_t addr)
885{
886 struct kvm_io_device *dev;
887
888 dev = vcpu_find_pervcpu_dev(vcpu, addr);
889 if (dev == NULL)
890 dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
891 return dev;
892}
893
894static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, 830static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
895 gpa_t addr) 831 gpa_t addr)
896{ 832{
897 return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr); 833 return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr);
898} 834}
899 835
900static int emulator_read_emulated(unsigned long addr,
901 void *val,
902 unsigned int bytes,
903 struct kvm_vcpu *vcpu)
904{
905 struct kvm_io_device *mmio_dev;
906 gpa_t gpa;
907
908 if (vcpu->mmio_read_completed) {
909 memcpy(val, vcpu->mmio_data, bytes);
910 vcpu->mmio_read_completed = 0;
911 return X86EMUL_CONTINUE;
912 }
913
914 gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
915
916 /* For APIC access vmexit */
917 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
918 goto mmio;
919
920 if (emulator_read_std(addr, val, bytes, vcpu)
921 == X86EMUL_CONTINUE)
922 return X86EMUL_CONTINUE;
923 if (gpa == UNMAPPED_GVA)
924 return X86EMUL_PROPAGATE_FAULT;
925
926mmio:
927 /*
928 * Is this MMIO handled locally?
929 */
930 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
931 if (mmio_dev) {
932 kvm_iodevice_read(mmio_dev, gpa, bytes, val);
933 return X86EMUL_CONTINUE;
934 }
935
936 vcpu->mmio_needed = 1;
937 vcpu->mmio_phys_addr = gpa;
938 vcpu->mmio_size = bytes;
939 vcpu->mmio_is_write = 0;
940
941 return X86EMUL_UNHANDLEABLE;
942}
943
944static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
945 const void *val, int bytes)
946{
947 int ret;
948
949 ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
950 if (ret < 0)
951 return 0;
952 kvm_mmu_pte_write(vcpu, gpa, val, bytes);
953 return 1;
954}
955
956static int emulator_write_emulated_onepage(unsigned long addr,
957 const void *val,
958 unsigned int bytes,
959 struct kvm_vcpu *vcpu)
960{
961 struct kvm_io_device *mmio_dev;
962 gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
963
964 if (gpa == UNMAPPED_GVA) {
965 kvm_x86_ops->inject_page_fault(vcpu, addr, 2);
966 return X86EMUL_PROPAGATE_FAULT;
967 }
968
969 /* For APIC access vmexit */
970 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
971 goto mmio;
972
973 if (emulator_write_phys(vcpu, gpa, val, bytes))
974 return X86EMUL_CONTINUE;
975
976mmio:
977 /*
978 * Is this MMIO handled locally?
979 */
980 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
981 if (mmio_dev) {
982 kvm_iodevice_write(mmio_dev, gpa, bytes, val);
983 return X86EMUL_CONTINUE;
984 }
985
986 vcpu->mmio_needed = 1;
987 vcpu->mmio_phys_addr = gpa;
988 vcpu->mmio_size = bytes;
989 vcpu->mmio_is_write = 1;
990 memcpy(vcpu->mmio_data, val, bytes);
991
992 return X86EMUL_CONTINUE;
993}
994
995int emulator_write_emulated(unsigned long addr,
996 const void *val,
997 unsigned int bytes,
998 struct kvm_vcpu *vcpu)
999{
1000 /* Crossing a page boundary? */
1001 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
1002 int rc, now;
1003
1004 now = -addr & ~PAGE_MASK;
1005 rc = emulator_write_emulated_onepage(addr, val, now, vcpu);
1006 if (rc != X86EMUL_CONTINUE)
1007 return rc;
1008 addr += now;
1009 val += now;
1010 bytes -= now;
1011 }
1012 return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
1013}
1014EXPORT_SYMBOL_GPL(emulator_write_emulated);
1015
1016static int emulator_cmpxchg_emulated(unsigned long addr,
1017 const void *old,
1018 const void *new,
1019 unsigned int bytes,
1020 struct kvm_vcpu *vcpu)
1021{
1022 static int reported;
1023
1024 if (!reported) {
1025 reported = 1;
1026 printk(KERN_WARNING "kvm: emulating exchange as write\n");
1027 }
1028 return emulator_write_emulated(addr, new, bytes, vcpu);
1029}
1030
1031static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
1032{
1033 return kvm_x86_ops->get_segment_base(vcpu, seg);
1034}
1035
1036int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
1037{
1038 return X86EMUL_CONTINUE;
1039}
1040
1041int emulate_clts(struct kvm_vcpu *vcpu)
1042{
1043 kvm_x86_ops->set_cr0(vcpu, vcpu->cr0 & ~X86_CR0_TS);
1044 return X86EMUL_CONTINUE;
1045}
1046
1047int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest)
1048{
1049 struct kvm_vcpu *vcpu = ctxt->vcpu;
1050
1051 switch (dr) {
1052 case 0 ... 3:
1053 *dest = kvm_x86_ops->get_dr(vcpu, dr);
1054 return X86EMUL_CONTINUE;
1055 default:
1056 pr_unimpl(vcpu, "%s: unexpected dr %u\n", __FUNCTION__, dr);
1057 return X86EMUL_UNHANDLEABLE;
1058 }
1059}
1060
1061int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
1062{
1063 unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U;
1064 int exception;
1065
1066 kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask, &exception);
1067 if (exception) {
1068 /* FIXME: better handling */
1069 return X86EMUL_UNHANDLEABLE;
1070 }
1071 return X86EMUL_CONTINUE;
1072}
1073
1074void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
1075{
1076 static int reported;
1077 u8 opcodes[4];
1078 unsigned long rip = vcpu->rip;
1079 unsigned long rip_linear;
1080
1081 rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
1082
1083 if (reported)
1084 return;
1085
1086 emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu);
1087
1088 printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
1089 context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
1090 reported = 1;
1091}
1092EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
1093
1094struct x86_emulate_ops emulate_ops = {
1095 .read_std = emulator_read_std,
1096 .write_std = emulator_write_std,
1097 .read_emulated = emulator_read_emulated,
1098 .write_emulated = emulator_write_emulated,
1099 .cmpxchg_emulated = emulator_cmpxchg_emulated,
1100};
1101
1102int emulate_instruction(struct kvm_vcpu *vcpu,
1103 struct kvm_run *run,
1104 unsigned long cr2,
1105 u16 error_code,
1106 int no_decode)
1107{
1108 int r;
1109
1110 vcpu->mmio_fault_cr2 = cr2;
1111 kvm_x86_ops->cache_regs(vcpu);
1112
1113 vcpu->mmio_is_write = 0;
1114 vcpu->pio.string = 0;
1115
1116 if (!no_decode) {
1117 int cs_db, cs_l;
1118 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
1119
1120 vcpu->emulate_ctxt.vcpu = vcpu;
1121 vcpu->emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
1122 vcpu->emulate_ctxt.cr2 = cr2;
1123 vcpu->emulate_ctxt.mode =
1124 (vcpu->emulate_ctxt.eflags & X86_EFLAGS_VM)
1125 ? X86EMUL_MODE_REAL : cs_l
1126 ? X86EMUL_MODE_PROT64 : cs_db
1127 ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
1128
1129 if (vcpu->emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
1130 vcpu->emulate_ctxt.cs_base = 0;
1131 vcpu->emulate_ctxt.ds_base = 0;
1132 vcpu->emulate_ctxt.es_base = 0;
1133 vcpu->emulate_ctxt.ss_base = 0;
1134 } else {
1135 vcpu->emulate_ctxt.cs_base =
1136 get_segment_base(vcpu, VCPU_SREG_CS);
1137 vcpu->emulate_ctxt.ds_base =
1138 get_segment_base(vcpu, VCPU_SREG_DS);
1139 vcpu->emulate_ctxt.es_base =
1140 get_segment_base(vcpu, VCPU_SREG_ES);
1141 vcpu->emulate_ctxt.ss_base =
1142 get_segment_base(vcpu, VCPU_SREG_SS);
1143 }
1144
1145 vcpu->emulate_ctxt.gs_base =
1146 get_segment_base(vcpu, VCPU_SREG_GS);
1147 vcpu->emulate_ctxt.fs_base =
1148 get_segment_base(vcpu, VCPU_SREG_FS);
1149
1150 r = x86_decode_insn(&vcpu->emulate_ctxt, &emulate_ops);
1151 if (r) {
1152 if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
1153 return EMULATE_DONE;
1154 return EMULATE_FAIL;
1155 }
1156 }
1157
1158 r = x86_emulate_insn(&vcpu->emulate_ctxt, &emulate_ops);
1159
1160 if (vcpu->pio.string)
1161 return EMULATE_DO_MMIO;
1162
1163 if ((r || vcpu->mmio_is_write) && run) {
1164 run->exit_reason = KVM_EXIT_MMIO;
1165 run->mmio.phys_addr = vcpu->mmio_phys_addr;
1166 memcpy(run->mmio.data, vcpu->mmio_data, 8);
1167 run->mmio.len = vcpu->mmio_size;
1168 run->mmio.is_write = vcpu->mmio_is_write;
1169 }
1170
1171 if (r) {
1172 if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
1173 return EMULATE_DONE;
1174 if (!vcpu->mmio_needed) {
1175 kvm_report_emulation_failure(vcpu, "mmio");
1176 return EMULATE_FAIL;
1177 }
1178 return EMULATE_DO_MMIO;
1179 }
1180
1181 kvm_x86_ops->decache_regs(vcpu);
1182 kvm_x86_ops->set_rflags(vcpu, vcpu->emulate_ctxt.eflags);
1183
1184 if (vcpu->mmio_is_write) {
1185 vcpu->mmio_needed = 0;
1186 return EMULATE_DO_MMIO;
1187 }
1188
1189 return EMULATE_DONE;
1190}
1191EXPORT_SYMBOL_GPL(emulate_instruction);
1192
1193/* 836/*
1194 * The vCPU has executed a HLT instruction with in-kernel mode enabled. 837 * The vCPU has executed a HLT instruction with in-kernel mode enabled.
1195 */ 838 */
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
index 786274347512..fe3733d8ece5 100644
--- a/drivers/kvm/x86.c
+++ b/drivers/kvm/x86.c
@@ -983,6 +983,364 @@ static __init void kvm_init_msr_list(void)
983 num_msrs_to_save = j; 983 num_msrs_to_save = j;
984} 984}
985 985
986/*
987 * Only apic need an MMIO device hook, so shortcut now..
988 */
989static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
990 gpa_t addr)
991{
992 struct kvm_io_device *dev;
993
994 if (vcpu->apic) {
995 dev = &vcpu->apic->dev;
996 if (dev->in_range(dev, addr))
997 return dev;
998 }
999 return NULL;
1000}
1001
1002
1003static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
1004 gpa_t addr)
1005{
1006 struct kvm_io_device *dev;
1007
1008 dev = vcpu_find_pervcpu_dev(vcpu, addr);
1009 if (dev == NULL)
1010 dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
1011 return dev;
1012}
1013
1014int emulator_read_std(unsigned long addr,
1015 void *val,
1016 unsigned int bytes,
1017 struct kvm_vcpu *vcpu)
1018{
1019 void *data = val;
1020
1021 while (bytes) {
1022 gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
1023 unsigned offset = addr & (PAGE_SIZE-1);
1024 unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
1025 int ret;
1026
1027 if (gpa == UNMAPPED_GVA)
1028 return X86EMUL_PROPAGATE_FAULT;
1029 ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy);
1030 if (ret < 0)
1031 return X86EMUL_UNHANDLEABLE;
1032
1033 bytes -= tocopy;
1034 data += tocopy;
1035 addr += tocopy;
1036 }
1037
1038 return X86EMUL_CONTINUE;
1039}
1040EXPORT_SYMBOL_GPL(emulator_read_std);
1041
1042static int emulator_write_std(unsigned long addr,
1043 const void *val,
1044 unsigned int bytes,
1045 struct kvm_vcpu *vcpu)
1046{
1047 pr_unimpl(vcpu, "emulator_write_std: addr %lx n %d\n", addr, bytes);
1048 return X86EMUL_UNHANDLEABLE;
1049}
1050
1051static int emulator_read_emulated(unsigned long addr,
1052 void *val,
1053 unsigned int bytes,
1054 struct kvm_vcpu *vcpu)
1055{
1056 struct kvm_io_device *mmio_dev;
1057 gpa_t gpa;
1058
1059 if (vcpu->mmio_read_completed) {
1060 memcpy(val, vcpu->mmio_data, bytes);
1061 vcpu->mmio_read_completed = 0;
1062 return X86EMUL_CONTINUE;
1063 }
1064
1065 gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
1066
1067 /* For APIC access vmexit */
1068 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
1069 goto mmio;
1070
1071 if (emulator_read_std(addr, val, bytes, vcpu)
1072 == X86EMUL_CONTINUE)
1073 return X86EMUL_CONTINUE;
1074 if (gpa == UNMAPPED_GVA)
1075 return X86EMUL_PROPAGATE_FAULT;
1076
1077mmio:
1078 /*
1079 * Is this MMIO handled locally?
1080 */
1081 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
1082 if (mmio_dev) {
1083 kvm_iodevice_read(mmio_dev, gpa, bytes, val);
1084 return X86EMUL_CONTINUE;
1085 }
1086
1087 vcpu->mmio_needed = 1;
1088 vcpu->mmio_phys_addr = gpa;
1089 vcpu->mmio_size = bytes;
1090 vcpu->mmio_is_write = 0;
1091
1092 return X86EMUL_UNHANDLEABLE;
1093}
1094
1095static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
1096 const void *val, int bytes)
1097{
1098 int ret;
1099
1100 ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
1101 if (ret < 0)
1102 return 0;
1103 kvm_mmu_pte_write(vcpu, gpa, val, bytes);
1104 return 1;
1105}
1106
1107static int emulator_write_emulated_onepage(unsigned long addr,
1108 const void *val,
1109 unsigned int bytes,
1110 struct kvm_vcpu *vcpu)
1111{
1112 struct kvm_io_device *mmio_dev;
1113 gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
1114
1115 if (gpa == UNMAPPED_GVA) {
1116 kvm_x86_ops->inject_page_fault(vcpu, addr, 2);
1117 return X86EMUL_PROPAGATE_FAULT;
1118 }
1119
1120 /* For APIC access vmexit */
1121 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
1122 goto mmio;
1123
1124 if (emulator_write_phys(vcpu, gpa, val, bytes))
1125 return X86EMUL_CONTINUE;
1126
1127mmio:
1128 /*
1129 * Is this MMIO handled locally?
1130 */
1131 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
1132 if (mmio_dev) {
1133 kvm_iodevice_write(mmio_dev, gpa, bytes, val);
1134 return X86EMUL_CONTINUE;
1135 }
1136
1137 vcpu->mmio_needed = 1;
1138 vcpu->mmio_phys_addr = gpa;
1139 vcpu->mmio_size = bytes;
1140 vcpu->mmio_is_write = 1;
1141 memcpy(vcpu->mmio_data, val, bytes);
1142
1143 return X86EMUL_CONTINUE;
1144}
1145
1146int emulator_write_emulated(unsigned long addr,
1147 const void *val,
1148 unsigned int bytes,
1149 struct kvm_vcpu *vcpu)
1150{
1151 /* Crossing a page boundary? */
1152 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
1153 int rc, now;
1154
1155 now = -addr & ~PAGE_MASK;
1156 rc = emulator_write_emulated_onepage(addr, val, now, vcpu);
1157 if (rc != X86EMUL_CONTINUE)
1158 return rc;
1159 addr += now;
1160 val += now;
1161 bytes -= now;
1162 }
1163 return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
1164}
1165EXPORT_SYMBOL_GPL(emulator_write_emulated);
1166
1167static int emulator_cmpxchg_emulated(unsigned long addr,
1168 const void *old,
1169 const void *new,
1170 unsigned int bytes,
1171 struct kvm_vcpu *vcpu)
1172{
1173 static int reported;
1174
1175 if (!reported) {
1176 reported = 1;
1177 printk(KERN_WARNING "kvm: emulating exchange as write\n");
1178 }
1179 return emulator_write_emulated(addr, new, bytes, vcpu);
1180}
1181
1182static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
1183{
1184 return kvm_x86_ops->get_segment_base(vcpu, seg);
1185}
1186
1187int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
1188{
1189 return X86EMUL_CONTINUE;
1190}
1191
1192int emulate_clts(struct kvm_vcpu *vcpu)
1193{
1194 kvm_x86_ops->set_cr0(vcpu, vcpu->cr0 & ~X86_CR0_TS);
1195 return X86EMUL_CONTINUE;
1196}
1197
1198int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest)
1199{
1200 struct kvm_vcpu *vcpu = ctxt->vcpu;
1201
1202 switch (dr) {
1203 case 0 ... 3:
1204 *dest = kvm_x86_ops->get_dr(vcpu, dr);
1205 return X86EMUL_CONTINUE;
1206 default:
1207 pr_unimpl(vcpu, "%s: unexpected dr %u\n", __FUNCTION__, dr);
1208 return X86EMUL_UNHANDLEABLE;
1209 }
1210}
1211
1212int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
1213{
1214 unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U;
1215 int exception;
1216
1217 kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask, &exception);
1218 if (exception) {
1219 /* FIXME: better handling */
1220 return X86EMUL_UNHANDLEABLE;
1221 }
1222 return X86EMUL_CONTINUE;
1223}
1224
1225void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
1226{
1227 static int reported;
1228 u8 opcodes[4];
1229 unsigned long rip = vcpu->rip;
1230 unsigned long rip_linear;
1231
1232 rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
1233
1234 if (reported)
1235 return;
1236
1237 emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu);
1238
1239 printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
1240 context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
1241 reported = 1;
1242}
1243EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
1244
1245struct x86_emulate_ops emulate_ops = {
1246 .read_std = emulator_read_std,
1247 .write_std = emulator_write_std,
1248 .read_emulated = emulator_read_emulated,
1249 .write_emulated = emulator_write_emulated,
1250 .cmpxchg_emulated = emulator_cmpxchg_emulated,
1251};
1252
1253int emulate_instruction(struct kvm_vcpu *vcpu,
1254 struct kvm_run *run,
1255 unsigned long cr2,
1256 u16 error_code,
1257 int no_decode)
1258{
1259 int r;
1260
1261 vcpu->mmio_fault_cr2 = cr2;
1262 kvm_x86_ops->cache_regs(vcpu);
1263
1264 vcpu->mmio_is_write = 0;
1265 vcpu->pio.string = 0;
1266
1267 if (!no_decode) {
1268 int cs_db, cs_l;
1269 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
1270
1271 vcpu->emulate_ctxt.vcpu = vcpu;
1272 vcpu->emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
1273 vcpu->emulate_ctxt.cr2 = cr2;
1274 vcpu->emulate_ctxt.mode =
1275 (vcpu->emulate_ctxt.eflags & X86_EFLAGS_VM)
1276 ? X86EMUL_MODE_REAL : cs_l
1277 ? X86EMUL_MODE_PROT64 : cs_db
1278 ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
1279
1280 if (vcpu->emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
1281 vcpu->emulate_ctxt.cs_base = 0;
1282 vcpu->emulate_ctxt.ds_base = 0;
1283 vcpu->emulate_ctxt.es_base = 0;
1284 vcpu->emulate_ctxt.ss_base = 0;
1285 } else {
1286 vcpu->emulate_ctxt.cs_base =
1287 get_segment_base(vcpu, VCPU_SREG_CS);
1288 vcpu->emulate_ctxt.ds_base =
1289 get_segment_base(vcpu, VCPU_SREG_DS);
1290 vcpu->emulate_ctxt.es_base =
1291 get_segment_base(vcpu, VCPU_SREG_ES);
1292 vcpu->emulate_ctxt.ss_base =
1293 get_segment_base(vcpu, VCPU_SREG_SS);
1294 }
1295
1296 vcpu->emulate_ctxt.gs_base =
1297 get_segment_base(vcpu, VCPU_SREG_GS);
1298 vcpu->emulate_ctxt.fs_base =
1299 get_segment_base(vcpu, VCPU_SREG_FS);
1300
1301 r = x86_decode_insn(&vcpu->emulate_ctxt, &emulate_ops);
1302 if (r) {
1303 if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
1304 return EMULATE_DONE;
1305 return EMULATE_FAIL;
1306 }
1307 }
1308
1309 r = x86_emulate_insn(&vcpu->emulate_ctxt, &emulate_ops);
1310
1311 if (vcpu->pio.string)
1312 return EMULATE_DO_MMIO;
1313
1314 if ((r || vcpu->mmio_is_write) && run) {
1315 run->exit_reason = KVM_EXIT_MMIO;
1316 run->mmio.phys_addr = vcpu->mmio_phys_addr;
1317 memcpy(run->mmio.data, vcpu->mmio_data, 8);
1318 run->mmio.len = vcpu->mmio_size;
1319 run->mmio.is_write = vcpu->mmio_is_write;
1320 }
1321
1322 if (r) {
1323 if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
1324 return EMULATE_DONE;
1325 if (!vcpu->mmio_needed) {
1326 kvm_report_emulation_failure(vcpu, "mmio");
1327 return EMULATE_FAIL;
1328 }
1329 return EMULATE_DO_MMIO;
1330 }
1331
1332 kvm_x86_ops->decache_regs(vcpu);
1333 kvm_x86_ops->set_rflags(vcpu, vcpu->emulate_ctxt.eflags);
1334
1335 if (vcpu->mmio_is_write) {
1336 vcpu->mmio_needed = 0;
1337 return EMULATE_DO_MMIO;
1338 }
1339
1340 return EMULATE_DONE;
1341}
1342EXPORT_SYMBOL_GPL(emulate_instruction);
1343
986__init void kvm_arch_init(void) 1344__init void kvm_arch_init(void)
987{ 1345{
988 kvm_init_msr_list(); 1346 kvm_init_msr_list();