diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2009-08-14 16:58:45 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2009-08-14 16:58:45 -0400 |
| commit | d2dcd9101b1a940ce8496601ba871e47f84881ec (patch) | |
| tree | 3de9cb11379d51eb01b568a20c8d7c585c89d10e /arch/s390 | |
| parent | 8010fbe7a67c2f993cbb11b9d8b7e98528256dd1 (diff) | |
| parent | 606b4c992f3b28f906100f1b6eb49059909d8da7 (diff) | |
Merge branch 'master' into sh/cachetlb
Diffstat (limited to 'arch/s390')
| -rw-r--r-- | arch/s390/include/asm/tlb.h | 9 | ||||
| -rw-r--r-- | arch/s390/kernel/early.c | 7 | ||||
| -rw-r--r-- | arch/s390/kernel/smp.c | 7 | ||||
| -rw-r--r-- | arch/s390/kernel/vdso64/clock_gettime.S | 11 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/sigp.c | 7 | ||||
| -rw-r--r-- | arch/s390/power/swsusp.c | 36 | ||||
| -rw-r--r-- | arch/s390/power/swsusp_asm64.S | 35 |
8 files changed, 62 insertions, 52 deletions
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 3d8a96d39d9d..81150b053689 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h | |||
| @@ -96,7 +96,8 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) | |||
| 96 | * pte_free_tlb frees a pte table and clears the CRSTE for the | 96 | * pte_free_tlb frees a pte table and clears the CRSTE for the |
| 97 | * page table from the tlb. | 97 | * page table from the tlb. |
| 98 | */ | 98 | */ |
| 99 | static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) | 99 | static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, |
| 100 | unsigned long address) | ||
| 100 | { | 101 | { |
| 101 | if (!tlb->fullmm) { | 102 | if (!tlb->fullmm) { |
| 102 | tlb->array[tlb->nr_ptes++] = pte; | 103 | tlb->array[tlb->nr_ptes++] = pte; |
| @@ -113,7 +114,8 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) | |||
| 113 | * as the pgd. pmd_free_tlb checks the asce_limit against 2GB | 114 | * as the pgd. pmd_free_tlb checks the asce_limit against 2GB |
| 114 | * to avoid the double free of the pmd in this case. | 115 | * to avoid the double free of the pmd in this case. |
| 115 | */ | 116 | */ |
| 116 | static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) | 117 | static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, |
| 118 | unsigned long address) | ||
| 117 | { | 119 | { |
| 118 | #ifdef __s390x__ | 120 | #ifdef __s390x__ |
| 119 | if (tlb->mm->context.asce_limit <= (1UL << 31)) | 121 | if (tlb->mm->context.asce_limit <= (1UL << 31)) |
| @@ -134,7 +136,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) | |||
| 134 | * as the pgd. pud_free_tlb checks the asce_limit against 4TB | 136 | * as the pgd. pud_free_tlb checks the asce_limit against 4TB |
| 135 | * to avoid the double free of the pud in this case. | 137 | * to avoid the double free of the pud in this case. |
| 136 | */ | 138 | */ |
| 137 | static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) | 139 | static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, |
| 140 | unsigned long address) | ||
| 138 | { | 141 | { |
| 139 | #ifdef __s390x__ | 142 | #ifdef __s390x__ |
| 140 | if (tlb->mm->context.asce_limit <= (1UL << 42)) | 143 | if (tlb->mm->context.asce_limit <= (1UL << 42)) |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index f9b144049dc9..cae14c499511 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -208,9 +208,12 @@ static noinline __init void detect_machine_type(void) | |||
| 208 | machine_flags |= MACHINE_FLAG_KVM; | 208 | machine_flags |= MACHINE_FLAG_KVM; |
| 209 | else | 209 | else |
| 210 | machine_flags |= MACHINE_FLAG_VM; | 210 | machine_flags |= MACHINE_FLAG_VM; |
| 211 | |||
| 212 | /* Store machine flags for setting up lowcore early */ | ||
| 213 | S390_lowcore.machine_flags = machine_flags; | ||
| 211 | } | 214 | } |
| 212 | 215 | ||
| 213 | static void early_pgm_check_handler(void) | 216 | static __init void early_pgm_check_handler(void) |
| 214 | { | 217 | { |
| 215 | unsigned long addr; | 218 | unsigned long addr; |
| 216 | const struct exception_table_entry *fixup; | 219 | const struct exception_table_entry *fixup; |
| @@ -222,7 +225,7 @@ static void early_pgm_check_handler(void) | |||
| 222 | S390_lowcore.program_old_psw.addr = fixup->fixup | PSW_ADDR_AMODE; | 225 | S390_lowcore.program_old_psw.addr = fixup->fixup | PSW_ADDR_AMODE; |
| 223 | } | 226 | } |
| 224 | 227 | ||
| 225 | void setup_lowcore_early(void) | 228 | static noinline __init void setup_lowcore_early(void) |
| 226 | { | 229 | { |
| 227 | psw_t psw; | 230 | psw_t psw; |
| 228 | 231 | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 2270730f5354..be2cae083406 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -687,13 +687,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
| 687 | #ifndef CONFIG_64BIT | 687 | #ifndef CONFIG_64BIT |
| 688 | if (MACHINE_HAS_IEEE) | 688 | if (MACHINE_HAS_IEEE) |
| 689 | lowcore->extended_save_area_addr = (u32) save_area; | 689 | lowcore->extended_save_area_addr = (u32) save_area; |
| 690 | #else | ||
| 691 | if (vdso_alloc_per_cpu(smp_processor_id(), lowcore)) | ||
| 692 | BUG(); | ||
| 693 | #endif | 690 | #endif |
| 694 | set_prefix((u32)(unsigned long) lowcore); | 691 | set_prefix((u32)(unsigned long) lowcore); |
| 695 | local_mcck_enable(); | 692 | local_mcck_enable(); |
| 696 | local_irq_enable(); | 693 | local_irq_enable(); |
| 694 | #ifdef CONFIG_64BIT | ||
| 695 | if (vdso_alloc_per_cpu(smp_processor_id(), &S390_lowcore)) | ||
| 696 | BUG(); | ||
| 697 | #endif | ||
| 697 | for_each_possible_cpu(cpu) | 698 | for_each_possible_cpu(cpu) |
| 698 | if (cpu != smp_processor_id()) | 699 | if (cpu != smp_processor_id()) |
| 699 | smp_create_idle(cpu); | 700 | smp_create_idle(cpu); |
diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S index 79dbfee831ec..49106c6e6f88 100644 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ b/arch/s390/kernel/vdso64/clock_gettime.S | |||
| @@ -88,10 +88,17 @@ __kernel_clock_gettime: | |||
| 88 | llilh %r4,0x0100 | 88 | llilh %r4,0x0100 |
| 89 | sar %a4,%r4 | 89 | sar %a4,%r4 |
| 90 | lghi %r4,0 | 90 | lghi %r4,0 |
| 91 | epsw %r5,0 | ||
| 91 | sacf 512 /* Magic ectg instruction */ | 92 | sacf 512 /* Magic ectg instruction */ |
| 92 | .insn ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 | 93 | .insn ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 |
| 93 | sacf 0 | 94 | tml %r5,0x4000 |
| 94 | sar %a4,%r2 | 95 | jo 11f |
| 96 | tml %r5,0x8000 | ||
| 97 | jno 10f | ||
| 98 | sacf 256 | ||
| 99 | j 11f | ||
| 100 | 10: sacf 0 | ||
| 101 | 11: sar %a4,%r2 | ||
| 95 | algr %r1,%r0 /* r1 = cputime as TOD value */ | 102 | algr %r1,%r0 /* r1 = cputime as TOD value */ |
| 96 | mghi %r1,1000 /* convert to nanoseconds */ | 103 | mghi %r1,1000 /* convert to nanoseconds */ |
| 97 | srlg %r1,%r1,12 /* r1 = cputime in nanosec */ | 104 | srlg %r1,%r1,12 /* r1 = cputime in nanosec */ |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index f04f5301b1b4..4d613415c435 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -386,7 +386,7 @@ no_timer: | |||
| 386 | } | 386 | } |
| 387 | __unset_cpu_idle(vcpu); | 387 | __unset_cpu_idle(vcpu); |
| 388 | __set_current_state(TASK_RUNNING); | 388 | __set_current_state(TASK_RUNNING); |
| 389 | remove_wait_queue(&vcpu->wq, &wait); | 389 | remove_wait_queue(&vcpu->arch.local_int.wq, &wait); |
| 390 | spin_unlock_bh(&vcpu->arch.local_int.lock); | 390 | spin_unlock_bh(&vcpu->arch.local_int.lock); |
| 391 | spin_unlock(&vcpu->arch.local_int.float_int->lock); | 391 | spin_unlock(&vcpu->arch.local_int.float_int->lock); |
| 392 | hrtimer_try_to_cancel(&vcpu->arch.ckc_timer); | 392 | hrtimer_try_to_cancel(&vcpu->arch.ckc_timer); |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 36678835034d..0ef81d6776e9 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
| @@ -169,7 +169,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, | |||
| 169 | unsigned long *reg) | 169 | unsigned long *reg) |
| 170 | { | 170 | { |
| 171 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | 171 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
| 172 | struct kvm_s390_local_interrupt *li; | 172 | struct kvm_s390_local_interrupt *li = NULL; |
| 173 | struct kvm_s390_interrupt_info *inti; | 173 | struct kvm_s390_interrupt_info *inti; |
| 174 | int rc; | 174 | int rc; |
| 175 | u8 tmp; | 175 | u8 tmp; |
| @@ -189,9 +189,10 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, | |||
| 189 | return 2; /* busy */ | 189 | return 2; /* busy */ |
| 190 | 190 | ||
| 191 | spin_lock(&fi->lock); | 191 | spin_lock(&fi->lock); |
| 192 | li = fi->local_int[cpu_addr]; | 192 | if (cpu_addr < KVM_MAX_VCPUS) |
| 193 | li = fi->local_int[cpu_addr]; | ||
| 193 | 194 | ||
| 194 | if ((cpu_addr >= KVM_MAX_VCPUS) || (li == NULL)) { | 195 | if (li == NULL) { |
| 195 | rc = 1; /* incorrect state */ | 196 | rc = 1; /* incorrect state */ |
| 196 | *reg &= SIGP_STAT_INCORRECT_STATE; | 197 | *reg &= SIGP_STAT_INCORRECT_STATE; |
| 197 | kfree(inti); | 198 | kfree(inti); |
diff --git a/arch/s390/power/swsusp.c b/arch/s390/power/swsusp.c index e6a4fe9f5f24..bd1f5c6b0b8c 100644 --- a/arch/s390/power/swsusp.c +++ b/arch/s390/power/swsusp.c | |||
| @@ -7,24 +7,36 @@ | |||
| 7 | * | 7 | * |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <asm/system.h> | ||
| 10 | 11 | ||
| 11 | /* | ||
| 12 | * save CPU registers before creating a hibernation image and before | ||
| 13 | * restoring the memory state from it | ||
| 14 | */ | ||
| 15 | void save_processor_state(void) | 12 | void save_processor_state(void) |
| 16 | { | 13 | { |
| 17 | /* implentation contained in the | 14 | /* swsusp_arch_suspend() actually saves all cpu register contents. |
| 18 | * swsusp_arch_suspend function | 15 | * Machine checks must be disabled since swsusp_arch_suspend() stores |
| 16 | * register contents to their lowcore save areas. That's the same | ||
| 17 | * place where register contents on machine checks would be saved. | ||
| 18 | * To avoid register corruption disable machine checks. | ||
| 19 | * We must also disable machine checks in the new psw mask for | ||
| 20 | * program checks, since swsusp_arch_suspend() may generate program | ||
| 21 | * checks. Disabling machine checks for all other new psw masks is | ||
| 22 | * just paranoia. | ||
| 19 | */ | 23 | */ |
| 24 | local_mcck_disable(); | ||
| 25 | /* Disable lowcore protection */ | ||
| 26 | __ctl_clear_bit(0,28); | ||
| 27 | S390_lowcore.external_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
| 28 | S390_lowcore.svc_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
| 29 | S390_lowcore.io_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
| 30 | S390_lowcore.program_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
| 20 | } | 31 | } |
| 21 | 32 | ||
| 22 | /* | ||
| 23 | * restore the contents of CPU registers | ||
| 24 | */ | ||
| 25 | void restore_processor_state(void) | 33 | void restore_processor_state(void) |
| 26 | { | 34 | { |
| 27 | /* implentation contained in the | 35 | S390_lowcore.external_new_psw.mask |= PSW_MASK_MCHECK; |
| 28 | * swsusp_arch_resume function | 36 | S390_lowcore.svc_new_psw.mask |= PSW_MASK_MCHECK; |
| 29 | */ | 37 | S390_lowcore.io_new_psw.mask |= PSW_MASK_MCHECK; |
| 38 | S390_lowcore.program_new_psw.mask |= PSW_MASK_MCHECK; | ||
| 39 | /* Enable lowcore protection */ | ||
| 40 | __ctl_set_bit(0,28); | ||
| 41 | local_mcck_enable(); | ||
| 30 | } | 42 | } |
diff --git a/arch/s390/power/swsusp_asm64.S b/arch/s390/power/swsusp_asm64.S index 76d688da32fa..b26df5c5933e 100644 --- a/arch/s390/power/swsusp_asm64.S +++ b/arch/s390/power/swsusp_asm64.S | |||
| @@ -32,19 +32,14 @@ swsusp_arch_suspend: | |||
| 32 | /* Deactivate DAT */ | 32 | /* Deactivate DAT */ |
| 33 | stnsm __SF_EMPTY(%r15),0xfb | 33 | stnsm __SF_EMPTY(%r15),0xfb |
| 34 | 34 | ||
| 35 | /* Switch off lowcore protection */ | ||
| 36 | stctg %c0,%c0,__SF_EMPTY(%r15) | ||
| 37 | ni __SF_EMPTY+4(%r15),0xef | ||
| 38 | lctlg %c0,%c0,__SF_EMPTY(%r15) | ||
| 39 | |||
| 40 | /* Store prefix register on stack */ | 35 | /* Store prefix register on stack */ |
| 41 | stpx __SF_EMPTY(%r15) | 36 | stpx __SF_EMPTY(%r15) |
| 42 | 37 | ||
| 43 | /* Setup base register for lowcore (absolute 0) */ | 38 | /* Save prefix register contents for lowcore */ |
| 44 | llgf %r1,__SF_EMPTY(%r15) | 39 | llgf %r4,__SF_EMPTY(%r15) |
| 45 | 40 | ||
| 46 | /* Get pointer to save area */ | 41 | /* Get pointer to save area */ |
| 47 | aghi %r1,0x1000 | 42 | lghi %r1,0x1000 |
| 48 | 43 | ||
| 49 | /* Store registers */ | 44 | /* Store registers */ |
| 50 | mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ | 45 | mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ |
| @@ -79,17 +74,15 @@ swsusp_arch_suspend: | |||
| 79 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) | 74 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) |
| 80 | spx __SF_EMPTY(%r15) | 75 | spx __SF_EMPTY(%r15) |
| 81 | 76 | ||
| 82 | /* Setup lowcore */ | 77 | lghi %r2,0 |
| 83 | brasl %r14,setup_lowcore_early | 78 | lghi %r3,2*PAGE_SIZE |
| 79 | lghi %r5,2*PAGE_SIZE | ||
| 80 | 1: mvcle %r2,%r4,0 | ||
| 81 | jo 1b | ||
| 84 | 82 | ||
| 85 | /* Save image */ | 83 | /* Save image */ |
| 86 | brasl %r14,swsusp_save | 84 | brasl %r14,swsusp_save |
| 87 | 85 | ||
| 88 | /* Switch on lowcore protection */ | ||
| 89 | stctg %c0,%c0,__SF_EMPTY(%r15) | ||
| 90 | oi __SF_EMPTY+4(%r15),0x10 | ||
| 91 | lctlg %c0,%c0,__SF_EMPTY(%r15) | ||
| 92 | |||
| 93 | /* Restore prefix register and return */ | 86 | /* Restore prefix register and return */ |
| 94 | lghi %r1,0x1000 | 87 | lghi %r1,0x1000 |
| 95 | spx 0x318(%r1) | 88 | spx 0x318(%r1) |
| @@ -117,11 +110,6 @@ swsusp_arch_resume: | |||
| 117 | /* Deactivate DAT */ | 110 | /* Deactivate DAT */ |
| 118 | stnsm __SF_EMPTY(%r15),0xfb | 111 | stnsm __SF_EMPTY(%r15),0xfb |
| 119 | 112 | ||
| 120 | /* Switch off lowcore protection */ | ||
| 121 | stctg %c0,%c0,__SF_EMPTY(%r15) | ||
| 122 | ni __SF_EMPTY+4(%r15),0xef | ||
| 123 | lctlg %c0,%c0,__SF_EMPTY(%r15) | ||
| 124 | |||
| 125 | /* Set prefix page to zero */ | 113 | /* Set prefix page to zero */ |
| 126 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) | 114 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) |
| 127 | spx __SF_EMPTY(%r15) | 115 | spx __SF_EMPTY(%r15) |
| @@ -175,7 +163,7 @@ swsusp_arch_resume: | |||
| 175 | /* Load old stack */ | 163 | /* Load old stack */ |
| 176 | lg %r15,0x2f8(%r13) | 164 | lg %r15,0x2f8(%r13) |
| 177 | 165 | ||
| 178 | /* Pointer to save arae */ | 166 | /* Pointer to save area */ |
| 179 | lghi %r13,0x1000 | 167 | lghi %r13,0x1000 |
| 180 | 168 | ||
| 181 | #ifdef CONFIG_SMP | 169 | #ifdef CONFIG_SMP |
| @@ -187,11 +175,6 @@ swsusp_arch_resume: | |||
| 187 | /* Restore prefix register */ | 175 | /* Restore prefix register */ |
| 188 | spx 0x318(%r13) | 176 | spx 0x318(%r13) |
| 189 | 177 | ||
| 190 | /* Switch on lowcore protection */ | ||
| 191 | stctg %c0,%c0,__SF_EMPTY(%r15) | ||
| 192 | oi __SF_EMPTY+4(%r15),0x10 | ||
| 193 | lctlg %c0,%c0,__SF_EMPTY(%r15) | ||
| 194 | |||
| 195 | /* Activate DAT */ | 178 | /* Activate DAT */ |
| 196 | stosm __SF_EMPTY(%r15),0x04 | 179 | stosm __SF_EMPTY(%r15),0x04 |
| 197 | 180 | ||
