Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull second set of s390 patches from Martin Schwidefsky:
 "The second part of Heikos uaccess rework, the page table walker for
  uaccess is now a thing of the past (yay!)

  The code change to fix the theoretical TLB flush problem allows us to
  add a TLB flush optimization for zEC12, this machine has new
  instructions that allow to do CPU local TLB flushes for single pages
  and for all pages of a specific address space.

  Plus the usual bug fixing and some more cleanup"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/uaccess: rework uaccess code - fix locking issues
  s390/mm,tlb: optimize TLB flushing for zEC12
  s390/mm,tlb: safeguard against speculative TLB creation
  s390/irq: Use defines for external interruption codes
  s390/irq: Add defines for external interruption codes
  s390/sclp: add timeout for queued requests
  kvm/s390: also set guest pages back to stable on kexec/kdump
  lcs: Add missing destroy_timer_on_stack()
  s390/tape: Add missing destroy_timer_on_stack()
  s390/tape: Use del_timer_sync()
  s390/3270: fix crash with multiple reset device requests
  s390/bitops,atomic: add missing memory barriers
  s390/zcrypt: add length check for aligned data to avoid overflow in msg-type 6
This commit is contained in:
Linus Torvalds
2014-04-08 12:02:28 -07:00
47 changed files with 1034 additions and 981 deletions

View File

@@ -136,6 +136,7 @@ int main(void)
DEFINE(__LC_RESTART_FN, offsetof(struct _lowcore, restart_fn));
DEFINE(__LC_RESTART_DATA, offsetof(struct _lowcore, restart_data));
DEFINE(__LC_RESTART_SOURCE, offsetof(struct _lowcore, restart_source));
DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce));
DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));

View File

@@ -386,6 +386,8 @@ static __init void detect_machine_facilities(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
if (test_facility(66))
S390_lowcore.machine_flags |= MACHINE_FLAG_RRBM;
if (test_facility(51))
S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC;
#endif
}

View File

@@ -38,9 +38,9 @@ __PT_R14 = __PT_GPRS + 56
__PT_R15 = __PT_GPRS + 60
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING | _TIF_PER_TRAP )
_TIF_MCCK_PENDING | _TIF_PER_TRAP | _TIF_ASCE)
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING)
_TIF_MCCK_PENDING | _TIF_ASCE)
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
_TIF_SYSCALL_TRACEPOINT)
_TIF_TRANSFER = (_TIF_MCCK_PENDING | _TIF_TLB_WAIT)
@@ -241,6 +241,8 @@ sysc_work:
jo sysc_sigpending
tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
jo sysc_notify_resume
tm __TI_flags+3(%r12),_TIF_ASCE
jo sysc_uaccess
j sysc_return # beware of critical section cleanup
#
@@ -259,6 +261,14 @@ sysc_mcck_pending:
la %r14,BASED(sysc_return)
br %r1 # TIF bit will be cleared by handler
#
# _TIF_ASCE is set, load user space asce
#
sysc_uaccess:
ni __TI_flags+3(%r12),255-_TIF_ASCE
lctl %c1,%c1,__LC_USER_ASCE # load primary asce
j sysc_return
#
# _TIF_SIGPENDING is set, call do_signal
#
@@ -522,6 +532,8 @@ io_work_tif:
jo io_sigpending
tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
jo io_notify_resume
tm __TI_flags+3(%r12),_TIF_ASCE
jo io_uaccess
j io_return # beware of critical section cleanup
#
@@ -534,6 +546,14 @@ io_mcck_pending:
TRACE_IRQS_OFF
j io_return
#
# _TIF_ASCE is set, load user space asce
#
io_uaccess:
ni __TI_flags+3(%r12),255-_TIF_ASCE
lctl %c1,%c1,__LC_USER_ASCE # load primary asce
j io_return
#
# _TIF_NEED_RESCHED is set, call schedule
#

View File

