Skip to content

Commit e6a1c1e

Browse files
committed
Merge tag 'powerpc-4.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - Fix build error on 32-bit with checkpoint restart from Aneesh Kumar - Fix dedotify for binutils >= 2.26 from Andreas Schwab - Don't trace hcalls on offline CPUs from Denis Kirjanov - eeh: Fix stale cached primary bus from Gavin Shan - eeh: Fix stale PE primary bus from Gavin Shan - mm: Fix Multi hit ERAT cause by recent THP update from Aneesh Kumar K.V - ioda: Set "read" permission when "write" is set from Alexey Kardashevskiy * tag 'powerpc-4.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/ioda: Set "read" permission when "write" is set powerpc/mm: Fix Multi hit ERAT cause by recent THP update powerpc/powernv: Fix stale PE primary bus powerpc/eeh: Fix stale cached primary bus powerpc/pseries: Don't trace hcalls on offline CPUs powerpc: Fix dedotify for binutils >= 2.26 powerpc/book3s_32: Fix build error with checkpoint restart
2 parents da6b736 + 6ecad91 commit e6a1c1e

File tree

14 files changed

+91
-7
lines changed

14 files changed

+91
-7
lines changed

arch/powerpc/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ choice
557557

558558
config PPC_4K_PAGES
559559
bool "4k page size"
560-
select HAVE_ARCH_SOFT_DIRTY if CHECKPOINT_RESTORE && PPC_BOOK3S
560+
select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
561561

562562
config PPC_16K_PAGES
563563
bool "16k page size"
@@ -566,7 +566,7 @@ config PPC_16K_PAGES
566566
config PPC_64K_PAGES
567567
bool "64k page size"
568568
depends on !PPC_FSL_BOOK3E && (44x || PPC_STD_MMU_64 || PPC_BOOK3E_64)
569-
select HAVE_ARCH_SOFT_DIRTY if CHECKPOINT_RESTORE && PPC_BOOK3S
569+
select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
570570

571571
config PPC_256K_PAGES
572572
bool "256k page size"

arch/powerpc/include/asm/book3s/64/pgtable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
281281
extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
282282
pmd_t *pmdp);
283283

284+
#define __HAVE_ARCH_PMDP_HUGE_SPLIT_PREPARE
285+
extern void pmdp_huge_split_prepare(struct vm_area_struct *vma,
286+
unsigned long address, pmd_t *pmdp);
287+
284288
#define pmd_move_must_withdraw pmd_move_must_withdraw
285289
struct spinlock;
286290
static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,

arch/powerpc/include/asm/eeh.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct pci_dn;
8181
#define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */
8282
#define EEH_PE_CFG_RESTRICTED (1 << 9) /* Block config on error */
8383
#define EEH_PE_REMOVED (1 << 10) /* Removed permanently */
84+
#define EEH_PE_PRI_BUS (1 << 11) /* Cached primary bus */
8485

