Commit eb5f95f1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 's390-5.9-6' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Vasily Gorbik:

 - Fix order in trace_hardirqs_off_caller() to make locking state
   consistent even if the IRQ tracer calls into lockdep again. Touches
   common code. Acked-by Peter Zijlstra.

 - Correctly handle secure storage violation exception to avoid kernel
   panic triggered by user space misbehaviour.

 - Switch the idle->seqcount over to using raw_write_*() to avoid
  "suspicious RCU usage".

 - Fix memory leaks on hard unplug in pci code.

 - Use kvmalloc instead of kmalloc for larger allocations in zcrypt.

 - Add few missing __init annotations to static functions to avoid
   section mismatch complains when functions are not inlined.

* tag 's390-5.9-6' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390: add 3f program exception handler
  lockdep: fix order in trace_hardirqs_off_caller()
  s390/pci: fix leak of DMA tables on hard unplug
  s390/init: add missing __init annotations
  s390/zcrypt: fix kmalloc 256k failure
  s390/idle: fix suspicious RCU usage
parents 92ab97ad cd4d3d5f
...@@ -26,6 +26,7 @@ void do_protection_exception(struct pt_regs *regs); ...@@ -26,6 +26,7 @@ void do_protection_exception(struct pt_regs *regs);
void do_dat_exception(struct pt_regs *regs); void do_dat_exception(struct pt_regs *regs);
void do_secure_storage_access(struct pt_regs *regs); void do_secure_storage_access(struct pt_regs *regs);
void do_non_secure_storage_access(struct pt_regs *regs); void do_non_secure_storage_access(struct pt_regs *regs);
void do_secure_storage_violation(struct pt_regs *regs);
void addressing_exception(struct pt_regs *regs); void addressing_exception(struct pt_regs *regs);
void data_exception(struct pt_regs *regs); void data_exception(struct pt_regs *regs);
......
...@@ -39,14 +39,13 @@ void enabled_wait(void) ...@@ -39,14 +39,13 @@ void enabled_wait(void)
local_irq_restore(flags); local_irq_restore(flags);
/* Account time spent with enabled wait psw loaded as idle time. */ /* Account time spent with enabled wait psw loaded as idle time. */
/* XXX seqcount has tracepoints that require RCU */ raw_write_seqcount_begin(&idle->seqcount);
write_seqcount_begin(&idle->seqcount);
idle_time = idle->clock_idle_exit - idle->clock_idle_enter; idle_time = idle->clock_idle_exit - idle->clock_idle_enter;
idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; idle->clock_idle_enter = idle->clock_idle_exit = 0ULL;
idle->idle_time += idle_time; idle->idle_time += idle_time;
idle->idle_count++; idle->idle_count++;
account_idle_time(cputime_to_nsecs(idle_time)); account_idle_time(cputime_to_nsecs(idle_time));
write_seqcount_end(&idle->seqcount); raw_write_seqcount_end(&idle->seqcount);
} }
NOKPROBE_SYMBOL(enabled_wait); NOKPROBE_SYMBOL(enabled_wait);
......
...@@ -80,7 +80,7 @@ PGM_CHECK(do_dat_exception) /* 3b */ ...@@ -80,7 +80,7 @@ PGM_CHECK(do_dat_exception) /* 3b */
PGM_CHECK_DEFAULT /* 3c */ PGM_CHECK_DEFAULT /* 3c */
PGM_CHECK(do_secure_storage_access) /* 3d */ PGM_CHECK(do_secure_storage_access) /* 3d */
PGM_CHECK(do_non_secure_storage_access) /* 3e */ PGM_CHECK(do_non_secure_storage_access) /* 3e */
PGM_CHECK_DEFAULT /* 3f */ PGM_CHECK(do_secure_storage_violation) /* 3f */
PGM_CHECK(monitor_event_exception) /* 40 */ PGM_CHECK(monitor_event_exception) /* 40 */
PGM_CHECK_DEFAULT /* 41 */ PGM_CHECK_DEFAULT /* 41 */
PGM_CHECK_DEFAULT /* 42 */ PGM_CHECK_DEFAULT /* 42 */
......
...@@ -619,7 +619,7 @@ static struct notifier_block kdump_mem_nb = { ...@@ -619,7 +619,7 @@ static struct notifier_block kdump_mem_nb = {
/* /*
* Make sure that the area behind memory_end is protected * Make sure that the area behind memory_end is protected
*/ */
static void reserve_memory_end(void) static void __init reserve_memory_end(void)
{ {
if (memory_end_set) if (memory_end_set)
memblock_reserve(memory_end, ULONG_MAX); memblock_reserve(memory_end, ULONG_MAX);
...@@ -628,7 +628,7 @@ static void reserve_memory_end(void) ...@@ -628,7 +628,7 @@ static void reserve_memory_end(void)
/* /*
* Make sure that oldmem, where the dump is stored, is protected * Make sure that oldmem, where the dump is stored, is protected
*/ */
static void reserve_oldmem(void) static void __init reserve_oldmem(void)
{ {
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
if (OLDMEM_BASE) if (OLDMEM_BASE)
...@@ -640,7 +640,7 @@ static void reserve_oldmem(void) ...@@ -640,7 +640,7 @@ static void reserve_oldmem(void)
/* /*
* Make sure that oldmem, where the dump is stored, is protected * Make sure that oldmem, where the dump is stored, is protected
*/ */
static void remove_oldmem(void) static void __init remove_oldmem(void)
{ {
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
if (OLDMEM_BASE) if (OLDMEM_BASE)
......
...@@ -859,6 +859,21 @@ void do_non_secure_storage_access(struct pt_regs *regs) ...@@ -859,6 +859,21 @@ void do_non_secure_storage_access(struct pt_regs *regs)
} }
NOKPROBE_SYMBOL(do_non_secure_storage_access); NOKPROBE_SYMBOL(do_non_secure_storage_access);
void do_secure_storage_violation(struct pt_regs *regs)
{
/*
* Either KVM messed up the secure guest mapping or the same
* page is mapped into multiple secure guests.
*
* This exception is only triggered when a guest 2 is running
* and can therefore never occur in kernel context.
*/
printk_ratelimited(KERN_WARNING
"Secure storage violation in task: %s, pid %d\n",
current->comm, current->pid);
send_sig(SIGSEGV, current, 0);
}
#else #else
void do_secure_storage_access(struct pt_regs *regs) void do_secure_storage_access(struct pt_regs *regs)
{ {
...@@ -869,4 +884,9 @@ void do_non_secure_storage_access(struct pt_regs *regs) ...@@ -869,4 +884,9 @@ void do_non_secure_storage_access(struct pt_regs *regs)
{ {
default_trap_handler(regs); default_trap_handler(regs);
} }
void do_secure_storage_violation(struct pt_regs *regs)
{
default_trap_handler(regs);
}
#endif #endif
...@@ -668,6 +668,10 @@ EXPORT_SYMBOL_GPL(zpci_enable_device); ...@@ -668,6 +668,10 @@ EXPORT_SYMBOL_GPL(zpci_enable_device);
int zpci_disable_device(struct zpci_dev *zdev) int zpci_disable_device(struct zpci_dev *zdev)
{ {
zpci_dma_exit_device(zdev); zpci_dma_exit_device(zdev);
/*
* The zPCI function may already be disabled by the platform, this is
* detected in clp_disable_fh() which becomes a no-op.
*/
return clp_disable_fh(zdev); return clp_disable_fh(zdev);
} }
EXPORT_SYMBOL_GPL(zpci_disable_device); EXPORT_SYMBOL_GPL(zpci_disable_device);
......
...@@ -143,6 +143,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) ...@@ -143,6 +143,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
zpci_remove_device(zdev); zpci_remove_device(zdev);
} }
zdev->fh = ccdf->fh;
zpci_disable_device(zdev);
zdev->state = ZPCI_FN_STATE_STANDBY; zdev->state = ZPCI_FN_STATE_STANDBY;
if (!clp_get_state(ccdf->fid, &state) && if (!clp_get_state(ccdf->fid, &state) &&
state == ZPCI_FN_STATE_RESERVED) { state == ZPCI_FN_STATE_RESERVED) {
......
...@@ -1692,9 +1692,9 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, ...@@ -1692,9 +1692,9 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
*nr_apqns = 0; *nr_apqns = 0;
/* fetch status of all crypto cards */ /* fetch status of all crypto cards */
device_status = kmalloc_array(MAX_ZDEV_ENTRIES_EXT, device_status = kvmalloc_array(MAX_ZDEV_ENTRIES_EXT,
sizeof(struct zcrypt_device_status_ext), sizeof(struct zcrypt_device_status_ext),
GFP_KERNEL); GFP_KERNEL);
if (!device_status) if (!device_status)
return -ENOMEM; return -ENOMEM;
zcrypt_device_status_mask_ext(device_status); zcrypt_device_status_mask_ext(device_status);
...@@ -1762,7 +1762,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, ...@@ -1762,7 +1762,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
verify = 0; verify = 0;
} }
kfree(device_status); kvfree(device_status);
return rc; return rc;
} }
EXPORT_SYMBOL(cca_findcard2); EXPORT_SYMBOL(cca_findcard2);
......
...@@ -102,14 +102,14 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_caller); ...@@ -102,14 +102,14 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_caller);
__visible void trace_hardirqs_off_caller(unsigned long caller_addr) __visible void trace_hardirqs_off_caller(unsigned long caller_addr)
{ {
lockdep_hardirqs_off(CALLER_ADDR0);
if (!this_cpu_read(tracing_irq_cpu)) { if (!this_cpu_read(tracing_irq_cpu)) {
this_cpu_write(tracing_irq_cpu, 1); this_cpu_write(tracing_irq_cpu, 1);
tracer_hardirqs_off(CALLER_ADDR0, caller_addr); tracer_hardirqs_off(CALLER_ADDR0, caller_addr);
if (!in_nmi()) if (!in_nmi())
trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr); trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
} }
lockdep_hardirqs_off(CALLER_ADDR0);
} }
EXPORT_SYMBOL(trace_hardirqs_off_caller); EXPORT_SYMBOL(trace_hardirqs_off_caller);
NOKPROBE_SYMBOL(trace_hardirqs_off_caller); NOKPROBE_SYMBOL(trace_hardirqs_off_caller);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment