在 Linux 内核中维护进程独立寄存器失败

问题描述 投票:0回答:1

我修改了arm的硬件(在gem5上)添加了两个寄存器。我希望它们是进程独立的,每个进程都有自己对应的值存储在这些寄存器中,就像

ttbr0

我想修改Linux内核(v5.15.36)来维护这两个寄存器。我做了如下修改,但是出现了一个错误,就是这两个寄存器的值变成了0,这是无意义的。

首先我在

pt_regs
处添加了这两个寄存器对应的变量
arch/arm64/include/asm/ptrace.h

我还在
struct pt_regs {
    union {
        struct user_pt_regs user_regs;
        struct {
            u64 regs[31];
            u64 sp;
            u64 pc;
            u64 pstate;
        };
    };

    // other original code .......

    u64 isa_domain;     // <================ my register
    u64 inst_priv_base; // <================ my register
};
处添加了相应的宏定义:

arch/arm/kernel/asm-offsets.h

我将在
  DEFINE(S_ISA_DOMAIN,          offsetof(struct pt_regs, isa_domain));
  DEFINE(S_INST_PRIV_BASE,          offsetof(struct pt_regs, inst_priv_base));

copying_thread

的子函数)at
初始化这两个寄存器
fork

最后,我将它们保存并恢复到
int copy_thread(unsigned long clone_flags, unsigned long stack_start,
        unsigned long stk_sz, struct task_struct *p, unsigned long tls)
{
    struct pt_regs *childregs = task_pt_regs(p);
    memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));

    fpsimd_flush_task_state(p);

    ptrauth_thread_init_kernel(p);

    if (likely(!(p->flags & (PF_KTHREAD | PF_IO_WORKER)))) {
        *childregs = *current_pt_regs();
        childregs->regs[0] = 0;
        // <=============== init the register
        childregs->inst_priv_base = isa_grid_get_inst_base_pa(user_id);
        regs->isa_domain = 1;
        // other code .....
    }
}

kernel_entry

中的堆栈中
kernel_exit
/arch/arm64/kernel/entry.S

但似乎有时寄存器的值为0(我不会将这两个寄存器初始化为0)我是否缺少一些维护步骤?
    

最终我修复了这个错误。该错误不是由我未能维护上下文恢复和保存引起的,而是由于我的初始化没有考虑像
linux linux-kernel cpu-registers
1个回答
0
投票
进程和

init

 这样的情况,其中内核线程变成了用户进程通过 
User-mode Helper
.
此外,我之前在 
kernel_execve

中维护寄存器的方法是不合适的(但正确);对于每个进程独立的变量,不需要每次发生异常或中断时维护它们,而只在进程切换时维护。我现在已经修改了

pt_regs

 文件中的 
__switch_to()
 函数来维护变量。现在运行良好且高效!

© www.soinside.com 2019 - 2024. All rights reserved.