Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 patches from Martin Schwidefsky: "Some more bug fixes and a config change. The signal bug is nasty, if the clock_gettime vdso function is interrupted by a signal while in access-register-mode we end up with an endless signal loop until the signal stack is full. The config change is for aligned struct pages, gives us 8% improvement with hackbench." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/3215: fix tty close handling s390/mm: have 16 byte aligned struct pages s390/gup: fix access_ok() usage in __get_user_pages_fast() s390/gup: add missing TASK_SIZE check to get_user_pages_fast() s390/topology: fix core id vs physical package id mix-up s390/signal: set correct address space control
This commit is contained in:
commit
62735e5231
|
@ -96,6 +96,7 @@ config S390
|
|||
select HAVE_MEMBLOCK_NODE_MAP
|
||||
select HAVE_CMPXCHG_LOCAL
|
||||
select HAVE_CMPXCHG_DOUBLE
|
||||
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
|
||||
select HAVE_VIRT_CPU_ACCOUNTING
|
||||
select VIRT_CPU_ACCOUNTING
|
||||
select ARCH_DISCARD_MEMBLOCK
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define PSW32_MASK_CC 0x00003000UL
|
||||
#define PSW32_MASK_PM 0x00000f00UL
|
||||
|
||||
#define PSW32_MASK_USER 0x00003F00UL
|
||||
#define PSW32_MASK_USER 0x0000FF00UL
|
||||
|
||||
#define PSW32_ADDR_AMODE 0x80000000UL
|
||||
#define PSW32_ADDR_INSN 0x7FFFFFFFUL
|
||||
|
|
|
@ -8,6 +8,9 @@ struct cpu;
|
|||
|
||||
#ifdef CONFIG_SCHED_BOOK
|
||||
|
||||
extern unsigned char cpu_socket_id[NR_CPUS];
|
||||
#define topology_physical_package_id(cpu) (cpu_socket_id[cpu])
|
||||
|
||||
extern unsigned char cpu_core_id[NR_CPUS];
|
||||
extern cpumask_t cpu_core_map[NR_CPUS];
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ typedef struct
|
|||
#define PSW_MASK_EA 0x00000000UL
|
||||
#define PSW_MASK_BA 0x00000000UL
|
||||
|
||||
#define PSW_MASK_USER 0x00003F00UL
|
||||
#define PSW_MASK_USER 0x0000FF00UL
|
||||
|
||||
#define PSW_ADDR_AMODE 0x80000000UL
|
||||
#define PSW_ADDR_INSN 0x7FFFFFFFUL
|
||||
|
@ -269,7 +269,7 @@ typedef struct
|
|||
#define PSW_MASK_EA 0x0000000100000000UL
|
||||
#define PSW_MASK_BA 0x0000000080000000UL
|
||||
|
||||
#define PSW_MASK_USER 0x00003F8180000000UL
|
||||
#define PSW_MASK_USER 0x0000FF8180000000UL
|
||||
|
||||
#define PSW_ADDR_AMODE 0x0000000000000000UL
|
||||
#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL
|
||||
|
|
|
@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
|
|||
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
||||
(__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 |
|
||||
(__u64)(regs32.psw.addr & PSW32_ADDR_AMODE);
|
||||
/* Check for invalid user address space control. */
|
||||
if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
|
||||
regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
|
||||
for (i = 0; i < NUM_GPRS; i++)
|
||||
regs->gprs[i] = (__u64) regs32.gprs[i];
|
||||
|
@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
|
|||
|
||||
/* Set up registers for signal handler */
|
||||
regs->gprs[15] = (__force __u64) frame;
|
||||
regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */
|
||||
/* Force 31 bit amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (__force __u64) ka->sa.sa_handler;
|
||||
|
||||
regs->gprs[2] = map_signal(sig);
|
||||
|
@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
|
||||
/* Set up registers for signal handler */
|
||||
regs->gprs[15] = (__force __u64) frame;
|
||||
regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */
|
||||
/* Force 31 bit amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (__u64) ka->sa.sa_handler;
|
||||
|
||||
regs->gprs[2] = map_signal(sig);
|
||||
|
|
|
@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
|
|||
/* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */
|
||||
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
||||
(user_sregs.regs.psw.mask & PSW_MASK_USER);
|
||||
/* Check for invalid user address space control. */
|
||||
if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
|
||||
regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
/* Check for invalid amode */
|
||||
if (regs->psw.mask & PSW_MASK_EA)
|
||||
regs->psw.mask |= PSW_MASK_BA;
|
||||
|
@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka,
|
|||
|
||||
/* Set up registers for signal handler */
|
||||
regs->gprs[15] = (unsigned long) frame;
|
||||
regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */
|
||||
/* Force default amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
|
||||
|
||||
regs->gprs[2] = map_signal(sig);
|
||||
|
@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
|
||||
/* Set up registers for signal handler */
|
||||
regs->gprs[15] = (unsigned long) frame;
|
||||
regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */
|
||||
/* Force default amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
|
||||
|
||||
regs->gprs[2] = map_signal(sig);
|
||||
|
|
|
@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock);
|
|||
static struct mask_info core_info;
|
||||
cpumask_t cpu_core_map[NR_CPUS];
|
||||
unsigned char cpu_core_id[NR_CPUS];
|
||||
unsigned char cpu_socket_id[NR_CPUS];
|
||||
|
||||
static struct mask_info book_info;
|
||||
cpumask_t cpu_book_map[NR_CPUS];
|
||||
|
@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
|
|||
cpumask_set_cpu(lcpu, &book->mask);
|
||||
cpu_book_id[lcpu] = book->id;
|
||||
cpumask_set_cpu(lcpu, &core->mask);
|
||||
cpu_core_id[lcpu] = rcpu;
|
||||
if (one_core_per_cpu) {
|
||||
cpu_core_id[lcpu] = rcpu;
|
||||
cpu_socket_id[lcpu] = rcpu;
|
||||
core = core->next;
|
||||
} else {
|
||||
cpu_core_id[lcpu] = core->id;
|
||||
cpu_socket_id[lcpu] = core->id;
|
||||
}
|
||||
smp_cpu_set_polarization(lcpu, tl_cpu->pp);
|
||||
}
|
||||
|
|
|
@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
|||
addr = start;
|
||||
len = (unsigned long) nr_pages << PAGE_SHIFT;
|
||||
end = start + len;
|
||||
if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
|
||||
(void __user *)start, len)))
|
||||
if ((end < start) || (end > TASK_SIZE))
|
||||
return 0;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
@ -229,7 +228,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
|||
addr = start;
|
||||
len = (unsigned long) nr_pages << PAGE_SHIFT;
|
||||
end = start + len;
|
||||
if (end < start)
|
||||
if ((end < start) || (end > TASK_SIZE))
|
||||
goto slow_irqon;
|
||||
|
||||
/*
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#define RAW3215_NR_CCWS 3
|
||||
#define RAW3215_TIMEOUT HZ/10 /* time for delayed output */
|
||||
|
||||
#define RAW3215_FIXED 1 /* 3215 console device is not be freed */
|
||||
#define RAW3215_WORKING 4 /* set if a request is being worked on */
|
||||
#define RAW3215_THROTTLED 8 /* set if reading is disabled */
|
||||
#define RAW3215_STOPPED 16 /* set if writing is disabled */
|
||||
|
@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data)
|
|||
struct tty_struct *tty;
|
||||
|
||||
tty = tty_port_tty_get(&raw->port);
|
||||
tty_wakeup(tty);
|
||||
tty_kref_put(tty);
|
||||
if (tty) {
|
||||
tty_wakeup(tty);
|
||||
tty_kref_put(tty);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
|
|||
DECLARE_WAITQUEUE(wait, current);
|
||||
unsigned long flags;
|
||||
|
||||
if (!(raw->port.flags & ASYNC_INITIALIZED) ||
|
||||
(raw->flags & RAW3215_FIXED))
|
||||
if (!(raw->port.flags & ASYNC_INITIALIZED))
|
||||
return;
|
||||
/* Wait for outstanding requests, then free irq */
|
||||
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
|
||||
|
@ -926,8 +926,6 @@ static int __init con3215_init(void)
|
|||
dev_set_drvdata(&cdev->dev, raw);
|
||||
cdev->handler = raw3215_irq;
|
||||
|
||||
raw->flags |= RAW3215_FIXED;
|
||||
|
||||
/* Request the console irq */
|
||||
if (raw3215_startup(raw) != 0) {
|
||||
raw3215_free_info(raw);
|
||||
|
|
Loading…
Reference in New Issue