arch/s390/include/asm/stacktrace.h

Source file repositories/reference/linux-study-clean/arch/s390/include/asm/stacktrace.h

File Facts

System
Linux kernel
Corpus path
arch/s390/include/asm/stacktrace.h
Extension
.h
Size
8086 bytes
Lines
262
Domain
Architecture Layer
Bucket
arch/s390
Inferred role
Architecture Layer: implementation source
Status
source 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 stack_frame_user {
	unsigned long back_chain;
	unsigned long empty1[5];
	unsigned long gprs[10];
	unsigned long empty2[4];
};

struct stack_frame_vdso_wrapper {
	struct stack_frame_user sf;
	unsigned long return_address;
};

struct perf_callchain_entry_ctx;

void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie,
				 struct perf_callchain_entry_ctx *entry,
				 const struct pt_regs *regs, bool perf);

enum stack_type {
	STACK_TYPE_UNKNOWN,
	STACK_TYPE_TASK,
	STACK_TYPE_IRQ,
	STACK_TYPE_NODAT,
	STACK_TYPE_RESTART,
	STACK_TYPE_MCCK,
};

struct stack_info {
	enum stack_type type;
	unsigned long begin, end;
};

const char *stack_type_name(enum stack_type type);
int get_stack_info(unsigned long sp, struct task_struct *task,
		   struct stack_info *info, unsigned long *visit_mask);

static inline bool on_stack(struct stack_info *info,
			    unsigned long addr, size_t len)
{
	if (info->type == STACK_TYPE_UNKNOWN)
		return false;
	if (addr + len < addr)
		return false;
	return addr >= info->begin && addr + len <= info->end;
}

/*
 * Stack layout of a C stack frame.
 * Kernel uses the packed stack layout (-mpacked-stack).
 */
struct stack_frame {
	union {
		unsigned long empty[9];
		struct {
			unsigned long sie_control_block;
			unsigned long sie_savearea;
			unsigned long sie_return;
			unsigned long sie_flags;
			unsigned long sie_control_block_phys;
			unsigned long sie_guest_asce;
			unsigned long sie_irq;
		};
	};
	unsigned long gprs[10];
	unsigned long back_chain;
};

/*
 * Unlike current_stack_pointer which simply contains the current value of %r15
 * current_frame_address() returns function stack frame address, which matches
 * %r15 upon function invocation. It may differ from %r15 later if function
 * allocates stack for local variables or new stack frame to call other
 * functions.
 */
#define current_frame_address()						\
	((unsigned long)__builtin_frame_address(0) -			\
	 offsetof(struct stack_frame, back_chain))

static __always_inline unsigned long get_stack_pointer(struct task_struct *task,
						       struct pt_regs *regs)
{
	if (regs)
		return (unsigned long)kernel_stack_pointer(regs);
	if (task == current)
		return current_frame_address();
	return (unsigned long)task->thread.ksp;
}

/*
 * To keep this simple mark register 2-6 as being changed (volatile)

Annotation

Implementation Notes