Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
bffc880b
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
bffc880b
编写于
3月 22, 2017
作者:
M
Martin Schwidefsky
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'guarded-storage' into 'features' to make merging with
the KVM tree easier.
上级
ca681ec8
916cda1a
变更
27
隐藏空白更改
内联
并排
Showing
27 changed file
with
436 addition
and
46 deletion
+436
-46
arch/s390/include/asm/elf.h
arch/s390/include/asm/elf.h
+1
-0
arch/s390/include/asm/lowcore.h
arch/s390/include/asm/lowcore.h
+3
-6
arch/s390/include/asm/nmi.h
arch/s390/include/asm/nmi.h
+11
-1
arch/s390/include/asm/processor.h
arch/s390/include/asm/processor.h
+5
-0
arch/s390/include/asm/setup.h
arch/s390/include/asm/setup.h
+2
-0
arch/s390/include/asm/switch_to.h
arch/s390/include/asm/switch_to.h
+3
-0
arch/s390/include/asm/thread_info.h
arch/s390/include/asm/thread_info.h
+7
-5
arch/s390/include/uapi/asm/Kbuild
arch/s390/include/uapi/asm/Kbuild
+1
-0
arch/s390/include/uapi/asm/guarded_storage.h
arch/s390/include/uapi/asm/guarded_storage.h
+77
-0
arch/s390/include/uapi/asm/unistd.h
arch/s390/include/uapi/asm/unistd.h
+1
-1
arch/s390/kernel/Makefile
arch/s390/kernel/Makefile
+1
-1
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/asm-offsets.c
+1
-1
arch/s390/kernel/compat_wrapper.c
arch/s390/kernel/compat_wrapper.c
+1
-0
arch/s390/kernel/early.c
arch/s390/kernel/early.c
+2
-0
arch/s390/kernel/entry.S
arch/s390/kernel/entry.S
+25
-1
arch/s390/kernel/entry.h
arch/s390/kernel/entry.h
+2
-0
arch/s390/kernel/guarded_storage.c
arch/s390/kernel/guarded_storage.c
+128
-0
arch/s390/kernel/machine_kexec.c
arch/s390/kernel/machine_kexec.c
+12
-1
arch/s390/kernel/nmi.c
arch/s390/kernel/nmi.c
+17
-2
arch/s390/kernel/process.c
arch/s390/kernel/process.c
+6
-1
arch/s390/kernel/processor.c
arch/s390/kernel/processor.c
+1
-1
arch/s390/kernel/ptrace.c
arch/s390/kernel/ptrace.c
+72
-14
arch/s390/kernel/setup.c
arch/s390/kernel/setup.c
+15
-3
arch/s390/kernel/smp.c
arch/s390/kernel/smp.c
+38
-5
arch/s390/kernel/syscalls.S
arch/s390/kernel/syscalls.S
+1
-1
arch/s390/kvm/interrupt.c
arch/s390/kvm/interrupt.c
+2
-2
include/uapi/linux/elf.h
include/uapi/linux/elf.h
+1
-0
未找到文件。
arch/s390/include/asm/elf.h
浏览文件 @
bffc880b
...
@@ -105,6 +105,7 @@
...
@@ -105,6 +105,7 @@
#define HWCAP_S390_VXRS 2048
#define HWCAP_S390_VXRS 2048
#define HWCAP_S390_VXRS_BCD 4096
#define HWCAP_S390_VXRS_BCD 4096
#define HWCAP_S390_VXRS_EXT 8192
#define HWCAP_S390_VXRS_EXT 8192
#define HWCAP_S390_GS 16384
/* Internal bits, not exposed via elf */
/* Internal bits, not exposed via elf */
#define HWCAP_INT_SIE 1UL
#define HWCAP_INT_SIE 1UL
...
...
arch/s390/include/asm/lowcore.h
浏览文件 @
bffc880b
...
@@ -157,8 +157,8 @@ struct lowcore {
...
@@ -157,8 +157,8 @@ struct lowcore {
__u64
stfle_fac_list
[
32
];
/* 0x0f00 */
__u64
stfle_fac_list
[
32
];
/* 0x0f00 */
__u8
pad_0x1000
[
0x11b0
-
0x1000
];
/* 0x1000 */
__u8
pad_0x1000
[
0x11b0
-
0x1000
];
/* 0x1000 */
/* Pointer to
vector register
save area */
/* Pointer to
the machine check extended
save area */
__u64
vector_save_area_addr
;
/* 0x11b0 */
__u64
mcesad
;
/* 0x11b0 */
/* 64 bit extparam used for pfault/diag 250: defined by architecture */
/* 64 bit extparam used for pfault/diag 250: defined by architecture */
__u64
ext_params2
;
/* 0x11B8 */
__u64
ext_params2
;
/* 0x11B8 */
...
@@ -182,10 +182,7 @@ struct lowcore {
...
@@ -182,10 +182,7 @@ struct lowcore {
/* Transaction abort diagnostic block */
/* Transaction abort diagnostic block */
__u8
pgm_tdb
[
256
];
/* 0x1800 */
__u8
pgm_tdb
[
256
];
/* 0x1800 */
__u8
pad_0x1900
[
0x1c00
-
0x1900
];
/* 0x1900 */
__u8
pad_0x1900
[
0x2000
-
0x1900
];
/* 0x1900 */
/* Software defined save area for vector registers */
__u8
vector_save_area
[
1024
];
/* 0x1c00 */
}
__packed
;
}
__packed
;
#define S390_lowcore (*((struct lowcore *) 0))
#define S390_lowcore (*((struct lowcore *) 0))
...
...
arch/s390/include/asm/nmi.h
浏览文件 @
bffc880b
...
@@ -58,7 +58,9 @@ union mci {
...
@@ -58,7 +58,9 @@ union mci {
u64
ie
:
1
;
/* 32 indirect storage error */
u64
ie
:
1
;
/* 32 indirect storage error */
u64
ar
:
1
;
/* 33 access register validity */
u64
ar
:
1
;
/* 33 access register validity */
u64
da
:
1
;
/* 34 delayed access exception */
u64
da
:
1
;
/* 34 delayed access exception */
u64
:
7
;
/* 35-41 */
u64
:
1
;
/* 35 */
u64
gs
:
1
;
/* 36 guarded storage registers */
u64
:
5
;
/* 37-41 */
u64
pr
:
1
;
/* 42 tod programmable register validity */
u64
pr
:
1
;
/* 42 tod programmable register validity */
u64
fc
:
1
;
/* 43 fp control register validity */
u64
fc
:
1
;
/* 43 fp control register validity */
u64
ap
:
1
;
/* 44 ancillary report */
u64
ap
:
1
;
/* 44 ancillary report */
...
@@ -69,6 +71,14 @@ union mci {
...
@@ -69,6 +71,14 @@ union mci {
};
};
};
};
#define MCESA_ORIGIN_MASK (~0x3ffUL)
#define MCESA_LC_MASK (0xfUL)
struct
mcesa
{
u8
vector_save_area
[
1024
];
u8
guarded_storage_save_area
[
32
];
};
struct
pt_regs
;
struct
pt_regs
;
extern
void
s390_handle_mcck
(
void
);
extern
void
s390_handle_mcck
(
void
);
...
...
arch/s390/include/asm/processor.h
浏览文件 @
bffc880b
...
@@ -135,6 +135,8 @@ struct thread_struct {
...
@@ -135,6 +135,8 @@ struct thread_struct {
struct
list_head
list
;
struct
list_head
list
;
/* cpu runtime instrumentation */
/* cpu runtime instrumentation */
struct
runtime_instr_cb
*
ri_cb
;
struct
runtime_instr_cb
*
ri_cb
;
struct
gs_cb
*
gs_cb
;
/* Current guarded storage cb */
struct
gs_cb
*
gs_bc_cb
;
/* Broadcast guarded storage cb */
unsigned
char
trap_tdb
[
256
];
/* Transaction abort diagnose block */
unsigned
char
trap_tdb
[
256
];
/* Transaction abort diagnose block */
/*
/*
* Warning: 'fpu' is dynamically-sized. It *MUST* be at
* Warning: 'fpu' is dynamically-sized. It *MUST* be at
...
@@ -215,6 +217,9 @@ void show_cacheinfo(struct seq_file *m);
...
@@ -215,6 +217,9 @@ void show_cacheinfo(struct seq_file *m);
/* Free all resources held by a thread. */
/* Free all resources held by a thread. */
extern
void
release_thread
(
struct
task_struct
*
);
extern
void
release_thread
(
struct
task_struct
*
);
/* Free guarded storage control block for current */
void
exit_thread_gs
(
void
);
/*
/*
* Return saved PC of a blocked thread.
* Return saved PC of a blocked thread.
*/
*/
...
...
arch/s390/include/asm/setup.h
浏览文件 @
bffc880b
...
@@ -31,6 +31,7 @@
...
@@ -31,6 +31,7 @@
#define MACHINE_FLAG_VX _BITUL(13)
#define MACHINE_FLAG_VX _BITUL(13)
#define MACHINE_FLAG_CAD _BITUL(14)
#define MACHINE_FLAG_CAD _BITUL(14)
#define MACHINE_FLAG_NX _BITUL(15)
#define MACHINE_FLAG_NX _BITUL(15)
#define MACHINE_FLAG_GS _BITUL(16)
#define LPP_MAGIC _BITUL(31)
#define LPP_MAGIC _BITUL(31)
#define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL)
#define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL)
...
@@ -70,6 +71,7 @@ extern void detect_memory_memblock(void);
...
@@ -70,6 +71,7 @@ extern void detect_memory_memblock(void);
#define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX)
#define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX)
#define MACHINE_HAS_CAD (S390_lowcore.machine_flags & MACHINE_FLAG_CAD)
#define MACHINE_HAS_CAD (S390_lowcore.machine_flags & MACHINE_FLAG_CAD)
#define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX)
#define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX)
#define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS)
/*
/*
* Console mode. Override with conmode=
* Console mode. Override with conmode=
...
...
arch/s390/include/asm/switch_to.h
浏览文件 @
bffc880b
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#include <linux/thread_info.h>
#include <linux/thread_info.h>
#include <asm/fpu/api.h>
#include <asm/fpu/api.h>
#include <asm/ptrace.h>
#include <asm/ptrace.h>
#include <asm/guarded_storage.h>
extern
struct
task_struct
*
__switch_to
(
void
*
,
void
*
);
extern
struct
task_struct
*
__switch_to
(
void
*
,
void
*
);
extern
void
update_cr_regs
(
struct
task_struct
*
task
);
extern
void
update_cr_regs
(
struct
task_struct
*
task
);
...
@@ -33,12 +34,14 @@ static inline void restore_access_regs(unsigned int *acrs)
...
@@ -33,12 +34,14 @@ static inline void restore_access_regs(unsigned int *acrs)
save_fpu_regs(); \
save_fpu_regs(); \
save_access_regs(&prev->thread.acrs[0]); \
save_access_regs(&prev->thread.acrs[0]); \
save_ri_cb(prev->thread.ri_cb); \
save_ri_cb(prev->thread.ri_cb); \
save_gs_cb(prev->thread.gs_cb); \
} \
} \
if (next->mm) { \
if (next->mm) { \
update_cr_regs(next); \
update_cr_regs(next); \
set_cpu_flag(CIF_FPU); \
set_cpu_flag(CIF_FPU); \
restore_access_regs(&next->thread.acrs[0]); \
restore_access_regs(&next->thread.acrs[0]); \
restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
restore_gs_cb(next->thread.gs_cb); \
} \
} \
prev = __switch_to(prev,next); \
prev = __switch_to(prev,next); \
} while (0)
} while (0)
...
...
arch/s390/include/asm/thread_info.h
浏览文件 @
bffc880b
...
@@ -54,11 +54,12 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
...
@@ -54,11 +54,12 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
#define TIF_NOTIFY_RESUME 0
/* callback before returning to user */
#define TIF_NOTIFY_RESUME 0
/* callback before returning to user */
#define TIF_SIGPENDING 1
/* signal pending */
#define TIF_SIGPENDING 1
/* signal pending */
#define TIF_NEED_RESCHED 2
/* rescheduling necessary */
#define TIF_NEED_RESCHED 2
/* rescheduling necessary */
#define TIF_SYSCALL_TRACE 3
/* syscall trace active */
#define TIF_UPROBE 3
/* breakpointed or single-stepping */
#define TIF_SYSCALL_AUDIT 4
/* syscall auditing active */
#define TIF_GUARDED_STORAGE 4
/* load guarded storage control block */
#define TIF_SECCOMP 5
/* secure computing */
#define TIF_SYSCALL_TRACE 8
/* syscall trace active */
#define TIF_SYSCALL_TRACEPOINT 6
/* syscall tracepoint instrumentation */
#define TIF_SYSCALL_AUDIT 9
/* syscall auditing active */
#define TIF_UPROBE 7
/* breakpointed or single-stepping */
#define TIF_SECCOMP 10
/* secure computing */
#define TIF_SYSCALL_TRACEPOINT 11
/* syscall tracepoint instrumentation */
#define TIF_31BIT 16
/* 32bit process */
#define TIF_31BIT 16
/* 32bit process */
#define TIF_MEMDIE 17
/* is terminating due to OOM killer */
#define TIF_MEMDIE 17
/* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 18
/* restore signal mask in do_signal() */
#define TIF_RESTORE_SIGMASK 18
/* restore signal mask in do_signal() */
...
@@ -76,5 +77,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
...
@@ -76,5 +77,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
#define _TIF_UPROBE _BITUL(TIF_UPROBE)
#define _TIF_UPROBE _BITUL(TIF_UPROBE)
#define _TIF_31BIT _BITUL(TIF_31BIT)
#define _TIF_31BIT _BITUL(TIF_31BIT)
#define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP)
#define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP)
#define _TIF_GUARDED_STORAGE _BITUL(TIF_GUARDED_STORAGE)
#endif
/* _ASM_THREAD_INFO_H */
#endif
/* _ASM_THREAD_INFO_H */
arch/s390/include/uapi/asm/Kbuild
浏览文件 @
bffc880b
...
@@ -12,6 +12,7 @@ header-y += dasd.h
...
@@ -12,6 +12,7 @@ header-y += dasd.h
header-y += debug.h
header-y += debug.h
header-y += errno.h
header-y += errno.h
header-y += fcntl.h
header-y += fcntl.h
header-y += guarded_storage.h
header-y += hypfs.h
header-y += hypfs.h
header-y += ioctl.h
header-y += ioctl.h
header-y += ioctls.h
header-y += ioctls.h
...
...
arch/s390/include/uapi/asm/guarded_storage.h
0 → 100644
浏览文件 @
bffc880b
#ifndef _GUARDED_STORAGE_H
#define _GUARDED_STORAGE_H
#include <linux/types.h>
struct
gs_cb
{
__u64
reserved
;
__u64
gsd
;
__u64
gssm
;
__u64
gs_epl_a
;
};
struct
gs_epl
{
__u8
pad1
;
union
{
__u8
gs_eam
;
struct
{
__u8
:
6
;
__u8
e
:
1
;
__u8
b
:
1
;
};
};
union
{
__u8
gs_eci
;
struct
{
__u8
tx
:
1
;
__u8
cx
:
1
;
__u8
:
5
;
__u8
in
:
1
;
};
};
union
{
__u8
gs_eai
;
struct
{
__u8
:
1
;
__u8
t
:
1
;
__u8
as
:
2
;
__u8
ar
:
4
;
};
};
__u32
pad2
;
__u64
gs_eha
;
__u64
gs_eia
;
__u64
gs_eoa
;
__u64
gs_eir
;
__u64
gs_era
;
};
#define GS_ENABLE 0
#define GS_DISABLE 1
#define GS_SET_BC_CB 2
#define GS_CLEAR_BC_CB 3
#define GS_BROADCAST 4
static
inline
void
load_gs_cb
(
struct
gs_cb
*
gs_cb
)
{
asm
volatile
(
".insn rxy,0xe3000000004d,0,%0"
:
:
"Q"
(
*
gs_cb
));
}
static
inline
void
store_gs_cb
(
struct
gs_cb
*
gs_cb
)
{
asm
volatile
(
".insn rxy,0xe30000000049,0,%0"
:
:
"Q"
(
*
gs_cb
));
}
static
inline
void
save_gs_cb
(
struct
gs_cb
*
gs_cb
)
{
if
(
gs_cb
)
store_gs_cb
(
gs_cb
);
}
static
inline
void
restore_gs_cb
(
struct
gs_cb
*
gs_cb
)
{
if
(
gs_cb
)
load_gs_cb
(
gs_cb
);
}
#endif
/* _GUARDED_STORAGE_H */
arch/s390/include/uapi/asm/unistd.h
浏览文件 @
bffc880b
...
@@ -313,7 +313,7 @@
...
@@ -313,7 +313,7 @@
#define __NR_copy_file_range 375
#define __NR_copy_file_range 375
#define __NR_preadv2 376
#define __NR_preadv2 376
#define __NR_pwritev2 377
#define __NR_pwritev2 377
/* Number 378 is reserved for guarded storage */
#define __NR_s390_guarded_storage 378
#define __NR_statx 379
#define __NR_statx 379
#define NR_syscalls 380
#define NR_syscalls 380
...
...
arch/s390/kernel/Makefile
浏览文件 @
bffc880b
...
@@ -57,7 +57,7 @@ obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o
...
@@ -57,7 +57,7 @@ obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o
obj-y
+=
processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
obj-y
+=
processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
obj-y
+=
debug.o irq.o ipl.o dis.o diag.o vdso.o als.o
obj-y
+=
debug.o irq.o ipl.o dis.o diag.o vdso.o als.o
obj-y
+=
sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
obj-y
+=
sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
obj-y
+=
runtime_instr.o cache.o fpu.o dumpstack.o
obj-y
+=
runtime_instr.o cache.o fpu.o dumpstack.o
guarded_storage.o
obj-y
+=
entry.o reipl.o relocate_kernel.o
obj-y
+=
entry.o reipl.o relocate_kernel.o
extra-y
+=
head.o head64.o vmlinux.lds
extra-y
+=
head.o head64.o vmlinux.lds
...
...
arch/s390/kernel/asm-offsets.c
浏览文件 @
bffc880b
...
@@ -175,7 +175,7 @@ int main(void)
...
@@ -175,7 +175,7 @@ int main(void)
/* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
/* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
OFFSET
(
__LC_DUMP_REIPL
,
lowcore
,
ipib
);
OFFSET
(
__LC_DUMP_REIPL
,
lowcore
,
ipib
);
/* hardware defined lowcore locations 0x1000 - 0x18ff */
/* hardware defined lowcore locations 0x1000 - 0x18ff */
OFFSET
(
__LC_
VX_SAVE_AREA_ADDR
,
lowcore
,
vector_save_area_addr
);
OFFSET
(
__LC_
MCESAD
,
lowcore
,
mcesad
);
OFFSET
(
__LC_EXT_PARAMS2
,
lowcore
,
ext_params2
);
OFFSET
(
__LC_EXT_PARAMS2
,
lowcore
,
ext_params2
);
OFFSET
(
__LC_FPREGS_SAVE_AREA
,
lowcore
,
floating_pt_save_area
);
OFFSET
(
__LC_FPREGS_SAVE_AREA
,
lowcore
,
floating_pt_save_area
);
OFFSET
(
__LC_GPREGS_SAVE_AREA
,
lowcore
,
gpregs_save_area
);
OFFSET
(
__LC_GPREGS_SAVE_AREA
,
lowcore
,
gpregs_save_area
);
...
...
arch/s390/kernel/compat_wrapper.c
浏览文件 @
bffc880b
...
@@ -178,4 +178,5 @@ COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
...
@@ -178,4 +178,5 @@ COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
COMPAT_SYSCALL_WRAP6
(
sendto
,
int
,
fd
,
void
__user
*
,
buff
,
size_t
,
len
,
unsigned
int
,
flags
,
struct
sockaddr
__user
*
,
addr
,
int
,
addr_len
);
COMPAT_SYSCALL_WRAP6
(
sendto
,
int
,
fd
,
void
__user
*
,
buff
,
size_t
,
len
,
unsigned
int
,
flags
,
struct
sockaddr
__user
*
,
addr
,
int
,
addr_len
);
COMPAT_SYSCALL_WRAP3
(
mlock2
,
unsigned
long
,
start
,
size_t
,
len
,
int
,
flags
);
COMPAT_SYSCALL_WRAP3
(
mlock2
,
unsigned
long
,
start
,
size_t
,
len
,
int
,
flags
);
COMPAT_SYSCALL_WRAP6
(
copy_file_range
,
int
,
fd_in
,
loff_t
__user
*
,
off_in
,
int
,
fd_out
,
loff_t
__user
*
,
off_out
,
size_t
,
len
,
unsigned
int
,
flags
);
COMPAT_SYSCALL_WRAP6
(
copy_file_range
,
int
,
fd_in
,
loff_t
__user
*
,
off_in
,
int
,
fd_out
,
loff_t
__user
*
,
off_out
,
size_t
,
len
,
unsigned
int
,
flags
);
COMPAT_SYSCALL_WRAP2
(
s390_guarded_storage
,
int
,
command
,
struct
gs_cb
*
,
gs_cb
);
COMPAT_SYSCALL_WRAP5
(
statx
,
int
,
dfd
,
const
char
__user
*
,
path
,
unsigned
,
flags
,
unsigned
,
mask
,
struct
statx
__user
*
,
buffer
);
COMPAT_SYSCALL_WRAP5
(
statx
,
int
,
dfd
,
const
char
__user
*
,
path
,
unsigned
,
flags
,
unsigned
,
mask
,
struct
statx
__user
*
,
buffer
);
arch/s390/kernel/early.c
浏览文件 @
bffc880b
...
@@ -358,6 +358,8 @@ static __init void detect_machine_facilities(void)
...
@@ -358,6 +358,8 @@ static __init void detect_machine_facilities(void)
S390_lowcore
.
machine_flags
|=
MACHINE_FLAG_NX
;
S390_lowcore
.
machine_flags
|=
MACHINE_FLAG_NX
;
__ctl_set_bit
(
0
,
20
);
__ctl_set_bit
(
0
,
20
);
}
}
if
(
test_facility
(
133
))
S390_lowcore
.
machine_flags
|=
MACHINE_FLAG_GS
;
}
}
static
inline
void
save_vector_registers
(
void
)
static
inline
void
save_vector_registers
(
void
)
...
...
arch/s390/kernel/entry.S
浏览文件 @
bffc880b
...
@@ -47,7 +47,7 @@ STACK_SIZE = 1 << STACK_SHIFT
...
@@ -47,7 +47,7 @@ STACK_SIZE = 1 << STACK_SHIFT
STACK_INIT
=
STACK_SIZE
-
STACK_FRAME_OVERHEAD
-
__PT_SIZE
STACK_INIT
=
STACK_SIZE
-
STACK_FRAME_OVERHEAD
-
__PT_SIZE
_TIF_WORK
=
(
_TIF_SIGPENDING
| _TIF_NOTIFY_RESUME |
_TIF_NEED_RESCHED
|
\
_TIF_WORK
=
(
_TIF_SIGPENDING
| _TIF_NOTIFY_RESUME |
_TIF_NEED_RESCHED
|
\
_TIF_UPROBE
)
_TIF_UPROBE
|
_TIF_GUARDED_STORAGE
)
_TIF_TRACE
=
(
_TIF_SYSCALL_TRACE
| _TIF_SYSCALL_AUDIT |
_TIF_SECCOMP
|
\
_TIF_TRACE
=
(
_TIF_SYSCALL_TRACE
| _TIF_SYSCALL_AUDIT |
_TIF_SECCOMP
|
\
_TIF_SYSCALL_TRACEPOINT
)
_TIF_SYSCALL_TRACEPOINT
)
_CIF_WORK
=
(
_CIF_MCCK_PENDING
| _CIF_ASCE_PRIMARY |
\
_CIF_WORK
=
(
_CIF_MCCK_PENDING
| _CIF_ASCE_PRIMARY |
\
...
@@ -332,6 +332,8 @@ ENTRY(system_call)
...
@@ -332,6 +332,8 @@ ENTRY(system_call)
TSTMSK
__TI_flags
(%
r12
),
_TIF_UPROBE
TSTMSK
__TI_flags
(%
r12
),
_TIF_UPROBE
jo
.
Lsysc_uprobe_notify
jo
.
Lsysc_uprobe_notify
#endif
#endif
TSTMSK
__TI_flags
(%
r12
),
_TIF_GUARDED_STORAGE
jo
.
Lsysc_guarded_storage
TSTMSK
__PT_FLAGS
(%
r11
),
_PIF_PER_TRAP
TSTMSK
__PT_FLAGS
(%
r11
),
_PIF_PER_TRAP
jo
.
Lsysc_singlestep
jo
.
Lsysc_singlestep
TSTMSK
__TI_flags
(%
r12
),
_TIF_SIGPENDING
TSTMSK
__TI_flags
(%
r12
),
_TIF_SIGPENDING
...
@@ -408,6 +410,14 @@ ENTRY(system_call)
...
@@ -408,6 +410,14 @@ ENTRY(system_call)
jg
uprobe_notify_resume
jg
uprobe_notify_resume
#endif
#endif
#
#
_TIF_GUARDED_STORAGE
is
set
,
call
guarded_storage_load
#
.
Lsysc_guarded_storage
:
lgr
%
r2
,%
r11
#
pass
pointer
to
pt_regs
larl
%
r14
,
.
Lsysc_return
jg
gs_load_bc_cb
#
#
#
_PIF_PER_TRAP
is
set
,
call
do_per_trap
#
_PIF_PER_TRAP
is
set
,
call
do_per_trap
#
#
...
@@ -663,6 +673,8 @@ ENTRY(io_int_handler)
...
@@ -663,6 +673,8 @@ ENTRY(io_int_handler)
jo
.
Lio_sigpending
jo
.
Lio_sigpending
TSTMSK
__TI_flags
(%
r12
),
_TIF_NOTIFY_RESUME
TSTMSK
__TI_flags
(%
r12
),
_TIF_NOTIFY_RESUME
jo
.
Lio_notify_resume
jo
.
Lio_notify_resume
TSTMSK
__TI_flags
(%
r12
),
_TIF_GUARDED_STORAGE
jo
.
Lio_guarded_storage
TSTMSK
__LC_CPU_FLAGS
,
_CIF_FPU
TSTMSK
__LC_CPU_FLAGS
,
_CIF_FPU
jo
.
Lio_vxrs
jo
.
Lio_vxrs
TSTMSK
__LC_CPU_FLAGS
,(
_CIF_ASCE_PRIMARY
|
_CIF_ASCE_SECONDARY
)
TSTMSK
__LC_CPU_FLAGS
,(
_CIF_ASCE_PRIMARY
|
_CIF_ASCE_SECONDARY
)
...
@@ -696,6 +708,18 @@ ENTRY(io_int_handler)
...
@@ -696,6 +708,18 @@ ENTRY(io_int_handler)
larl
%
r14
,
.
Lio_return
larl
%
r14
,
.
Lio_return
jg
load_fpu_regs
jg
load_fpu_regs
#
#
_TIF_GUARDED_STORAGE
is
set
,
call
guarded_storage_load
#
.
Lio_guarded_storage
:
#
TRACE_IRQS_ON
already
done
at
.
Lio_return
ssm
__LC_SVC_NEW_PSW
#
reenable
interrupts
lgr
%
r2
,%
r11
#
pass
pointer
to
pt_regs
brasl
%
r14
,
gs_load_bc_cb
ssm
__LC_PGM_NEW_PSW
#
disable
I
/
O
and
ext
.
interrupts
TRACE_IRQS_OFF
j
.
Lio_return
#
#
#
_TIF_NEED_RESCHED
is
set
,
call
schedule
#
_TIF_NEED_RESCHED
is
set
,
call
schedule
#
#
...
...
arch/s390/kernel/entry.h
浏览文件 @
bffc880b
...
@@ -74,12 +74,14 @@ long sys_sigreturn(void);
...
@@ -74,12 +74,14 @@ long sys_sigreturn(void);
long
sys_s390_personality
(
unsigned
int
personality
);
long
sys_s390_personality
(
unsigned
int
personality
);
long
sys_s390_runtime_instr
(
int
command
,
int
signum
);
long
sys_s390_runtime_instr
(
int
command
,
int
signum
);
long
sys_s390_guarded_storage
(
int
command
,
struct
gs_cb
__user
*
);
long
sys_s390_pci_mmio_write
(
unsigned
long
,
const
void
__user
*
,
size_t
);
long
sys_s390_pci_mmio_write
(
unsigned
long
,
const
void
__user
*
,
size_t
);
long
sys_s390_pci_mmio_read
(
unsigned
long
,
void
__user
*
,
size_t
);
long
sys_s390_pci_mmio_read
(
unsigned
long
,
void
__user
*
,
size_t
);
DECLARE_PER_CPU
(
u64
,
mt_cycles
[
8
]);
DECLARE_PER_CPU
(
u64
,
mt_cycles
[
8
]);
void
verify_facilities
(
void
);
void
verify_facilities
(
void
);
void
gs_load_bc_cb
(
struct
pt_regs
*
regs
);
void
set_fs_fixup
(
void
);
void
set_fs_fixup
(
void
);
#endif
/* _ENTRY_H */
#endif
/* _ENTRY_H */
arch/s390/kernel/guarded_storage.c
0 → 100644
浏览文件 @
bffc880b
/*
* Copyright IBM Corp. 2016
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/guarded_storage.h>
#include "entry.h"
void
exit_thread_gs
(
void
)
{
kfree
(
current
->
thread
.
gs_cb
);
kfree
(
current
->
thread
.
gs_bc_cb
);
current
->
thread
.
gs_cb
=
current
->
thread
.
gs_bc_cb
=
NULL
;
}
static
int
gs_enable
(
void
)
{
struct
gs_cb
*
gs_cb
;
if
(
!
current
->
thread
.
gs_cb
)
{
gs_cb
=
kzalloc
(
sizeof
(
*
gs_cb
),
GFP_KERNEL
);
if
(
!
gs_cb
)
return
-
ENOMEM
;
gs_cb
->
gsd
=
25
;
preempt_disable
();
__ctl_set_bit
(
2
,
4
);
load_gs_cb
(
gs_cb
);
current
->
thread
.
gs_cb
=
gs_cb
;
preempt_enable
();
}
return
0
;
}
static
int
gs_disable
(
void
)
{
if
(
current
->
thread
.
gs_cb
)
{
preempt_disable
();
kfree
(
current
->
thread
.
gs_cb
);
current
->
thread
.
gs_cb
=
NULL
;
__ctl_clear_bit
(
2
,
4
);
preempt_enable
();
}
return
0
;
}
static
int
gs_set_bc_cb
(
struct
gs_cb
__user
*
u_gs_cb
)
{
struct
gs_cb
*
gs_cb
;
gs_cb
=
current
->
thread
.
gs_bc_cb
;
if
(
!
gs_cb
)
{
gs_cb
=
kzalloc
(
sizeof
(
*
gs_cb
),
GFP_KERNEL
);
if
(
!
gs_cb
)
return
-
ENOMEM
;
current
->
thread
.
gs_bc_cb
=
gs_cb
;
}
if
(
copy_from_user
(
gs_cb
,
u_gs_cb
,
sizeof
(
*
gs_cb
)))
return
-
EFAULT
;
return
0
;
}
static
int
gs_clear_bc_cb
(
void
)
{
struct
gs_cb
*
gs_cb
;
gs_cb
=
current
->
thread
.
gs_bc_cb
;
current
->
thread
.
gs_bc_cb
=
NULL
;
kfree
(
gs_cb
);
return
0
;
}
void
gs_load_bc_cb
(
struct
pt_regs
*
regs
)
{
struct
gs_cb
*
gs_cb
;
preempt_disable
();
clear_thread_flag
(
TIF_GUARDED_STORAGE
);
gs_cb
=
current
->
thread
.
gs_bc_cb
;
if
(
gs_cb
)
{
kfree
(
current
->
thread
.
gs_cb
);
current
->
thread
.
gs_bc_cb
=
NULL
;
__ctl_set_bit
(
2
,
4
);
load_gs_cb
(
gs_cb
);
current
->
thread
.
gs_cb
=
gs_cb
;
}
preempt_enable
();
}
static
int
gs_broadcast
(
void
)
{
struct
task_struct
*
sibling
;
read_lock
(
&
tasklist_lock
);
for_each_thread
(
current
,
sibling
)
{
if
(
!
sibling
->
thread
.
gs_bc_cb
)
continue
;
if
(
test_and_set_tsk_thread_flag
(
sibling
,
TIF_GUARDED_STORAGE
))
kick_process
(
sibling
);
}
read_unlock
(
&
tasklist_lock
);
return
0
;
}
SYSCALL_DEFINE2
(
s390_guarded_storage
,
int
,
command
,
struct
gs_cb
__user
*
,
gs_cb
)
{
if
(
!
MACHINE_HAS_GS
)
return
-
EOPNOTSUPP
;
switch
(
command
)
{
case
GS_ENABLE
:
return
gs_enable
();
case
GS_DISABLE
:
return
gs_disable
();
case
GS_SET_BC_CB
:
return
gs_set_bc_cb
(
gs_cb
);
case
GS_CLEAR_BC_CB
:
return
gs_clear_bc_cb
();
case
GS_BROADCAST
:
return
gs_broadcast
();
default:
return
-
EINVAL
;
}
}
arch/s390/kernel/machine_kexec.c
浏览文件 @
bffc880b
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <asm/cacheflush.h>
#include <asm/cacheflush.h>
#include <asm/os_info.h>
#include <asm/os_info.h>
#include <asm/switch_to.h>
#include <asm/switch_to.h>
#include <asm/nmi.h>
typedef
void
(
*
relocate_kernel_t
)(
kimage_entry_t
*
,
unsigned
long
);
typedef
void
(
*
relocate_kernel_t
)(
kimage_entry_t
*
,
unsigned
long
);
...
@@ -102,6 +103,8 @@ static void __do_machine_kdump(void *image)
...
@@ -102,6 +103,8 @@ static void __do_machine_kdump(void *image)
*/
*/
static
noinline
void
__machine_kdump
(
void
*
image
)
static
noinline
void
__machine_kdump
(
void
*
image
)
{
{
struct
mcesa
*
mcesa
;
unsigned
long
cr2_old
,
cr2_new
;
int
this_cpu
,
cpu
;
int
this_cpu
,
cpu
;
lgr_info_log
();
lgr_info_log
();
...
@@ -114,8 +117,16 @@ static noinline void __machine_kdump(void *image)
...
@@ -114,8 +117,16 @@ static noinline void __machine_kdump(void *image)
continue
;
continue
;
}
}
/* Store status of the boot CPU */
/* Store status of the boot CPU */
mcesa
=
(
struct
mcesa
*
)(
S390_lowcore
.
mcesad
&
MCESA_ORIGIN_MASK
);
if
(
MACHINE_HAS_VX
)
if
(
MACHINE_HAS_VX
)
save_vx_regs
((
void
*
)
&
S390_lowcore
.
vector_save_area
);
save_vx_regs
((
__vector128
*
)
mcesa
->
vector_save_area
);
if
(
MACHINE_HAS_GS
)
{
__ctl_store
(
cr2_old
,
2
,
2
);
cr2_new
=
cr2_old
|
(
1UL
<<
4
);
__ctl_load
(
cr2_new
,
2
,
2
);
save_gs_cb
((
struct
gs_cb
*
)
mcesa
->
guarded_storage_save_area
);
__ctl_load
(
cr2_old
,
2
,
2
);
}
/*
/*
* To create a good backchain for this CPU in the dump store_status
* To create a good backchain for this CPU in the dump store_status
* is passed the address of a function. The address is saved into
* is passed the address of a function. The address is saved into
...
...
arch/s390/kernel/nmi.c
浏览文件 @
bffc880b
...
@@ -106,6 +106,7 @@ static int notrace s390_validate_registers(union mci mci, int umode)
...
@@ -106,6 +106,7 @@ static int notrace s390_validate_registers(union mci mci, int umode)
int
kill_task
;
int
kill_task
;
u64
zero
;
u64
zero
;
void
*
fpt_save_area
;
void
*
fpt_save_area
;
struct
mcesa
*
mcesa
;
kill_task
=
0
;
kill_task
=
0
;
zero
=
0
;
zero
=
0
;
...
@@ -165,6 +166,7 @@ static int notrace s390_validate_registers(union mci mci, int umode)
...
@@ -165,6 +166,7 @@ static int notrace s390_validate_registers(union mci mci, int umode)
:
:
"Q"
(
S390_lowcore
.
fpt_creg_save_area
));
:
:
"Q"
(
S390_lowcore
.
fpt_creg_save_area
));
}
}
mcesa
=
(
struct
mcesa
*
)(
S390_lowcore
.
mcesad
&
MCESA_ORIGIN_MASK
);
if
(
!
MACHINE_HAS_VX
)
{
if
(
!
MACHINE_HAS_VX
)
{
/* Validate floating point registers */
/* Validate floating point registers */
asm
volatile
(
asm
volatile
(
...
@@ -209,8 +211,8 @@ static int notrace s390_validate_registers(union mci mci, int umode)
...
@@ -209,8 +211,8 @@ static int notrace s390_validate_registers(union mci mci, int umode)
" la 1,%0
\n
"
" la 1,%0
\n
"
" .word 0xe70f,0x1000,0x0036
\n
"
/* vlm 0,15,0(1) */
" .word 0xe70f,0x1000,0x0036
\n
"
/* vlm 0,15,0(1) */
" .word 0xe70f,0x1100,0x0c36
\n
"
/* vlm 16,31,256(1) */
" .word 0xe70f,0x1100,0x0c36
\n
"
/* vlm 16,31,256(1) */
:
:
"Q"
(
*
(
struct
vx_array
*
)
:
:
"Q"
(
*
(
struct
vx_array
*
)
mcesa
->
vector_save_area
)
&
S390_lowcore
.
vector_save_area
)
:
"1"
);
:
"1"
);
__ctl_load
(
S390_lowcore
.
cregs_save_area
[
0
],
0
,
0
);
__ctl_load
(
S390_lowcore
.
cregs_save_area
[
0
],
0
,
0
);
}
}
/* Validate access registers */
/* Validate access registers */
...
@@ -224,6 +226,19 @@ static int notrace s390_validate_registers(union mci mci, int umode)
...
@@ -224,6 +226,19 @@ static int notrace s390_validate_registers(union mci mci, int umode)
*/
*/
kill_task
=
1
;
kill_task
=
1
;
}
}
/* Validate guarded storage registers */
if
(
MACHINE_HAS_GS
&&
(
S390_lowcore
.
cregs_save_area
[
2
]
&
(
1UL
<<
4
)))
{
if
(
!
mci
.
gs
)
/*
* Guarded storage register can't be restored and
* the current processes uses guarded storage.
* It has to be terminated.
*/
kill_task
=
1
;
else
load_gs_cb
((
struct
gs_cb
*
)
mcesa
->
guarded_storage_save_area
);
}
/*
/*
* We don't even try to validate the TOD register, since we simply
* We don't even try to validate the TOD register, since we simply
* can't write something sensible into that register.
* can't write something sensible into that register.
...
...
arch/s390/kernel/process.c
浏览文件 @
bffc880b
...
@@ -73,8 +73,10 @@ extern void kernel_thread_starter(void);
...
@@ -73,8 +73,10 @@ extern void kernel_thread_starter(void);
*/
*/
void
exit_thread
(
struct
task_struct
*
tsk
)
void
exit_thread
(
struct
task_struct
*
tsk
)
{
{
if
(
tsk
==
current
)
if
(
tsk
==
current
)
{
exit_thread_runtime_instr
();
exit_thread_runtime_instr
();
exit_thread_gs
();
}
}
}
void
flush_thread
(
void
)
void
flush_thread
(
void
)
...
@@ -159,6 +161,9 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long new_stackp,
...
@@ -159,6 +161,9 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long new_stackp,
/* Don't copy runtime instrumentation info */
/* Don't copy runtime instrumentation info */
p
->
thread
.
ri_cb
=
NULL
;
p
->
thread
.
ri_cb
=
NULL
;
frame
->
childregs
.
psw
.
mask
&=
~
PSW_MASK_RI
;
frame
->
childregs
.
psw
.
mask
&=
~
PSW_MASK_RI
;
/* Don't copy guarded storage control block */
p
->
thread
.
gs_cb
=
NULL
;
p
->
thread
.
gs_bc_cb
=
NULL
;
/* Set a new TLS ? */
/* Set a new TLS ? */
if
(
clone_flags
&
CLONE_SETTLS
)
{
if
(
clone_flags
&
CLONE_SETTLS
)
{
...
...
arch/s390/kernel/processor.c
浏览文件 @
bffc880b
...
@@ -95,7 +95,7 @@ static void show_cpu_summary(struct seq_file *m, void *v)
...
@@ -95,7 +95,7 @@ static void show_cpu_summary(struct seq_file *m, void *v)
{
{
static
const
char
*
hwcap_str
[]
=
{
static
const
char
*
hwcap_str
[]
=
{
"esan3"
,
"zarch"
,
"stfle"
,
"msa"
,
"ldisp"
,
"eimm"
,
"dfp"
,
"esan3"
,
"zarch"
,
"stfle"
,
"msa"
,
"ldisp"
,
"eimm"
,
"dfp"
,
"edat"
,
"etf3eh"
,
"highgprs"
,
"te"
,
"vx"
,
"vxd"
,
"vxe"
"edat"
,
"etf3eh"
,
"highgprs"
,
"te"
,
"vx"
,
"vxd"
,
"vxe"
,
"gs"
};
};
static
const
char
*
const
int_hwcap_str
[]
=
{
static
const
char
*
const
int_hwcap_str
[]
=
{
"sie"
"sie"
...
...
arch/s390/kernel/ptrace.c
浏览文件 @
bffc880b
...
@@ -44,30 +44,42 @@ void update_cr_regs(struct task_struct *task)
...
@@ -44,30 +44,42 @@ void update_cr_regs(struct task_struct *task)
struct
pt_regs
*
regs
=
task_pt_regs
(
task
);
struct
pt_regs
*
regs
=
task_pt_regs
(
task
);
struct
thread_struct
*
thread
=
&
task
->
thread
;
struct
thread_struct
*
thread
=
&
task
->
thread
;
struct
per_regs
old
,
new
;
struct
per_regs
old
,
new
;
unsigned
long
cr0_old
,
cr0_new
;
unsigned
long
cr2_old
,
cr2_new
;
int
cr0_changed
,
cr2_changed
;
__ctl_store
(
cr0_old
,
0
,
0
);
__ctl_store
(
cr2_old
,
2
,
2
);
cr0_new
=
cr0_old
;
cr2_new
=
cr2_old
;
/* Take care of the enable/disable of transactional execution. */
/* Take care of the enable/disable of transactional execution. */
if
(
MACHINE_HAS_TE
)
{
if
(
MACHINE_HAS_TE
)
{
unsigned
long
cr
,
cr_new
;
__ctl_store
(
cr
,
0
,
0
);
/* Set or clear transaction execution TXC bit 8. */
/* Set or clear transaction execution TXC bit 8. */
cr
_new
=
cr
|
(
1UL
<<
55
);
cr
0_new
|=
(
1UL
<<
55
);
if
(
task
->
thread
.
per_flags
&
PER_FLAG_NO_TE
)
if
(
task
->
thread
.
per_flags
&
PER_FLAG_NO_TE
)
cr_new
&=
~
(
1UL
<<
55
);
cr0_new
&=
~
(
1UL
<<
55
);
if
(
cr_new
!=
cr
)
__ctl_load
(
cr_new
,
0
,
0
);
/* Set or clear transaction execution TDC bits 62 and 63. */
/* Set or clear transaction execution TDC bits 62 and 63. */
__ctl_store
(
cr
,
2
,
2
);
cr2_new
&=
~
3UL
;
cr_new
=
cr
&
~
3UL
;
if
(
task
->
thread
.
per_flags
&
PER_FLAG_TE_ABORT_RAND
)
{
if
(
task
->
thread
.
per_flags
&
PER_FLAG_TE_ABORT_RAND
)
{
if
(
task
->
thread
.
per_flags
&
PER_FLAG_TE_ABORT_RAND_TEND
)
if
(
task
->
thread
.
per_flags
&
PER_FLAG_TE_ABORT_RAND_TEND
)
cr_new
|=
1UL
;
cr
2
_new
|=
1UL
;
else
else
cr_new
|=
2UL
;
cr
2
_new
|=
2UL
;
}
}
if
(
cr_new
!=
cr
)
__ctl_load
(
cr_new
,
2
,
2
);
}
}
/* Take care of enable/disable of guarded storage. */
if
(
MACHINE_HAS_GS
)
{
cr2_new
&=
~
(
1UL
<<
4
);
if
(
task
->
thread
.
gs_cb
)
cr2_new
|=
(
1UL
<<
4
);
}
/* Load control register 0/2 iff changed */
cr0_changed
=
cr0_new
!=
cr0_old
;
cr2_changed
=
cr2_new
!=
cr2_old
;
if
(
cr0_changed
)
__ctl_load
(
cr0_new
,
0
,
0
);
if
(
cr2_changed
)
__ctl_load
(
cr2_new
,
2
,
2
);
/* Copy user specified PER registers */
/* Copy user specified PER registers */
new
.
control
=
thread
->
per_user
.
control
;
new
.
control
=
thread
->
per_user
.
control
;
new
.
start
=
thread
->
per_user
.
start
;
new
.
start
=
thread
->
per_user
.
start
;
...
@@ -1137,6 +1149,36 @@ static int s390_system_call_set(struct task_struct *target,
...
@@ -1137,6 +1149,36 @@ static int s390_system_call_set(struct task_struct *target,
data
,
0
,
sizeof
(
unsigned
int
));
data
,
0
,
sizeof
(
unsigned
int
));
}
}
static
int
s390_gs_cb_get
(
struct
task_struct
*
target
,
const
struct
user_regset
*
regset
,
unsigned
int
pos
,
unsigned
int
count
,
void
*
kbuf
,
void
__user
*
ubuf
)
{
struct
gs_cb
*
data
=
target
->
thread
.
gs_cb
;
if
(
!
MACHINE_HAS_GS
)
return
-
ENODEV
;
if
(
!
data
)
return
-
ENODATA
;
return
user_regset_copyout
(
&
pos
,
&
count
,
&
kbuf
,
&
ubuf
,
data
,
0
,
sizeof
(
struct
gs_cb
));
}
static
int
s390_gs_cb_set
(
struct
task_struct
*
target
,
const
struct
user_regset
*
regset
,
unsigned
int
pos
,
unsigned
int
count
,
const
void
*
kbuf
,
const
void
__user
*
ubuf
)
{
struct
gs_cb
*
data
=
target
->
thread
.
gs_cb
;
if
(
!
MACHINE_HAS_GS
)
return
-
ENODEV
;
if
(
!
data
)
return
-
ENODATA
;
return
user_regset_copyin
(
&
pos
,
&
count
,
&
kbuf
,
&
ubuf
,
data
,
0
,
sizeof
(
struct
gs_cb
));
}
static
const
struct
user_regset
s390_regsets
[]
=
{
static
const
struct
user_regset
s390_regsets
[]
=
{
{
{
.
core_note_type
=
NT_PRSTATUS
,
.
core_note_type
=
NT_PRSTATUS
,
...
@@ -1194,6 +1236,14 @@ static const struct user_regset s390_regsets[] = {
...
@@ -1194,6 +1236,14 @@ static const struct user_regset s390_regsets[] = {
.
get
=
s390_vxrs_high_get
,
.
get
=
s390_vxrs_high_get
,
.
set
=
s390_vxrs_high_set
,
.
set
=
s390_vxrs_high_set
,
},
},
{
.
core_note_type
=
NT_S390_GS_CB
,
.
n
=
sizeof
(
struct
gs_cb
)
/
sizeof
(
__u64
),
.
size
=
sizeof
(
__u64
),
.
align
=
sizeof
(
__u64
),
.
get
=
s390_gs_cb_get
,
.
set
=
s390_gs_cb_set
,
},
};
};
static
const
struct
user_regset_view
user_s390_view
=
{
static
const
struct
user_regset_view
user_s390_view
=
{
...
@@ -1422,6 +1472,14 @@ static const struct user_regset s390_compat_regsets[] = {
...
@@ -1422,6 +1472,14 @@ static const struct user_regset s390_compat_regsets[] = {
.
get
=
s390_compat_regs_high_get
,
.
get
=
s390_compat_regs_high_get
,
.
set
=
s390_compat_regs_high_set
,
.
set
=
s390_compat_regs_high_set
,
},
},
{
.
core_note_type
=
NT_S390_GS_CB
,
.
n
=
sizeof
(
struct
gs_cb
)
/
sizeof
(
__u64
),
.
size
=
sizeof
(
__u64
),
.
align
=
sizeof
(
__u64
),
.
get
=
s390_gs_cb_get
,
.
set
=
s390_gs_cb_set
,
},
};
};
static
const
struct
user_regset_view
user_s390_compat_view
=
{
static
const
struct
user_regset_view
user_s390_compat_view
=
{
...
...
arch/s390/kernel/setup.c
浏览文件 @
bffc880b
...
@@ -339,9 +339,15 @@ static void __init setup_lowcore(void)
...
@@ -339,9 +339,15 @@ static void __init setup_lowcore(void)
lc
->
stfl_fac_list
=
S390_lowcore
.
stfl_fac_list
;
lc
->
stfl_fac_list
=
S390_lowcore
.
stfl_fac_list
;
memcpy
(
lc
->
stfle_fac_list
,
S390_lowcore
.
stfle_fac_list
,
memcpy
(
lc
->
stfle_fac_list
,
S390_lowcore
.
stfle_fac_list
,
MAX_FACILITY_BIT
/
8
);
MAX_FACILITY_BIT
/
8
);
if
(
MACHINE_HAS_VX
)
if
(
MACHINE_HAS_VX
||
MACHINE_HAS_GS
)
{
lc
->
vector_save_area_addr
=
unsigned
long
bits
,
size
;
(
unsigned
long
)
&
lc
->
vector_save_area
;
bits
=
MACHINE_HAS_GS
?
11
:
10
;
size
=
1UL
<<
bits
;
lc
->
mcesad
=
(
__u64
)
memblock_virt_alloc
(
size
,
size
);
if
(
MACHINE_HAS_GS
)
lc
->
mcesad
|=
bits
;
}
lc
->
vdso_per_cpu_data
=
(
unsigned
long
)
&
lc
->
paste
[
0
];
lc
->
vdso_per_cpu_data
=
(
unsigned
long
)
&
lc
->
paste
[
0
];
lc
->
sync_enter_timer
=
S390_lowcore
.
sync_enter_timer
;
lc
->
sync_enter_timer
=
S390_lowcore
.
sync_enter_timer
;
lc
->
async_enter_timer
=
S390_lowcore
.
async_enter_timer
;
lc
->
async_enter_timer
=
S390_lowcore
.
async_enter_timer
;
...
@@ -779,6 +785,12 @@ static int __init setup_hwcaps(void)
...
@@ -779,6 +785,12 @@ static int __init setup_hwcaps(void)
elf_hwcap
|=
HWCAP_S390_VXRS_BCD
;
elf_hwcap
|=
HWCAP_S390_VXRS_BCD
;
}
}
/*
* Guarded storage support HWCAP_S390_GS is bit 12.
*/
if
(
MACHINE_HAS_GS
)
elf_hwcap
|=
HWCAP_S390_GS
;
get_cpu_id
(
&
cpu_id
);
get_cpu_id
(
&
cpu_id
);
add_device_randomness
(
&
cpu_id
,
sizeof
(
cpu_id
));
add_device_randomness
(
&
cpu_id
,
sizeof
(
cpu_id
));
switch
(
cpu_id
.
machine
)
{
switch
(
cpu_id
.
machine
)
{
...
...
arch/s390/kernel/smp.c
浏览文件 @
bffc880b
...
@@ -51,6 +51,7 @@
...
@@ -51,6 +51,7 @@
#include <asm/os_info.h>
#include <asm/os_info.h>
#include <asm/sigp.h>
#include <asm/sigp.h>
#include <asm/idle.h>
#include <asm/idle.h>
#include <asm/nmi.h>
#include "entry.h"
#include "entry.h"
enum
{
enum
{
...
@@ -78,6 +79,8 @@ struct pcpu {
...
@@ -78,6 +79,8 @@ struct pcpu {
static
u8
boot_core_type
;
static
u8
boot_core_type
;
static
struct
pcpu
pcpu_devices
[
NR_CPUS
];
static
struct
pcpu
pcpu_devices
[
NR_CPUS
];
static
struct
kmem_cache
*
pcpu_mcesa_cache
;
unsigned
int
smp_cpu_mt_shift
;
unsigned
int
smp_cpu_mt_shift
;
EXPORT_SYMBOL
(
smp_cpu_mt_shift
);
EXPORT_SYMBOL
(
smp_cpu_mt_shift
);
...
@@ -188,8 +191,10 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit)
...
@@ -188,8 +191,10 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit)
static
int
pcpu_alloc_lowcore
(
struct
pcpu
*
pcpu
,
int
cpu
)
static
int
pcpu_alloc_lowcore
(
struct
pcpu
*
pcpu
,
int
cpu
)
{
{
unsigned
long
async_stack
,
panic_stack
;
unsigned
long
async_stack
,
panic_stack
;
unsigned
long
mcesa_origin
,
mcesa_bits
;
struct
lowcore
*
lc
;
struct
lowcore
*
lc
;
mcesa_origin
=
mcesa_bits
=
0
;
if
(
pcpu
!=
&
pcpu_devices
[
0
])
{
if
(
pcpu
!=
&
pcpu_devices
[
0
])
{
pcpu
->
lowcore
=
(
struct
lowcore
*
)
pcpu
->
lowcore
=
(
struct
lowcore
*
)
__get_free_pages
(
GFP_KERNEL
|
GFP_DMA
,
LC_ORDER
);
__get_free_pages
(
GFP_KERNEL
|
GFP_DMA
,
LC_ORDER
);
...
@@ -197,20 +202,27 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
...
@@ -197,20 +202,27 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
panic_stack
=
__get_free_page
(
GFP_KERNEL
);
panic_stack
=
__get_free_page
(
GFP_KERNEL
);
if
(
!
pcpu
->
lowcore
||
!
panic_stack
||
!
async_stack
)
if
(
!
pcpu
->
lowcore
||
!
panic_stack
||
!
async_stack
)
goto
out
;
goto
out
;
if
(
MACHINE_HAS_VX
||
MACHINE_HAS_GS
)
{
mcesa_origin
=
(
unsigned
long
)
kmem_cache_alloc
(
pcpu_mcesa_cache
,
GFP_KERNEL
);
if
(
!
mcesa_origin
)
goto
out
;
mcesa_bits
=
MACHINE_HAS_GS
?
11
:
0
;
}
}
else
{
}
else
{
async_stack
=
pcpu
->
lowcore
->
async_stack
-
ASYNC_FRAME_OFFSET
;
async_stack
=
pcpu
->
lowcore
->
async_stack
-
ASYNC_FRAME_OFFSET
;
panic_stack
=
pcpu
->
lowcore
->
panic_stack
-
PANIC_FRAME_OFFSET
;
panic_stack
=
pcpu
->
lowcore
->
panic_stack
-
PANIC_FRAME_OFFSET
;
mcesa_origin
=
pcpu
->
lowcore
->
mcesad
&
MCESA_ORIGIN_MASK
;
mcesa_bits
=
pcpu
->
lowcore
->
mcesad
&
MCESA_LC_MASK
;
}
}
lc
=
pcpu
->
lowcore
;
lc
=
pcpu
->
lowcore
;
memcpy
(
lc
,
&
S390_lowcore
,
512
);
memcpy
(
lc
,
&
S390_lowcore
,
512
);
memset
((
char
*
)
lc
+
512
,
0
,
sizeof
(
*
lc
)
-
512
);
memset
((
char
*
)
lc
+
512
,
0
,
sizeof
(
*
lc
)
-
512
);
lc
->
async_stack
=
async_stack
+
ASYNC_FRAME_OFFSET
;
lc
->
async_stack
=
async_stack
+
ASYNC_FRAME_OFFSET
;
lc
->
panic_stack
=
panic_stack
+
PANIC_FRAME_OFFSET
;
lc
->
panic_stack
=
panic_stack
+
PANIC_FRAME_OFFSET
;
lc
->
mcesad
=
mcesa_origin
|
mcesa_bits
;
lc
->
cpu_nr
=
cpu
;
lc
->
cpu_nr
=
cpu
;
lc
->
spinlock_lockval
=
arch_spin_lockval
(
cpu
);
lc
->
spinlock_lockval
=
arch_spin_lockval
(
cpu
);
if
(
MACHINE_HAS_VX
)
lc
->
vector_save_area_addr
=
(
unsigned
long
)
&
lc
->
vector_save_area
;
if
(
vdso_alloc_per_cpu
(
lc
))
if
(
vdso_alloc_per_cpu
(
lc
))
goto
out
;
goto
out
;
lowcore_ptr
[
cpu
]
=
lc
;
lowcore_ptr
[
cpu
]
=
lc
;
...
@@ -218,6 +230,9 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
...
@@ -218,6 +230,9 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
return
0
;
return
0
;
out:
out:
if
(
pcpu
!=
&
pcpu_devices
[
0
])
{
if
(
pcpu
!=
&
pcpu_devices
[
0
])
{
if
(
mcesa_origin
)
kmem_cache_free
(
pcpu_mcesa_cache
,
(
void
*
)
mcesa_origin
);
free_page
(
panic_stack
);
free_page
(
panic_stack
);
free_pages
(
async_stack
,
ASYNC_ORDER
);
free_pages
(
async_stack
,
ASYNC_ORDER
);
free_pages
((
unsigned
long
)
pcpu
->
lowcore
,
LC_ORDER
);
free_pages
((
unsigned
long
)
pcpu
->
lowcore
,
LC_ORDER
);
...
@@ -229,11 +244,17 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
...
@@ -229,11 +244,17 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
static
void
pcpu_free_lowcore
(
struct
pcpu
*
pcpu
)
static
void
pcpu_free_lowcore
(
struct
pcpu
*
pcpu
)
{
{
unsigned
long
mcesa_origin
;
pcpu_sigp_retry
(
pcpu
,
SIGP_SET_PREFIX
,
0
);
pcpu_sigp_retry
(
pcpu
,
SIGP_SET_PREFIX
,
0
);
lowcore_ptr
[
pcpu
-
pcpu_devices
]
=
NULL
;
lowcore_ptr
[
pcpu
-
pcpu_devices
]
=
NULL
;
vdso_free_per_cpu
(
pcpu
->
lowcore
);
vdso_free_per_cpu
(
pcpu
->
lowcore
);
if
(
pcpu
==
&
pcpu_devices
[
0
])
if
(
pcpu
==
&
pcpu_devices
[
0
])
return
;
return
;
if
(
MACHINE_HAS_VX
||
MACHINE_HAS_GS
)
{
mcesa_origin
=
pcpu
->
lowcore
->
mcesad
&
MCESA_ORIGIN_MASK
;
kmem_cache_free
(
pcpu_mcesa_cache
,
(
void
*
)
mcesa_origin
);
}
free_page
(
pcpu
->
lowcore
->
panic_stack
-
PANIC_FRAME_OFFSET
);
free_page
(
pcpu
->
lowcore
->
panic_stack
-
PANIC_FRAME_OFFSET
);
free_pages
(
pcpu
->
lowcore
->
async_stack
-
ASYNC_FRAME_OFFSET
,
ASYNC_ORDER
);
free_pages
(
pcpu
->
lowcore
->
async_stack
-
ASYNC_FRAME_OFFSET
,
ASYNC_ORDER
);
free_pages
((
unsigned
long
)
pcpu
->
lowcore
,
LC_ORDER
);
free_pages
((
unsigned
long
)
pcpu
->
lowcore
,
LC_ORDER
);
...
@@ -550,9 +571,11 @@ int smp_store_status(int cpu)
...
@@ -550,9 +571,11 @@ int smp_store_status(int cpu)
if
(
__pcpu_sigp_relax
(
pcpu
->
address
,
SIGP_STORE_STATUS_AT_ADDRESS
,
if
(
__pcpu_sigp_relax
(
pcpu
->
address
,
SIGP_STORE_STATUS_AT_ADDRESS
,
pa
)
!=
SIGP_CC_ORDER_CODE_ACCEPTED
)
pa
)
!=
SIGP_CC_ORDER_CODE_ACCEPTED
)
return
-
EIO
;
return
-
EIO
;
if
(
!
MACHINE_HAS_VX
)
if
(
!
MACHINE_HAS_VX
&&
!
MACHINE_HAS_GS
)
return
0
;
return
0
;
pa
=
__pa
(
pcpu
->
lowcore
->
vector_save_area_addr
);
pa
=
__pa
(
pcpu
->
lowcore
->
mcesad
&
MCESA_ORIGIN_MASK
);
if
(
MACHINE_HAS_GS
)
pa
|=
pcpu
->
lowcore
->
mcesad
&
MCESA_LC_MASK
;
if
(
__pcpu_sigp_relax
(
pcpu
->
address
,
SIGP_STORE_ADDITIONAL_STATUS
,
if
(
__pcpu_sigp_relax
(
pcpu
->
address
,
SIGP_STORE_ADDITIONAL_STATUS
,
pa
)
!=
SIGP_CC_ORDER_CODE_ACCEPTED
)
pa
)
!=
SIGP_CC_ORDER_CODE_ACCEPTED
)
return
-
EIO
;
return
-
EIO
;
...
@@ -897,12 +920,22 @@ void __init smp_fill_possible_mask(void)
...
@@ -897,12 +920,22 @@ void __init smp_fill_possible_mask(void)
void
__init
smp_prepare_cpus
(
unsigned
int
max_cpus
)
void
__init
smp_prepare_cpus
(
unsigned
int
max_cpus
)
{
{
unsigned
long
size
;
/* request the 0x1201 emergency signal external interrupt */
/* request the 0x1201 emergency signal external interrupt */
if
(
register_external_irq
(
EXT_IRQ_EMERGENCY_SIG
,
do_ext_call_interrupt
))
if
(
register_external_irq
(
EXT_IRQ_EMERGENCY_SIG
,
do_ext_call_interrupt
))
panic
(
"Couldn't request external interrupt 0x1201"
);
panic
(
"Couldn't request external interrupt 0x1201"
);
/* request the 0x1202 external call external interrupt */
/* request the 0x1202 external call external interrupt */
if
(
register_external_irq
(
EXT_IRQ_EXTERNAL_CALL
,
do_ext_call_interrupt
))
if
(
register_external_irq
(
EXT_IRQ_EXTERNAL_CALL
,
do_ext_call_interrupt
))
panic
(
"Couldn't request external interrupt 0x1202"
);
panic
(
"Couldn't request external interrupt 0x1202"
);
/* create slab cache for the machine-check-extended-save-areas */
if
(
MACHINE_HAS_VX
||
MACHINE_HAS_GS
)
{
size
=
1UL
<<
(
MACHINE_HAS_GS
?
11
:
10
);
pcpu_mcesa_cache
=
kmem_cache_create
(
"nmi_save_areas"
,
size
,
size
,
0
,
NULL
);
if
(
!
pcpu_mcesa_cache
)
panic
(
"Couldn't create nmi save area cache"
);
}
}
}
void
__init
smp_prepare_boot_cpu
(
void
)
void
__init
smp_prepare_boot_cpu
(
void
)
...
...
arch/s390/kernel/syscalls.S
浏览文件 @
bffc880b
...
@@ -386,5 +386,5 @@ SYSCALL(sys_mlock2,compat_sys_mlock2)
...
@@ -386,5 +386,5 @@ SYSCALL(sys_mlock2,compat_sys_mlock2)
SYSCALL
(
sys_copy_file_range
,
compat_sys_copy_file_range
)
/
*
375
*/
SYSCALL
(
sys_copy_file_range
,
compat_sys_copy_file_range
)
/
*
375
*/
SYSCALL
(
sys_preadv2
,
compat_sys_preadv2
)
SYSCALL
(
sys_preadv2
,
compat_sys_preadv2
)
SYSCALL
(
sys_pwritev2
,
compat_sys_pwritev2
)
SYSCALL
(
sys_pwritev2
,
compat_sys_pwritev2
)
NI_SYSCALL
SYSCALL
(
sys_s390_guarded_storage
,
compat_sys_s390_guarded_storage
)
/
*
378
*/
SYSCALL
(
sys_statx
,
compat_sys_statx
)
SYSCALL
(
sys_statx
,
compat_sys_statx
)
arch/s390/kvm/interrupt.c
浏览文件 @
bffc880b
...
@@ -420,8 +420,8 @@ static int __write_machine_check(struct kvm_vcpu *vcpu,
...
@@ -420,8 +420,8 @@ static int __write_machine_check(struct kvm_vcpu *vcpu,
save_access_regs
(
vcpu
->
run
->
s
.
regs
.
acrs
);
save_access_regs
(
vcpu
->
run
->
s
.
regs
.
acrs
);
/* Extended save area */
/* Extended save area */
rc
=
read_guest_lc
(
vcpu
,
__LC_
VX_SAVE_AREA_ADDR
,
&
ext_sa_addr
,
rc
=
read_guest_lc
(
vcpu
,
__LC_
MCESAD
,
&
ext_sa_addr
,
sizeof
(
unsigned
long
));
sizeof
(
unsigned
long
));
/* Only bits 0-53 are used for address formation */
/* Only bits 0-53 are used for address formation */
ext_sa_addr
&=
~
0x3ffUL
;
ext_sa_addr
&=
~
0x3ffUL
;
if
(
!
rc
&&
mci
.
vr
&&
ext_sa_addr
&&
test_kvm_facility
(
vcpu
->
kvm
,
129
))
{
if
(
!
rc
&&
mci
.
vr
&&
ext_sa_addr
&&
test_kvm_facility
(
vcpu
->
kvm
,
129
))
{
...
...
include/uapi/linux/elf.h
浏览文件 @
bffc880b
...
@@ -409,6 +409,7 @@ typedef struct elf64_shdr {
...
@@ -409,6 +409,7 @@ typedef struct elf64_shdr {
#define NT_S390_TDB 0x308
/* s390 transaction diagnostic block */
#define NT_S390_TDB 0x308
/* s390 transaction diagnostic block */
#define NT_S390_VXRS_LOW 0x309
/* s390 vector registers 0-15 upper half */
#define NT_S390_VXRS_LOW 0x309
/* s390 vector registers 0-15 upper half */
#define NT_S390_VXRS_HIGH 0x30a
/* s390 vector registers 16-31 */
#define NT_S390_VXRS_HIGH 0x30a
/* s390 vector registers 16-31 */
#define NT_S390_GS_CB 0x30b
/* s390 guarded storage registers */
#define NT_ARM_VFP 0x400
/* ARM VFP/NEON registers */
#define NT_ARM_VFP 0x400
/* ARM VFP/NEON registers */
#define NT_ARM_TLS 0x401
/* ARM TLS register */
#define NT_ARM_TLS 0x401
/* ARM TLS register */
#define NT_ARM_HW_BREAK 0x402
/* ARM hardware breakpoint registers */
#define NT_ARM_HW_BREAK 0x402
/* ARM hardware breakpoint registers */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录