提交 09c2fe60 编写于 作者: L Linus Torvalds

Merge tag 's390-5.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Martin Schwidefsky:

 - Do not claim to run under z/VM if the hypervisor can not be
   identified

 - Fix crashes due to outdated ASCEs in CR1

 - Avoid a deadlock in regard to CPU hotplug

 - Really fix the vdso mapping issue for compat tasks

 - Avoid crash on restart due to an incorrect stack address

* tag 's390-5.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/smp: Fix calling smp_call_ipl_cpu() from ipl CPU
  s390/vdso: correct vdso mapping for compat tasks
  s390/smp: fix CPU hotplug deadlock with CPU rescan
  s390/mm: always force a load of the primary ASCE on context switch
  s390/early: improve machine detection
...@@ -25,7 +25,7 @@ static inline int init_new_context(struct task_struct *tsk, ...@@ -25,7 +25,7 @@ static inline int init_new_context(struct task_struct *tsk,
atomic_set(&mm->context.flush_count, 0); atomic_set(&mm->context.flush_count, 0);
mm->context.gmap_asce = 0; mm->context.gmap_asce = 0;
mm->context.flush_mm = 0; mm->context.flush_mm = 0;
mm->context.compat_mm = 0; mm->context.compat_mm = test_thread_flag(TIF_31BIT);
#ifdef CONFIG_PGSTE #ifdef CONFIG_PGSTE
mm->context.alloc_pgste = page_table_allocate_pgste || mm->context.alloc_pgste = page_table_allocate_pgste ||
test_thread_flag(TIF_PGSTE) || test_thread_flag(TIF_PGSTE) ||
...@@ -90,8 +90,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, ...@@ -90,8 +90,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
{ {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
if (prev == next)
return;
S390_lowcore.user_asce = next->context.asce; S390_lowcore.user_asce = next->context.asce;
cpumask_set_cpu(cpu, &next->context.cpu_attach_mask); cpumask_set_cpu(cpu, &next->context.cpu_attach_mask);
/* Clear previous user-ASCE from CR1 and CR7 */ /* Clear previous user-ASCE from CR1 and CR7 */
...@@ -103,7 +101,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, ...@@ -103,7 +101,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
__ctl_load(S390_lowcore.vdso_asce, 7, 7); __ctl_load(S390_lowcore.vdso_asce, 7, 7);
clear_cpu_flag(CIF_ASCE_SECONDARY); clear_cpu_flag(CIF_ASCE_SECONDARY);
} }
cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask); if (prev != next)
cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask);
} }
#define finish_arch_post_lock_switch finish_arch_post_lock_switch #define finish_arch_post_lock_switch finish_arch_post_lock_switch
......
...@@ -63,10 +63,10 @@ static noinline __init void detect_machine_type(void) ...@@ -63,10 +63,10 @@ static noinline __init void detect_machine_type(void)
if (stsi(vmms, 3, 2, 2) || !vmms->count) if (stsi(vmms, 3, 2, 2) || !vmms->count)
return; return;
/* Running under KVM? If not we assume z/VM */ /* Detect known hypervisors */
if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3)) if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3))
S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; S390_lowcore.machine_flags |= MACHINE_FLAG_KVM;
else else if (!memcmp(vmms->vm[0].cpi, "\xa9\x61\xe5\xd4", 4))
S390_lowcore.machine_flags |= MACHINE_FLAG_VM; S390_lowcore.machine_flags |= MACHINE_FLAG_VM;
} }
......
...@@ -1006,6 +1006,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -1006,6 +1006,8 @@ void __init setup_arch(char **cmdline_p)
pr_info("Linux is running under KVM in 64-bit mode\n"); pr_info("Linux is running under KVM in 64-bit mode\n");
else if (MACHINE_IS_LPAR) else if (MACHINE_IS_LPAR)
pr_info("Linux is running natively in 64-bit mode\n"); pr_info("Linux is running natively in 64-bit mode\n");
else
pr_info("Linux is running as a guest in 64-bit mode\n");
/* Have one command line that is parsed and saved in /proc/cmdline */ /* Have one command line that is parsed and saved in /proc/cmdline */
/* boot_command_line has been already set up in early.c */ /* boot_command_line has been already set up in early.c */
......
...@@ -381,8 +381,13 @@ void smp_call_online_cpu(void (*func)(void *), void *data) ...@@ -381,8 +381,13 @@ void smp_call_online_cpu(void (*func)(void *), void *data)
*/ */
void smp_call_ipl_cpu(void (*func)(void *), void *data) void smp_call_ipl_cpu(void (*func)(void *), void *data)
{ {
struct lowcore *lc = pcpu_devices->lowcore;
if (pcpu_devices[0].address == stap())
lc = &S390_lowcore;
pcpu_delegate(&pcpu_devices[0], func, data, pcpu_delegate(&pcpu_devices[0], func, data,
pcpu_devices->lowcore->nodat_stack); lc->nodat_stack);
} }
int smp_find_processor_id(u16 address) int smp_find_processor_id(u16 address)
...@@ -1166,7 +1171,11 @@ static ssize_t __ref rescan_store(struct device *dev, ...@@ -1166,7 +1171,11 @@ static ssize_t __ref rescan_store(struct device *dev,
{ {
int rc; int rc;
rc = lock_device_hotplug_sysfs();
if (rc)
return rc;
rc = smp_rescan_cpus(); rc = smp_rescan_cpus();
unlock_device_hotplug();
return rc ? rc : count; return rc ? rc : count;
} }
static DEVICE_ATTR_WO(rescan); static DEVICE_ATTR_WO(rescan);
......
...@@ -224,10 +224,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) ...@@ -224,10 +224,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
vdso_pages = vdso64_pages; vdso_pages = vdso64_pages;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
if (is_compat_task()) { mm->context.compat_mm = is_compat_task();
if (mm->context.compat_mm)
vdso_pages = vdso32_pages; vdso_pages = vdso32_pages;
mm->context.compat_mm = 1;
}
#endif #endif
/* /*
* vDSO has a problem and was disabled, just don't "enable" it for * vDSO has a problem and was disabled, just don't "enable" it for
......
...@@ -60,7 +60,9 @@ static void sclp_cpu_capability_notify(struct work_struct *work) ...@@ -60,7 +60,9 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
static void __ref sclp_cpu_change_notify(struct work_struct *work) static void __ref sclp_cpu_change_notify(struct work_struct *work)
{ {
lock_device_hotplug();
smp_rescan_cpus(); smp_rescan_cpus();
unlock_device_hotplug();
} }
static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册