8586
struct eeh_pe {
8687
int type; /* PE type: PHB/Bus/Device */

arch/powerpc/include/asm/trace.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,14 @@ DEFINE_EVENT(ppc64_interrupt_class, timer_interrupt_exit,
5757
extern void hcall_tracepoint_regfunc(void);
5858
extern void hcall_tracepoint_unregfunc(void);
5959

60-
TRACE_EVENT_FN(hcall_entry,
60+
TRACE_EVENT_FN_COND(hcall_entry,
6161

6262
TP_PROTO(unsigned long opcode, unsigned long *args),
6363

6464
TP_ARGS(opcode, args),
6565

66+
TP_CONDITION(cpu_online(raw_smp_processor_id())),
67+
6668
TP_STRUCT__entry(
6769
__field(unsigned long, opcode)
6870
),
@@ -76,13 +78,15 @@ TRACE_EVENT_FN(hcall_entry,
7678
hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
7779
);
7880

79-
TRACE_EVENT_FN(hcall_exit,
81+
TRACE_EVENT_FN_COND(hcall_exit,
8082

8183
TP_PROTO(unsigned long opcode, unsigned long retval,
8284
unsigned long *retbuf),
8385

8486
TP_ARGS(opcode, retval, retbuf),
8587

88+
TP_CONDITION(cpu_online(raw_smp_processor_id())),
89+
8690
TP_STRUCT__entry(
8791
__field(unsigned long, opcode)
8892
__field(unsigned long, retval)

arch/powerpc/kernel/eeh_driver.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
564564
*/
565565
eeh_pe_state_mark(pe, EEH_PE_KEEP);
566566
if (bus) {
567+
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
567568
pci_lock_rescan_remove();
568569
pcibios_remove_pci_devices(bus);
569570
pci_unlock_rescan_remove();
@@ -803,6 +804,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
803804
* the their PCI config any more.
804805
*/
805806
if (frozen_bus) {
807+
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
806808
eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
807809

808810
pci_lock_rescan_remove();
@@ -886,6 +888,7 @@ static void eeh_handle_special_event(void)
886888
continue;
887889

888890
/* Notify all devices to be down */
891+
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
889892
bus = eeh_pe_bus_get(phb_pe);
890893
eeh_pe_dev_traverse(pe,
891894
eeh_report_failure, NULL);

arch/powerpc/kernel/eeh_pe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
928928
bus = pe->phb->bus;
929929
} else if (pe->type & EEH_PE_BUS ||
930930
pe->type & EEH_PE_DEVICE) {
931-
if (pe->bus) {
931+
if (pe->state & EEH_PE_PRI_BUS) {
932932
bus = pe->bus;
933933
goto out;
934934
}

arch/powerpc/kernel/module_64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
340340
if (name[0] == '.') {
341341
if (strcmp(name+1, "TOC.") == 0)
342342
syms[i].st_shndx = SHN_ABS;
343-
memmove(name, name+1, strlen(name));
343+
syms[i].st_name++;
344344
}
345345
}
346346
}

arch/powerpc/mm/pgtable_64.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,28 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
646646
return pgtable;
647647
}
648648

649+
void pmdp_huge_split_prepare(struct vm_area_struct *vma,
650+
unsigned long address, pmd_t *pmdp)
651+
{
652+
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
653+
VM_BUG_ON(REGION_ID(address) != USER_REGION_ID);
654+
655+
/*
656+
* We can't mark the pmd none here, because that will cause a race
657+
* against exit_mmap. We need to continue mark pmd TRANS HUGE, while
658+
* we spilt, but at the same time we wan't rest of the ppc64 code
659+
* not to insert hash pte on this, because we will be modifying
660+
* the deposited pgtable in the caller of this function. Hence
661+
* clear the _PAGE_USER so that we move the fault handling to
662+
* higher level function and that will serialize against ptl.
663+
* We need to flush existing hash pte entries here even though,
664+
* the translation is still valid, because we will withdraw
665+
* pgtable_t after this.
666+
*/
667+
pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_USER, 0);
668+
}
669+
670+
649671
/*
650672
* set a new huge pmd. We should not be called for updating
651673
* an existing pmd entry. That should go via pmd_hugepage_update.
@@ -663,10 +685,20 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
663685
return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd));
664686
}
665687

688+
/*
689+
* We use this to invalidate a pmdp entry before switching from a
690+
* hugepte to regular pmd entry.
691+
*/
666692
void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
667693
pmd_t *pmdp)
668694
{
669695
pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, 0);
696+
697+
/*
698+
* This ensures that generic code that rely on IRQ disabling
699+
* to prevent a parallel THP split work as expected.
700+
*/
701+
kick_all_cpus_sync();
670702
}
671703

672704
/*

arch/powerpc/platforms/powernv/eeh-powernv.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,12 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
444444
* PCI devices of the PE are expected to be removed prior
445445
* to PE reset.
446446
*/
447-
if (!edev->pe->bus)
447+
if (!(edev->pe->state & EEH_PE_PRI_BUS)) {
448448
edev->pe->bus = pci_find_bus(hose->global_number,
449449
pdn->busno);
450+
if (edev->pe->bus)
451+
edev->pe->state |= EEH_PE_PRI_BUS;
452+
}
450453

451454
/*
452455
* Enable EEH explicitly so that we will do EEH check

arch/powerpc/platforms/powernv/pci-ioda.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3180,6 +3180,7 @@ static void pnv_pci_ioda_shutdown(struct pci_controller *hose)
31803180

31813181
static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
31823182
.dma_dev_setup = pnv_pci_dma_dev_setup,
3183+
.dma_bus_setup = pnv_pci_dma_bus_setup,
31833184
#ifdef CONFIG_PCI_MSI
31843185
.setup_msi_irqs = pnv_setup_msi_irqs,
31853186
.teardown_msi_irqs = pnv_teardown_msi_irqs,

arch/powerpc/platforms/powernv/pci.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,9 @@ int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
599599
u64 rpn = __pa(uaddr) >> tbl->it_page_shift;
600600
long i;
601601

602+
if (proto_tce & TCE_PCI_WRITE)
603+
proto_tce |= TCE_PCI_READ;
604+
602605
for (i = 0; i < npages; i++) {
603606
unsigned long newtce = proto_tce |
604607
((rpn + i) << tbl->it_page_shift);
@@ -620,6 +623,9 @@ int pnv_tce_xchg(struct iommu_table *tbl, long index,
620623

621624
BUG_ON(*hpa & ~IOMMU_PAGE_MASK(tbl));
622625

626+
if (newtce & TCE_PCI_WRITE)
627+
newtce |= TCE_PCI_READ;
628+
623629
oldtce = xchg(pnv_tce(tbl, idx), cpu_to_be64(newtce));
624630
*hpa = be64_to_cpu(oldtce) & ~(TCE_PCI_READ | TCE_PCI_WRITE);
625631
*direction = iommu_tce_direction(oldtce);
@@ -760,6 +766,26 @@ void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
760766
phb->dma_dev_setup(phb, pdev);
761767
}
762768

769+
void pnv_pci_dma_bus_setup(struct pci_bus *bus)
770+
{
771+
struct pci_controller *hose = bus->sysdata;
772+
struct pnv_phb *phb = hose->private_data;
773+
struct pnv_ioda_pe *pe;
774+
775+
list_for_each_entry(pe, &phb->ioda.pe_list, list) {
776+
if (!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)))
777+
continue;
778+
779+
if (!pe->pbus)
780+
continue;
781+
782+
if (bus->number == ((pe->rid >> 8) & 0xFF)) {
783+
pe->pbus = bus;
784+
break;
785+
}
786+
}
787+
}
788+
763789
void pnv_pci_shutdown(void)
764790
{
765791
struct pci_controller *hose;

arch/powerpc/platforms/powernv/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
242242
extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
243243

244244
extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev);
245+
extern void pnv_pci_dma_bus_setup(struct pci_bus *bus);
245246
extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
246247
extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);
247248

include/asm-generic/pgtable.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
239239
pmd_t *pmdp);
240240
#endif
241241

242+
#ifndef __HAVE_ARCH_PMDP_HUGE_SPLIT_PREPARE
243+
static inline void pmdp_huge_split_prepare(struct vm_area_struct *vma,
244+
unsigned long address, pmd_t *pmdp)
245+
{
246+
247+
}
248+
#endif
249+
242250
#ifndef __HAVE_ARCH_PTE_SAME
243251
static inline int pte_same(pte_t pte_a, pte_t pte_b)
244252
{

mm/huge_memory.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2861,6 +2861,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
28612861
young = pmd_young(*pmd);
28622862
dirty = pmd_dirty(*pmd);
28632863

2864+
pmdp_huge_split_prepare(vma, haddr, pmd);
28642865
pgtable = pgtable_trans_huge_withdraw(mm, pmd);
28652866
pmd_populate(mm, &_pmd, pgtable);
28662867

0 commit comments

Comments
 (0)