emulate.c (d86c1ebe8e3d8a13aea9ce8437405d0ea3765698) | emulate.c (258f3a2ea93ff7e322006c716cedc4fa3d861453) |
---|---|
1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * KVM/MIPS: Instruction/Exception emulation 7 * 8 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. --- 958 unchanged lines hidden (view full) --- 967 if (cpu_has_fre) 968 mask |= MIPS_CONF5_FRE; 969 /* We don't support UFR or UFE */ 970 } 971 972 return mask; 973} 974 | 1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * KVM/MIPS: Instruction/Exception emulation 7 * 8 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. --- 958 unchanged lines hidden (view full) --- 967 if (cpu_has_fre) 968 mask |= MIPS_CONF5_FRE; 969 /* We don't support UFR or UFE */ 970 } 971 972 return mask; 973} 974 |
975enum emulation_result kvm_mips_emulate_CP0(u32 inst, u32 *opc, u32 cause, | 975enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst, 976 u32 *opc, u32 cause, |
976 struct kvm_run *run, 977 struct kvm_vcpu *vcpu) 978{ 979 struct mips_coproc *cop0 = vcpu->arch.cop0; 980 enum emulation_result er = EMULATE_DONE; | 977 struct kvm_run *run, 978 struct kvm_vcpu *vcpu) 979{ 980 struct mips_coproc *cop0 = vcpu->arch.cop0; 981 enum emulation_result er = EMULATE_DONE; |
981 u32 rt, rd, copz, sel, co_bit, op; | 982 u32 rt, rd, sel; |
982 unsigned long curr_pc; 983 984 /* 985 * Update PC and hold onto current PC in case there is 986 * an error and we want to rollback the PC 987 */ 988 curr_pc = vcpu->arch.pc; 989 er = update_pc(vcpu, cause); 990 if (er == EMULATE_FAIL) 991 return er; 992 | 983 unsigned long curr_pc; 984 985 /* 986 * Update PC and hold onto current PC in case there is 987 * an error and we want to rollback the PC 988 */ 989 curr_pc = vcpu->arch.pc; 990 er = update_pc(vcpu, cause); 991 if (er == EMULATE_FAIL) 992 return er; 993 |
993 copz = (inst >> 21) & 0x1f; 994 rt = (inst >> 16) & 0x1f; 995 rd = (inst >> 11) & 0x1f; 996 sel = inst & 0x7; 997 co_bit = (inst >> 25) & 1; 998 999 if (co_bit) { 1000 op = (inst) & 0xff; 1001 1002 switch (op) { | 994 if (inst.co_format.co) { 995 switch (inst.co_format.func) { |
1003 case tlbr_op: /* Read indexed TLB entry */ 1004 er = kvm_mips_emul_tlbr(vcpu); 1005 break; 1006 case tlbwi_op: /* Write indexed */ 1007 er = kvm_mips_emul_tlbwi(vcpu); 1008 break; 1009 case tlbwr_op: /* Write random */ 1010 er = kvm_mips_emul_tlbwr(vcpu); 1011 break; 1012 case tlbp_op: /* TLB Probe */ 1013 er = kvm_mips_emul_tlbp(vcpu); 1014 break; 1015 case rfe_op: 1016 kvm_err("!!!COP0_RFE!!!\n"); 1017 break; 1018 case eret_op: 1019 er = kvm_mips_emul_eret(vcpu); 1020 goto dont_update_pc; | 996 case tlbr_op: /* Read indexed TLB entry */ 997 er = kvm_mips_emul_tlbr(vcpu); 998 break; 999 case tlbwi_op: /* Write indexed */ 1000 er = kvm_mips_emul_tlbwi(vcpu); 1001 break; 1002 case tlbwr_op: /* Write random */ 1003 er = kvm_mips_emul_tlbwr(vcpu); 1004 break; 1005 case tlbp_op: /* TLB Probe */ 1006 er = kvm_mips_emul_tlbp(vcpu); 1007 break; 1008 case rfe_op: 1009 kvm_err("!!!COP0_RFE!!!\n"); 1010 break; 1011 case eret_op: 1012 er = kvm_mips_emul_eret(vcpu); 1013 goto dont_update_pc; |
1021 break; | |
1022 case wait_op: 1023 er = kvm_mips_emul_wait(vcpu); 1024 break; 1025 } 1026 } else { | 1014 case wait_op: 1015 er = kvm_mips_emul_wait(vcpu); 1016 break; 1017 } 1018 } else { |
1027 switch (copz) { | 1019 rt = inst.c0r_format.rt; 1020 rd = inst.c0r_format.rd; 1021 sel = inst.c0r_format.sel; 1022 1023 switch (inst.c0r_format.rs) { |
1028 case mfc_op: 1029#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS 1030 cop0->stat[rd][sel]++; 1031#endif 1032 /* Get reg */ 1033 if ((rd == MIPS_CP0_COUNT) && (sel == 0)) { 1034 vcpu->arch.gprs[rt] = kvm_mips_read_count(vcpu); 1035 } else if ((rd == MIPS_CP0_ERRCTL) && (sel == 0)) { --- 217 unchanged lines hidden (view full) --- 1253 case mfmc0_op: 1254#ifdef KVM_MIPS_DEBUG_COP0_COUNTERS 1255 cop0->stat[MIPS_CP0_STATUS][0]++; 1256#endif 1257 if (rt != 0) 1258 vcpu->arch.gprs[rt] = 1259 kvm_read_c0_guest_status(cop0); 1260 /* EI */ | 1024 case mfc_op: 1025#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS 1026 cop0->stat[rd][sel]++; 1027#endif 1028 /* Get reg */ 1029 if ((rd == MIPS_CP0_COUNT) && (sel == 0)) { 1030 vcpu->arch.gprs[rt] = kvm_mips_read_count(vcpu); 1031 } else if ((rd == MIPS_CP0_ERRCTL) && (sel == 0)) { --- 217 unchanged lines hidden (view full) --- 1249 case mfmc0_op: 1250#ifdef KVM_MIPS_DEBUG_COP0_COUNTERS 1251 cop0->stat[MIPS_CP0_STATUS][0]++; 1252#endif 1253 if (rt != 0) 1254 vcpu->arch.gprs[rt] = 1255 kvm_read_c0_guest_status(cop0); 1256 /* EI */ |
1261 if (inst & 0x20) { | 1257 if (inst.mfmc0_format.sc) { |
1262 kvm_debug("[%#lx] mfmc0_op: EI\n", 1263 vcpu->arch.pc); 1264 kvm_set_c0_guest_status(cop0, ST0_IE); 1265 } else { 1266 kvm_debug("[%#lx] mfmc0_op: DI\n", 1267 vcpu->arch.pc); 1268 kvm_clear_c0_guest_status(cop0, ST0_IE); 1269 } --- 15 unchanged lines hidden (view full) --- 1285 } 1286 kvm_debug("WRPGPR[%d][%d] = %#lx\n", pss, rd, 1287 vcpu->arch.gprs[rt]); 1288 vcpu->arch.gprs[rd] = vcpu->arch.gprs[rt]; 1289 } 1290 break; 1291 default: 1292 kvm_err("[%#lx]MachEmulateCP0: unsupported COP0, copz: 0x%x\n", | 1258 kvm_debug("[%#lx] mfmc0_op: EI\n", 1259 vcpu->arch.pc); 1260 kvm_set_c0_guest_status(cop0, ST0_IE); 1261 } else { 1262 kvm_debug("[%#lx] mfmc0_op: DI\n", 1263 vcpu->arch.pc); 1264 kvm_clear_c0_guest_status(cop0, ST0_IE); 1265 } --- 15 unchanged lines hidden (view full) --- 1281 } 1282 kvm_debug("WRPGPR[%d][%d] = %#lx\n", pss, rd, 1283 vcpu->arch.gprs[rt]); 1284 vcpu->arch.gprs[rd] = vcpu->arch.gprs[rt]; 1285 } 1286 break; 1287 default: 1288 kvm_err("[%#lx]MachEmulateCP0: unsupported COP0, copz: 0x%x\n", |
1293 vcpu->arch.pc, copz); | 1289 vcpu->arch.pc, inst.c0r_format.rs); |
1294 er = EMULATE_FAIL; 1295 break; 1296 } 1297 } 1298 1299done: 1300 /* Rollback PC only if emulation was unsuccessful */ 1301 if (er == EMULATE_FAIL) --- 4 unchanged lines hidden (view full) --- 1306 * This is for special instructions whose emulation 1307 * updates the PC, so do not overwrite the PC under 1308 * any circumstances 1309 */ 1310 1311 return er; 1312} 1313 | 1290 er = EMULATE_FAIL; 1291 break; 1292 } 1293 } 1294 1295done: 1296 /* Rollback PC only if emulation was unsuccessful */ 1297 if (er == EMULATE_FAIL) --- 4 unchanged lines hidden (view full) --- 1302 * This is for special instructions whose emulation 1303 * updates the PC, so do not overwrite the PC under 1304 * any circumstances 1305 */ 1306 1307 return er; 1308} 1309 |
1314enum emulation_result kvm_mips_emulate_store(u32 inst, u32 cause, | 1310enum emulation_result kvm_mips_emulate_store(union mips_instruction inst, 1311 u32 cause, |
1315 struct kvm_run *run, 1316 struct kvm_vcpu *vcpu) 1317{ 1318 enum emulation_result er = EMULATE_DO_MMIO; | 1312 struct kvm_run *run, 1313 struct kvm_vcpu *vcpu) 1314{ 1315 enum emulation_result er = EMULATE_DO_MMIO; |
1319 u32 op, base, rt; 1320 s16 offset; | 1316 u32 rt; |
1321 u32 bytes; 1322 void *data = run->mmio.data; 1323 unsigned long curr_pc; 1324 1325 /* 1326 * Update PC and hold onto current PC in case there is 1327 * an error and we want to rollback the PC 1328 */ 1329 curr_pc = vcpu->arch.pc; 1330 er = update_pc(vcpu, cause); 1331 if (er == EMULATE_FAIL) 1332 return er; 1333 | 1317 u32 bytes; 1318 void *data = run->mmio.data; 1319 unsigned long curr_pc; 1320 1321 /* 1322 * Update PC and hold onto current PC in case there is 1323 * an error and we want to rollback the PC 1324 */ 1325 curr_pc = vcpu->arch.pc; 1326 er = update_pc(vcpu, cause); 1327 if (er == EMULATE_FAIL) 1328 return er; 1329 |
1334 rt = (inst >> 16) & 0x1f; 1335 base = (inst >> 21) & 0x1f; 1336 offset = (s16)inst; 1337 op = (inst >> 26) & 0x3f; | 1330 rt = inst.i_format.rt; |
1338 | 1331 |
1339 switch (op) { | 1332 switch (inst.i_format.opcode) { |
1340 case sb_op: 1341 bytes = 1; 1342 if (bytes > sizeof(run->mmio.data)) { 1343 kvm_err("%s: bad MMIO length: %d\n", __func__, 1344 run->mmio.len); 1345 } 1346 run->mmio.phys_addr = 1347 kvm_mips_callbacks->gva_to_gpa(vcpu->arch. --- 60 unchanged lines hidden (view full) --- 1408 1409 kvm_debug("[%#lx] OP_SH: eaddr: %#lx, gpr: %#lx, data: %#x\n", 1410 vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, 1411 vcpu->arch.gprs[rt], *(u32 *) data); 1412 break; 1413 1414 default: 1415 kvm_err("Store not yet supported (inst=0x%08x)\n", | 1333 case sb_op: 1334 bytes = 1; 1335 if (bytes > sizeof(run->mmio.data)) { 1336 kvm_err("%s: bad MMIO length: %d\n", __func__, 1337 run->mmio.len); 1338 } 1339 run->mmio.phys_addr = 1340 kvm_mips_callbacks->gva_to_gpa(vcpu->arch. --- 60 unchanged lines hidden (view full) --- 1401 1402 kvm_debug("[%#lx] OP_SH: eaddr: %#lx, gpr: %#lx, data: %#x\n", 1403 vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, 1404 vcpu->arch.gprs[rt], *(u32 *) data); 1405 break; 1406 1407 default: 1408 kvm_err("Store not yet supported (inst=0x%08x)\n", |
1416 inst); | 1409 inst.word); |
1417 er = EMULATE_FAIL; 1418 break; 1419 } 1420 1421 /* Rollback PC if emulation was unsuccessful */ 1422 if (er == EMULATE_FAIL) 1423 vcpu->arch.pc = curr_pc; 1424 1425 return er; 1426} 1427 | 1410 er = EMULATE_FAIL; 1411 break; 1412 } 1413 1414 /* Rollback PC if emulation was unsuccessful */ 1415 if (er == EMULATE_FAIL) 1416 vcpu->arch.pc = curr_pc; 1417 1418 return er; 1419} 1420 |
1428enum emulation_result kvm_mips_emulate_load(u32 inst, u32 cause, 1429 struct kvm_run *run, | 1421enum emulation_result kvm_mips_emulate_load(union mips_instruction inst, 1422 u32 cause, struct kvm_run *run, |
1430 struct kvm_vcpu *vcpu) 1431{ 1432 enum emulation_result er = EMULATE_DO_MMIO; | 1423 struct kvm_vcpu *vcpu) 1424{ 1425 enum emulation_result er = EMULATE_DO_MMIO; |
1433 u32 op, base, rt; 1434 s16 offset; | 1426 u32 op, rt; |
1435 u32 bytes; 1436 | 1427 u32 bytes; 1428 |
1437 rt = (inst >> 16) & 0x1f; 1438 base = (inst >> 21) & 0x1f; 1439 offset = (s16)inst; 1440 op = (inst >> 26) & 0x3f; | 1429 rt = inst.i_format.rt; 1430 op = inst.i_format.opcode; |
1441 1442 vcpu->arch.pending_load_cause = cause; 1443 vcpu->arch.io_gpr = rt; 1444 1445 switch (op) { 1446 case lw_op: 1447 bytes = 4; 1448 if (bytes > sizeof(run->mmio.data)) { --- 70 unchanged lines hidden (view full) --- 1519 vcpu->mmio_needed = 2; 1520 else 1521 vcpu->mmio_needed = 1; 1522 1523 break; 1524 1525 default: 1526 kvm_err("Load not yet supported (inst=0x%08x)\n", | 1431 1432 vcpu->arch.pending_load_cause = cause; 1433 vcpu->arch.io_gpr = rt; 1434 1435 switch (op) { 1436 case lw_op: 1437 bytes = 4; 1438 if (bytes > sizeof(run->mmio.data)) { --- 70 unchanged lines hidden (view full) --- 1509 vcpu->mmio_needed = 2; 1510 else 1511 vcpu->mmio_needed = 1; 1512 1513 break; 1514 1515 default: 1516 kvm_err("Load not yet supported (inst=0x%08x)\n", |
1527 inst); | 1517 inst.word); |
1528 er = EMULATE_FAIL; 1529 break; 1530 } 1531 1532 return er; 1533} 1534 | 1518 er = EMULATE_FAIL; 1519 break; 1520 } 1521 1522 return er; 1523} 1524 |
1535enum emulation_result kvm_mips_emulate_cache(u32 inst, u32 *opc, 1536 u32 cause, | 1525enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst, 1526 u32 *opc, u32 cause, |
1537 struct kvm_run *run, 1538 struct kvm_vcpu *vcpu) 1539{ 1540 struct mips_coproc *cop0 = vcpu->arch.cop0; 1541 enum emulation_result er = EMULATE_DONE; 1542 u32 cache, op_inst, op, base; 1543 s16 offset; 1544 struct kvm_vcpu_arch *arch = &vcpu->arch; --- 4 unchanged lines hidden (view full) --- 1549 * Update PC and hold onto current PC in case there is 1550 * an error and we want to rollback the PC 1551 */ 1552 curr_pc = vcpu->arch.pc; 1553 er = update_pc(vcpu, cause); 1554 if (er == EMULATE_FAIL) 1555 return er; 1556 | 1527 struct kvm_run *run, 1528 struct kvm_vcpu *vcpu) 1529{ 1530 struct mips_coproc *cop0 = vcpu->arch.cop0; 1531 enum emulation_result er = EMULATE_DONE; 1532 u32 cache, op_inst, op, base; 1533 s16 offset; 1534 struct kvm_vcpu_arch *arch = &vcpu->arch; --- 4 unchanged lines hidden (view full) --- 1539 * Update PC and hold onto current PC in case there is 1540 * an error and we want to rollback the PC 1541 */ 1542 curr_pc = vcpu->arch.pc; 1543 er = update_pc(vcpu, cause); 1544 if (er == EMULATE_FAIL) 1545 return er; 1546 |
1557 base = (inst >> 21) & 0x1f; 1558 op_inst = (inst >> 16) & 0x1f; 1559 offset = (s16)inst; | 1547 base = inst.i_format.rs; 1548 op_inst = inst.i_format.rt; 1549 offset = inst.i_format.simmediate; |
1560 cache = op_inst & CacheOp_Cache; 1561 op = op_inst & CacheOp_Op; 1562 1563 va = arch->gprs[base] + offset; 1564 1565 kvm_debug("CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n", 1566 cache, op, base, arch->gprs[base], offset); 1567 --- 120 unchanged lines hidden (view full) --- 1688 1689 return er; 1690} 1691 1692enum emulation_result kvm_mips_emulate_inst(u32 cause, u32 *opc, 1693 struct kvm_run *run, 1694 struct kvm_vcpu *vcpu) 1695{ | 1550 cache = op_inst & CacheOp_Cache; 1551 op = op_inst & CacheOp_Op; 1552 1553 va = arch->gprs[base] + offset; 1554 1555 kvm_debug("CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n", 1556 cache, op, base, arch->gprs[base], offset); 1557 --- 120 unchanged lines hidden (view full) --- 1678 1679 return er; 1680} 1681 1682enum emulation_result kvm_mips_emulate_inst(u32 cause, u32 *opc, 1683 struct kvm_run *run, 1684 struct kvm_vcpu *vcpu) 1685{ |
1686 union mips_instruction inst; |
|
1696 enum emulation_result er = EMULATE_DONE; | 1687 enum emulation_result er = EMULATE_DONE; |
1697 u32 inst; | |
1698 1699 /* Fetch the instruction. */ 1700 if (cause & CAUSEF_BD) 1701 opc += 1; 1702 | 1688 1689 /* Fetch the instruction. */ 1690 if (cause & CAUSEF_BD) 1691 opc += 1; 1692 |
1703 inst = kvm_get_inst(opc, vcpu); | 1693 inst.word = kvm_get_inst(opc, vcpu); |
1704 | 1694 |
1705 switch (((union mips_instruction)inst).r_format.opcode) { | 1695 switch (inst.r_format.opcode) { |
1706 case cop0_op: 1707 er = kvm_mips_emulate_CP0(inst, opc, cause, run, vcpu); 1708 break; 1709 case sb_op: 1710 case sh_op: 1711 case sw_op: 1712 er = kvm_mips_emulate_store(inst, cause, run, vcpu); 1713 break; --- 8 unchanged lines hidden (view full) --- 1722 case cache_op: 1723 ++vcpu->stat.cache_exits; 1724 trace_kvm_exit(vcpu, KVM_TRACE_EXIT_CACHE); 1725 er = kvm_mips_emulate_cache(inst, opc, cause, run, vcpu); 1726 break; 1727 1728 default: 1729 kvm_err("Instruction emulation not supported (%p/%#x)\n", opc, | 1696 case cop0_op: 1697 er = kvm_mips_emulate_CP0(inst, opc, cause, run, vcpu); 1698 break; 1699 case sb_op: 1700 case sh_op: 1701 case sw_op: 1702 er = kvm_mips_emulate_store(inst, cause, run, vcpu); 1703 break; --- 8 unchanged lines hidden (view full) --- 1712 case cache_op: 1713 ++vcpu->stat.cache_exits; 1714 trace_kvm_exit(vcpu, KVM_TRACE_EXIT_CACHE); 1715 er = kvm_mips_emulate_cache(inst, opc, cause, run, vcpu); 1716 break; 1717 1718 default: 1719 kvm_err("Instruction emulation not supported (%p/%#x)\n", opc, |
1730 inst); | 1720 inst.word); |
1731 kvm_arch_vcpu_dump_regs(vcpu); 1732 er = EMULATE_FAIL; 1733 break; 1734 } 1735 1736 return er; 1737} 1738 --- 518 unchanged lines hidden (view full) --- 2257 } else { 2258 kvm_err("Trying to deliver MSADIS when EXL is already set\n"); 2259 er = EMULATE_FAIL; 2260 } 2261 2262 return er; 2263} 2264 | 1721 kvm_arch_vcpu_dump_regs(vcpu); 1722 er = EMULATE_FAIL; 1723 break; 1724 } 1725 1726 return er; 1727} 1728 --- 518 unchanged lines hidden (view full) --- 2247 } else { 2248 kvm_err("Trying to deliver MSADIS when EXL is already set\n"); 2249 er = EMULATE_FAIL; 2250 } 2251 2252 return er; 2253} 2254 |
2265/* ll/sc, rdhwr, sync emulation */ 2266 2267#define OPCODE 0xfc000000 2268#define BASE 0x03e00000 2269#define RT 0x001f0000 2270#define OFFSET 0x0000ffff 2271#define LL 0xc0000000 2272#define SC 0xe0000000 2273#define SPEC0 0x00000000 2274#define SPEC3 0x7c000000 2275#define RD 0x0000f800 2276#define FUNC 0x0000003f 2277#define SYNC 0x0000000f 2278#define RDHWR 0x0000003b 2279 | |
2280enum emulation_result kvm_mips_handle_ri(u32 cause, u32 *opc, 2281 struct kvm_run *run, 2282 struct kvm_vcpu *vcpu) 2283{ 2284 struct mips_coproc *cop0 = vcpu->arch.cop0; 2285 struct kvm_vcpu_arch *arch = &vcpu->arch; 2286 enum emulation_result er = EMULATE_DONE; 2287 unsigned long curr_pc; | 2255enum emulation_result kvm_mips_handle_ri(u32 cause, u32 *opc, 2256 struct kvm_run *run, 2257 struct kvm_vcpu *vcpu) 2258{ 2259 struct mips_coproc *cop0 = vcpu->arch.cop0; 2260 struct kvm_vcpu_arch *arch = &vcpu->arch; 2261 enum emulation_result er = EMULATE_DONE; 2262 unsigned long curr_pc; |
2288 u32 inst; | 2263 union mips_instruction inst; |
2289 2290 /* 2291 * Update PC and hold onto current PC in case there is 2292 * an error and we want to rollback the PC 2293 */ 2294 curr_pc = vcpu->arch.pc; 2295 er = update_pc(vcpu, cause); 2296 if (er == EMULATE_FAIL) 2297 return er; 2298 2299 /* Fetch the instruction. */ 2300 if (cause & CAUSEF_BD) 2301 opc += 1; 2302 | 2264 2265 /* 2266 * Update PC and hold onto current PC in case there is 2267 * an error and we want to rollback the PC 2268 */ 2269 curr_pc = vcpu->arch.pc; 2270 er = update_pc(vcpu, cause); 2271 if (er == EMULATE_FAIL) 2272 return er; 2273 2274 /* Fetch the instruction. */ 2275 if (cause & CAUSEF_BD) 2276 opc += 1; 2277 |
2303 inst = kvm_get_inst(opc, vcpu); | 2278 inst.word = kvm_get_inst(opc, vcpu); |
2304 | 2279 |
2305 if (inst == KVM_INVALID_INST) { | 2280 if (inst.word == KVM_INVALID_INST) { |
2306 kvm_err("%s: Cannot get inst @ %p\n", __func__, opc); 2307 return EMULATE_FAIL; 2308 } 2309 | 2281 kvm_err("%s: Cannot get inst @ %p\n", __func__, opc); 2282 return EMULATE_FAIL; 2283 } 2284 |
2310 if ((inst & OPCODE) == SPEC3 && (inst & FUNC) == RDHWR) { | 2285 if (inst.r_format.opcode == spec3_op && 2286 inst.r_format.func == rdhwr_op) { |
2311 int usermode = !KVM_GUEST_KERNEL_MODE(vcpu); | 2287 int usermode = !KVM_GUEST_KERNEL_MODE(vcpu); |
2312 int rd = (inst & RD) >> 11; 2313 int rt = (inst & RT) >> 16; 2314 int sel = (inst >> 6) & 0x7; | 2288 int rd = inst.r_format.rd; 2289 int rt = inst.r_format.rt; 2290 int sel = inst.r_format.re & 0x7; |
2315 2316 /* If usermode, check RDHWR rd is allowed by guest HWREna */ 2317 if (usermode && !(kvm_read_c0_guest_hwrena(cop0) & BIT(rd))) { 2318 kvm_debug("RDHWR %#x disallowed by HWREna @ %p\n", 2319 rd, opc); 2320 goto emulate_ri; 2321 } 2322 switch (rd) { --- 24 unchanged lines hidden (view full) --- 2347 default: 2348 kvm_debug("RDHWR %#x not supported @ %p\n", rd, opc); 2349 goto emulate_ri; 2350 } 2351 2352 trace_kvm_hwr(vcpu, KVM_TRACE_RDHWR, KVM_TRACE_HWR(rd, sel), 2353 vcpu->arch.gprs[rt]); 2354 } else { | 2291 2292 /* If usermode, check RDHWR rd is allowed by guest HWREna */ 2293 if (usermode && !(kvm_read_c0_guest_hwrena(cop0) & BIT(rd))) { 2294 kvm_debug("RDHWR %#x disallowed by HWREna @ %p\n", 2295 rd, opc); 2296 goto emulate_ri; 2297 } 2298 switch (rd) { --- 24 unchanged lines hidden (view full) --- 2323 default: 2324 kvm_debug("RDHWR %#x not supported @ %p\n", rd, opc); 2325 goto emulate_ri; 2326 } 2327 2328 trace_kvm_hwr(vcpu, KVM_TRACE_RDHWR, KVM_TRACE_HWR(rd, sel), 2329 vcpu->arch.gprs[rt]); 2330 } else { |
2355 kvm_debug("Emulate RI not supported @ %p: %#x\n", opc, inst); | 2331 kvm_debug("Emulate RI not supported @ %p: %#x\n", 2332 opc, inst.word); |
2356 goto emulate_ri; 2357 } 2358 2359 return EMULATE_DONE; 2360 2361emulate_ri: 2362 /* 2363 * Rollback PC (if in branch delay slot then the PC already points to --- 250 unchanged lines hidden --- | 2333 goto emulate_ri; 2334 } 2335 2336 return EMULATE_DONE; 2337 2338emulate_ri: 2339 /* 2340 * Rollback PC (if in branch delay slot then the PC already points to --- 250 unchanged lines hidden --- |