From 338679f7ba4a81906b3fdfa6507824fdf704be80 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 4 Jun 2013 09:53:59 +0200 Subject: s390/pgtable: Fix guest overindication for change bit When doing the transition invalid->valid in the host page table for a guest, then the guest view of C/R is in the pgste. After validation the view is pgste OR real key. We must zero out the real key C/R to avoid guest over-indication for change (and reference). Touching the real key is ok also for the host: The change bit is tracked via write protection and the reference bit is also ok because set_pte_at was called and the page will be touched anyway soon. Furthermore architecture defines reference as "substantially accurate", over- and underindication are ok. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index ac01463..391e592 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -704,17 +704,19 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry) { #ifdef CONFIG_PGSTE unsigned long address; - unsigned long okey, nkey; + unsigned long nkey; if (pte_val(entry) & _PAGE_INVALID) return; + VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID)); address = pte_val(entry) & PAGE_MASK; - okey = nkey = page_get_storage_key(address); - nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); - /* Set page access key and fetch protection bit from pgste */ - nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; - if (okey != nkey) - page_set_storage_key(address, nkey, 0); + /* + * Set page access key and fetch protection bit from pgste. + * The guest C/R information is still in the PGSTE, set real + * key C/R to 0. + */ + nkey = (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; + page_set_storage_key(address, nkey, 0); #endif } -- cgit v0.10.2 From 9cc5c206d9b44b7763aab3082a5be72c78a3ef7a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 4 Jun 2013 11:00:08 +0200 Subject: s390/dumpstack: fix address ranges for asynchronous and panic stack git commit dc7ee00d4771b321 "s390: lowcore stack pointer offsets" introduced a regression in regard to show_stack(). The stack pointer for the asynchronous and the panic stack in the lowcore now have an additional offset applied to them. This offset needs to be taken into account in the calculation for the low and high address for the stacks. Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 2982974..87acc38 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) static void show_trace(struct task_struct *task, unsigned long *stack) { + const unsigned long frame_size = + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); register unsigned long __r15 asm ("15"); unsigned long sp; @@ -82,11 +84,13 @@ static void show_trace(struct task_struct *task, unsigned long *stack) sp = task ? task->thread.ksp : __r15; printk("Call Trace:\n"); #ifdef CONFIG_CHECK_STACK - sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, - S390_lowcore.panic_stack); + sp = __show_trace(sp, + S390_lowcore.panic_stack + frame_size - 4096, + S390_lowcore.panic_stack + frame_size); #endif - sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, - S390_lowcore.async_stack); + sp = __show_trace(sp, + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, + S390_lowcore.async_stack + frame_size); if (task) __show_trace(sp, (unsigned long) task_stack_page(task), (unsigned long) task_stack_page(task) + THREAD_SIZE); -- cgit v0.10.2 From 3a82603be4f5523ce21dd468a323aa36ff845f6d Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 5 Jun 2013 09:22:33 +0200 Subject: s390/pgtable: Save pgste during modify_prot_start/commit In modify_prot_start we update the pgste value but never store it back into the original location. Lets save the calculated result, since modify_prot_commit will use the value of the pgste. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 391e592..f9a0a70 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -640,6 +640,13 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) #endif } +static inline void pgste_set(pte_t *ptep, pgste_t pgste) +{ +#ifdef CONFIG_PGSTE + *(pgste_t *)(ptep + PTRS_PER_PTE) = pgste; +#endif +} + static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) { #ifdef CONFIG_PGSTE @@ -1101,8 +1108,10 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, if (!mm_exclusive(mm)) __ptep_ipte(address, ptep); - if (mm_has_pgste(mm)) + if (mm_has_pgste(mm)) { pgste = pgste_update_all(&pte, pgste); + pgste_set(ptep, pgste); + } return pte; } -- cgit v0.10.2 From a8f6e7f7953d1baa05a346bf7cee44f1d022c63d Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 5 Jun 2013 09:25:34 +0200 Subject: s390/pgtable: make pgste lock an explicit barrier Getting and Releasing the pgste lock has lock semantics. Make the code an explicit barrier. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index f9a0a70..e8b6e5b 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) " csg %0,%1,%2\n" " jl 0b\n" : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE]) - : "Q" (ptep[PTRS_PER_PTE]) : "cc"); + : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory"); #endif return __pgste(new); } @@ -635,7 +635,8 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) " nihh %1,0xff7f\n" /* clear RCP_PCL_BIT */ " stg %1,%0\n" : "=Q" (ptep[PTRS_PER_PTE]) - : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc"); + : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) + : "cc", "memory"); preempt_enable(); #endif } -- cgit v0.10.2 From 98f6d1a6681b9398968f9fe5e016d19c259b04c2 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Wed, 5 Jun 2013 15:51:57 +0200 Subject: s390/sclp: fix new line detection When printing multi-line text using sclp_print, line endings are not correctly handled. The routine is expecting an EBCDIC new line character as line terminator while the input text is encoded in ASCII format. Fix this problem by modifying sclp_print to scan for ASCII new line characters. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index b6506ee..29bd7be 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S @@ -225,7 +225,7 @@ _sclp_print: ahi %r2,1 ltr %r0,%r0 # end of string? jz .LfinalizemtoS4 - chi %r0,0x15 # end of line (NL)? + chi %r0,0x0a # end of line (NL)? jz .LfinalizemtoS4 stc %r0,0(%r6,%r7) # copy to mto la %r11,0(%r6,%r7) -- cgit v0.10.2 From c46b54f7406780ec4cf9c9124d1cfb777674dc70 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 10 Jun 2013 15:34:04 +0200 Subject: s390/pci: Implement IRQ functions if !PCI All architectures must implement IRQ functions. Since various dependencies on !S390 were removed, there are various drivers that can be selected but will fail to link. Provide a dummy implementation of these functions for the !PCI case. Signed-off-by: Ben Hutchings Cc: stable@vger.kernel.org # 3.9 Acked-by: David S. Miller Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index f7fb589..408e866 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -311,3 +311,67 @@ void measurement_alert_subclass_unregister(void) spin_unlock(&ma_subclass_lock); } EXPORT_SYMBOL(measurement_alert_subclass_unregister); + +void synchronize_irq(unsigned int irq) +{ + /* + * Not needed, the handler is protected by a lock and IRQs that occur + * after the handler is deleted are just NOPs. + */ +} +EXPORT_SYMBOL_GPL(synchronize_irq); + +#ifndef CONFIG_PCI + +/* Only PCI devices have dynamically-defined IRQ handlers */ + +int request_irq(unsigned int irq, irq_handler_t handler, + unsigned long irqflags, const char *devname, void *dev_id) +{ + return -EINVAL; +} +EXPORT_SYMBOL_GPL(request_irq); + +void free_irq(unsigned int irq, void *dev_id) +{ + WARN_ON(1); +} +EXPORT_SYMBOL_GPL(free_irq); + +void enable_irq(unsigned int irq) +{ + WARN_ON(1); +} +EXPORT_SYMBOL_GPL(enable_irq); + +void disable_irq(unsigned int irq) +{ + WARN_ON(1); +} +EXPORT_SYMBOL_GPL(disable_irq); + +#endif /* !CONFIG_PCI */ + +void disable_irq_nosync(unsigned int irq) +{ + disable_irq(irq); +} +EXPORT_SYMBOL_GPL(disable_irq_nosync); + +unsigned long probe_irq_on(void) +{ + return 0; +} +EXPORT_SYMBOL_GPL(probe_irq_on); + +int probe_irq_off(unsigned long val) +{ + return 0; +} +EXPORT_SYMBOL_GPL(probe_irq_off); + +unsigned int probe_irq_mask(unsigned long val) +{ + return val; +} +EXPORT_SYMBOL_GPL(probe_irq_mask); diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index e6f15b5..f1e5be8 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) return rc; } -void synchronize_irq(unsigned int irq) -{ - /* - * Not needed, the handler is protected by a lock and IRQs that occur - * after the handler is deleted are just NOPs. - */ -} -EXPORT_SYMBOL_GPL(synchronize_irq); - void enable_irq(unsigned int irq) { struct msi_desc *msi = irq_get_msi_desc(irq); @@ -327,30 +318,6 @@ void disable_irq(unsigned int irq) } EXPORT_SYMBOL_GPL(disable_irq); -void disable_irq_nosync(unsigned int irq) -{ - disable_irq(irq); -} -EXPORT_SYMBOL_GPL(disable_irq_nosync); - -unsigned long probe_irq_on(void) -{ - return 0; -} -EXPORT_SYMBOL_GPL(probe_irq_on); - -int probe_irq_off(unsigned long val) -{ - return 0; -} -EXPORT_SYMBOL_GPL(probe_irq_off); - -unsigned int probe_irq_mask(unsigned long val) -{ - return val; -} -EXPORT_SYMBOL_GPL(probe_irq_mask); - void pcibios_fixup_bus(struct pci_bus *bus) { } -- cgit v0.10.2