@@ -43,9 +43,9 @@ STACK_SIZE = 1 << STACK_SHIFT
STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING | _TIF_PER_TRAP )
_TIF_MCCK_PENDING | _TIF_PER_TRAP | _TIF_ASCE)
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING)
_TIF_MCCK_PENDING | _TIF_ASCE)
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
_TIF_SYSCALL_TRACEPOINT)
_TIF_TRANSFER = (_TIF_MCCK_PENDING | _TIF_TLB_WAIT)
@@ -275,6 +275,8 @@ sysc_work:
jo sysc_sigpending
tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
jo sysc_notify_resume
tm __TI_flags+7(%r12),_TIF_ASCE
jo sysc_uaccess
j sysc_return # beware of critical section cleanup
#
@@ -291,6 +293,14 @@ sysc_mcck_pending:
larl %r14,sysc_return
jg s390_handle_mcck # TIF bit will be cleared by handler
#
# _TIF_ASCE is set, load user space asce
#
sysc_uaccess:
ni __TI_flags+7(%r12),255-_TIF_ASCE
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
j sysc_return
#
# _TIF_SIGPENDING is set, call do_signal
#
@@ -559,6 +569,8 @@ io_work_tif:
jo io_sigpending
tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
jo io_notify_resume
tm __TI_flags+7(%r12),_TIF_ASCE
jo io_uaccess
j io_return # beware of critical section cleanup
#
@@ -570,6 +582,14 @@ io_mcck_pending:
TRACE_IRQS_OFF
j io_return
#
# _TIF_ASCE is set, load user space asce
#
io_uaccess:
ni __TI_flags+7(%r12),255-_TIF_ASCE
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
j io_return
#
# _TIF_NEED_RESCHED is set, call schedule
#

View File

@@ -207,7 +207,7 @@ static inline int ext_hash(u16 code)
return (code + (code >> 9)) & (ARRAY_SIZE(ext_int_hash) - 1);
}
int register_external_interrupt(u16 code, ext_int_handler_t handler)
int register_external_irq(u16 code, ext_int_handler_t handler)
{
struct ext_int_info *p;
unsigned long flags;
@@ -225,9 +225,9 @@ int register_external_interrupt(u16 code, ext_int_handler_t handler)
spin_unlock_irqrestore(&ext_int_hash_lock, flags);
return 0;
}
EXPORT_SYMBOL(register_external_interrupt);
EXPORT_SYMBOL(register_external_irq);
int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
int unregister_external_irq(u16 code, ext_int_handler_t handler)
{
struct ext_int_info *p;
unsigned long flags;
@@ -243,7 +243,7 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
spin_unlock_irqrestore(&ext_int_hash_lock, flags);
return 0;
}
EXPORT_SYMBOL(unregister_external_interrupt);
EXPORT_SYMBOL(unregister_external_irq);
static irqreturn_t do_ext_interrupt(int irq, void *dummy)
{
@@ -253,7 +253,7 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy)
int index;
ext_code = *(struct ext_code *) &regs->int_code;
if (ext_code.code != 0x1004)
if (ext_code.code != EXT_IRQ_CLK_COMP)
__get_cpu_var(s390_idle).nohz_delay = 1;
index = ext_hash(ext_code.code);

View File

@@ -673,7 +673,8 @@ static int __init cpumf_pmu_init(void)
ctl_clear_bit(0, 48);
/* register handler for measurement-alert interruptions */
rc = register_external_interrupt(0x1407, cpumf_measurement_alert);
rc = register_external_irq(EXT_IRQ_MEASURE_ALERT,
cpumf_measurement_alert);
if (rc) {
pr_err("Registering for CPU-measurement alerts "
"failed with rc=%i\n", rc);
@@ -684,7 +685,8 @@ static int __init cpumf_pmu_init(void)
rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW);
if (rc) {
pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc);
unregister_external_interrupt(0x1407, cpumf_measurement_alert);
unregister_external_irq(EXT_IRQ_MEASURE_ALERT,
cpumf_measurement_alert);
goto out;
}
perf_cpu_notifier(cpumf_pmu_notifier);

View File

