Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/regset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/pkeys.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "ptrace-decl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) struct pt_regs_offset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 	int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define STR(s)	#s			/* convert to string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define GPR_OFFSET_NAME(num)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	{.name = STR(r##num), .offset = offsetof(struct pt_regs, gpr[num])}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	{.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define REG_OFFSET_END {.name = NULL, .offset = 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static const struct pt_regs_offset regoffset_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	GPR_OFFSET_NAME(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	GPR_OFFSET_NAME(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	GPR_OFFSET_NAME(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	GPR_OFFSET_NAME(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	GPR_OFFSET_NAME(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	GPR_OFFSET_NAME(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	GPR_OFFSET_NAME(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	GPR_OFFSET_NAME(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	GPR_OFFSET_NAME(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	GPR_OFFSET_NAME(9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	GPR_OFFSET_NAME(10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	GPR_OFFSET_NAME(11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	GPR_OFFSET_NAME(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	GPR_OFFSET_NAME(13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	GPR_OFFSET_NAME(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	GPR_OFFSET_NAME(15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	GPR_OFFSET_NAME(16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	GPR_OFFSET_NAME(17),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	GPR_OFFSET_NAME(18),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	GPR_OFFSET_NAME(19),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	GPR_OFFSET_NAME(20),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	GPR_OFFSET_NAME(21),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	GPR_OFFSET_NAME(22),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	GPR_OFFSET_NAME(23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	GPR_OFFSET_NAME(24),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	GPR_OFFSET_NAME(25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	GPR_OFFSET_NAME(26),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	GPR_OFFSET_NAME(27),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	GPR_OFFSET_NAME(28),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	GPR_OFFSET_NAME(29),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	GPR_OFFSET_NAME(30),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	GPR_OFFSET_NAME(31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	REG_OFFSET_NAME(nip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	REG_OFFSET_NAME(msr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	REG_OFFSET_NAME(ctr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	REG_OFFSET_NAME(link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	REG_OFFSET_NAME(xer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	REG_OFFSET_NAME(ccr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	REG_OFFSET_NAME(softe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	REG_OFFSET_NAME(mq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	REG_OFFSET_NAME(trap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	REG_OFFSET_NAME(dar),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	REG_OFFSET_NAME(dsisr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	REG_OFFSET_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * regs_query_register_offset() - query register offset from its name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * @name:	the name of a register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * regs_query_register_offset() returns the offset of a register in struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * pt_regs from its name. If the name is invalid, this returns -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) int regs_query_register_offset(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	const struct pt_regs_offset *roff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	for (roff = regoffset_table; roff->name != NULL; roff++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		if (!strcmp(roff->name, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			return roff->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * regs_query_register_name() - query register name from its offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * @offset:	the offset of a register in struct pt_regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * regs_query_register_name() returns the name of a register from its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) const char *regs_query_register_name(unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	const struct pt_regs_offset *roff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	for (roff = regoffset_table; roff->name != NULL; roff++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		if (roff->offset == offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			return roff->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * does not yet catch signals sent when the child dies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * in exit.c or in signal.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static unsigned long get_user_msr(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return task->thread.regs->msr | task->thread.fpexc_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int set_user_msr(struct task_struct *task, unsigned long msr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	task->thread.regs->msr &= ~MSR_DEBUGCHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	task->thread.regs->msr |= msr & MSR_DEBUGCHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int get_user_dscr(struct task_struct *task, unsigned long *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	*data = task->thread.dscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int set_user_dscr(struct task_struct *task, unsigned long dscr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	task->thread.dscr = dscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	task->thread.dscr_inherit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int get_user_dscr(struct task_struct *task, unsigned long *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int set_user_dscr(struct task_struct *task, unsigned long dscr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * We prevent mucking around with the reserved area of trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * which are used internally by the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int set_user_trap(struct task_struct *task, unsigned long trap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	set_trap(task->thread.regs, trap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * Get contents of register REGNO in task TASK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	unsigned int regs_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (task->thread.regs == NULL || !data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (regno == PT_MSR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		*data = get_user_msr(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	if (regno == PT_DSCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		return get_user_dscr(task, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	 * softe copies paca->irq_soft_mask variable state. Since irq_soft_mask is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	 * no more used as a flag, lets force usr to alway see the softe value as 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	 * which means interrupts are not soft disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (IS_ENABLED(CONFIG_PPC64) && regno == PT_SOFTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		*data = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		return  0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	regs_max = sizeof(struct user_pt_regs) / sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	if (regno < regs_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		regno = array_index_nospec(regno, regs_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		*data = ((unsigned long *)task->thread.regs)[regno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * Write contents of register REGNO in task TASK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	if (task->thread.regs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (regno == PT_MSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return set_user_msr(task, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (regno == PT_TRAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		return set_user_trap(task, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (regno == PT_DSCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		return set_user_dscr(task, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (regno <= PT_MAX_PUT_REG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		regno = array_index_nospec(regno, PT_MAX_PUT_REG + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		((unsigned long *)task->thread.regs)[regno] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int gpr_get(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		   struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (target->thread.regs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (!FULL_REGS(target->thread.regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		/* We have a partial register set.  Fill 14-31 with bogus values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		for (i = 14; i < 32; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			target->thread.regs->gpr[i] = NV_REG_POISON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	membuf_write(&to, target->thread.regs, offsetof(struct pt_regs, msr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	membuf_store(&to, get_user_msr(target));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		     offsetof(struct pt_regs, msr) + sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	membuf_write(&to, &target->thread.regs->orig_gpr3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			sizeof(struct user_pt_regs) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			offsetof(struct pt_regs, orig_gpr3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				 sizeof(struct user_pt_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int gpr_set(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		   unsigned int pos, unsigned int count, const void *kbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		   const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	unsigned long reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (target->thread.regs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	CHECK_FULL_REGS(target->thread.regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 				 target->thread.regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 				 0, PT_MSR * sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (!ret && count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 					 PT_MSR * sizeof(reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 					 (PT_MSR + 1) * sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			ret = set_user_msr(target, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		     offsetof(struct pt_regs, msr) + sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 					 &target->thread.regs->orig_gpr3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 					 PT_ORIG_R3 * sizeof(reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 					 (PT_MAX_PUT_REG + 1) * sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 						(PT_MAX_PUT_REG + 1) * sizeof(reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 						PT_TRAP * sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	if (!ret && count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 					 PT_TRAP * sizeof(reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 					 (PT_TRAP + 1) * sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			ret = set_user_trap(target, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 						(PT_TRAP + 1) * sizeof(reg), -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int ppr_get(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		   struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	return membuf_write(&to, &target->thread.regs->ppr, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int ppr_set(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		   unsigned int pos, unsigned int count, const void *kbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		   const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				  &target->thread.regs->ppr, 0, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int dscr_get(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		    struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	return membuf_write(&to, &target->thread.dscr, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int dscr_set(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		    unsigned int pos, unsigned int count, const void *kbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		    const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 				  &target->thread.dscr, 0, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #ifdef CONFIG_PPC_BOOK3S_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static int tar_get(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		   struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return membuf_write(&to, &target->thread.tar, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int tar_set(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		   unsigned int pos, unsigned int count, const void *kbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		   const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 				  &target->thread.tar, 0, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int ebb_active(struct task_struct *target, const struct user_regset *regset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (target->thread.used_ebb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		return regset->n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int ebb_get(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		   struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	/* Build tests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (!target->thread.used_ebb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	return membuf_write(&to, &target->thread.ebbrr, 3 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static int ebb_set(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		   unsigned int pos, unsigned int count, const void *kbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		   const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	/* Build tests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	if (target->thread.used_ebb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ebbrr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 				 0, sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 					 &target->thread.ebbhr, sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 					 2 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 					 &target->thread.bescr, 2 * sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 					 3 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static int pmu_active(struct task_struct *target, const struct user_regset *regset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	return regset->n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static int pmu_get(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		   struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	/* Build tests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) != TSO(sdar));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	BUILD_BUG_ON(TSO(sdar) + sizeof(unsigned long) != TSO(sier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	BUILD_BUG_ON(TSO(sier) + sizeof(unsigned long) != TSO(mmcr2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	BUILD_BUG_ON(TSO(mmcr2) + sizeof(unsigned long) != TSO(mmcr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	return membuf_write(&to, &target->thread.siar, 5 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int pmu_set(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		   unsigned int pos, unsigned int count, const void *kbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		   const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	/* Build tests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) != TSO(sdar));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	BUILD_BUG_ON(TSO(sdar) + sizeof(unsigned long) != TSO(sier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	BUILD_BUG_ON(TSO(sier) + sizeof(unsigned long) != TSO(mmcr2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	BUILD_BUG_ON(TSO(mmcr2) + sizeof(unsigned long) != TSO(mmcr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.siar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 				 0, sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 					 &target->thread.sdar, sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 					 2 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 					 &target->thread.sier, 2 * sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 					 3 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 					 &target->thread.mmcr2, 3 * sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 					 4 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 					 &target->thread.mmcr0, 4 * sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 					 5 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #ifdef CONFIG_PPC_MEM_KEYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int pkey_active(struct task_struct *target, const struct user_regset *regset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (!arch_pkeys_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	return regset->n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int pkey_get(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		    struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	BUILD_BUG_ON(TSO(amr) + sizeof(unsigned long) != TSO(iamr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	if (!arch_pkeys_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	membuf_write(&to, &target->thread.amr, 2 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	return membuf_store(&to, default_uamor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int pkey_set(struct task_struct *target, const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		    unsigned int pos, unsigned int count, const void *kbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		    const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	u64 new_amr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	if (!arch_pkeys_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	/* Only the AMR can be set from userspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (pos != 0 || count != sizeof(new_amr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 				 &new_amr, 0, sizeof(new_amr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	 * UAMOR determines which bits of the AMR can be set from userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	 * UAMOR value 0b11 indicates that the AMR value can be modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	 * from userspace. If the kernel is using a specific key, we avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	 * userspace modifying the AMR value for that key by masking them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	 * via UAMOR 0b00.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	 * Pick the AMR values for the keys that kernel is using. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	 * will be indicated by the ~default_uamor bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	target->thread.amr = (new_amr & default_uamor) | (target->thread.amr & ~default_uamor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #endif /* CONFIG_PPC_MEM_KEYS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static const struct user_regset native_regsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	[REGSET_GPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		.core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		.size = sizeof(long), .align = sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		.regset_get = gpr_get, .set = gpr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	[REGSET_FPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		.size = sizeof(double), .align = sizeof(double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		.regset_get = fpr_get, .set = fpr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #ifdef CONFIG_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	[REGSET_VMX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		.core_note_type = NT_PPC_VMX, .n = 34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		.size = sizeof(vector128), .align = sizeof(vector128),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		.active = vr_active, .regset_get = vr_get, .set = vr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	[REGSET_VSX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		.core_note_type = NT_PPC_VSX, .n = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		.size = sizeof(double), .align = sizeof(double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		.active = vsr_active, .regset_get = vsr_get, .set = vsr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) #ifdef CONFIG_SPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	[REGSET_SPE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		.core_note_type = NT_PPC_SPE, .n = 35,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		.size = sizeof(u32), .align = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		.active = evr_active, .regset_get = evr_get, .set = evr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	[REGSET_TM_CGPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		.core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		.size = sizeof(long), .align = sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		.active = tm_cgpr_active, .regset_get = tm_cgpr_get, .set = tm_cgpr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	[REGSET_TM_CFPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		.core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		.size = sizeof(double), .align = sizeof(double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		.active = tm_cfpr_active, .regset_get = tm_cfpr_get, .set = tm_cfpr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	[REGSET_TM_CVMX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		.core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		.size = sizeof(vector128), .align = sizeof(vector128),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		.active = tm_cvmx_active, .regset_get = tm_cvmx_get, .set = tm_cvmx_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	[REGSET_TM_CVSX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		.core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		.size = sizeof(double), .align = sizeof(double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		.active = tm_cvsx_active, .regset_get = tm_cvsx_get, .set = tm_cvsx_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	[REGSET_TM_SPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		.core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		.active = tm_spr_active, .regset_get = tm_spr_get, .set = tm_spr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	[REGSET_TM_CTAR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		.core_note_type = NT_PPC_TM_CTAR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		.active = tm_tar_active, .regset_get = tm_tar_get, .set = tm_tar_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	[REGSET_TM_CPPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		.core_note_type = NT_PPC_TM_CPPR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		.active = tm_ppr_active, .regset_get = tm_ppr_get, .set = tm_ppr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	[REGSET_TM_CDSCR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		.core_note_type = NT_PPC_TM_CDSCR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		.active = tm_dscr_active, .regset_get = tm_dscr_get, .set = tm_dscr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	[REGSET_PPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		.core_note_type = NT_PPC_PPR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		.regset_get = ppr_get, .set = ppr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	[REGSET_DSCR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		.core_note_type = NT_PPC_DSCR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		.regset_get = dscr_get, .set = dscr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) #ifdef CONFIG_PPC_BOOK3S_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	[REGSET_TAR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		.core_note_type = NT_PPC_TAR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		.regset_get = tar_get, .set = tar_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	[REGSET_EBB] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		.core_note_type = NT_PPC_EBB, .n = ELF_NEBB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		.active = ebb_active, .regset_get = ebb_get, .set = ebb_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	[REGSET_PMR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		.core_note_type = NT_PPC_PMU, .n = ELF_NPMU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		.active = pmu_active, .regset_get = pmu_get, .set = pmu_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #ifdef CONFIG_PPC_MEM_KEYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	[REGSET_PKEY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		.core_note_type = NT_PPC_PKEY, .n = ELF_NPKEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		.active = pkey_active, .regset_get = pkey_get, .set = pkey_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) const struct user_regset_view user_ppc_native_view = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	.name = UTS_MACHINE, .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) int gpr32_get_common(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		     const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		     struct membuf to, unsigned long *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	for (i = 0; i < PT_MSR; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		membuf_store(&to, (u32)regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	membuf_store(&to, (u32)get_user_msr(target));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	for (i++ ; i < PT_REGS_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		membuf_store(&to, (u32)regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	return membuf_zero(&to, (ELF_NGREG - PT_REGS_COUNT) * sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int gpr32_set_common(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		     const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		     unsigned int pos, unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		     const void *kbuf, const void __user *ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		     unsigned long *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	const compat_ulong_t *k = kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	const compat_ulong_t __user *u = ubuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	compat_ulong_t reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	pos /= sizeof(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	count /= sizeof(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	if (kbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		for (; count > 0 && pos < PT_MSR; --count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			regs[pos++] = *k++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		for (; count > 0 && pos < PT_MSR; --count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			if (__get_user(reg, u++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 				return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			regs[pos++] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	if (count > 0 && pos == PT_MSR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		if (kbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 			reg = *k++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		else if (__get_user(reg, u++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		set_user_msr(target, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		++pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		--count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (kbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		for (; count > 0 && pos <= PT_MAX_PUT_REG; --count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 			regs[pos++] = *k++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		for (; count > 0 && pos < PT_TRAP; --count, ++pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			++k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 			if (__get_user(reg, u++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 				return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 			regs[pos++] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		for (; count > 0 && pos < PT_TRAP; --count, ++pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 			if (__get_user(reg, u++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 				return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	if (count > 0 && pos == PT_TRAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		if (kbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 			reg = *k++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		else if (__get_user(reg, u++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		set_user_trap(target, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		++pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		--count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	kbuf = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	ubuf = u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	pos *= sizeof(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	count *= sizeof(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 					 (PT_TRAP + 1) * sizeof(reg), -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static int gpr32_get(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		     const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		     struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	if (target->thread.regs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	if (!FULL_REGS(target->thread.regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 		 * We have a partial register set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		 * Fill 14-31 with bogus values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		for (i = 14; i < 32; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 			target->thread.regs->gpr[i] = NV_REG_POISON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	return gpr32_get_common(target, regset, to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 			&target->thread.regs->gpr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static int gpr32_set(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		     const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		     unsigned int pos, unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		     const void *kbuf, const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	if (target->thread.regs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	CHECK_FULL_REGS(target->thread.regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 			&target->thread.regs->gpr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)  * These are the regset flavors matching the CONFIG_PPC32 native set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static const struct user_regset compat_regsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	[REGSET_GPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		.core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		.size = sizeof(compat_long_t), .align = sizeof(compat_long_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		.regset_get = gpr32_get, .set = gpr32_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	[REGSET_FPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		.size = sizeof(double), .align = sizeof(double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		.regset_get = fpr_get, .set = fpr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) #ifdef CONFIG_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	[REGSET_VMX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		.core_note_type = NT_PPC_VMX, .n = 34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 		.size = sizeof(vector128), .align = sizeof(vector128),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		.active = vr_active, .regset_get = vr_get, .set = vr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) #ifdef CONFIG_SPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	[REGSET_SPE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 		.core_note_type = NT_PPC_SPE, .n = 35,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		.size = sizeof(u32), .align = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		.active = evr_active, .regset_get = evr_get, .set = evr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	[REGSET_TM_CGPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		.core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		.size = sizeof(long), .align = sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		.active = tm_cgpr_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		.regset_get = tm_cgpr32_get, .set = tm_cgpr32_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	[REGSET_TM_CFPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		.core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		.size = sizeof(double), .align = sizeof(double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		.active = tm_cfpr_active, .regset_get = tm_cfpr_get, .set = tm_cfpr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	[REGSET_TM_CVMX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 		.core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		.size = sizeof(vector128), .align = sizeof(vector128),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		.active = tm_cvmx_active, .regset_get = tm_cvmx_get, .set = tm_cvmx_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	[REGSET_TM_CVSX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 		.core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		.size = sizeof(double), .align = sizeof(double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 		.active = tm_cvsx_active, .regset_get = tm_cvsx_get, .set = tm_cvsx_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	[REGSET_TM_SPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		.core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		.active = tm_spr_active, .regset_get = tm_spr_get, .set = tm_spr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	[REGSET_TM_CTAR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		.core_note_type = NT_PPC_TM_CTAR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 		.active = tm_tar_active, .regset_get = tm_tar_get, .set = tm_tar_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	[REGSET_TM_CPPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 		.core_note_type = NT_PPC_TM_CPPR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		.active = tm_ppr_active, .regset_get = tm_ppr_get, .set = tm_ppr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	[REGSET_TM_CDSCR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 		.core_note_type = NT_PPC_TM_CDSCR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 		.active = tm_dscr_active, .regset_get = tm_dscr_get, .set = tm_dscr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	[REGSET_PPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		.core_note_type = NT_PPC_PPR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 		.regset_get = ppr_get, .set = ppr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	[REGSET_DSCR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		.core_note_type = NT_PPC_DSCR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 		.regset_get = dscr_get, .set = dscr_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) #ifdef CONFIG_PPC_BOOK3S_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	[REGSET_TAR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 		.core_note_type = NT_PPC_TAR, .n = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 		.regset_get = tar_get, .set = tar_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	[REGSET_EBB] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		.core_note_type = NT_PPC_EBB, .n = ELF_NEBB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		.size = sizeof(u64), .align = sizeof(u64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		.active = ebb_active, .regset_get = ebb_get, .set = ebb_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static const struct user_regset_view user_ppc_compat_view = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	.name = "ppc", .e_machine = EM_PPC, .ei_osabi = ELF_OSABI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	.regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) const struct user_regset_view *task_user_regset_view(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	if (IS_ENABLED(CONFIG_PPC64) && test_tsk_thread_flag(task, TIF_32BIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 		return &user_ppc_compat_view;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	return &user_ppc_native_view;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }