syscall: fix call source detection
This commit is contained in:
parent
aa722fc34f
commit
57fb52dc1e
4 changed files with 14 additions and 12 deletions
arch/at91sam3x8e
|
@ -13,7 +13,7 @@
|
|||
|
||||
#ifdef CONFIG_CHECK_SYSCALL_SOURCE
|
||||
/* syscall.S */
|
||||
extern uintptr_t __syscall_entry_point;
|
||||
extern uint16_t __syscall_return_point;
|
||||
#endif
|
||||
|
||||
void arch_enter(void *sp)
|
||||
|
@ -27,10 +27,11 @@ void arch_enter(void *sp)
|
|||
# ifdef CONFIG_CHECK_SYSCALL_SOURCE
|
||||
/*
|
||||
* We need to ignore the program counter's LSB because the CPU uses
|
||||
* that as a flag for whether it's operating in ARM or Thumb mode
|
||||
* (1 for Thumb); the instructions are always 2-byte aligned.
|
||||
* that as a flag for whether it's operating in ARM or Thumb mode;
|
||||
* the instructions are always 2-byte aligned. Additionally, the PC
|
||||
* points to the instruction *after* the SVC, not SVC itself.
|
||||
*/
|
||||
if ((regs->hw.pc & 0xfffffffe) != __syscall_entry_point) {
|
||||
if (((uintptr_t)regs->hw.pc & 0xfffffffe) != (uintptr_t)&__syscall_return_point) {
|
||||
arch_syscall_set_rval(regs, -EACCES);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ struct reg_sw_snapshot {
|
|||
* lr is saved by hardware, but we need to store it twice
|
||||
* because the IRQ entry overwrites it
|
||||
*/
|
||||
uintptr_t lr; /* alias r14 */
|
||||
void *lr; /* alias r14 */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -42,8 +42,8 @@ struct reg_hw_snapshot {
|
|||
word_t r2;
|
||||
word_t r3;
|
||||
word_t r12;
|
||||
uintptr_t lr; /* alias r14 */
|
||||
uintptr_t pc; /* alias r15 */
|
||||
void *lr; /* alias r14 */
|
||||
void *pc; /* alias r15 */
|
||||
word_t psr;
|
||||
};
|
||||
|
||||
|
|
|
@ -61,9 +61,9 @@ void arch_sched_task_init(struct task *task, void (*entry)(void))
|
|||
task->sp = regs;
|
||||
|
||||
memset(regs, 0, sizeof(*regs));
|
||||
regs->hw.pc = (uintptr_t)entry;
|
||||
regs->hw.psr = 0x01000000U;
|
||||
regs->sw.lr = 0xfffffff9U;
|
||||
regs->hw.pc = entry;
|
||||
regs->hw.psr = 0x01000000;
|
||||
regs->sw.lr = (void *)0xfffffff9;
|
||||
}
|
||||
|
||||
void yield(enum task_state state)
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/* this is only invoked from user space, obviously */
|
||||
.section .text.shared
|
||||
|
||||
.global __syscall_return_point
|
||||
|
||||
/* int syscall(int number, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); */
|
||||
func_begin syscall
|
||||
|
||||
|
@ -32,10 +34,9 @@ func_begin syscall
|
|||
ldr r4, [sp, #16] /* arg5 */
|
||||
ldr r5, [sp, #20] /* arg6 */
|
||||
|
||||
.global __syscall_entry_point
|
||||
__syscall_entry_point:
|
||||
svc #0
|
||||
|
||||
__syscall_return_point:
|
||||
pop {r4-r5,r7}
|
||||
|
||||
/* r0 (return value) is set by the kernel */
|
||||
|
|
Loading…
Reference in a new issue