@@ -1621,7 +1621,8 @@ static int __init init_cpum_sampling_pmu(void)
pr_err("Registering for s390dbf failed\n");
debug_register_view(sfdbg, &debug_sprintf_view);
err = register_external_interrupt(0x1407, cpumf_measurement_alert);
err = register_external_irq(EXT_IRQ_MEASURE_ALERT,
cpumf_measurement_alert);
if (err) {
pr_cpumsf_err(RS_INIT_FAILURE_ALRT);
goto out;
@@ -1630,7 +1631,8 @@ static int __init init_cpum_sampling_pmu(void)
err = perf_pmu_register(&cpumf_sampling, "cpum_sf", PERF_TYPE_RAW);
if (err) {
pr_cpumsf_err(RS_INIT_FAILURE_PERF);
unregister_external_interrupt(0x1407, cpumf_measurement_alert);
unregister_external_irq(EXT_IRQ_MEASURE_ALERT,
cpumf_measurement_alert);
goto out;
}
perf_cpu_notifier(cpumf_pmu_notifier);

View File

@@ -138,7 +138,8 @@ static int __init runtime_instr_init(void)
return 0;
irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
rc = register_external_interrupt(0x1407, runtime_instr_int_handler);
rc = register_external_irq(EXT_IRQ_MEASURE_ALERT,
runtime_instr_int_handler);
if (rc)
irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
else

View File

@@ -9,6 +9,7 @@
*/
#include <linux/linkage.h>
#include <asm/irq.h>
LC_EXT_NEW_PSW = 0x58 # addr of ext int handler
LC_EXT_NEW_PSW_64 = 0x1b0 # addr of ext int handler 64 bit
@@ -73,9 +74,9 @@ _sclp_wait_int:
lpsw .LwaitpswS1-.LbaseS1(%r13) # wait until interrupt
.LwaitS1:
lh %r7,LC_EXT_INT_CODE
chi %r7,0x1004 # timeout?
chi %r7,EXT_IRQ_CLK_COMP # timeout?
je .LtimeoutS1
chi %r7,0x2401 # service int?
chi %r7,EXT_IRQ_SERVICE_SIG # service int?
jne .LloopS1
sr %r2,%r2
l %r3,LC_EXT_INT_PARAM

View File

@@ -236,6 +236,9 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
{
struct _lowcore *lc = pcpu->lowcore;
if (MACHINE_HAS_TLB_LC)
cpumask_set_cpu(cpu, &init_mm.context.cpu_attach_mask);
cpumask_set_cpu(cpu, mm_cpumask(&init_mm));
atomic_inc(&init_mm.context.attach_count);
lc->cpu_nr = cpu;
lc->percpu_offset = __per_cpu_offset[cpu];
@@ -760,6 +763,9 @@ void __cpu_die(unsigned int cpu)
cpu_relax();
pcpu_free_lowcore(pcpu);
atomic_dec(&init_mm.context.attach_count);
cpumask_clear_cpu(cpu, mm_cpumask(&init_mm));
if (MACHINE_HAS_TLB_LC)
cpumask_clear_cpu(cpu, &init_mm.context.cpu_attach_mask);
}
void __noreturn cpu_die(void)
@@ -785,10 +791,10 @@ void __init smp_fill_possible_mask(void)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
/* request the 0x1201 emergency signal external interrupt */
if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
if (register_external_irq(EXT_IRQ_EMERGENCY_SIG, do_ext_call_interrupt))
panic("Couldn't request external interrupt 0x1201");
/* request the 0x1202 external call external interrupt */
if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0)
if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt))
panic("Couldn't request external interrupt 0x1202");
smp_detect_cpus();
}

View File

@@ -262,11 +262,11 @@ void __init time_init(void)
stp_reset();
/* request the clock comparator external interrupt */
if (register_external_interrupt(0x1004, clock_comparator_interrupt))
panic("Couldn't request external interrupt 0x1004");
if (register_external_irq(EXT_IRQ_CLK_COMP, clock_comparator_interrupt))
panic("Couldn't request external interrupt 0x1004");
/* request the timing alert external interrupt */
if (register_external_interrupt(0x1406, timing_alert_interrupt))
if (register_external_irq(EXT_IRQ_TIMING_ALERT, timing_alert_interrupt))
panic("Couldn't request external interrupt 0x1406");
if (clocksource_register(&clocksource_tod) != 0)