Import QEMU upstream snapshot d2e570c

Upstream: https://gitlab.com/qemu-project/qemu.git

Upstream-Commit: d2e570cc0f97b936902a5b1b86b73c0f5998b475
This commit is contained in:
2026-08-31 02:15:30 +02:00
commit cf256aa081
11315 changed files with 3598369 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
include $(BUILD_DIR)/tests/tcg/loongarch64-linux-user/config-target.mak
SUBDIR = $(SRC_PATH)/linux-user/loongarch64
VPATH += $(SUBDIR)
all: $(SUBDIR)/vdso.so
$(SUBDIR)/vdso.so: vdso.S vdso.ld vdso-asmoffset.h
$(CC) -o $@ -nostdlib -shared -fpic -Wl,-h,linux-vdso.so.1 \
-Wl,--build-id=sha1 -Wl,--hash-style=both \
-Wl,--no-warn-rwx-segments -Wl,-z,max-page-size=4096 \
-Wl,-T,$(SUBDIR)/vdso.ld $<
+131
View File
@@ -0,0 +1,131 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* QEMU LoongArch user cpu_loop.
*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
#include "user/cpu_loop.h"
#include "signal-common.h"
/* Break codes */
enum {
BRK_OVERFLOW = 6,
BRK_DIVZERO = 7
};
void cpu_loop(CPULoongArchState *env)
{
CPUSysState *sys = env_sys(env);
CPUState *cs = env_cpu(env);
int trapnr, si_code;
abi_long ret;
for (;;) {
cpu_exec_start(cs);
trapnr = cpu_exec(cs);
cpu_exec_end(cs);
qemu_process_cpu_events(cs);
switch (trapnr) {
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
case EXCCODE_SYS:
env->pc += 4;
ret = do_syscall(env, env->gpr[11],
env->gpr[4], env->gpr[5],
env->gpr[6], env->gpr[7],
env->gpr[8], env->gpr[9],
-1, -1);
if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 4;
break;
}
if (ret == -QEMU_ESIGRETURN || ret == -QEMU_ESETPC) {
/*
* Returning from a successful sigreturn syscall or from
* control flow diversion in a plugin callback.
* Avoid clobbering register state.
*/
break;
}
env->gpr[4] = ret;
break;
case EXCCODE_INE:
force_sig_fault(TARGET_SIGILL, 0, env->pc);
break;
case EXCCODE_FPE:
si_code = TARGET_FPE_FLTUNK;
if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
si_code = TARGET_FPE_FLTINV;
} else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) {
si_code = TARGET_FPE_FLTDIV;
} else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) {
si_code = TARGET_FPE_FLTOVF;
} else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) {
si_code = TARGET_FPE_FLTUND;
} else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) {
si_code = TARGET_FPE_FLTRES;
}
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
break;
case EXCP_DEBUG:
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCCODE_BRK:
{
unsigned int opcode;
get_user_u32(opcode, env->pc);
switch (opcode & 0x7fff) {
case BRK_OVERFLOW:
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, env->pc);
break;
case BRK_DIVZERO:
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->pc);
break;
default:
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
}
}
break;
case EXCCODE_BCE:
force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);
break;
/*
* Begin with LSX and LASX disabled, then enable on the first trap.
* In this way we can tell if the unit is in use. This is used to
* choose the layout of any signal frame.
*/
case EXCCODE_SXD:
sys->CSR_EUEN |= R_CSR_EUEN_SXE_MASK;
break;
case EXCCODE_ASXD:
sys->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK;
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
break;
default:
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
exit(EXIT_FAILURE);
}
process_pending_signals(env);
}
}
void init_main_thread(CPUState *cs, struct image_info *info)
{
CPUArchState *env = cpu_env(cs);
env->pc = info->entry;
env->gpr[3] = info->start_stack;
}
+100
View File
@@ -0,0 +1,100 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
{
return "la464";
}
/* See arch/loongarch/include/uapi/asm/hwcap.h */
enum {
HWCAP_LOONGARCH_CPUCFG = (1 << 0),
HWCAP_LOONGARCH_LAM = (1 << 1),
HWCAP_LOONGARCH_UAL = (1 << 2),
HWCAP_LOONGARCH_FPU = (1 << 3),
HWCAP_LOONGARCH_LSX = (1 << 4),
HWCAP_LOONGARCH_LASX = (1 << 5),
HWCAP_LOONGARCH_CRC32 = (1 << 6),
HWCAP_LOONGARCH_COMPLEX = (1 << 7),
HWCAP_LOONGARCH_CRYPTO = (1 << 8),
HWCAP_LOONGARCH_LVZ = (1 << 9),
HWCAP_LOONGARCH_LBT_X86 = (1 << 10),
HWCAP_LOONGARCH_LBT_ARM = (1 << 11),
HWCAP_LOONGARCH_LBT_MIPS = (1 << 12),
};
const char *elf_hwcap_str(uint32_t bit)
{
static const char *hwcap_str[] = {
[__builtin_ctz(HWCAP_LOONGARCH_CPUCFG )] = "cpucfg",
[__builtin_ctz(HWCAP_LOONGARCH_LAM )] = "lam",
[__builtin_ctz(HWCAP_LOONGARCH_UAL )] = "lam_bh",
[__builtin_ctz(HWCAP_LOONGARCH_FPU )] = "fpu",
[__builtin_ctz(HWCAP_LOONGARCH_LSX )] = "lsx",
[__builtin_ctz(HWCAP_LOONGARCH_LASX )] = "lasx",
[__builtin_ctz(HWCAP_LOONGARCH_CRC32 )] = "crc32",
[__builtin_ctz(HWCAP_LOONGARCH_COMPLEX )] = "complex",
[__builtin_ctz(HWCAP_LOONGARCH_CRYPTO )] = "crypto",
[__builtin_ctz(HWCAP_LOONGARCH_LVZ )] = "lvz",
[__builtin_ctz(HWCAP_LOONGARCH_LBT_X86 )] = "lbt_x86",
[__builtin_ctz(HWCAP_LOONGARCH_LBT_ARM )] = "lbt_arm",
[__builtin_ctz(HWCAP_LOONGARCH_LBT_MIPS)] = "lbt_mips",
};
return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
}
abi_ulong get_elf_hwcap(CPUState *cs)
{
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
abi_ulong hwcaps = 0;
hwcaps |= HWCAP_LOONGARCH_CRC32;
if (FIELD_EX32(cpu->env.cpucfg[1], CPUCFG1, UAL)) {
hwcaps |= HWCAP_LOONGARCH_UAL;
}
if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, FP)) {
hwcaps |= HWCAP_LOONGARCH_FPU;
}
if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LAM)) {
hwcaps |= HWCAP_LOONGARCH_LAM;
}
if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
hwcaps |= HWCAP_LOONGARCH_LSX;
}
if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
hwcaps |= HWCAP_LOONGARCH_LASX;
}
return hwcaps;
}
const char *get_elf_platform(CPUState *cs)
{
return "loongarch";
}
#define tswapreg(ptr) tswapal(ptr)
void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env)
{
CPUSysState *sys = env_sys((CPULoongArchState *)env);
r->pt.regs[0] = 0;
for (int i = 1; i < ARRAY_SIZE(env->gpr); i++) {
r->pt.regs[i] = tswapreg(env->gpr[i]);
}
r->pt.csr_era = tswapreg(env->pc);
r->pt.csr_badv = tswapreg(sys->CSR_BADV);
}
+11
View File
@@ -0,0 +1,11 @@
vdso_inc = gen_vdso.process('vdso.so',
extra_args: ['-r', '__vdso_rt_sigreturn'])
linux_user_ss.add(when: 'TARGET_LOONGARCH64', if_true: vdso_inc)
syscall_nr_generators += {
'loongarch64': generator(sh,
arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ],
output: '@BASENAME@_nr.h')
}
+458
View File
@@ -0,0 +1,458 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* LoongArch emulation of Linux signals
*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"
#include "target/loongarch/internals.h"
#include "target/loongarch/vec.h"
#include "vdso-asmoffset.h"
/* FP context was used */
#define SC_USED_FP (1 << 0)
struct target_sigcontext {
abi_ulong sc_pc;
abi_ulong sc_regs[32];
abi_uint sc_flags;
abi_ulong sc_extcontext[0] QEMU_ALIGNED(16);
};
QEMU_BUILD_BUG_ON(sizeof(struct target_sigcontext) != sizeof_sigcontext);
QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, sc_pc)
!= offsetof_sigcontext_pc);
QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, sc_regs)
!= offsetof_sigcontext_gr);
#define FPU_CTX_MAGIC 0x46505501
#define FPU_CTX_ALIGN 8
struct target_fpu_context {
abi_ulong regs[32];
abi_ulong fcc;
abi_uint fcsr;
} QEMU_ALIGNED(FPU_CTX_ALIGN);
QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
!= offsetof_fpucontext_fr);
#define LSX_CTX_MAGIC 0x53580001
#define LSX_CTX_ALIGN 16
struct target_lsx_context {
abi_ulong regs[2 * 32];
abi_ulong fcc;
abi_uint fcsr;
} QEMU_ALIGNED(LSX_CTX_ALIGN);
#define LASX_CTX_MAGIC 0x41535801
#define LASX_CTX_ALIGN 32
struct target_lasx_context {
abi_ulong regs[4 * 32];
abi_ulong fcc;
abi_uint fcsr;
} QEMU_ALIGNED(LASX_CTX_ALIGN);
#define CONTEXT_INFO_ALIGN 16
struct target_sctx_info {
abi_uint magic;
abi_uint size;
abi_ulong padding;
} QEMU_ALIGNED(CONTEXT_INFO_ALIGN);
QEMU_BUILD_BUG_ON(sizeof(struct target_sctx_info) != sizeof_sctx_info);
struct target_ucontext {
abi_ulong tuc_flags;
abi_ptr tuc_link;
target_stack_t tuc_stack;
target_sigset_t tuc_sigmask;
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
struct target_sigcontext tuc_mcontext;
};
struct target_rt_sigframe {
struct target_siginfo rs_info;
struct target_ucontext rs_uc;
};
QEMU_BUILD_BUG_ON(sizeof(struct target_rt_sigframe)
!= sizeof_rt_sigframe);
QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe, rs_uc.tuc_mcontext)
!= offsetof_sigcontext);
/*
* These two structures are not present in guest memory, are private
* to the signal implementation, but are largely copied from the
* kernel's signal implementation.
*/
struct ctx_layout {
void *haddr;
abi_ptr gaddr;
unsigned int size;
};
struct extctx_layout {
unsigned long size;
unsigned int flags;
struct ctx_layout fpu;
struct ctx_layout lsx;
struct ctx_layout lasx;
struct ctx_layout end;
};
static abi_ptr extframe_alloc(struct extctx_layout *extctx,
struct ctx_layout *sctx, unsigned size,
unsigned align, abi_ptr orig_sp)
{
abi_ptr sp = orig_sp;
sp -= sizeof(struct target_sctx_info) + size;
align = MAX(align, CONTEXT_INFO_ALIGN);
sp = ROUND_DOWN(sp, align);
sctx->gaddr = sp;
size = orig_sp - sp;
sctx->size = size;
extctx->size += size;
return sp;
}
static abi_ptr setup_extcontext(CPULoongArchState *env,
struct extctx_layout *extctx, abi_ptr sp)
{
CPUSysState *sys = env_sys(env);
memset(extctx, 0, sizeof(struct extctx_layout));
/* Grow down, alloc "end" context info first. */
sp = extframe_alloc(extctx, &extctx->end, 0, CONTEXT_INFO_ALIGN, sp);
/* For qemu, there is no lazy fp context switch, so fp always present. */
extctx->flags = SC_USED_FP;
if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) {
sp = extframe_alloc(extctx, &extctx->lasx,
sizeof(struct target_lasx_context), LASX_CTX_ALIGN, sp);
} else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) {
sp = extframe_alloc(extctx, &extctx->lsx,
sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp);
} else {
sp = extframe_alloc(extctx, &extctx->fpu,
sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
}
return sp;
}
static void setup_sigframe(CPULoongArchState *env,
struct target_sigcontext *sc,
struct extctx_layout *extctx)
{
CPUSysState *sys = env_sys(env);
struct target_sctx_info *info;
int i;
__put_user(extctx->flags, &sc->sc_flags);
__put_user(env->pc, &sc->sc_pc);
__put_user(0, &sc->sc_regs[0]);
for (i = 1; i < 32; ++i) {
__put_user(env->gpr[i], &sc->sc_regs[i]);
}
/*
* Set extension context
*/
if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) {
struct target_lasx_context *lasx_ctx;
info = extctx->lasx.haddr;
__put_user(LASX_CTX_MAGIC, &info->magic);
__put_user(extctx->lasx.size, &info->size);
lasx_ctx = (struct target_lasx_context *)(info + 1);
for (i = 0; i < 32; ++i) {
__put_user(env->fpr[i].vreg.UD(0), &lasx_ctx->regs[4 * i]);
__put_user(env->fpr[i].vreg.UD(1), &lasx_ctx->regs[4 * i + 1]);
__put_user(env->fpr[i].vreg.UD(2), &lasx_ctx->regs[4 * i + 2]);
__put_user(env->fpr[i].vreg.UD(3), &lasx_ctx->regs[4 * i + 3]);
}
__put_user(read_fcc(env), &lasx_ctx->fcc);
__put_user(env->fcsr0, &lasx_ctx->fcsr);
} else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) {
struct target_lsx_context *lsx_ctx;
info = extctx->lsx.haddr;
__put_user(LSX_CTX_MAGIC, &info->magic);
__put_user(extctx->lsx.size, &info->size);
lsx_ctx = (struct target_lsx_context *)(info + 1);
for (i = 0; i < 32; ++i) {
__put_user(env->fpr[i].vreg.UD(0), &lsx_ctx->regs[2 * i]);
__put_user(env->fpr[i].vreg.UD(1), &lsx_ctx->regs[2 * i + 1]);
}
__put_user(read_fcc(env), &lsx_ctx->fcc);
__put_user(env->fcsr0, &lsx_ctx->fcsr);
} else {
struct target_fpu_context *fpu_ctx;
info = extctx->fpu.haddr;
__put_user(FPU_CTX_MAGIC, &info->magic);
__put_user(extctx->fpu.size, &info->size);
fpu_ctx = (struct target_fpu_context *)(info + 1);
for (i = 0; i < 32; ++i) {
__put_user(env->fpr[i].vreg.UD(0), &fpu_ctx->regs[i]);
}
__put_user(read_fcc(env), &fpu_ctx->fcc);
__put_user(env->fcsr0, &fpu_ctx->fcsr);
}
/*
* Set end context
*/
info = extctx->end.haddr;
__put_user(0, &info->magic);
__put_user(0, &info->size);
}
static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
{
memset(extctx, 0, sizeof(*extctx));
while (1) {
abi_uint magic, size;
if (get_user_u32(magic, frame) || get_user_u32(size, frame + 4)) {
return false;
}
switch (magic) {
case 0: /* END */
extctx->end.gaddr = frame;
extctx->end.size = size;
extctx->size += size;
return true;
case FPU_CTX_MAGIC:
if (size < (sizeof(struct target_sctx_info) +
sizeof(struct target_fpu_context))) {
return false;
}
extctx->fpu.gaddr = frame;
extctx->fpu.size = size;
extctx->size += size;
break;
case LSX_CTX_MAGIC:
if (size < (sizeof(struct target_sctx_info) +
sizeof(struct target_lsx_context))) {
return false;
}
extctx->lsx.gaddr = frame;
extctx->lsx.size = size;
extctx->size += size;
break;
case LASX_CTX_MAGIC:
if (size < (sizeof(struct target_sctx_info) +
sizeof(struct target_lasx_context))) {
return false;
}
extctx->lasx.gaddr = frame;
extctx->lasx.size = size;
extctx->size += size;
break;
default:
return false;
}
frame += size;
}
}
static void restore_sigframe(CPULoongArchState *env,
struct target_sigcontext *sc,
struct extctx_layout *extctx)
{
int i;
abi_ulong fcc;
__get_user(env->pc, &sc->sc_pc);
for (i = 1; i < 32; ++i) {
__get_user(env->gpr[i], &sc->sc_regs[i]);
}
if (extctx->lasx.haddr) {
struct target_lasx_context *lasx_ctx =
extctx->lasx.haddr + sizeof(struct target_sctx_info);
for (i = 0; i < 32; ++i) {
__get_user(env->fpr[i].vreg.UD(0), &lasx_ctx->regs[4 * i]);
__get_user(env->fpr[i].vreg.UD(1), &lasx_ctx->regs[4 * i + 1]);
__get_user(env->fpr[i].vreg.UD(2), &lasx_ctx->regs[4 * i + 2]);
__get_user(env->fpr[i].vreg.UD(3), &lasx_ctx->regs[4 * i + 3]);
}
__get_user(fcc, &lasx_ctx->fcc);
write_fcc(env, fcc);
__get_user(env->fcsr0, &lasx_ctx->fcsr);
restore_fp_status(env);
} else if (extctx->lsx.haddr) {
struct target_lsx_context *lsx_ctx =
extctx->lsx.haddr + sizeof(struct target_sctx_info);
for (i = 0; i < 32; ++i) {
__get_user(env->fpr[i].vreg.UD(0), &lsx_ctx->regs[2 * i]);
__get_user(env->fpr[i].vreg.UD(1), &lsx_ctx->regs[2 * i + 1]);
}
__get_user(fcc, &lsx_ctx->fcc);
write_fcc(env, fcc);
__get_user(env->fcsr0, &lsx_ctx->fcsr);
restore_fp_status(env);
} else if (extctx->fpu.haddr) {
struct target_fpu_context *fpu_ctx =
extctx->fpu.haddr + sizeof(struct target_sctx_info);
for (i = 0; i < 32; ++i) {
__get_user(env->fpr[i].vreg.UD(0), &fpu_ctx->regs[i]);
}
__get_user(fcc, &fpu_ctx->fcc);
write_fcc(env, fcc);
__get_user(env->fcsr0, &fpu_ctx->fcsr);
restore_fp_status(env);
}
}
/*
* Determine which stack to use.
*/
static abi_ptr get_sigframe(struct target_sigaction *ka,
CPULoongArchState *env,
struct extctx_layout *extctx)
{
abi_ulong sp;
sp = target_sigsp(get_sp_from_cpustate(env), ka);
sp = ROUND_DOWN(sp, 16);
sp = setup_extcontext(env, extctx, sp);
sp -= sizeof(struct target_rt_sigframe);
assert(QEMU_IS_ALIGNED(sp, 16));
return sp;
}
void setup_rt_frame(int sig, struct target_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPULoongArchState *env)
{
CPUSysState *sys = env_sys(env);
struct target_rt_sigframe *frame;
struct extctx_layout extctx;
abi_ptr frame_addr;
int i;
frame_addr = get_sigframe(ka, env, &extctx);
trace_user_setup_rt_frame(env, frame_addr);
frame = lock_user(VERIFY_WRITE, frame_addr,
sizeof(*frame) + extctx.size, 0);
if (!frame) {
force_sigsegv(sig);
return;
}
if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) {
extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
} else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) {
extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
} else {
extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
}
frame->rs_info = *info;
__put_user(0, &frame->rs_uc.tuc_flags);
__put_user(0, &frame->rs_uc.tuc_link);
target_save_altstack(&frame->rs_uc.tuc_stack, env);
setup_sigframe(env, &frame->rs_uc.tuc_mcontext, &extctx);
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
__put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
}
env->gpr[4] = sig;
env->gpr[5] = frame_addr + offsetof(struct target_rt_sigframe, rs_info);
env->gpr[6] = frame_addr + offsetof(struct target_rt_sigframe, rs_uc);
env->gpr[3] = frame_addr;
env->gpr[1] = default_rt_sigreturn;
env->pc = ka->_sa_handler;
unlock_user(frame, frame_addr, sizeof(*frame) + extctx.size);
}
long do_rt_sigreturn(CPULoongArchState *env)
{
struct target_rt_sigframe *frame;
struct extctx_layout extctx;
abi_ulong frame_addr;
sigset_t blocked;
frame_addr = env->gpr[3];
trace_user_do_rt_sigreturn(env, frame_addr);
if (!parse_extcontext(&extctx, frame_addr + sizeof(*frame))) {
goto badframe;
}
frame = lock_user(VERIFY_READ, frame_addr,
sizeof(*frame) + extctx.size, 1);
if (!frame) {
goto badframe;
}
if (extctx.lasx.gaddr) {
extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
} else if (extctx.lsx.gaddr) {
extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
} else if (extctx.fpu.gaddr) {
extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
}
target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
set_sigmask(&blocked);
restore_sigframe(env, &frame->rs_uc.tuc_mcontext, &extctx);
target_restore_altstack(&frame->rs_uc.tuc_stack, env);
unlock_user(frame, frame_addr, 0);
return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
{
uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
assert(tramp != NULL);
__put_user(0x03822c0b, tramp + 0); /* ori a7, zero, 0x8b */
__put_user(0x002b0000, tramp + 1); /* syscall 0 */
default_rt_sigreturn = sigtramp_page;
unlock_user(tramp, sigtramp_page, 8);
}
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_SOCKBITS_H
#define LOONGARCH_TARGET_SOCKBITS_H
#include "../generic/sockbits.h"
#endif
+405
View File
@@ -0,0 +1,405 @@
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# This file contains the system call numbers for all of the
# more recently added architectures.
#
# As a basic principle, no duplication of functionality
# should be added, e.g. we don't use lseek when llseek
# is present. New architectures should use this file
# and implement the less feature-full calls in user space.
#
0 common io_setup sys_io_setup compat_sys_io_setup
1 common io_destroy sys_io_destroy
2 common io_submit sys_io_submit compat_sys_io_submit
3 common io_cancel sys_io_cancel
4 time32 io_getevents sys_io_getevents_time32
4 64 io_getevents sys_io_getevents
5 common setxattr sys_setxattr
6 common lsetxattr sys_lsetxattr
7 common fsetxattr sys_fsetxattr
8 common getxattr sys_getxattr
9 common lgetxattr sys_lgetxattr
10 common fgetxattr sys_fgetxattr
11 common listxattr sys_listxattr
12 common llistxattr sys_llistxattr
13 common flistxattr sys_flistxattr
14 common removexattr sys_removexattr
15 common lremovexattr sys_lremovexattr
16 common fremovexattr sys_fremovexattr
17 common getcwd sys_getcwd
18 common lookup_dcookie sys_ni_syscall
19 common eventfd2 sys_eventfd2
20 common epoll_create1 sys_epoll_create1
21 common epoll_ctl sys_epoll_ctl
22 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait
23 common dup sys_dup
24 common dup3 sys_dup3
25 32 fcntl64 sys_fcntl64 compat_sys_fcntl64
25 64 fcntl sys_fcntl
26 common inotify_init1 sys_inotify_init1
27 common inotify_add_watch sys_inotify_add_watch
28 common inotify_rm_watch sys_inotify_rm_watch
29 common ioctl sys_ioctl compat_sys_ioctl
30 common ioprio_set sys_ioprio_set
31 common ioprio_get sys_ioprio_get
32 common flock sys_flock
33 common mknodat sys_mknodat
34 common mkdirat sys_mkdirat
35 common unlinkat sys_unlinkat
36 common symlinkat sys_symlinkat
37 common linkat sys_linkat
# renameat is superseded with flags by renameat2
38 renameat renameat sys_renameat
39 common umount2 sys_umount
40 common mount sys_mount
41 common pivot_root sys_pivot_root
42 common nfsservctl sys_ni_syscall
43 32 statfs64 sys_statfs64 compat_sys_statfs64
43 64 statfs sys_statfs
44 32 fstatfs64 sys_fstatfs64 compat_sys_fstatfs64
44 64 fstatfs sys_fstatfs
45 32 truncate64 sys_truncate64 compat_sys_truncate64
45 64 truncate sys_truncate
46 32 ftruncate64 sys_ftruncate64 compat_sys_ftruncate64
46 64 ftruncate sys_ftruncate
47 common fallocate sys_fallocate compat_sys_fallocate
48 common faccessat sys_faccessat
49 common chdir sys_chdir
50 common fchdir sys_fchdir
51 common chroot sys_chroot
52 common fchmod sys_fchmod
53 common fchmodat sys_fchmodat
54 common fchownat sys_fchownat
55 common fchown sys_fchown
56 common openat sys_openat
57 common close sys_close
58 common vhangup sys_vhangup
59 common pipe2 sys_pipe2
60 common quotactl sys_quotactl
61 common getdents64 sys_getdents64
62 32 llseek sys_llseek
62 64 lseek sys_lseek
63 common read sys_read
64 common write sys_write
65 common readv sys_readv sys_readv
66 common writev sys_writev sys_writev
67 common pread64 sys_pread64 compat_sys_pread64
68 common pwrite64 sys_pwrite64 compat_sys_pwrite64
69 common preadv sys_preadv compat_sys_preadv
70 common pwritev sys_pwritev compat_sys_pwritev
71 32 sendfile64 sys_sendfile64
71 64 sendfile sys_sendfile64
72 time32 pselect6 sys_pselect6_time32 compat_sys_pselect6_time32
72 64 pselect6 sys_pselect6
73 time32 ppoll sys_ppoll_time32 compat_sys_ppoll_time32
73 64 ppoll sys_ppoll
74 common signalfd4 sys_signalfd4 compat_sys_signalfd4
75 common vmsplice sys_vmsplice
76 common splice sys_splice
77 common tee sys_tee
78 common readlinkat sys_readlinkat
79 stat64 fstatat64 sys_fstatat64
79 64 newfstatat sys_newfstatat
80 stat64 fstat64 sys_fstat64
80 64 fstat sys_newfstat
81 common sync sys_sync
82 common fsync sys_fsync
83 common fdatasync sys_fdatasync
84 common sync_file_range sys_sync_file_range compat_sys_sync_file_range
85 common timerfd_create sys_timerfd_create
86 time32 timerfd_settime sys_timerfd_settime32
86 64 timerfd_settime sys_timerfd_settime
87 time32 timerfd_gettime sys_timerfd_gettime32
87 64 timerfd_gettime sys_timerfd_gettime
88 time32 utimensat sys_utimensat_time32
88 64 utimensat sys_utimensat
89 common acct sys_acct
90 common capget sys_capget
91 common capset sys_capset
92 common personality sys_personality
93 common exit sys_exit
94 common exit_group sys_exit_group
95 common waitid sys_waitid compat_sys_waitid
96 common set_tid_address sys_set_tid_address
97 common unshare sys_unshare
98 time32 futex sys_futex_time32
98 64 futex sys_futex
99 common set_robust_list sys_set_robust_list compat_sys_set_robust_list
100 common get_robust_list sys_get_robust_list compat_sys_get_robust_list
101 time32 nanosleep sys_nanosleep_time32
101 64 nanosleep sys_nanosleep
102 common getitimer sys_getitimer compat_sys_getitimer
103 common setitimer sys_setitimer compat_sys_setitimer
104 common kexec_load sys_kexec_load compat_sys_kexec_load
105 common init_module sys_init_module
106 common delete_module sys_delete_module
107 common timer_create sys_timer_create compat_sys_timer_create
108 time32 timer_gettime sys_timer_gettime32
108 64 timer_gettime sys_timer_gettime
109 common timer_getoverrun sys_timer_getoverrun
110 time32 timer_settime sys_timer_settime32
110 64 timer_settime sys_timer_settime
111 common timer_delete sys_timer_delete
112 time32 clock_settime sys_clock_settime32
112 64 clock_settime sys_clock_settime
113 time32 clock_gettime sys_clock_gettime32
113 64 clock_gettime sys_clock_gettime
114 time32 clock_getres sys_clock_getres_time32
114 64 clock_getres sys_clock_getres
115 time32 clock_nanosleep sys_clock_nanosleep_time32
115 64 clock_nanosleep sys_clock_nanosleep
116 common syslog sys_syslog
117 common ptrace sys_ptrace compat_sys_ptrace
118 common sched_setparam sys_sched_setparam
119 common sched_setscheduler sys_sched_setscheduler
120 common sched_getscheduler sys_sched_getscheduler
121 common sched_getparam sys_sched_getparam
122 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity
123 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity
124 common sched_yield sys_sched_yield
125 common sched_get_priority_max sys_sched_get_priority_max
126 common sched_get_priority_min sys_sched_get_priority_min
127 time32 sched_rr_get_interval sys_sched_rr_get_interval_time32
127 64 sched_rr_get_interval sys_sched_rr_get_interval
128 common restart_syscall sys_restart_syscall
129 common kill sys_kill
130 common tkill sys_tkill
131 common tgkill sys_tgkill
132 common sigaltstack sys_sigaltstack compat_sys_sigaltstack
133 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
134 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
135 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask
136 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
137 time32 rt_sigtimedwait sys_rt_sigtimedwait_time32 compat_sys_rt_sigtimedwait_time32
137 64 rt_sigtimedwait sys_rt_sigtimedwait
138 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
139 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn
140 common setpriority sys_setpriority
141 common getpriority sys_getpriority
142 common reboot sys_reboot
143 common setregid sys_setregid
144 common setgid sys_setgid
145 common setreuid sys_setreuid
146 common setuid sys_setuid
147 common setresuid sys_setresuid
148 common getresuid sys_getresuid
149 common setresgid sys_setresgid
150 common getresgid sys_getresgid
151 common setfsuid sys_setfsuid
152 common setfsgid sys_setfsgid
153 common times sys_times compat_sys_times
154 common setpgid sys_setpgid
155 common getpgid sys_getpgid
156 common getsid sys_getsid
157 common setsid sys_setsid
158 common getgroups sys_getgroups
159 common setgroups sys_setgroups
160 common uname sys_newuname
161 common sethostname sys_sethostname
162 common setdomainname sys_setdomainname
# getrlimit and setrlimit are superseded with prlimit64
163 rlimit getrlimit sys_getrlimit compat_sys_getrlimit
164 rlimit setrlimit sys_setrlimit compat_sys_setrlimit
165 common getrusage sys_getrusage compat_sys_getrusage
166 common umask sys_umask
167 common prctl sys_prctl
168 common getcpu sys_getcpu
169 time32 gettimeofday sys_gettimeofday compat_sys_gettimeofday
169 64 gettimeofday sys_gettimeofday
170 time32 settimeofday sys_settimeofday compat_sys_settimeofday
170 64 settimeofday sys_settimeofday
171 time32 adjtimex sys_adjtimex_time32
171 64 adjtimex sys_adjtimex
172 common getpid sys_getpid
173 common getppid sys_getppid
174 common getuid sys_getuid
175 common geteuid sys_geteuid
176 common getgid sys_getgid
177 common getegid sys_getegid
178 common gettid sys_gettid
179 common sysinfo sys_sysinfo compat_sys_sysinfo
180 common mq_open sys_mq_open compat_sys_mq_open
181 common mq_unlink sys_mq_unlink
182 time32 mq_timedsend sys_mq_timedsend_time32
182 64 mq_timedsend sys_mq_timedsend
183 time32 mq_timedreceive sys_mq_timedreceive_time32
183 64 mq_timedreceive sys_mq_timedreceive
184 common mq_notify sys_mq_notify compat_sys_mq_notify
185 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr
186 common msgget sys_msgget
187 common msgctl sys_msgctl compat_sys_msgctl
188 common msgrcv sys_msgrcv compat_sys_msgrcv
189 common msgsnd sys_msgsnd compat_sys_msgsnd
190 common semget sys_semget
191 common semctl sys_semctl compat_sys_semctl
192 time32 semtimedop sys_semtimedop_time32
192 64 semtimedop sys_semtimedop
193 common semop sys_semop
194 common shmget sys_shmget
195 common shmctl sys_shmctl compat_sys_shmctl
196 common shmat sys_shmat compat_sys_shmat
197 common shmdt sys_shmdt
198 common socket sys_socket
199 common socketpair sys_socketpair
200 common bind sys_bind
201 common listen sys_listen
202 common accept sys_accept
203 common connect sys_connect
204 common getsockname sys_getsockname
205 common getpeername sys_getpeername
206 common sendto sys_sendto
207 common recvfrom sys_recvfrom compat_sys_recvfrom
208 common setsockopt sys_setsockopt sys_setsockopt
209 common getsockopt sys_getsockopt sys_getsockopt
210 common shutdown sys_shutdown
211 common sendmsg sys_sendmsg compat_sys_sendmsg
212 common recvmsg sys_recvmsg compat_sys_recvmsg
213 common readahead sys_readahead compat_sys_readahead
214 common brk sys_brk
215 common munmap sys_munmap
216 common mremap sys_mremap
217 common add_key sys_add_key
218 common request_key sys_request_key
219 common keyctl sys_keyctl compat_sys_keyctl
220 common clone sys_clone
221 common execve sys_execve compat_sys_execve
222 32 mmap2 sys_mmap2
222 64 mmap sys_mmap
223 32 fadvise64_64 sys_fadvise64_64 compat_sys_fadvise64_64
223 64 fadvise64 sys_fadvise64_64
224 common swapon sys_swapon
225 common swapoff sys_swapoff
226 common mprotect sys_mprotect
227 common msync sys_msync
228 common mlock sys_mlock
229 common munlock sys_munlock
230 common mlockall sys_mlockall
231 common munlockall sys_munlockall
232 common mincore sys_mincore
233 common madvise sys_madvise
234 common remap_file_pages sys_remap_file_pages
235 common mbind sys_mbind
236 common get_mempolicy sys_get_mempolicy
237 common set_mempolicy sys_set_mempolicy
238 common migrate_pages sys_migrate_pages
239 common move_pages sys_move_pages
240 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
241 common perf_event_open sys_perf_event_open
242 common accept4 sys_accept4
243 time32 recvmmsg sys_recvmmsg_time32 compat_sys_recvmmsg_time32
243 64 recvmmsg sys_recvmmsg
# Architectures may provide up to 16 syscalls of their own between 244 and 259
244 arc cacheflush sys_cacheflush
245 arc arc_settls sys_arc_settls
246 arc arc_gettls sys_arc_gettls
247 arc sysfs sys_sysfs
248 arc arc_usr_cmpxchg sys_arc_usr_cmpxchg
244 csky set_thread_area sys_set_thread_area
245 csky cacheflush sys_cacheflush
244 nios2 cacheflush sys_cacheflush
244 or1k or1k_atomic sys_or1k_atomic
258 riscv riscv_hwprobe sys_riscv_hwprobe
259 riscv riscv_flush_icache sys_riscv_flush_icache
260 time32 wait4 sys_wait4 compat_sys_wait4
260 64 wait4 sys_wait4
261 common prlimit64 sys_prlimit64
262 common fanotify_init sys_fanotify_init
263 common fanotify_mark sys_fanotify_mark
264 common name_to_handle_at sys_name_to_handle_at
265 common open_by_handle_at sys_open_by_handle_at
266 time32 clock_adjtime sys_clock_adjtime32
266 64 clock_adjtime sys_clock_adjtime
267 common syncfs sys_syncfs
268 common setns sys_setns
269 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
270 common process_vm_readv sys_process_vm_readv
271 common process_vm_writev sys_process_vm_writev
272 common kcmp sys_kcmp
273 common finit_module sys_finit_module
274 common sched_setattr sys_sched_setattr
275 common sched_getattr sys_sched_getattr
276 common renameat2 sys_renameat2
277 common seccomp sys_seccomp
278 common getrandom sys_getrandom
279 common memfd_create sys_memfd_create
280 common bpf sys_bpf
281 common execveat sys_execveat compat_sys_execveat
282 common userfaultfd sys_userfaultfd
283 common membarrier sys_membarrier
284 common mlock2 sys_mlock2
285 common copy_file_range sys_copy_file_range
286 common preadv2 sys_preadv2 compat_sys_preadv2
287 common pwritev2 sys_pwritev2 compat_sys_pwritev2
288 common pkey_mprotect sys_pkey_mprotect
289 common pkey_alloc sys_pkey_alloc
290 common pkey_free sys_pkey_free
291 common statx sys_statx
292 time32 io_pgetevents sys_io_pgetevents_time32 compat_sys_io_pgetevents
292 64 io_pgetevents sys_io_pgetevents
293 common rseq sys_rseq
294 common kexec_file_load sys_kexec_file_load
# 295 through 402 are unassigned to sync up with generic numbers don't use
403 32 clock_gettime64 sys_clock_gettime
404 32 clock_settime64 sys_clock_settime
405 32 clock_adjtime64 sys_clock_adjtime
406 32 clock_getres_time64 sys_clock_getres
407 32 clock_nanosleep_time64 sys_clock_nanosleep
408 32 timer_gettime64 sys_timer_gettime
409 32 timer_settime64 sys_timer_settime
410 32 timerfd_gettime64 sys_timerfd_gettime
411 32 timerfd_settime64 sys_timerfd_settime
412 32 utimensat_time64 sys_utimensat
413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64
414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64
416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64
417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64
418 32 mq_timedsend_time64 sys_mq_timedsend
419 32 mq_timedreceive_time64 sys_mq_timedreceive
420 32 semtimedop_time64 sys_semtimedop
421 32 rt_sigtimedwait_time64 sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time64
422 32 futex_time64 sys_futex
423 32 sched_rr_get_interval_time64 sys_sched_rr_get_interval
424 common pidfd_send_signal sys_pidfd_send_signal
425 common io_uring_setup sys_io_uring_setup
426 common io_uring_enter sys_io_uring_enter
427 common io_uring_register sys_io_uring_register
428 common open_tree sys_open_tree
429 common move_mount sys_move_mount
430 common fsopen sys_fsopen
431 common fsconfig sys_fsconfig
432 common fsmount sys_fsmount
433 common fspick sys_fspick
434 common pidfd_open sys_pidfd_open
435 common clone3 sys_clone3
436 common close_range sys_close_range
437 common openat2 sys_openat2
438 common pidfd_getfd sys_pidfd_getfd
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
443 common quotactl_fd sys_quotactl_fd
444 common landlock_create_ruleset sys_landlock_create_ruleset
445 common landlock_add_rule sys_landlock_add_rule
446 common landlock_restrict_self sys_landlock_restrict_self
447 memfd_secret memfd_secret sys_memfd_secret
448 common process_mrelease sys_process_mrelease
449 common futex_waitv sys_futex_waitv
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
457 common statmount sys_statmount
458 common listmount sys_listmount
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
+28
View File
@@ -0,0 +1,28 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
in="$1"
out="$2"
my_abis=`echo "($3)" | tr ',' '|'`
prefix="$4"
offset="$5"
fileguard=LINUX_USER_LOONGARCH64_`basename "$out" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
echo "#ifndef ${fileguard}"
echo "#define ${fileguard} 1"
echo ""
while read nr abi name entry compat ; do
if [ -z "$offset" ]; then
echo "#define TARGET_NR_${prefix}${name} $nr"
else
echo "#define TARGET_NR_${prefix}${name} ($offset + $nr)"
fi
done
echo ""
echo "#endif /* ${fileguard} */"
) > "$out"
+34
View File
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* LoongArch specific CPU ABI and functions for linux-user
*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_CPU_H
#define LOONGARCH_TARGET_CPU_H
static inline void cpu_clone_regs_child(CPULoongArchState *env,
target_ulong newsp, unsigned flags)
{
if (newsp) {
env->gpr[3] = newsp;
}
env->gpr[4] = 0;
}
static inline void cpu_clone_regs_parent(CPULoongArchState *env,
unsigned flags)
{
}
static inline void cpu_set_tls(CPULoongArchState *env, target_ulong newtls)
{
env->gpr[2] = newtls;
}
static inline abi_ulong get_sp_from_cpustate(CPULoongArchState *state)
{
return state->gpr[3];
}
#endif
+25
View File
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_ELF_H
#define LOONGARCH_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS64
#define ELF_MACHINE EM_LOONGARCH
#define EXSTACK_DEFAULT true
#define VDSO_HEADER "vdso.c.inc"
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
/* See linux kernel: arch/loongarch/include/asm/elf.h */
typedef struct target_elf_gregset_t {
struct target_user_pt_regs pt;
} target_elf_gregset_t;
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_ERRNO_DEFS_H
#define LOONGARCH_TARGET_ERRNO_DEFS_H
/* Target uses generic errno */
#include "../generic/target_errno_defs.h"
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_FCNTL_H
#define LOONGARCH_TARGET_FCNTL_H
#include "../generic/fcntl.h"
#endif
+12
View File
@@ -0,0 +1,12 @@
/*
* arch/loongarch/include/asm/processor.h:
* TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
* TASK_SIZE64 0x1UL << (... ? VA_BITS : ...)
*/
#define TASK_UNMAPPED_BASE \
TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
/* arch/loongarch/include/asm/elf.h */
#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2)
#include "../generic/target_mman.h"
+1
View File
@@ -0,0 +1 @@
/* No special prctl support required. */
+78
View File
@@ -0,0 +1,78 @@
/*
* Loongson specific proc functions for linux-user
*
* Copyright (c) 2026 Helge Deller
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef LOONGARCH_TARGET_PROC_H
#define LOONGARCH_TARGET_PROC_H
static int open_cpuinfo(CPUArchState *cpu_env, int fd)
{
uint32_t elf_hwcap = get_elf_hwcap(env_cpu(cpu_env));
uint32_t prid, ser_id, pabits, vabits, i, n, num_cpus;
bool is_64bit = is_la64(cpu_env);
const char *hwcap_str;
struct timespec res;
double freq_mhz;
#if TARGET_LONG_BITS == 32
pabits = 31;
vabits = 31;
#else
pabits = FIELD_EX32(cpu_env->cpucfg[1], CPUCFG1, PALEN);
vabits = FIELD_EX32(cpu_env->cpucfg[1], CPUCFG1, VALEN);
#endif
if (clock_getres(CLOCK_REALTIME, &res) == -1) {
res.tv_nsec = 1;
}
freq_mhz = 1000.0 / res.tv_nsec;
ser_id = FIELD_EX32(cpu_env->cpucfg[0], CPUCFG0, SERID);
prid = FIELD_EX32(cpu_env->cpucfg[0], CPUCFG0, PRID);
dprintf(fd, "system type\t\t: generic-loongson-machine\n");
num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
for (n = 0; n < num_cpus; n++) {
dprintf(fd, "\nprocessor\t\t: %d\n", n);
dprintf(fd, "package\t\t\t: 0\n");
dprintf(fd, "core\t\t\t: %d\n", n);
dprintf(fd, "global_id\t\t: %d\n", n);
dprintf(fd, "CPU Family\t\t: Loongson-%dbit\n", is_64bit ? 64 : 32);
dprintf(fd, "Model Name\t\t: QEMU_user-v" QEMU_VERSION "\n");
dprintf(fd, "PRID\t\t\t: %s (%08x)\n",
ser_id == PRID_SERIES_LA464 ? "LA464" :
ser_id == PRID_SERIES_LA132 ? "LA132" : "Unknown",
cpu_env->cpucfg[0]);
dprintf(fd, "CPU Revision\t\t: 0x%02x\n", prid);
dprintf(fd, "FPU Revision\t\t: 0x%02x\n",
FIELD_EX32(cpu_env->cpucfg[2], CPUCFG2, FP_VER));
dprintf(fd, "CPU MHz\t\t\t: %.2f\n", freq_mhz);
dprintf(fd, "Address Sizes\t\t: %d bits physical, %d bits virtual\n",
pabits + 1, vabits + 1);
dprintf(fd, "ISA\t\t\t:%s", " loongarch32r loongarch32s");
if (is_64bit) {
dprintf(fd, " loongarch64");
}
dprintf(fd, "\nFeatures\t\t:");
for (i = 0; i < sizeof(elf_hwcap) * 8; i++) {
if (!(elf_hwcap & (1 << i))) {
continue;
}
hwcap_str = elf_hwcap_str(i);
if (hwcap_str) {
dprintf(fd, " %s", hwcap_str);
}
}
dprintf(fd, "\nHardware Watchpoint\t: no\n");
}
return 0;
}
#define HAVE_ARCH_PROC_CPUINFO
#endif /* LOONGARCH_TARGET_PROC_H */
+15
View File
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef LOONGARCH64_TARGET_PTRACE_H
#define LOONGARCH64_TARGET_PTRACE_H
/* See arch/loongarch/include/uapi/asm/ptrace.h. */
struct target_user_pt_regs {
abi_ulong regs[32];
abi_ulong orig_a0;
abi_ulong csr_era;
abi_ulong csr_badv;
abi_ulong reserved[10];
};
#endif /* LOONGARCH64_TARGET_PTRACE_H */
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_RESOURCE_H
#define LOONGARCH_TARGET_RESOURCE_H
#include "../generic/target_resource.h"
#endif
+13
View File
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_SIGNAL_H
#define LOONGARCH_TARGET_SIGNAL_H
#include "../generic/signal.h"
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
#endif /* LOONGARCH_TARGET_SIGNAL_H */
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_STRUCTS_H
#define LOONGARCH_TARGET_STRUCTS_H
#include "../generic/target_structs.h"
#endif
+18
View File
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_SYSCALL_H
#define LOONGARCH_TARGET_SYSCALL_H
#include "qemu/units.h"
#define UNAME_MACHINE "loongarch64"
#define UNAME_MINIMUM_RELEASE "5.19.0"
#define TARGET_MCL_CURRENT 1
#define TARGET_MCL_FUTURE 2
#define TARGET_MCL_ONFAULT 4
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
#ifndef LOONGARCH_TARGET_TERMBITS_H
#define LOONGARCH_TARGET_TERMBITS_H
#include "../generic/termbits.h"
#endif
+8
View File
@@ -0,0 +1,8 @@
#define sizeof_rt_sigframe 0x240
#define sizeof_sigcontext 0x110
#define sizeof_sctx_info 0x10
#define offsetof_sigcontext 0x130
#define offsetof_sigcontext_pc 0
#define offsetof_sigcontext_gr 8
#define offsetof_fpucontext_fr 0
+132
View File
@@ -0,0 +1,132 @@
/*
* Loongarch64 linux replacement vdso.
*
* Copyright 2023 Linaro, Ltd.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <asm/unistd.h>
#include <asm/errno.h>
#include "vdso-asmoffset.h"
.text
.macro endf name
.globl \name
.type \name, @function
.size \name, . - \name
.endm
.macro vdso_syscall name, nr
\name:
li.w $a7, \nr
syscall 0
jr $ra
endf \name
.endm
.cfi_startproc
vdso_syscall __vdso_gettimeofday, __NR_gettimeofday
vdso_syscall __vdso_clock_gettime, __NR_clock_gettime
vdso_syscall __vdso_clock_getres, __NR_clock_getres
vdso_syscall __vdso_getcpu, __NR_getcpu
.cfi_endproc
/*
* Start the unwind info at least one instruction before the signal
* trampoline, because the unwinder will assume we are returning
* after a call site.
*/
.cfi_startproc simple
.cfi_signal_frame
#define B_GR offsetof_sigcontext_gr
#define B_FR sizeof_sigcontext + sizeof_sctx_info + offsetof_fpucontext_fr
.cfi_def_cfa 2, offsetof_sigcontext
/* Return address */
.cfi_return_column 64
.cfi_offset 64, offsetof_sigcontext_pc /* pc */
/* Integer registers */
.cfi_offset 1, B_GR + 1 * 8
.cfi_offset 2, B_GR + 2 * 8
.cfi_offset 3, B_GR + 3 * 8
.cfi_offset 4, B_GR + 4 * 8
.cfi_offset 5, B_GR + 5 * 8
.cfi_offset 6, B_GR + 6 * 8
.cfi_offset 7, B_GR + 7 * 8
.cfi_offset 8, B_GR + 8 * 8
.cfi_offset 9, B_GR + 9 * 8
.cfi_offset 10, B_GR + 10 * 8
.cfi_offset 11, B_GR + 11 * 8
.cfi_offset 12, B_GR + 12 * 8
.cfi_offset 13, B_GR + 13 * 8
.cfi_offset 14, B_GR + 14 * 8
.cfi_offset 15, B_GR + 15 * 8
.cfi_offset 16, B_GR + 16 * 8
.cfi_offset 17, B_GR + 17 * 8
.cfi_offset 18, B_GR + 18 * 8
.cfi_offset 19, B_GR + 19 * 8
.cfi_offset 20, B_GR + 20 * 8
.cfi_offset 21, B_GR + 21 * 8
.cfi_offset 22, B_GR + 22 * 8
.cfi_offset 23, B_GR + 23 * 8
.cfi_offset 24, B_GR + 24 * 8
.cfi_offset 25, B_GR + 25 * 8
.cfi_offset 26, B_GR + 26 * 8
.cfi_offset 27, B_GR + 27 * 8
.cfi_offset 28, B_GR + 28 * 8
.cfi_offset 29, B_GR + 29 * 8
.cfi_offset 30, B_GR + 30 * 8
.cfi_offset 31, B_GR + 31 * 8
/* Floating point registers */
.cfi_offset 32, B_FR + 0
.cfi_offset 33, B_FR + 1 * 8
.cfi_offset 34, B_FR + 2 * 8
.cfi_offset 35, B_FR + 3 * 8
.cfi_offset 36, B_FR + 4 * 8
.cfi_offset 37, B_FR + 5 * 8
.cfi_offset 38, B_FR + 6 * 8
.cfi_offset 39, B_FR + 7 * 8
.cfi_offset 40, B_FR + 8 * 8
.cfi_offset 41, B_FR + 9 * 8
.cfi_offset 42, B_FR + 10 * 8
.cfi_offset 43, B_FR + 11 * 8
.cfi_offset 44, B_FR + 12 * 8
.cfi_offset 45, B_FR + 13 * 8
.cfi_offset 46, B_FR + 14 * 8
.cfi_offset 47, B_FR + 15 * 8
.cfi_offset 48, B_FR + 16 * 8
.cfi_offset 49, B_FR + 17 * 8
.cfi_offset 50, B_FR + 18 * 8
.cfi_offset 51, B_FR + 19 * 8
.cfi_offset 52, B_FR + 20 * 8
.cfi_offset 53, B_FR + 21 * 8
.cfi_offset 54, B_FR + 22 * 8
.cfi_offset 55, B_FR + 23 * 8
.cfi_offset 56, B_FR + 24 * 8
.cfi_offset 57, B_FR + 25 * 8
.cfi_offset 58, B_FR + 26 * 8
.cfi_offset 59, B_FR + 27 * 8
.cfi_offset 60, B_FR + 28 * 8
.cfi_offset 61, B_FR + 29 * 8
.cfi_offset 62, B_FR + 30 * 8
.cfi_offset 63, B_FR + 31 * 8
nop
__vdso_rt_sigreturn:
li.w $a7, __NR_rt_sigreturn
sigreturn_region_start:
syscall 0
sigreturn_region_end:
.cfi_endproc
endf __vdso_rt_sigreturn
+73
View File
@@ -0,0 +1,73 @@
/*
* Linker script for linux loongarch64 replacement vdso.
*
* Copyright 2023 Linaro, Ltd.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
VERSION {
LINUX_5.10 {
global:
__vdso_getcpu;
__vdso_clock_getres;
__vdso_clock_gettime;
__vdso_gettimeofday;
__vdso_rt_sigreturn;
local: *;
};
}
PHDRS {
phdr PT_PHDR FLAGS(4) PHDRS;
load PT_LOAD FLAGS(7) FILEHDR PHDRS;
dynamic PT_DYNAMIC FLAGS(4);
eh_frame_hdr PT_GNU_EH_FRAME;
note PT_NOTE FLAGS(4);
}
SECTIONS {
/*
* We can't prelink to any address without knowing something about
* the virtual memory space of the host, since that leaks over into
* the available memory space of the guest.
*/
. = SIZEOF_HEADERS;
/*
* The following, including the FILEHDRS and PHDRS, are modified
* when we relocate the binary. We want them to be initially
* writable for the relocation; we'll force them read-only after.
*/
.note : { *(.note*) } :load :note
.dynamic : { *(.dynamic) } :load :dynamic
.dynsym : { *(.dynsym) } :load
/*
* There ought not be any real read-write data.
* But since we manipulated the segment layout,
* we have to put these sections somewhere.
*/
.data : {
*(.data*)
*(.sdata*)
*(.got.plt) *(.got)
*(.gnu.linkonce.d.*)
*(.bss*)
*(.dynbss*)
*(.gnu.linkonce.b.*)
}
.rodata : { *(.rodata*) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.eh_frame_hdr : { *(.eh_frame_hdr) } :load :eh_frame_hdr
.eh_frame : { *(.eh_frame) } :load
.text : { *(.text*) } :load =0xd503201f
}
BIN
View File
Binary file not shown.