diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-13 14:02:31 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-13 14:02:31 -0400 |
| commit | dcae7f2dfcc6c948c313d72df6a0d7e466c6707a (patch) | |
| tree | 0aca1c9397b81ea67f94cf422d5da830f00f5ea3 | |
| parent | 509768f751986f171710319f44170e7dbab37394 (diff) | |
| parent | c46b54f7406780ec4cf9c9124d1cfb777674dc70 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky:
"Three kvm related memory management fixes, a fix for show_trace, a fix
for early console output and a patch from Ben to help prevent compile
errors in regard to irq functions (or our lack thereof)"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/pci: Implement IRQ functions if !PCI
s390/sclp: fix new line detection
s390/pgtable: make pgste lock an explicit barrier
s390/pgtable: Save pgste during modify_prot_start/commit
s390/dumpstack: fix address ranges for asynchronous and panic stack
s390/pgtable: Fix guest overindication for change bit
| -rw-r--r-- | arch/s390/include/asm/pgtable.h | 32 | ||||
| -rw-r--r-- | arch/s390/kernel/dumpstack.c | 12 | ||||
| -rw-r--r-- | arch/s390/kernel/irq.c | 64 | ||||
| -rw-r--r-- | arch/s390/kernel/sclp.S | 2 | ||||
| -rw-r--r-- | arch/s390/pci/pci.c | 33 |
5 files changed, 95 insertions, 48 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index ac01463038f1..e8b6e5b8932c 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
| @@ -623,7 +623,7 @@ static inline pgste_t pgste_get_lock(pte_t *ptep) | |||
| 623 | " csg %0,%1,%2\n" | 623 | " csg %0,%1,%2\n" |
| 624 | " jl 0b\n" | 624 | " jl 0b\n" |
| 625 | : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE]) | 625 | : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE]) |
| 626 | : "Q" (ptep[PTRS_PER_PTE]) : "cc"); | 626 | : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory"); |
| 627 | #endif | 627 | #endif |
| 628 | return __pgste(new); | 628 | return __pgste(new); |
| 629 | } | 629 | } |
| @@ -635,11 +635,19 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) | |||
| 635 | " nihh %1,0xff7f\n" /* clear RCP_PCL_BIT */ | 635 | " nihh %1,0xff7f\n" /* clear RCP_PCL_BIT */ |
| 636 | " stg %1,%0\n" | 636 | " stg %1,%0\n" |
| 637 | : "=Q" (ptep[PTRS_PER_PTE]) | 637 | : "=Q" (ptep[PTRS_PER_PTE]) |
| 638 | : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc"); | 638 | : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) |
| 639 | : "cc", "memory"); | ||
| 639 | preempt_enable(); | 640 | preempt_enable(); |
| 640 | #endif | 641 | #endif |
| 641 | } | 642 | } |
| 642 | 643 | ||
| 644 | static inline void pgste_set(pte_t *ptep, pgste_t pgste) | ||
| 645 | { | ||
| 646 | #ifdef CONFIG_PGSTE | ||
| 647 | *(pgste_t *)(ptep + PTRS_PER_PTE) = pgste; | ||
| 648 | #endif | ||
| 649 | } | ||
| 650 | |||
| 643 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) | 651 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) |
| 644 | { | 652 | { |
| 645 | #ifdef CONFIG_PGSTE | 653 | #ifdef CONFIG_PGSTE |
| @@ -704,17 +712,19 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry) | |||
| 704 | { | 712 | { |
| 705 | #ifdef CONFIG_PGSTE | 713 | #ifdef CONFIG_PGSTE |
| 706 | unsigned long address; | 714 | unsigned long address; |
| 707 | unsigned long okey, nkey; | 715 | unsigned long nkey; |
| 708 | 716 | ||
| 709 | if (pte_val(entry) & _PAGE_INVALID) | 717 | if (pte_val(entry) & _PAGE_INVALID) |
| 710 | return; | 718 | return; |
| 719 | VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID)); | ||
| 711 | address = pte_val(entry) & PAGE_MASK; | 720 | address = pte_val(entry) & PAGE_MASK; |
| 712 | okey = nkey = page_get_storage_key(address); | 721 | /* |
| 713 | nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); | 722 | * Set page access key and fetch protection bit from pgste. |
| 714 | /* Set page access key and fetch protection bit from pgste */ | 723 | * The guest C/R information is still in the PGSTE, set real |
| 715 | nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; | 724 | * key C/R to 0. |
| 716 | if (okey != nkey) | 725 | */ |
| 717 | page_set_storage_key(address, nkey, 0); | 726 | nkey = (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; |
| 727 | page_set_storage_key(address, nkey, 0); | ||
| 718 | #endif | 728 | #endif |
| 719 | } | 729 | } |
| 720 | 730 | ||
| @@ -1099,8 +1109,10 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, | |||
| 1099 | if (!mm_exclusive(mm)) | 1109 | if (!mm_exclusive(mm)) |
| 1100 | __ptep_ipte(address, ptep); | 1110 | __ptep_ipte(address, ptep); |
| 1101 | 1111 | ||
| 1102 | if (mm_has_pgste(mm)) | 1112 | if (mm_has_pgste(mm)) { |
| 1103 | pgste = pgste_update_all(&pte, pgste); | 1113 | pgste = pgste_update_all(&pte, pgste); |
| 1114 | pgste_set(ptep, pgste); | ||
| 1115 | } | ||
| 1104 | return pte; | 1116 | return pte; |
| 1105 | } | 1117 | } |
| 1106 | 1118 | ||
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 298297477257..87acc38f73c6 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c | |||
| @@ -74,6 +74,8 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) | |||
| 74 | 74 | ||
| 75 | static void show_trace(struct task_struct *task, unsigned long *stack) | 75 | static void show_trace(struct task_struct *task, unsigned long *stack) |
| 76 | { | 76 | { |
| 77 | const unsigned long frame_size = | ||
| 78 | STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); | ||
| 77 | register unsigned long __r15 asm ("15"); | 79 | register unsigned long __r15 asm ("15"); |
| 78 | unsigned long sp; | 80 | unsigned long sp; |
| 79 | 81 | ||
| @@ -82,11 +84,13 @@ static void show_trace(struct task_struct *task, unsigned long *stack) | |||
| 82 | sp = task ? task->thread.ksp : __r15; | 84 | sp = task ? task->thread.ksp : __r15; |
| 83 | printk("Call Trace:\n"); | 85 | printk("Call Trace:\n"); |
| 84 | #ifdef CONFIG_CHECK_STACK | 86 | #ifdef CONFIG_CHECK_STACK |
| 85 | sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, | 87 | sp = __show_trace(sp, |
| 86 | S390_lowcore.panic_stack); | 88 | S390_lowcore.panic_stack + frame_size - 4096, |
| 89 | S390_lowcore.panic_stack + frame_size); | ||
| 87 | #endif | 90 | #endif |
| 88 | sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, | 91 | sp = __show_trace(sp, |
| 89 | S390_lowcore.async_stack); | 92 | S390_lowcore.async_stack + frame_size - ASYNC_SIZE, |
| 93 | S390_lowcore.async_stack + frame_size); | ||
| 90 | if (task) | 94 | if (task) |
| 91 | __show_trace(sp, (unsigned long) task_stack_page(task), | 95 | __show_trace(sp, (unsigned long) task_stack_page(task), |
| 92 | (unsigned long) task_stack_page(task) + THREAD_SIZE); | 96 | (unsigned long) task_stack_page(task) + THREAD_SIZE); |
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index f7fb58903f6a..408e866ae548 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c | |||
| @@ -311,3 +311,67 @@ void measurement_alert_subclass_unregister(void) | |||
| 311 | spin_unlock(&ma_subclass_lock); | 311 | spin_unlock(&ma_subclass_lock); |
| 312 | } | 312 | } |
| 313 | EXPORT_SYMBOL(measurement_alert_subclass_unregister); | 313 | EXPORT_SYMBOL(measurement_alert_subclass_unregister); |
| 314 | |||
| 315 | void synchronize_irq(unsigned int irq) | ||
| 316 | { | ||
| 317 | /* | ||
| 318 | * Not needed, the handler is protected by a lock and IRQs that occur | ||
| 319 | * after the handler is deleted are just NOPs. | ||
| 320 | */ | ||
| 321 | } | ||
| 322 | EXPORT_SYMBOL_GPL(synchronize_irq); | ||
| 323 | |||
| 324 | #ifndef CONFIG_PCI | ||
| 325 | |||
| 326 | /* Only PCI devices have dynamically-defined IRQ handlers */ | ||
| 327 | |||
| 328 | int request_irq(unsigned int irq, irq_handler_t handler, | ||
| 329 | unsigned long irqflags, const char *devname, void *dev_id) | ||
| 330 | { | ||
| 331 | return -EINVAL; | ||
| 332 | } | ||
| 333 | EXPORT_SYMBOL_GPL(request_irq); | ||
| 334 | |||
| 335 | void free_irq(unsigned int irq, void *dev_id) | ||
| 336 | { | ||
| 337 | WARN_ON(1); | ||
| 338 | } | ||
| 339 | EXPORT_SYMBOL_GPL(free_irq); | ||
| 340 | |||
| 341 | void enable_irq(unsigned int irq) | ||
| 342 | { | ||
| 343 | WARN_ON(1); | ||
| 344 | } | ||
| 345 | EXPORT_SYMBOL_GPL(enable_irq); | ||
| 346 | |||
| 347 | void disable_irq(unsigned int irq) | ||
| 348 | { | ||
| 349 | WARN_ON(1); | ||
| 350 | } | ||
| 351 | EXPORT_SYMBOL_GPL(disable_irq); | ||
| 352 | |||
| 353 | #endif /* !CONFIG_PCI */ | ||
| 354 | |||
| 355 | void disable_irq_nosync(unsigned int irq) | ||
| 356 | { | ||
| 357 | disable_irq(irq); | ||
| 358 | } | ||
| 359 | EXPORT_SYMBOL_GPL(disable_irq_nosync); | ||
| 360 | |||
| 361 | unsigned long probe_irq_on(void) | ||
| 362 | { | ||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | EXPORT_SYMBOL_GPL(probe_irq_on); | ||
| 366 | |||
| 367 | int probe_irq_off(unsigned long val) | ||
| 368 | { | ||
| 369 | return 0; | ||
| 370 | } | ||
| 371 | EXPORT_SYMBOL_GPL(probe_irq_off); | ||
| 372 | |||
| 373 | unsigned int probe_irq_mask(unsigned long val) | ||
| 374 | { | ||
| 375 | return val; | ||
| 376 | } | ||
| 377 | EXPORT_SYMBOL_GPL(probe_irq_mask); | ||
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index b6506ee32a36..29bd7bec4176 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S | |||
| @@ -225,7 +225,7 @@ _sclp_print: | |||
| 225 | ahi %r2,1 | 225 | ahi %r2,1 |
| 226 | ltr %r0,%r0 # end of string? | 226 | ltr %r0,%r0 # end of string? |
| 227 | jz .LfinalizemtoS4 | 227 | jz .LfinalizemtoS4 |
| 228 | chi %r0,0x15 # end of line (NL)? | 228 | chi %r0,0x0a # end of line (NL)? |
| 229 | jz .LfinalizemtoS4 | 229 | jz .LfinalizemtoS4 |
| 230 | stc %r0,0(%r6,%r7) # copy to mto | 230 | stc %r0,0(%r6,%r7) # copy to mto |
| 231 | la %r11,0(%r6,%r7) | 231 | la %r11,0(%r6,%r7) |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index e6f15b5d8b7d..f1e5be85d592 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
| @@ -302,15 +302,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) | |||
| 302 | return rc; | 302 | return rc; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | void synchronize_irq(unsigned int irq) | ||
| 306 | { | ||
| 307 | /* | ||
| 308 | * Not needed, the handler is protected by a lock and IRQs that occur | ||
| 309 | * after the handler is deleted are just NOPs. | ||
| 310 | */ | ||
| 311 | } | ||
| 312 | EXPORT_SYMBOL_GPL(synchronize_irq); | ||
| 313 | |||
| 314 | void enable_irq(unsigned int irq) | 305 | void enable_irq(unsigned int irq) |
| 315 | { | 306 | { |
| 316 | struct msi_desc *msi = irq_get_msi_desc(irq); | 307 | struct msi_desc *msi = irq_get_msi_desc(irq); |
| @@ -327,30 +318,6 @@ void disable_irq(unsigned int irq) | |||
| 327 | } | 318 | } |
| 328 | EXPORT_SYMBOL_GPL(disable_irq); | 319 | EXPORT_SYMBOL_GPL(disable_irq); |
| 329 | 320 | ||
| 330 | void disable_irq_nosync(unsigned int irq) | ||
| 331 | { | ||
| 332 | disable_irq(irq); | ||
| 333 | } | ||
| 334 | EXPORT_SYMBOL_GPL(disable_irq_nosync); | ||
| 335 | |||
| 336 | unsigned long probe_irq_on(void) | ||
| 337 | { | ||
| 338 | return 0; | ||
| 339 | } | ||
| 340 | EXPORT_SYMBOL_GPL(probe_irq_on); | ||
| 341 | |||
| 342 | int probe_irq_off(unsigned long val) | ||
| 343 | { | ||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | EXPORT_SYMBOL_GPL(probe_irq_off); | ||
| 347 | |||
| 348 | unsigned int probe_irq_mask(unsigned long val) | ||
| 349 | { | ||
| 350 | return val; | ||
| 351 | } | ||
| 352 | EXPORT_SYMBOL_GPL(probe_irq_mask); | ||
| 353 | |||
| 354 | void pcibios_fixup_bus(struct pci_bus *bus) | 321 | void pcibios_fixup_bus(struct pci_bus *bus) |
| 355 | { | 322 | { |
| 356 | } | 323 | } |
