Loading arch/powerpc/kernel/time.c +14 −15 Original line number Diff line number Diff line Loading @@ -615,8 +615,6 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) return; } /* Conditionally hard-enable interrupts. */ if (should_hard_irq_enable()) { /* * Ensure a positive value is written to the decrementer, or * else some CPUs will continue to take decrementer exceptions. Loading @@ -630,8 +628,9 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) else set_dec(decrementer_max); /* Conditionally hard-enable interrupts. */ if (should_hard_irq_enable()) do_hard_irq_enable(); } #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) if (atomic_read(&ppc_n_lost_interrupts) != 0) Loading arch/powerpc/kernel/vdso/gettimeofday.S +7 −2 Original line number Diff line number Diff line Loading @@ -22,12 +22,15 @@ .macro cvdso_call funct call_time=0 .cfi_startproc PPC_STLU r1, -PPC_MIN_STKFRM(r1) .cfi_adjust_cfa_offset PPC_MIN_STKFRM mflr r0 .cfi_register lr, r0 PPC_STLU r1, -PPC_MIN_STKFRM(r1) .cfi_adjust_cfa_offset PPC_MIN_STKFRM PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF #ifdef __powerpc64__ PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1) .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT #endif get_datapage r5 .ifeq \call_time Loading @@ -39,13 +42,15 @@ PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) #ifdef __powerpc64__ PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1) .cfi_restore r2 #endif .ifeq \call_time cmpwi r3, 0 .endif mtlr r0 .cfi_restore lr addi r1, r1, 2 * PPC_MIN_STKFRM .cfi_restore lr .cfi_def_cfa_offset 0 crclr so .ifeq \call_time beqlr+ Loading arch/powerpc/kvm/book3s_32_sr.S +21 −5 Original line number Diff line number Diff line Loading @@ -122,11 +122,27 @@ /* 0x0 - 0xb */ /* 'current->mm' needs to be in r4 */ tophys(r4, r2) lwz r4, MM(r4) tophys(r4, r4) /* This only clobbers r0, r3, r4 and r5 */ /* switch_mmu_context() needs paging, let's enable it */ mfmsr r9 ori r11, r9, MSR_DR mtmsr r11 sync /* switch_mmu_context() clobbers r12, rescue it */ SAVE_GPR(12, r1) /* Calling switch_mmu_context(<inv>, current->mm, <inv>); */ lwz r4, MM(r2) bl switch_mmu_context /* restore r12 */ REST_GPR(12, r1) /* Disable paging again */ mfmsr r9 li r6, MSR_DR andc r9, r9, r6 mtmsr r9 sync .endm arch/powerpc/kvm/book3s_64_vio.c +23 −22 Original line number Diff line number Diff line Loading @@ -420,13 +420,19 @@ static void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt, tbl[idx % TCES_PER_PAGE] = tce; } static void kvmppc_clear_tce(struct mm_struct *mm, struct iommu_table *tbl, unsigned long entry) static void kvmppc_clear_tce(struct mm_struct *mm, struct kvmppc_spapr_tce_table *stt, struct iommu_table *tbl, unsigned long entry) { unsigned long i; unsigned long subpages = 1ULL << (stt->page_shift - tbl->it_page_shift); unsigned long io_entry = entry << (stt->page_shift - tbl->it_page_shift); for (i = 0; i < subpages; ++i) { unsigned long hpa = 0; enum dma_data_direction dir = DMA_NONE; iommu_tce_xchg_no_kill(mm, tbl, entry, &hpa, &dir); iommu_tce_xchg_no_kill(mm, tbl, io_entry + i, &hpa, &dir); } } static long kvmppc_tce_iommu_mapped_dec(struct kvm *kvm, Loading Loading @@ -485,6 +491,8 @@ static long kvmppc_tce_iommu_unmap(struct kvm *kvm, break; } iommu_tce_kill(tbl, io_entry, subpages); return ret; } Loading Loading @@ -544,6 +552,8 @@ static long kvmppc_tce_iommu_map(struct kvm *kvm, break; } iommu_tce_kill(tbl, io_entry, subpages); return ret; } Loading Loading @@ -590,10 +600,9 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, ret = kvmppc_tce_iommu_map(vcpu->kvm, stt, stit->tbl, entry, ua, dir); iommu_tce_kill(stit->tbl, entry, 1); if (ret != H_SUCCESS) { kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry); goto unlock_exit; } } Loading Loading @@ -669,13 +678,13 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, */ if (get_user(tce, tces + i)) { ret = H_TOO_HARD; goto invalidate_exit; goto unlock_exit; } tce = be64_to_cpu(tce); if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) { ret = H_PARAMETER; goto invalidate_exit; goto unlock_exit; } list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { Loading @@ -684,19 +693,15 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, iommu_tce_direction(tce)); if (ret != H_SUCCESS) { kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); goto invalidate_exit; kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry + i); goto unlock_exit; } } kvmppc_tce_put(stt, entry + i, tce); } invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill(stit->tbl, entry, npages); unlock_exit: srcu_read_unlock(&vcpu->kvm->srcu, idx); Loading Loading @@ -735,20 +740,16 @@ long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu, continue; if (ret == H_TOO_HARD) goto invalidate_exit; return ret; WARN_ON_ONCE(1); kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry + i); } } for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value); invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill(stit->tbl, ioba >> stt->page_shift, npages); return ret; } EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce); arch/powerpc/kvm/book3s_64_vio_hv.c +22 −22 Original line number Diff line number Diff line Loading @@ -247,13 +247,19 @@ static void iommu_tce_kill_rm(struct iommu_table *tbl, tbl->it_ops->tce_kill(tbl, entry, pages, true); } static void kvmppc_rm_clear_tce(struct kvm *kvm, struct iommu_table *tbl, unsigned long entry) static void kvmppc_rm_clear_tce(struct kvm *kvm, struct kvmppc_spapr_tce_table *stt, struct iommu_table *tbl, unsigned long entry) { unsigned long i; unsigned long subpages = 1ULL << (stt->page_shift - tbl->it_page_shift); unsigned long io_entry = entry << (stt->page_shift - tbl->it_page_shift); for (i = 0; i < subpages; ++i) { unsigned long hpa = 0; enum dma_data_direction dir = DMA_NONE; iommu_tce_xchg_no_kill_rm(kvm->mm, tbl, entry, &hpa, &dir); iommu_tce_xchg_no_kill_rm(kvm->mm, tbl, io_entry + i, &hpa, &dir); } } static long kvmppc_rm_tce_iommu_mapped_dec(struct kvm *kvm, Loading Loading @@ -316,6 +322,8 @@ static long kvmppc_rm_tce_iommu_unmap(struct kvm *kvm, break; } iommu_tce_kill_rm(tbl, io_entry, subpages); return ret; } Loading Loading @@ -379,6 +387,8 @@ static long kvmppc_rm_tce_iommu_map(struct kvm *kvm, break; } iommu_tce_kill_rm(tbl, io_entry, subpages); return ret; } Loading Loading @@ -420,10 +430,8 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt, stit->tbl, entry, ua, dir); iommu_tce_kill_rm(stit->tbl, entry, 1); if (ret != H_SUCCESS) { kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry); return ret; } } Loading Loading @@ -561,7 +569,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu, ua = 0; if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua)) { ret = H_PARAMETER; goto invalidate_exit; goto unlock_exit; } list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { Loading @@ -570,19 +578,15 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu, iommu_tce_direction(tce)); if (ret != H_SUCCESS) { kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); goto invalidate_exit; kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry + i); goto unlock_exit; } } kvmppc_rm_tce_put(stt, entry + i, tce); } invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill_rm(stit->tbl, entry, npages); unlock_exit: if (!prereg) arch_spin_unlock(&kvm->mmu_lock.rlock.raw_lock); Loading Loading @@ -620,20 +624,16 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu, continue; if (ret == H_TOO_HARD) goto invalidate_exit; return ret; WARN_ON_ONCE_RM(1); kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry + i); } } for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) kvmppc_rm_tce_put(stt, ioba >> stt->page_shift, tce_value); invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill_rm(stit->tbl, ioba >> stt->page_shift, npages); return ret; } Loading Loading
arch/powerpc/kernel/time.c +14 −15 Original line number Diff line number Diff line Loading @@ -615,8 +615,6 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) return; } /* Conditionally hard-enable interrupts. */ if (should_hard_irq_enable()) { /* * Ensure a positive value is written to the decrementer, or * else some CPUs will continue to take decrementer exceptions. Loading @@ -630,8 +628,9 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) else set_dec(decrementer_max); /* Conditionally hard-enable interrupts. */ if (should_hard_irq_enable()) do_hard_irq_enable(); } #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) if (atomic_read(&ppc_n_lost_interrupts) != 0) Loading
arch/powerpc/kernel/vdso/gettimeofday.S +7 −2 Original line number Diff line number Diff line Loading @@ -22,12 +22,15 @@ .macro cvdso_call funct call_time=0 .cfi_startproc PPC_STLU r1, -PPC_MIN_STKFRM(r1) .cfi_adjust_cfa_offset PPC_MIN_STKFRM mflr r0 .cfi_register lr, r0 PPC_STLU r1, -PPC_MIN_STKFRM(r1) .cfi_adjust_cfa_offset PPC_MIN_STKFRM PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF #ifdef __powerpc64__ PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1) .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT #endif get_datapage r5 .ifeq \call_time Loading @@ -39,13 +42,15 @@ PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) #ifdef __powerpc64__ PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1) .cfi_restore r2 #endif .ifeq \call_time cmpwi r3, 0 .endif mtlr r0 .cfi_restore lr addi r1, r1, 2 * PPC_MIN_STKFRM .cfi_restore lr .cfi_def_cfa_offset 0 crclr so .ifeq \call_time beqlr+ Loading
arch/powerpc/kvm/book3s_32_sr.S +21 −5 Original line number Diff line number Diff line Loading @@ -122,11 +122,27 @@ /* 0x0 - 0xb */ /* 'current->mm' needs to be in r4 */ tophys(r4, r2) lwz r4, MM(r4) tophys(r4, r4) /* This only clobbers r0, r3, r4 and r5 */ /* switch_mmu_context() needs paging, let's enable it */ mfmsr r9 ori r11, r9, MSR_DR mtmsr r11 sync /* switch_mmu_context() clobbers r12, rescue it */ SAVE_GPR(12, r1) /* Calling switch_mmu_context(<inv>, current->mm, <inv>); */ lwz r4, MM(r2) bl switch_mmu_context /* restore r12 */ REST_GPR(12, r1) /* Disable paging again */ mfmsr r9 li r6, MSR_DR andc r9, r9, r6 mtmsr r9 sync .endm
arch/powerpc/kvm/book3s_64_vio.c +23 −22 Original line number Diff line number Diff line Loading @@ -420,13 +420,19 @@ static void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt, tbl[idx % TCES_PER_PAGE] = tce; } static void kvmppc_clear_tce(struct mm_struct *mm, struct iommu_table *tbl, unsigned long entry) static void kvmppc_clear_tce(struct mm_struct *mm, struct kvmppc_spapr_tce_table *stt, struct iommu_table *tbl, unsigned long entry) { unsigned long i; unsigned long subpages = 1ULL << (stt->page_shift - tbl->it_page_shift); unsigned long io_entry = entry << (stt->page_shift - tbl->it_page_shift); for (i = 0; i < subpages; ++i) { unsigned long hpa = 0; enum dma_data_direction dir = DMA_NONE; iommu_tce_xchg_no_kill(mm, tbl, entry, &hpa, &dir); iommu_tce_xchg_no_kill(mm, tbl, io_entry + i, &hpa, &dir); } } static long kvmppc_tce_iommu_mapped_dec(struct kvm *kvm, Loading Loading @@ -485,6 +491,8 @@ static long kvmppc_tce_iommu_unmap(struct kvm *kvm, break; } iommu_tce_kill(tbl, io_entry, subpages); return ret; } Loading Loading @@ -544,6 +552,8 @@ static long kvmppc_tce_iommu_map(struct kvm *kvm, break; } iommu_tce_kill(tbl, io_entry, subpages); return ret; } Loading Loading @@ -590,10 +600,9 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, ret = kvmppc_tce_iommu_map(vcpu->kvm, stt, stit->tbl, entry, ua, dir); iommu_tce_kill(stit->tbl, entry, 1); if (ret != H_SUCCESS) { kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry); goto unlock_exit; } } Loading Loading @@ -669,13 +678,13 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, */ if (get_user(tce, tces + i)) { ret = H_TOO_HARD; goto invalidate_exit; goto unlock_exit; } tce = be64_to_cpu(tce); if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) { ret = H_PARAMETER; goto invalidate_exit; goto unlock_exit; } list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { Loading @@ -684,19 +693,15 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, iommu_tce_direction(tce)); if (ret != H_SUCCESS) { kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); goto invalidate_exit; kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry + i); goto unlock_exit; } } kvmppc_tce_put(stt, entry + i, tce); } invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill(stit->tbl, entry, npages); unlock_exit: srcu_read_unlock(&vcpu->kvm->srcu, idx); Loading Loading @@ -735,20 +740,16 @@ long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu, continue; if (ret == H_TOO_HARD) goto invalidate_exit; return ret; WARN_ON_ONCE(1); kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry + i); } } for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value); invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill(stit->tbl, ioba >> stt->page_shift, npages); return ret; } EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce);
arch/powerpc/kvm/book3s_64_vio_hv.c +22 −22 Original line number Diff line number Diff line Loading @@ -247,13 +247,19 @@ static void iommu_tce_kill_rm(struct iommu_table *tbl, tbl->it_ops->tce_kill(tbl, entry, pages, true); } static void kvmppc_rm_clear_tce(struct kvm *kvm, struct iommu_table *tbl, unsigned long entry) static void kvmppc_rm_clear_tce(struct kvm *kvm, struct kvmppc_spapr_tce_table *stt, struct iommu_table *tbl, unsigned long entry) { unsigned long i; unsigned long subpages = 1ULL << (stt->page_shift - tbl->it_page_shift); unsigned long io_entry = entry << (stt->page_shift - tbl->it_page_shift); for (i = 0; i < subpages; ++i) { unsigned long hpa = 0; enum dma_data_direction dir = DMA_NONE; iommu_tce_xchg_no_kill_rm(kvm->mm, tbl, entry, &hpa, &dir); iommu_tce_xchg_no_kill_rm(kvm->mm, tbl, io_entry + i, &hpa, &dir); } } static long kvmppc_rm_tce_iommu_mapped_dec(struct kvm *kvm, Loading Loading @@ -316,6 +322,8 @@ static long kvmppc_rm_tce_iommu_unmap(struct kvm *kvm, break; } iommu_tce_kill_rm(tbl, io_entry, subpages); return ret; } Loading Loading @@ -379,6 +387,8 @@ static long kvmppc_rm_tce_iommu_map(struct kvm *kvm, break; } iommu_tce_kill_rm(tbl, io_entry, subpages); return ret; } Loading Loading @@ -420,10 +430,8 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt, stit->tbl, entry, ua, dir); iommu_tce_kill_rm(stit->tbl, entry, 1); if (ret != H_SUCCESS) { kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry); return ret; } } Loading Loading @@ -561,7 +569,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu, ua = 0; if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua)) { ret = H_PARAMETER; goto invalidate_exit; goto unlock_exit; } list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { Loading @@ -570,19 +578,15 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu, iommu_tce_direction(tce)); if (ret != H_SUCCESS) { kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); goto invalidate_exit; kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry + i); goto unlock_exit; } } kvmppc_rm_tce_put(stt, entry + i, tce); } invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill_rm(stit->tbl, entry, npages); unlock_exit: if (!prereg) arch_spin_unlock(&kvm->mmu_lock.rlock.raw_lock); Loading Loading @@ -620,20 +624,16 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu, continue; if (ret == H_TOO_HARD) goto invalidate_exit; return ret; WARN_ON_ONCE_RM(1); kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry + i); } } for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) kvmppc_rm_tce_put(stt, ioba >> stt->page_shift, tce_value); invalidate_exit: list_for_each_entry_lockless(stit, &stt->iommu_tables, next) iommu_tce_kill_rm(stit->tbl, ioba >> stt->page_shift, npages); return ret; } Loading