Commit fe25591e7b98386cce2c9ec8a8878947b50e3741
1 parent
0b6d3ae0
SH4: Privilege check for instructions
This patch adds check for all SH4 instructions which are executed only in privileged mode. (Shin-ichiro KAWASAKI) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5224 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
47 additions
and
25 deletions
cpu-exec.c
@@ -209,7 +209,10 @@ static inline TranslationBlock *tb_find_fast(void) | @@ -209,7 +209,10 @@ static inline TranslationBlock *tb_find_fast(void) | ||
209 | cs_base = 0; | 209 | cs_base = 0; |
210 | pc = env->pc; | 210 | pc = env->pc; |
211 | #elif defined(TARGET_SH4) | 211 | #elif defined(TARGET_SH4) |
212 | - flags = env->flags; | 212 | + flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL |
213 | + | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */ | ||
214 | + | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */ | ||
215 | + | (env->sr & (SR_MD | SR_RB)); /* Bits 29-30 */ | ||
213 | cs_base = 0; | 216 | cs_base = 0; |
214 | pc = env->pc; | 217 | pc = env->pc; |
215 | #elif defined(TARGET_ALPHA) | 218 | #elif defined(TARGET_ALPHA) |
target-sh4/translate.c
@@ -48,6 +48,12 @@ typedef struct DisasContext { | @@ -48,6 +48,12 @@ typedef struct DisasContext { | ||
48 | int singlestep_enabled; | 48 | int singlestep_enabled; |
49 | } DisasContext; | 49 | } DisasContext; |
50 | 50 | ||
51 | +#if defined(CONFIG_USER_ONLY) | ||
52 | +#define IS_USER(ctx) 1 | ||
53 | +#else | ||
54 | +#define IS_USER(ctx) (!(ctx->sr & SR_MD)) | ||
55 | +#endif | ||
56 | + | ||
51 | enum { | 57 | enum { |
52 | BS_NONE = 0, /* We go out of the TB without reaching a branch or an | 58 | BS_NONE = 0, /* We go out of the TB without reaching a branch or an |
53 | * exception condition | 59 | * exception condition |
@@ -449,6 +455,13 @@ static inline void gen_store_fpr64 (TCGv t, int reg) | @@ -449,6 +455,13 @@ static inline void gen_store_fpr64 (TCGv t, int reg) | ||
449 | {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \ | 455 | {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \ |
450 | return;} | 456 | return;} |
451 | 457 | ||
458 | +#define CHECK_PRIVILEGED \ | ||
459 | + if (IS_USER(ctx)) { \ | ||
460 | + tcg_gen_helper_0_0(helper_raise_illegal_instruction); \ | ||
461 | + ctx->bstate = BS_EXCP; \ | ||
462 | + return; \ | ||
463 | + } | ||
464 | + | ||
452 | void _decode_opc(DisasContext * ctx) | 465 | void _decode_opc(DisasContext * ctx) |
453 | { | 466 | { |
454 | #if 0 | 467 | #if 0 |
@@ -475,13 +488,11 @@ void _decode_opc(DisasContext * ctx) | @@ -475,13 +488,11 @@ void _decode_opc(DisasContext * ctx) | ||
475 | gen_clr_t(); | 488 | gen_clr_t(); |
476 | return; | 489 | return; |
477 | case 0x0038: /* ldtlb */ | 490 | case 0x0038: /* ldtlb */ |
478 | -#if defined(CONFIG_USER_ONLY) | ||
479 | - assert(0); /* XXXXX */ | ||
480 | -#else | 491 | + CHECK_PRIVILEGED |
481 | tcg_gen_helper_0_0(helper_ldtlb); | 492 | tcg_gen_helper_0_0(helper_ldtlb); |
482 | -#endif | ||
483 | return; | 493 | return; |
484 | case 0x002b: /* rte */ | 494 | case 0x002b: /* rte */ |
495 | + CHECK_PRIVILEGED | ||
485 | CHECK_NOT_DELAY_SLOT | 496 | CHECK_NOT_DELAY_SLOT |
486 | tcg_gen_mov_i32(cpu_sr, cpu_ssr); | 497 | tcg_gen_mov_i32(cpu_sr, cpu_ssr); |
487 | tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc); | 498 | tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc); |
@@ -505,12 +516,8 @@ void _decode_opc(DisasContext * ctx) | @@ -505,12 +516,8 @@ void _decode_opc(DisasContext * ctx) | ||
505 | case 0x0009: /* nop */ | 516 | case 0x0009: /* nop */ |
506 | return; | 517 | return; |
507 | case 0x001b: /* sleep */ | 518 | case 0x001b: /* sleep */ |
508 | - if (ctx->memidx) { | ||
509 | - tcg_gen_helper_0_1(helper_sleep, tcg_const_i32(ctx->pc + 2)); | ||
510 | - } else { | ||
511 | - tcg_gen_helper_0_0(helper_raise_illegal_instruction); | ||
512 | - ctx->bstate = BS_EXCP; | ||
513 | - } | 519 | + CHECK_PRIVILEGED |
520 | + tcg_gen_helper_0_1(helper_sleep, tcg_const_i32(ctx->pc + 2)); | ||
514 | return; | 521 | return; |
515 | } | 522 | } |
516 | 523 | ||
@@ -1351,16 +1358,20 @@ void _decode_opc(DisasContext * ctx) | @@ -1351,16 +1358,20 @@ void _decode_opc(DisasContext * ctx) | ||
1351 | 1358 | ||
1352 | switch (ctx->opcode & 0xf08f) { | 1359 | switch (ctx->opcode & 0xf08f) { |
1353 | case 0x408e: /* ldc Rm,Rn_BANK */ | 1360 | case 0x408e: /* ldc Rm,Rn_BANK */ |
1361 | + CHECK_PRIVILEGED | ||
1354 | tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8)); | 1362 | tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8)); |
1355 | return; | 1363 | return; |
1356 | case 0x4087: /* ldc.l @Rm+,Rn_BANK */ | 1364 | case 0x4087: /* ldc.l @Rm+,Rn_BANK */ |
1365 | + CHECK_PRIVILEGED | ||
1357 | tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx); | 1366 | tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx); |
1358 | tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); | 1367 | tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); |
1359 | return; | 1368 | return; |
1360 | case 0x0082: /* stc Rm_BANK,Rn */ | 1369 | case 0x0082: /* stc Rm_BANK,Rn */ |
1370 | + CHECK_PRIVILEGED | ||
1361 | tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4)); | 1371 | tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4)); |
1362 | return; | 1372 | return; |
1363 | case 0x4083: /* stc.l Rm_BANK,@-Rn */ | 1373 | case 0x4083: /* stc.l Rm_BANK,@-Rn */ |
1374 | + CHECK_PRIVILEGED | ||
1364 | { | 1375 | { |
1365 | TCGv addr = tcg_temp_new(TCG_TYPE_I32); | 1376 | TCGv addr = tcg_temp_new(TCG_TYPE_I32); |
1366 | tcg_gen_subi_i32(addr, REG(B11_8), 4); | 1377 | tcg_gen_subi_i32(addr, REG(B11_8), 4); |
@@ -1408,11 +1419,13 @@ void _decode_opc(DisasContext * ctx) | @@ -1408,11 +1419,13 @@ void _decode_opc(DisasContext * ctx) | ||
1408 | ctx->flags |= DELAY_SLOT; | 1419 | ctx->flags |= DELAY_SLOT; |
1409 | ctx->delayed_pc = (uint32_t) - 1; | 1420 | ctx->delayed_pc = (uint32_t) - 1; |
1410 | return; | 1421 | return; |
1411 | - case 0x400e: /* lds Rm,SR */ | 1422 | + case 0x400e: /* ldc Rm,SR */ |
1423 | + CHECK_PRIVILEGED | ||
1412 | tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3); | 1424 | tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3); |
1413 | ctx->bstate = BS_STOP; | 1425 | ctx->bstate = BS_STOP; |
1414 | return; | 1426 | return; |
1415 | - case 0x4007: /* lds.l @Rm+,SR */ | 1427 | + case 0x4007: /* ldc.l @Rm+,SR */ |
1428 | + CHECK_PRIVILEGED | ||
1416 | { | 1429 | { |
1417 | TCGv val = tcg_temp_new(TCG_TYPE_I32); | 1430 | TCGv val = tcg_temp_new(TCG_TYPE_I32); |
1418 | tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx); | 1431 | tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx); |
@@ -1422,10 +1435,12 @@ void _decode_opc(DisasContext * ctx) | @@ -1422,10 +1435,12 @@ void _decode_opc(DisasContext * ctx) | ||
1422 | ctx->bstate = BS_STOP; | 1435 | ctx->bstate = BS_STOP; |
1423 | } | 1436 | } |
1424 | return; | 1437 | return; |
1425 | - case 0x0002: /* sts SR,Rn */ | 1438 | + case 0x0002: /* stc SR,Rn */ |
1439 | + CHECK_PRIVILEGED | ||
1426 | tcg_gen_mov_i32(REG(B11_8), cpu_sr); | 1440 | tcg_gen_mov_i32(REG(B11_8), cpu_sr); |
1427 | return; | 1441 | return; |
1428 | - case 0x4003: /* sts SR,@-Rn */ | 1442 | + case 0x4003: /* stc SR,@-Rn */ |
1443 | + CHECK_PRIVILEGED | ||
1429 | { | 1444 | { |
1430 | TCGv addr = tcg_temp_new(TCG_TYPE_I32); | 1445 | TCGv addr = tcg_temp_new(TCG_TYPE_I32); |
1431 | tcg_gen_subi_i32(addr, REG(B11_8), 4); | 1446 | tcg_gen_subi_i32(addr, REG(B11_8), 4); |
@@ -1434,18 +1449,22 @@ void _decode_opc(DisasContext * ctx) | @@ -1434,18 +1449,22 @@ void _decode_opc(DisasContext * ctx) | ||
1434 | tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4); | 1449 | tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4); |
1435 | } | 1450 | } |
1436 | return; | 1451 | return; |
1437 | -#define LDST(reg,ldnum,ldpnum,stnum,stpnum) \ | 1452 | +#define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk) \ |
1438 | case ldnum: \ | 1453 | case ldnum: \ |
1454 | + prechk \ | ||
1439 | tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \ | 1455 | tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \ |
1440 | return; \ | 1456 | return; \ |
1441 | case ldpnum: \ | 1457 | case ldpnum: \ |
1458 | + prechk \ | ||
1442 | tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx); \ | 1459 | tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx); \ |
1443 | tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \ | 1460 | tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \ |
1444 | return; \ | 1461 | return; \ |
1445 | case stnum: \ | 1462 | case stnum: \ |
1463 | + prechk \ | ||
1446 | tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \ | 1464 | tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \ |
1447 | return; \ | 1465 | return; \ |
1448 | case stpnum: \ | 1466 | case stpnum: \ |
1467 | + prechk \ | ||
1449 | { \ | 1468 | { \ |
1450 | TCGv addr = tcg_temp_new(TCG_TYPE_I32); \ | 1469 | TCGv addr = tcg_temp_new(TCG_TYPE_I32); \ |
1451 | tcg_gen_subi_i32(addr, REG(B11_8), 4); \ | 1470 | tcg_gen_subi_i32(addr, REG(B11_8), 4); \ |
@@ -1454,15 +1473,15 @@ void _decode_opc(DisasContext * ctx) | @@ -1454,15 +1473,15 @@ void _decode_opc(DisasContext * ctx) | ||
1454 | tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4); \ | 1473 | tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4); \ |
1455 | } \ | 1474 | } \ |
1456 | return; | 1475 | return; |
1457 | - LDST(gbr, 0x401e, 0x4017, 0x0012, 0x4013) | ||
1458 | - LDST(vbr, 0x402e, 0x4027, 0x0022, 0x4023) | ||
1459 | - LDST(ssr, 0x403e, 0x4037, 0x0032, 0x4033) | ||
1460 | - LDST(spc, 0x404e, 0x4047, 0x0042, 0x4043) | ||
1461 | - LDST(dbr, 0x40fa, 0x40f6, 0x00fa, 0x40f2) | ||
1462 | - LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002) | ||
1463 | - LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012) | ||
1464 | - LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022) | ||
1465 | - LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052) | 1476 | + LDST(gbr, 0x401e, 0x4017, 0x0012, 0x4013, {}) |
1477 | + LDST(vbr, 0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED) | ||
1478 | + LDST(ssr, 0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED) | ||
1479 | + LDST(spc, 0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED) | ||
1480 | + LDST(dbr, 0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED) | ||
1481 | + LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {}) | ||
1482 | + LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {}) | ||
1483 | + LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022, {}) | ||
1484 | + LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {}) | ||
1466 | case 0x406a: /* lds Rm,FPSCR */ | 1485 | case 0x406a: /* lds Rm,FPSCR */ |
1467 | tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8)); | 1486 | tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8)); |
1468 | ctx->bstate = BS_STOP; | 1487 | ctx->bstate = BS_STOP; |