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:
@@ -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));
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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 *) ®s->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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user