[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 22/26] target-hppa: Implement linux-user gateway pag
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 22/26] target-hppa: Implement linux-user gateway page |
Date: |
Fri, 16 Dec 2016 11:14:01 -0800 |
For linux, page 0 is mapped as an execute-only gateway. A gateway
page is a special bit in the page table that allows a B,GATE insn
within that page to raise processor permissions. This is how system
calls are implemented for HPPA.
Rather than actually map anything here, or handle permissions at all,
implement the semantics of the actual linux syscall entry points.
Signed-off-by: Richard Henderson <address@hidden>
---
target-hppa/translate.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 81 insertions(+), 4 deletions(-)
diff --git a/target-hppa/translate.c b/target-hppa/translate.c
index 1d0976f..14fe4bb 100644
--- a/target-hppa/translate.c
+++ b/target-hppa/translate.c
@@ -1123,6 +1123,64 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv
dest,
return NO_EXIT;
}
+/* On Linux, page zero is normally marked execute only + gateway.
+ Therefore normal read or write is supposed to fail, but specific
+ offsets have kernel code mapped to raise permissions to implement
+ system calls. Handling this via an explicit check here, rather
+ in than the "be disp(sr2,r0)" instruction that probably sent us
+ here, is the easiest way to handle the branch delay slot on the
+ aforementioned BE. */
+static ExitStatus do_page_zero(DisasContext *ctx)
+{
+ /* If by some means we get here with PSW[N]=1, that implies that
+ the B,GATE instruction would be skipped, and we'd fault on the
+ next insn within the privilaged page. */
+ switch (ctx->null_cond.c) {
+ case TCG_COND_NEVER:
+ break;
+ case TCG_COND_ALWAYS:
+ tcg_gen_movi_tl(cpu_psw_n, 0);
+ goto do_sigill;
+ default:
+ /* Since this is always the first (and only) insn within the
+ TB, we should know the state of PSW[N] from TB->FLAGS. */
+ g_assert_not_reached();
+ }
+
+ /* Check that we didn't arrive here via some means that allowed
+ non-sequential instruction execution. Normally the PSW[B] bit
+ detects this by disallowing the B,GATE instruction to execute
+ under such conditions. */
+ if (ctx->iaoq_b != ctx->iaoq_f + 4) {
+ goto do_sigill;
+ }
+
+ switch (ctx->iaoq_f) {
+ case 0x00: /* Null pointer call */
+ gen_excp_1(EXCP_SIGSEGV);
+ return EXIT_NORETURN;
+
+ case 0xb0: /* LWS */
+ gen_excp_1(EXCP_SYSCALL_LWS);
+ return EXIT_NORETURN;
+
+ case 0xe0: /* SET_THREAD_POINTER */
+ tcg_gen_mov_tl(cpu_cr27, cpu_gr[26]);
+ tcg_gen_mov_tl(cpu_iaoq_f, cpu_gr[31]);
+ tcg_gen_addi_tl(cpu_iaoq_b, cpu_iaoq_f, 4);
+ return EXIT_IAQ_N_UPDATED;
+
+ case 0x100: /* SYSCALL */
+ gen_excp_1(EXCP_SYSCALL);
+ return EXIT_NORETURN;
+
+ default:
+ do_sigill:
+ gen_excp_1(EXCP_SIGILL);
+ return EXIT_NORETURN;
+ }
+}
+
static ExitStatus trans_nop(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
@@ -1884,7 +1942,10 @@ void gen_intermediate_code(CPUHPPAState *env, struct
TranslationBlock *tb)
gen_io_start();
}
- {
+ if (ctx.iaoq_f < TARGET_PAGE_SIZE) {
+ ret = do_page_zero(&ctx);
+ assert(ret != NO_EXIT);
+ } else {
/* Always fetch the insn, even if nullified, so that we check
the page permissions for execute. */
uint32_t insn = cpu_ldl_code(env, ctx.iaoq_f);
@@ -1986,9 +2047,25 @@ void gen_intermediate_code(CPUHPPAState *env, struct
TranslationBlock *tb)
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
&& qemu_log_in_addr_range(tb->pc)) {
qemu_log_lock();
- qemu_log("IN: %s\n", lookup_symbol(tb->pc));
- log_target_disas(cs, tb->pc, tb->size, 1);
- qemu_log("\n");
+ switch (tb->pc) {
+ case 0x00:
+ qemu_log("IN:\n0x00000000: (null)\n\n");
+ break;
+ case 0xb0:
+ qemu_log("IN:\n0x000000b0: light-weight-syscall\n\n");
+ break;
+ case 0xe0:
+ qemu_log("IN:\n0x000000e0: set-thread-pointer-syscall\n\n");
+ break;
+ case 0x100:
+ qemu_log("IN:\n0x00000100: syscall\n\n");
+ break;
+ default:
+ qemu_log("IN: %s\n", lookup_symbol(tb->pc));
+ log_target_disas(cs, tb->pc, tb->size, 1);
+ qemu_log("\n");
+ break;
+ }
qemu_log_unlock();
}
#endif
--
2.9.3
- [Qemu-devel] [PATCH 06/26] linux-user: Handle more IPV6 sockopts, (continued)
- [Qemu-devel] [PATCH 06/26] linux-user: Handle more IPV6 sockopts, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 03/26] linux-user: Handle TIOCSTART and TIOCSTOP, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 14/26] linux-user: Add HPPA target_signal.h and target_cpu.h, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 15/26] linux-user: Add HPPA signal handling, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 11/26] linux-user: Add HPPA target_syscall.h, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 12/26] linux-user: Add HPPA definitions to syscall_defs.h, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 13/26] linux-user: Add HPPA target_structs.h, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 10/26] linux-user: Add HPPA termbits.h, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 16/26] linux-user: Add HPPA startup and main loop, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 19/26] target-hppa: Add nullification framework, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 22/26] target-hppa: Implement linux-user gateway page,
Richard Henderson <=
- [Qemu-devel] [PATCH 23/26] target-hppa: Implement shifts and deposits, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 17/26] target-hppa: Add softfloat specializations, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 21/26] target-hppa: Implement branches, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 18/26] target-hppa: Add framework and enable compilation, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 25/26] target-hppa: Implement system and memory-management insns, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 20/26] target-hppa: Implement basic arithmetic, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 24/26] target-hppa: Implement loads and stores, Richard Henderson, 2016/12/16
- [Qemu-devel] [PATCH 01/26] Revert "Remove remainders of HPPA backend", Richard Henderson, 2016/12/16