diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-03 05:04:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-03 05:04:07 -0400 |
commit | 286e050bc07a5ffcd7497e686c09b986d5ae6c6d (patch) | |
tree | aa95ca5ccc7f083cf1d99c171f7e60676f1bb869 /arch | |
parent | 7d80fea4263d9a83ffedea448afa8510b05d04d0 (diff) | |
parent | e86cbd8765bd2e1f9eeb209822449c9b1e5958cf (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky:
"Recent bug fixes, one of them touches a common code file.
It adds two #ifndef/#endif pairs to asm-generic/io.h to be able to
override xlate_dev_kmem_ptr and xlate_dev_mem_ptr."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/pgtable: Fix gmap notifier address
s390/dasd: fix handling of gone paths
s390/pgtable: Fix check for pgste/storage key handling
arch: s390: appldata: using strncpy() and strnlen() instead of sprintf()
s390/smp: lost IPIs on cpu hotplug
kernel: Fix s390 absolute memory access for /dev/mem
s390/dma: do not call debug_dma after free
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/appldata/appldata_base.c | 7 | ||||
-rw-r--r-- | arch/s390/include/asm/dma-mapping.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/io.h | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 15 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 27 | ||||
-rw-r--r-- | arch/s390/mm/pgtable.c | 2 |
6 files changed, 30 insertions, 24 deletions
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index bae0f402bf2a..87a22092b68f 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -212,7 +212,9 @@ appldata_timer_handler(ctl_table *ctl, int write, | |||
212 | return 0; | 212 | return 0; |
213 | } | 213 | } |
214 | if (!write) { | 214 | if (!write) { |
215 | len = sprintf(buf, appldata_timer_active ? "1\n" : "0\n"); | 215 | strncpy(buf, appldata_timer_active ? "1\n" : "0\n", |
216 | ARRAY_SIZE(buf)); | ||
217 | len = strnlen(buf, ARRAY_SIZE(buf)); | ||
216 | if (len > *lenp) | 218 | if (len > *lenp) |
217 | len = *lenp; | 219 | len = *lenp; |
218 | if (copy_to_user(buffer, buf, len)) | 220 | if (copy_to_user(buffer, buf, len)) |
@@ -317,7 +319,8 @@ appldata_generic_handler(ctl_table *ctl, int write, | |||
317 | return 0; | 319 | return 0; |
318 | } | 320 | } |
319 | if (!write) { | 321 | if (!write) { |
320 | len = sprintf(buf, ops->active ? "1\n" : "0\n"); | 322 | strncpy(buf, ops->active ? "1\n" : "0\n", ARRAY_SIZE(buf)); |
323 | len = strnlen(buf, ARRAY_SIZE(buf)); | ||
321 | if (len > *lenp) | 324 | if (len > *lenp) |
322 | len = *lenp; | 325 | len = *lenp; |
323 | if (copy_to_user(buffer, buf, len)) { | 326 | if (copy_to_user(buffer, buf, len)) { |
diff --git a/arch/s390/include/asm/dma-mapping.h b/arch/s390/include/asm/dma-mapping.h index 9411db653bac..886ac7d4937a 100644 --- a/arch/s390/include/asm/dma-mapping.h +++ b/arch/s390/include/asm/dma-mapping.h | |||
@@ -71,8 +71,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size, | |||
71 | { | 71 | { |
72 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 72 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
73 | 73 | ||
74 | dma_ops->free(dev, size, cpu_addr, dma_handle, NULL); | ||
75 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); | 74 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); |
75 | dma_ops->free(dev, size, cpu_addr, dma_handle, NULL); | ||
76 | } | 76 | } |
77 | 77 | ||
78 | #endif /* _ASM_S390_DMA_MAPPING_H */ | 78 | #endif /* _ASM_S390_DMA_MAPPING_H */ |
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index 379d96e2105e..fd9be010f9b2 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h | |||
@@ -36,6 +36,7 @@ static inline void * phys_to_virt(unsigned long address) | |||
36 | } | 36 | } |
37 | 37 | ||
38 | void *xlate_dev_mem_ptr(unsigned long phys); | 38 | void *xlate_dev_mem_ptr(unsigned long phys); |
39 | #define xlate_dev_mem_ptr xlate_dev_mem_ptr | ||
39 | void unxlate_dev_mem_ptr(unsigned long phys, void *addr); | 40 | void unxlate_dev_mem_ptr(unsigned long phys, void *addr); |
40 | 41 | ||
41 | /* | 42 | /* |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0f0de30e3e3f..ac01463038f1 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -646,7 +646,7 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) | |||
646 | unsigned long address, bits; | 646 | unsigned long address, bits; |
647 | unsigned char skey; | 647 | unsigned char skey; |
648 | 648 | ||
649 | if (!pte_present(*ptep)) | 649 | if (pte_val(*ptep) & _PAGE_INVALID) |
650 | return pgste; | 650 | return pgste; |
651 | address = pte_val(*ptep) & PAGE_MASK; | 651 | address = pte_val(*ptep) & PAGE_MASK; |
652 | skey = page_get_storage_key(address); | 652 | skey = page_get_storage_key(address); |
@@ -680,7 +680,7 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste) | |||
680 | #ifdef CONFIG_PGSTE | 680 | #ifdef CONFIG_PGSTE |
681 | int young; | 681 | int young; |
682 | 682 | ||
683 | if (!pte_present(*ptep)) | 683 | if (pte_val(*ptep) & _PAGE_INVALID) |
684 | return pgste; | 684 | return pgste; |
685 | /* Get referenced bit from storage key */ | 685 | /* Get referenced bit from storage key */ |
686 | young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK); | 686 | young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK); |
@@ -706,7 +706,7 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry) | |||
706 | unsigned long address; | 706 | unsigned long address; |
707 | unsigned long okey, nkey; | 707 | unsigned long okey, nkey; |
708 | 708 | ||
709 | if (!pte_present(entry)) | 709 | if (pte_val(entry) & _PAGE_INVALID) |
710 | return; | 710 | return; |
711 | address = pte_val(entry) & PAGE_MASK; | 711 | address = pte_val(entry) & PAGE_MASK; |
712 | okey = nkey = page_get_storage_key(address); | 712 | okey = nkey = page_get_storage_key(address); |
@@ -1098,6 +1098,9 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, | |||
1098 | pte = *ptep; | 1098 | pte = *ptep; |
1099 | if (!mm_exclusive(mm)) | 1099 | if (!mm_exclusive(mm)) |
1100 | __ptep_ipte(address, ptep); | 1100 | __ptep_ipte(address, ptep); |
1101 | |||
1102 | if (mm_has_pgste(mm)) | ||
1103 | pgste = pgste_update_all(&pte, pgste); | ||
1101 | return pte; | 1104 | return pte; |
1102 | } | 1105 | } |
1103 | 1106 | ||
@@ -1105,9 +1108,13 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm, | |||
1105 | unsigned long address, | 1108 | unsigned long address, |
1106 | pte_t *ptep, pte_t pte) | 1109 | pte_t *ptep, pte_t pte) |
1107 | { | 1110 | { |
1111 | pgste_t pgste; | ||
1112 | |||
1108 | if (mm_has_pgste(mm)) { | 1113 | if (mm_has_pgste(mm)) { |
1114 | pgste = *(pgste_t *)(ptep + PTRS_PER_PTE); | ||
1115 | pgste_set_key(ptep, pgste, pte); | ||
1109 | pgste_set_pte(ptep, pte); | 1116 | pgste_set_pte(ptep, pte); |
1110 | pgste_set_unlock(ptep, *(pgste_t *)(ptep + PTRS_PER_PTE)); | 1117 | pgste_set_unlock(ptep, pgste); |
1111 | } else | 1118 | } else |
1112 | *ptep = pte; | 1119 | *ptep = pte; |
1113 | } | 1120 | } |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 05674b669001..4f977d0d25c2 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -428,34 +428,27 @@ void smp_stop_cpu(void) | |||
428 | * This is the main routine where commands issued by other | 428 | * This is the main routine where commands issued by other |
429 | * cpus are handled. | 429 | * cpus are handled. |
430 | */ | 430 | */ |
431 | static void do_ext_call_interrupt(struct ext_code ext_code, | 431 | static void smp_handle_ext_call(void) |
432 | unsigned int param32, unsigned long param64) | ||
433 | { | 432 | { |
434 | unsigned long bits; | 433 | unsigned long bits; |
435 | int cpu; | ||
436 | |||
437 | cpu = smp_processor_id(); | ||
438 | if (ext_code.code == 0x1202) | ||
439 | inc_irq_stat(IRQEXT_EXC); | ||
440 | else | ||
441 | inc_irq_stat(IRQEXT_EMS); | ||
442 | /* | ||
443 | * handle bit signal external calls | ||
444 | */ | ||
445 | bits = xchg(&pcpu_devices[cpu].ec_mask, 0); | ||
446 | 434 | ||
435 | /* handle bit signal external calls */ | ||
436 | bits = xchg(&pcpu_devices[smp_processor_id()].ec_mask, 0); | ||
447 | if (test_bit(ec_stop_cpu, &bits)) | 437 | if (test_bit(ec_stop_cpu, &bits)) |
448 | smp_stop_cpu(); | 438 | smp_stop_cpu(); |
449 | |||
450 | if (test_bit(ec_schedule, &bits)) | 439 | if (test_bit(ec_schedule, &bits)) |
451 | scheduler_ipi(); | 440 | scheduler_ipi(); |
452 | |||
453 | if (test_bit(ec_call_function, &bits)) | 441 | if (test_bit(ec_call_function, &bits)) |
454 | generic_smp_call_function_interrupt(); | 442 | generic_smp_call_function_interrupt(); |
455 | |||
456 | if (test_bit(ec_call_function_single, &bits)) | 443 | if (test_bit(ec_call_function_single, &bits)) |
457 | generic_smp_call_function_single_interrupt(); | 444 | generic_smp_call_function_single_interrupt(); |
445 | } | ||
458 | 446 | ||
447 | static void do_ext_call_interrupt(struct ext_code ext_code, | ||
448 | unsigned int param32, unsigned long param64) | ||
449 | { | ||
450 | inc_irq_stat(ext_code.code == 0x1202 ? IRQEXT_EXC : IRQEXT_EMS); | ||
451 | smp_handle_ext_call(); | ||
459 | } | 452 | } |
460 | 453 | ||
461 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) | 454 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) |
@@ -760,6 +753,8 @@ int __cpu_disable(void) | |||
760 | { | 753 | { |
761 | unsigned long cregs[16]; | 754 | unsigned long cregs[16]; |
762 | 755 | ||
756 | /* Handle possible pending IPIs */ | ||
757 | smp_handle_ext_call(); | ||
763 | set_cpu_online(smp_processor_id(), false); | 758 | set_cpu_online(smp_processor_id(), false); |
764 | /* Disable pseudo page faults on this cpu. */ | 759 | /* Disable pseudo page faults on this cpu. */ |
765 | pfault_fini(); | 760 | pfault_fini(); |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 18dc417aaf79..a938b548f07e 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -492,7 +492,7 @@ static int gmap_connect_pgtable(unsigned long address, unsigned long segment, | |||
492 | mp = (struct gmap_pgtable *) page->index; | 492 | mp = (struct gmap_pgtable *) page->index; |
493 | rmap->gmap = gmap; | 493 | rmap->gmap = gmap; |
494 | rmap->entry = segment_ptr; | 494 | rmap->entry = segment_ptr; |
495 | rmap->vmaddr = address; | 495 | rmap->vmaddr = address & PMD_MASK; |
496 | spin_lock(&mm->page_table_lock); | 496 | spin_lock(&mm->page_table_lock); |
497 | if (*segment_ptr == segment) { | 497 | if (*segment_ptr == segment) { |
498 | list_add(&rmap->list, &mp->mapper); | 498 | list_add(&rmap->list, &mp->mapper); |