我目前正在开发一个项目,其中linux内核中的函数“A”在内核模块中调用另一个函数“B”。
基本思想是通过新创建的系统调用在内核模块中提供目标函数“B”的地址,该系统调用将接收到的地址写入内核全局变量。函数“A”读取该值并调用该地址。
调用函数“B”证明是成功的,因为我们通过在函数“B”的序言中插入一堆printk来验证。
但是在调用函数“B”之后系统会冻结一段时间,大概是因为只有控制流从内核传输到内核模块,因此所有其他上下文(堆栈帧等)保持不变。内核函数“A”
通过浏览一些引用,我写了一些应该保存/恢复上下文的x86_64 asm代码。
.macro SAVE
swapgs
mov (old_rsp), %r11
mov %rsp,%gs:(%r11)
mov (kernel_stack), %r11
mov %gs:(%r11),%rsp
sti
sub $0x50,%rsp
mov 0x50(%rsp),%rcx
mov 0x48(%rsp),%rbx
mov (%rsp),%r11
mov 0x8(%rsp),%r10
mov 0x10(%rsp),%r9
mov 0x18(%rsp),%r8
mov 0x20(%rsp),%rax
mov 0x30(%rsp),%rdx
mov 0x38(%rsp),%rsi
mov 0x40(%rsp),%rdi
.endm
.macro RESTORE
cli
mov %rdi,0x40(%rsp)
mov %rsi,0x38(%rsp)
mov %rdx,0x30(%rsp)
mov %rax,0x20(%rsp)
mov %r8,0x18(%rsp)
mov %r9,0x10(%rsp)
mov %r10,0x8(%rsp)
mov %r11,(%rsp)
mov %rbx,0x48(%rsp)
mov %rcx,0x50(%rsp)
add $0x50,%rsp
mov (old_rsp), %r11
mov %gs:(%r11),%rsp
jmp *syscall_after_swapgs
.endm
值old_rsp和kernel_stack是内核符号中的PER_CPU_VAR。 (linux 3.14) SAVE在调用B之前就开始了,RESTORE就在那之后。 但系统仍然冻结。
我有什么问题吗?或者代码中的某些问题可能?
提前致谢..