mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-12 16:58:53 +00:00
s390: add support for transactional memory
Allow user-space processes to use transactional execution (TX). If the TX facility is available user space programs can use transactions for fine-grained serialization based on the data objects that are referenced during a transaction. This is useful for lockless data structures and speculative compiler optimizations. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
e4b8b3f33f
commit
d35339a42d
@ -101,6 +101,7 @@
|
||||
#define HWCAP_S390_HPAGE 128
|
||||
#define HWCAP_S390_ETF3EH 256
|
||||
#define HWCAP_S390_HIGH_GPRS 512
|
||||
#define HWCAP_S390_TE 1024
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
|
@ -329,9 +329,13 @@ struct _lowcore {
|
||||
__u8 pad_0x1338[0x1340-0x1338]; /* 0x1338 */
|
||||
__u32 access_regs_save_area[16]; /* 0x1340 */
|
||||
__u64 cregs_save_area[16]; /* 0x1380 */
|
||||
__u8 pad_0x1400[0x1800-0x1400]; /* 0x1400 */
|
||||
|
||||
/* Transaction abort diagnostic block */
|
||||
__u8 pgm_tdb[256]; /* 0x1800 */
|
||||
|
||||
/* align to the top of the prefix area */
|
||||
__u8 pad_0x1400[0x2000-0x1400]; /* 0x1400 */
|
||||
__u8 pad_0x1900[0x2000-0x1900]; /* 0x1900 */
|
||||
} __packed;
|
||||
|
||||
#endif /* CONFIG_32BIT */
|
||||
|
@ -76,14 +76,20 @@ struct thread_struct {
|
||||
unsigned long gmap_addr; /* address of last gmap fault. */
|
||||
struct per_regs per_user; /* User specified PER registers */
|
||||
struct per_event per_event; /* Cause of the last PER trap */
|
||||
unsigned long per_flags; /* Flags to control debug behavior */
|
||||
/* pfault_wait is used to block the process on a pfault event */
|
||||
unsigned long pfault_wait;
|
||||
struct list_head list;
|
||||
/* cpu runtime instrumentation */
|
||||
struct runtime_instr_cb *ri_cb;
|
||||
int ri_signum;
|
||||
#ifdef CONFIG_64BIT
|
||||
unsigned char trap_tdb[256]; /* Transaction abort diagnose block */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define PER_FLAG_NO_TE 1UL /* Flag to disable transactions. */
|
||||
|
||||
typedef struct thread_struct thread_struct;
|
||||
|
||||
/*
|
||||
|
@ -361,17 +361,19 @@ struct per_struct_kernel {
|
||||
unsigned char access_id; /* PER trap access identification */
|
||||
};
|
||||
|
||||
#define PER_EVENT_MASK 0xE9000000UL
|
||||
#define PER_EVENT_MASK 0xEB000000UL
|
||||
|
||||
#define PER_EVENT_BRANCH 0x80000000UL
|
||||
#define PER_EVENT_IFETCH 0x40000000UL
|
||||
#define PER_EVENT_STORE 0x20000000UL
|
||||
#define PER_EVENT_STORE_REAL 0x08000000UL
|
||||
#define PER_EVENT_TRANSACTION_END 0x02000000UL
|
||||
#define PER_EVENT_NULLIFICATION 0x01000000UL
|
||||
|
||||
#define PER_CONTROL_MASK 0x00a00000UL
|
||||
#define PER_CONTROL_MASK 0x00e00000UL
|
||||
|
||||
#define PER_CONTROL_BRANCH_ADDRESS 0x00800000UL
|
||||
#define PER_CONTROL_SUSPENSION 0x00400000UL
|
||||
#define PER_CONTROL_ALTERATION 0x00200000UL
|
||||
|
||||
#endif
|
||||
@ -485,6 +487,8 @@ typedef struct
|
||||
#define PTRACE_GET_LAST_BREAK 0x5006
|
||||
#define PTRACE_PEEK_SYSTEM_CALL 0x5007
|
||||
#define PTRACE_POKE_SYSTEM_CALL 0x5008
|
||||
#define PTRACE_ENABLE_TE 0x5009
|
||||
#define PTRACE_DISABLE_TE 0x5010
|
||||
|
||||
/*
|
||||
* PT_PROT definition is loosely based on hppa bsd definition in
|
||||
|
@ -80,6 +80,7 @@ extern unsigned int addressing_mode;
|
||||
#define MACHINE_FLAG_LPAR (1UL << 12)
|
||||
#define MACHINE_FLAG_SPP (1UL << 13)
|
||||
#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
|
||||
#define MACHINE_FLAG_TE (1UL << 15)
|
||||
|
||||
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
|
||||
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
|
||||
@ -98,6 +99,7 @@ extern unsigned int addressing_mode;
|
||||
#define MACHINE_HAS_PFMF (0)
|
||||
#define MACHINE_HAS_SPP (0)
|
||||
#define MACHINE_HAS_TOPOLOGY (0)
|
||||
#define MACHINE_HAS_TE (0)
|
||||
#else /* CONFIG_64BIT */
|
||||
#define MACHINE_HAS_IEEE (1)
|
||||
#define MACHINE_HAS_CSP (1)
|
||||
@ -109,6 +111,7 @@ extern unsigned int addressing_mode;
|
||||
#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
|
||||
#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
|
||||
#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
|
||||
#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
#define ZFCPDUMP_HSA_SIZE (32UL<<20)
|
||||
|
@ -157,6 +157,8 @@ int main(void)
|
||||
DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
|
||||
DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
|
||||
DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
|
||||
DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb));
|
||||
DEFINE(__THREAD_trap_tdb, offsetof(struct task_struct, thread.trap_tdb));
|
||||
DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
|
||||
#endif /* CONFIG_32BIT */
|
||||
return 0;
|
||||
|
@ -317,6 +317,9 @@ enum {
|
||||
LONG_INSN_RISBLG,
|
||||
LONG_INSN_RINEXT,
|
||||
LONG_INSN_RIEMIT,
|
||||
LONG_INSN_TABORT,
|
||||
LONG_INSN_TBEGIN,
|
||||
LONG_INSN_TBEGINC,
|
||||
};
|
||||
|
||||
static char *long_insn_name[] = {
|
||||
@ -334,6 +337,9 @@ static char *long_insn_name[] = {
|
||||
[LONG_INSN_RISBLG] = "risblk",
|
||||
[LONG_INSN_RINEXT] = "rinext",
|
||||
[LONG_INSN_RIEMIT] = "riemit",
|
||||
[LONG_INSN_TABORT] = "tabort",
|
||||
[LONG_INSN_TBEGIN] = "tbegin",
|
||||
[LONG_INSN_TBEGINC] = "tbeginc",
|
||||
};
|
||||
|
||||
static struct insn opcode[] = {
|
||||
@ -609,6 +615,9 @@ static struct insn opcode_b2[] = {
|
||||
{ "lpswe", 0xb2, INSTR_S_RD },
|
||||
{ "srnmt", 0xb9, INSTR_S_RD },
|
||||
{ "lfas", 0xbd, INSTR_S_RD },
|
||||
{ "etndg", 0xec, INSTR_RRE_R0 },
|
||||
{ { 0, LONG_INSN_TABORT }, 0xfc, INSTR_S_RD },
|
||||
{ "tend", 0xf8, INSTR_S_RD },
|
||||
#endif
|
||||
{ "stidp", 0x02, INSTR_S_RD },
|
||||
{ "sck", 0x04, INSTR_S_RD },
|
||||
@ -1165,6 +1174,7 @@ static struct insn opcode_e3[] = {
|
||||
{ "stfh", 0xcb, INSTR_RXY_RRRD },
|
||||
{ "chf", 0xcd, INSTR_RXY_RRRD },
|
||||
{ "clhf", 0xcf, INSTR_RXY_RRRD },
|
||||
{ "ntstg", 0x25, INSTR_RXY_RRRD },
|
||||
#endif
|
||||
{ "lrv", 0x1e, INSTR_RXY_RRRD },
|
||||
{ "lrvh", 0x1f, INSTR_RXY_RRRD },
|
||||
@ -1188,6 +1198,8 @@ static struct insn opcode_e5[] = {
|
||||
{ "mvhhi", 0x44, INSTR_SIL_RDI },
|
||||
{ "mvhi", 0x4c, INSTR_SIL_RDI },
|
||||
{ "mvghi", 0x48, INSTR_SIL_RDI },
|
||||
{ { 0, LONG_INSN_TBEGIN }, 0x60, INSTR_SIL_RDU },
|
||||
{ { 0, LONG_INSN_TBEGINC }, 0x61, INSTR_SIL_RDU },
|
||||
#endif
|
||||
{ "lasp", 0x00, INSTR_SSE_RDRD },
|
||||
{ "tprot", 0x01, INSTR_SSE_RDRD },
|
||||
|
@ -370,6 +370,8 @@ static __init void detect_machine_facilities(void)
|
||||
S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
|
||||
if (test_facility(40))
|
||||
S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
|
||||
if (test_facility(50) && test_facility(73))
|
||||
S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -439,7 +441,6 @@ static void __init setup_boot_command_line(void)
|
||||
append_to_cmdline(append_ipl_scpdata);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save ipl parameters, clear bss memory, initialize storage keys
|
||||
* and create a kernel NSS at startup if the SAVESYS= parm is defined
|
||||
|
@ -412,6 +412,11 @@ ENTRY(pgm_check_handler)
|
||||
1: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
|
||||
LAST_BREAK %r14
|
||||
lg %r15,__LC_KERNEL_STACK
|
||||
lg %r14,__TI_task(%r12)
|
||||
lghi %r13,__LC_PGM_TDB
|
||||
tm __LC_PGM_ILC+2,0x02 # check for transaction abort
|
||||
jz 2f
|
||||
mvc __THREAD_trap_tdb(256,%r14),0(%r13)
|
||||
2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
|
||||
la %r11,STACK_FRAME_OVERHEAD(%r15)
|
||||
stmg %r0,%r7,__PT_R0(%r11)
|
||||
@ -422,13 +427,12 @@ ENTRY(pgm_check_handler)
|
||||
stg %r10,__PT_ARGS(%r11)
|
||||
tm __LC_PGM_ILC+3,0x80 # check for per exception
|
||||
jz 0f
|
||||
lg %r1,__TI_task(%r12)
|
||||
tmhh %r8,0x0001 # kernel per event ?
|
||||
jz pgm_kprobe
|
||||
oi __TI_flags+7(%r12),_TIF_PER_TRAP
|
||||
mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
|
||||
mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
|
||||
mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
|
||||
mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS
|
||||
mvc __THREAD_per_cause(2,%r14),__LC_PER_CAUSE
|
||||
mvc __THREAD_per_paid(1,%r14),__LC_PER_PAID
|
||||
0: REENABLE_IRQS
|
||||
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
||||
larl %r1,pgm_check_table
|
||||
|
@ -39,9 +39,9 @@ void __cpuinit cpu_init(void)
|
||||
*/
|
||||
static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
{
|
||||
static const char *hwcap_str[10] = {
|
||||
static const char *hwcap_str[11] = {
|
||||
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
|
||||
"edat", "etf3eh", "highgprs"
|
||||
"edat", "etf3eh", "highgprs", "te"
|
||||
};
|
||||
unsigned long n = (unsigned long) v - 1;
|
||||
int i;
|
||||
@ -54,7 +54,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
num_online_cpus(), loops_per_jiffy/(500000/HZ),
|
||||
(loops_per_jiffy/(5000/HZ))%100);
|
||||
seq_puts(m, "features\t: ");
|
||||
for (i = 0; i < 10; i++)
|
||||
for (i = 0; i < 11; i++)
|
||||
if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
|
||||
seq_printf(m, "%s ", hwcap_str[i]);
|
||||
seq_puts(m, "\n");
|
||||
|
@ -42,6 +42,7 @@ enum s390_regset {
|
||||
REGSET_GENERAL,
|
||||
REGSET_FP,
|
||||
REGSET_LAST_BREAK,
|
||||
REGSET_TDB,
|
||||
REGSET_SYSTEM_CALL,
|
||||
REGSET_GENERAL_EXTENDED,
|
||||
};
|
||||
@ -52,6 +53,21 @@ void update_per_regs(struct task_struct *task)
|
||||
struct thread_struct *thread = &task->thread;
|
||||
struct per_regs old, new;
|
||||
|
||||
/* Take care of the enable/disable of transactional execution. */
|
||||
if (MACHINE_HAS_TE) {
|
||||
unsigned long cr0, cr0_new;
|
||||
|
||||
__ctl_store(cr0, 0, 0);
|
||||
/* set or clear transaction execution bits 8 and 9. */
|
||||
if (task->thread.per_flags & PER_FLAG_NO_TE)
|
||||
cr0_new = cr0 & ~(3UL << 54);
|
||||
else
|
||||
cr0_new = cr0 | (3UL << 54);
|
||||
/* Only load control register 0 if necessary. */
|
||||
if (cr0 != cr0_new)
|
||||
__ctl_load(cr0_new, 0, 0);
|
||||
}
|
||||
|
||||
/* Copy user specified PER registers */
|
||||
new.control = thread->per_user.control;
|
||||
new.start = thread->per_user.start;
|
||||
@ -60,6 +76,10 @@ void update_per_regs(struct task_struct *task)
|
||||
/* merge TIF_SINGLE_STEP into user specified PER registers. */
|
||||
if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) {
|
||||
new.control |= PER_EVENT_IFETCH;
|
||||
#ifdef CONFIG_64BIT
|
||||
new.control |= PER_CONTROL_SUSPENSION;
|
||||
new.control |= PER_EVENT_TRANSACTION_END;
|
||||
#endif
|
||||
new.start = 0;
|
||||
new.end = PSW_ADDR_INSN;
|
||||
}
|
||||
@ -100,6 +120,7 @@ void ptrace_disable(struct task_struct *task)
|
||||
memset(&task->thread.per_event, 0, sizeof(task->thread.per_event));
|
||||
clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
|
||||
clear_tsk_thread_flag(task, TIF_PER_TRAP);
|
||||
task->thread.per_flags = 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
@ -416,6 +437,16 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
put_user(task_thread_info(child)->last_break,
|
||||
(unsigned long __user *) data);
|
||||
return 0;
|
||||
case PTRACE_ENABLE_TE:
|
||||
if (!MACHINE_HAS_TE)
|
||||
return -EIO;
|
||||
child->thread.per_flags &= ~PER_FLAG_NO_TE;
|
||||
return 0;
|
||||
case PTRACE_DISABLE_TE:
|
||||
if (!MACHINE_HAS_TE)
|
||||
return -EIO;
|
||||
child->thread.per_flags |= PER_FLAG_NO_TE;
|
||||
return 0;
|
||||
default:
|
||||
/* Removing high order bit from addr (only for 31 bit). */
|
||||
addr &= PSW_ADDR_INSN;
|
||||
@ -903,6 +934,28 @@ static int s390_last_break_set(struct task_struct *target,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s390_tdb_get(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf)
|
||||
{
|
||||
struct pt_regs *regs = task_pt_regs(target);
|
||||
unsigned char *data;
|
||||
|
||||
if (!(regs->int_code & 0x200))
|
||||
return -ENODATA;
|
||||
data = target->thread.trap_tdb;
|
||||
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, data, 0, 256);
|
||||
}
|
||||
|
||||
static int s390_tdb_set(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int s390_system_call_get(struct task_struct *target,
|
||||
@ -951,6 +1004,14 @@ static const struct user_regset s390_regsets[] = {
|
||||
.get = s390_last_break_get,
|
||||
.set = s390_last_break_set,
|
||||
},
|
||||
[REGSET_TDB] = {
|
||||
.core_note_type = NT_S390_TDB,
|
||||
.n = 1,
|
||||
.size = 256,
|
||||
.align = 1,
|
||||
.get = s390_tdb_get,
|
||||
.set = s390_tdb_set,
|
||||
},
|
||||
#endif
|
||||
[REGSET_SYSTEM_CALL] = {
|
||||
.core_note_type = NT_S390_SYSTEM_CALL,
|
||||
@ -1148,6 +1209,14 @@ static const struct user_regset s390_compat_regsets[] = {
|
||||
.get = s390_compat_last_break_get,
|
||||
.set = s390_compat_last_break_set,
|
||||
},
|
||||
[REGSET_TDB] = {
|
||||
.core_note_type = NT_S390_TDB,
|
||||
.n = 1,
|
||||
.size = 256,
|
||||
.align = 1,
|
||||
.get = s390_tdb_get,
|
||||
.set = s390_tdb_set,
|
||||
},
|
||||
[REGSET_SYSTEM_CALL] = {
|
||||
.core_note_type = NT_S390_SYSTEM_CALL,
|
||||
.n = 1,
|
||||
|
@ -980,6 +980,12 @@ static void __init setup_hwcaps(void)
|
||||
* HWCAP_S390_HIGH_GPRS is bit 9.
|
||||
*/
|
||||
elf_hwcap |= HWCAP_S390_HIGH_GPRS;
|
||||
|
||||
/*
|
||||
* Transactional execution support HWCAP_S390_TE is bit 10.
|
||||
*/
|
||||
if (test_facility(50) && test_facility(73))
|
||||
elf_hwcap |= HWCAP_S390_TE;
|
||||
#endif
|
||||
|
||||
get_cpu_id(&cpu_id);
|
||||
|
@ -57,6 +57,23 @@ static int kstack_depth_to_print = 12;
|
||||
static int kstack_depth_to_print = 20;
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
static inline void __user *get_trap_ip(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
unsigned long address;
|
||||
|
||||
if (regs->int_code & 0x200)
|
||||
address = *(unsigned long *)(current->thread.trap_tdb + 24);
|
||||
else
|
||||
address = regs->psw.addr;
|
||||
return (void __user *)
|
||||
((address - (regs->int_code >> 16)) & PSW_ADDR_INSN);
|
||||
#else
|
||||
return (void __user *)
|
||||
((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* For show_trace we have tree different stack to consider:
|
||||
* - the panic stack which is used if the kernel stack has overflown
|
||||
@ -285,12 +302,6 @@ int is_valid_bugaddr(unsigned long addr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void __user *get_psw_address(struct pt_regs *regs)
|
||||
{
|
||||
return (void __user *)
|
||||
((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
|
||||
}
|
||||
|
||||
static void __kprobes do_trap(struct pt_regs *regs,
|
||||
int si_signo, int si_code, char *str)
|
||||
{
|
||||
@ -304,7 +315,7 @@ static void __kprobes do_trap(struct pt_regs *regs,
|
||||
info.si_signo = si_signo;
|
||||
info.si_errno = 0;
|
||||
info.si_code = si_code;
|
||||
info.si_addr = get_psw_address(regs);
|
||||
info.si_addr = get_trap_ip(regs);
|
||||
force_sig_info(si_signo, &info, current);
|
||||
report_user_fault(regs, si_signo);
|
||||
} else {
|
||||
@ -381,6 +392,11 @@ DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
|
||||
DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
|
||||
"translation exception")
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN,
|
||||
"transaction constraint exception")
|
||||
#endif
|
||||
|
||||
static inline void do_fp_trap(struct pt_regs *regs, int fpc)
|
||||
{
|
||||
int si_code = 0;
|
||||
@ -408,7 +424,7 @@ static void __kprobes illegal_op(struct pt_regs *regs)
|
||||
__u16 __user *location;
|
||||
int signal = 0;
|
||||
|
||||
location = get_psw_address(regs);
|
||||
location = get_trap_ip(regs);
|
||||
|
||||
if (user_mode(regs)) {
|
||||
if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
|
||||
@ -476,7 +492,7 @@ void specification_exception(struct pt_regs *regs)
|
||||
__u16 __user *location = NULL;
|
||||
int signal = 0;
|
||||
|
||||
location = (__u16 __user *) get_psw_address(regs);
|
||||
location = (__u16 __user *) get_trap_ip(regs);
|
||||
|
||||
if (user_mode(regs)) {
|
||||
get_user(*((__u16 *) opcode), location);
|
||||
@ -525,7 +541,7 @@ static void data_exception(struct pt_regs *regs)
|
||||
__u16 __user *location;
|
||||
int signal = 0;
|
||||
|
||||
location = get_psw_address(regs);
|
||||
location = get_trap_ip(regs);
|
||||
|
||||
if (MACHINE_HAS_IEEE)
|
||||
asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
|
||||
@ -641,6 +657,7 @@ void __init trap_init(void)
|
||||
pgm_check_table[0x12] = &translation_exception;
|
||||
pgm_check_table[0x13] = &special_op_exception;
|
||||
#ifdef CONFIG_64BIT
|
||||
pgm_check_table[0x18] = &transaction_exception;
|
||||
pgm_check_table[0x38] = &do_asce_exception;
|
||||
pgm_check_table[0x39] = &do_dat_exception;
|
||||
pgm_check_table[0x3A] = &do_dat_exception;
|
||||
|
@ -387,6 +387,7 @@ typedef struct elf64_shdr {
|
||||
#define NT_S390_PREFIX 0x305 /* s390 prefix register */
|
||||
#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
|
||||
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
|
||||
#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
|
||||
#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user