arch/sparc/kernel/ptrace_64.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/ptrace_64.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/ptrace_64.c
Extension
.c
Size
28090 bytes
Lines
1177
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration 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

struct pt_regs_offset {
	const char *name;
	int offset;
};

#define REG_OFFSET_NAME(n, r) \
	{.name = n, .offset = (PT_V9_##r)}
#define REG_OFFSET_END {.name = NULL, .offset = 0}

static const struct pt_regs_offset regoffset_table[] = {
	REG_OFFSET_NAME("g0", G0),
	REG_OFFSET_NAME("g1", G1),
	REG_OFFSET_NAME("g2", G2),
	REG_OFFSET_NAME("g3", G3),
	REG_OFFSET_NAME("g4", G4),
	REG_OFFSET_NAME("g5", G5),
	REG_OFFSET_NAME("g6", G6),
	REG_OFFSET_NAME("g7", G7),

	REG_OFFSET_NAME("i0", I0),
	REG_OFFSET_NAME("i1", I1),
	REG_OFFSET_NAME("i2", I2),
	REG_OFFSET_NAME("i3", I3),
	REG_OFFSET_NAME("i4", I4),
	REG_OFFSET_NAME("i5", I5),
	REG_OFFSET_NAME("i6", I6),
	REG_OFFSET_NAME("i7", I7),

	REG_OFFSET_NAME("tstate", TSTATE),
	REG_OFFSET_NAME("pc", TPC),
	REG_OFFSET_NAME("npc", TNPC),
	REG_OFFSET_NAME("y", Y),
	REG_OFFSET_NAME("lr", I7),

	REG_OFFSET_END,
};

/*
 * Called by kernel/ptrace.c when detaching..
 *
 * Make sure single step bits etc are not set.
 */
void ptrace_disable(struct task_struct *child)
{
	/* nothing to do */
}

/* To get the necessary page struct, access_process_vm() first calls
 * get_user_pages().  This has done a flush_dcache_page() on the
 * accessed page.  Then our caller (copy_{to,from}_user_page()) did
 * to memcpy to read/write the data from that page.
 *
 * Now, the only thing we have to do is:
 * 1) flush the D-cache if it's possible than an illegal alias
 *    has been created
 * 2) flush the I-cache if this is pre-cheetah and we did a write
 */
void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
			 unsigned long uaddr, void *kaddr,
			 unsigned long len, int write)
{
	BUG_ON(len > PAGE_SIZE);

	if (tlb_type == hypervisor)
		return;

	preempt_disable();

#ifdef DCACHE_ALIASING_POSSIBLE
	/* If bit 13 of the kernel address we used to access the
	 * user page is the same as the virtual address that page
	 * is mapped to in the user's address space, we can skip the
	 * D-cache flush.
	 */
	if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
		unsigned long start = __pa(kaddr);
		unsigned long end = start + len;
		unsigned long dcache_line_size;

		dcache_line_size = local_cpu_data().dcache_line_size;

		if (tlb_type == spitfire) {
			for (; start < end; start += dcache_line_size)
				spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
		} else {
			start &= ~(dcache_line_size - 1);
			for (; start < end; start += dcache_line_size)
				__asm__ __volatile__(
					"stxa %%g0, [%0] %1\n\t"
					"membar #Sync"

Annotation

Implementation Notes