arch/parisc/kernel/syscall.S

Source file repositories/reference/linux-study-clean/arch/parisc/kernel/syscall.S

File Facts

System
Linux kernel
Corpus path
arch/parisc/kernel/syscall.S
Extension
.S
Size
38535 bytes
Lines
1376
Domain
Architecture Layer
Bucket
arch/parisc
Inferred role
Architecture Layer: syscall or user/kernel boundary
Status
core implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

How does the Linux gateway page on PA-RISC work?
------------------------------------------------
The Linux gateway page on PA-RISC is "special".
It actually has PAGE_GATEWAY bits set (this is linux terminology; in parisc
terminology it's Execute, promote to PL0) in the page map.  So anything
executing on this page executes with kernel level privilege (there's more to it
than that: to have this happen, you also have to use a branch with a ,gate
completer to activate the privilege promotion).  The upshot is that everything
that runs on the gateway page runs at kernel privilege but with the current
user process address space (although you have access to kernel space via %sr2).
For the 0x100 syscall entry, we redo the space registers to point to the kernel
address space (preserving the user address space in %sr3), move to wide mode if
required, save the user registers and branch into the kernel syscall entry
point.  For all the other functions, we execute at kernel privilege but don't
flip address spaces. The basic upshot of this is that these code snippets are
executed atomically (because the kernel can't be pre-empted) and they may
perform architecturally forbidden (to PL3) operations (like setting control
registers).
*/


#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/page.h>
#include <asm/psw.h>
#include <asm/thread_info.h>
#include <asm/assembly.h>
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/spinlock_types.h>

#include <linux/linkage.h>

	/* We fill the empty parts of the gateway page with
 	 * something that will kill the kernel or a
 	 * userspace application.
	 */
#define KILL_INSN	break	0,0

	.level          PA_ASM_LEVEL

	.macro	lws_pagefault_disable reg1,reg2
	mfctl	%cr30, \reg2
	ldo	TASK_PAGEFAULT_DISABLED(\reg2), \reg2
	ldw	0(%sr2,\reg2), \reg1
	ldo	1(\reg1), \reg1
	stw	\reg1, 0(%sr2,\reg2)
	.endm

	.macro	lws_pagefault_enable reg1,reg2
	mfctl	%cr30, \reg2
	ldo	TASK_PAGEFAULT_DISABLED(\reg2), \reg2
	ldw	0(%sr2,\reg2), \reg1
	ldo	-1(\reg1), \reg1
	stw	\reg1, 0(%sr2,\reg2)
	.endm

	/* raise exception if spinlock content is not zero or
	 * __ARCH_SPIN_LOCK_UNLOCKED_VAL */
	.macro	spinlock_check spin_val,tmpreg
#ifdef CONFIG_LIGHTWEIGHT_SPINLOCK_CHECK
	ldi	__ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmpreg
	andcm,=	\spin_val, \tmpreg, %r0
	.word	SPINLOCK_BREAK_INSN
#endif
	.endm

	.text

Annotation

Implementation Notes