Skip to content

Commit 45f7fdc

Browse files
committed
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc updates from Ben Herrenschmidt: "Here is some powerpc goodness for -rc2. Arguably -rc1 material more than -rc2 but I was travelling (again !) It's mostly bug fixes including regressions, but there are a couple of new things that I decided to drop-in. One is a straightforward patch from Michael to add a bunch of P8 cache events to perf. The other one is a patch by myself to add the direct DMA (iommu bypass) for PCIe on Power8 for 64-bit capable devices. This has been around for a while, I had lost track of it. However it's been in our internal kernels we use for testing P8 already and it affects only P8 related code. Since P8 is still unreleased the risk is pretty much nil at this point" * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc/powernv: Add iommu DMA bypass support for IODA2 powerpc: Fix endian issues in kexec and crash dump code powerpc/ppc32: Fix the bug in the init of non-base exception stack for UP powerpc/xmon: Don't signal we've entered until we're finished printing powerpc/xmon: Fix timeout loop in get_output_lock() powerpc/xmon: Don't loop forever in get_output_lock() powerpc/perf: Configure BHRB filter before enabling PMU interrupts crypto/nx/nx-842: Fix handling of vmalloc addresses powerpc/pseries: Select ARCH_RANDOM on pseries powerpc/perf: Add Power8 cache & TLB events powerpc/relocate fix relocate processing in LE mode powerpc: Fix kdump hang issue on p8 with relocation on exception enabled. powerpc/pseries: Disable relocation on exception while going down during crash. powerpc/eeh: Drop taken reference to driver on eeh_rmv_device powerpc: Fix build failure in sysdev/mpic.c for MPIC_WEIRD=y
2 parents bbb1955 + cd15b04 commit 45f7fdc

File tree

24 files changed

+398
-55
lines changed

24 files changed

+398
-55
lines changed

arch/powerpc/include/asm/dma-mapping.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ static inline int dma_supported(struct device *dev, u64 mask)
134134
}
135135

136136
extern int dma_set_mask(struct device *dev, u64 dma_mask);
137+
extern int __dma_set_mask(struct device *dev, u64 dma_mask);
137138

138139
#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL)
139140

arch/powerpc/include/asm/iommu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct iommu_table {
7777
#ifdef CONFIG_IOMMU_API
7878
struct iommu_group *it_group;
7979
#endif
80+
void (*set_bypass)(struct iommu_table *tbl, bool enable);
8081
};
8182

8283
/* Pure 2^n version of get_order */

arch/powerpc/include/asm/sections.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#ifdef __powerpc64__
1010

11+
extern char __start_interrupts[];
1112
extern char __end_interrupts[];
1213

1314
extern char __prom_init_toc_start[];
@@ -21,6 +22,17 @@ static inline int in_kernel_text(unsigned long addr)
2122
return 0;
2223
}
2324

25+
static inline int overlaps_interrupt_vector_text(unsigned long start,
26+
unsigned long end)
27+
{
28+
unsigned long real_start, real_end;
29+
real_start = __start_interrupts - _stext;
30+
real_end = __end_interrupts - _stext;
31+
32+
return start < (unsigned long)__va(real_end) &&
33+
(unsigned long)__va(real_start) < end;
34+
}
35+
2436
static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
2537
{
2638
return start < (unsigned long)__init_end &&

arch/powerpc/kernel/dma.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,23 @@ EXPORT_SYMBOL(dma_direct_ops);
191191

192192
#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
193193

194-
int dma_set_mask(struct device *dev, u64 dma_mask)
194+
int __dma_set_mask(struct device *dev, u64 dma_mask)
195195
{
196196
struct dma_map_ops *dma_ops = get_dma_ops(dev);
197197

198-
if (ppc_md.dma_set_mask)
199-
return ppc_md.dma_set_mask(dev, dma_mask);
200198
if ((dma_ops != NULL) && (dma_ops->set_dma_mask != NULL))
201199
return dma_ops->set_dma_mask(dev, dma_mask);
202200
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
203201
return -EIO;
204202
*dev->dma_mask = dma_mask;
205203
return 0;
206204
}
205+
int dma_set_mask(struct device *dev, u64 dma_mask)
206+
{
207+
if (ppc_md.dma_set_mask)
208+
return ppc_md.dma_set_mask(dev, dma_mask);
209+
return __dma_set_mask(dev, dma_mask);
210+
}
207211
EXPORT_SYMBOL(dma_set_mask);
208212

209213
u64 dma_get_required_mask(struct device *dev)

arch/powerpc/kernel/eeh_driver.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,13 @@ static void *eeh_rmv_device(void *data, void *userdata)
362362
*/
363363
if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
364364
return NULL;
365+
365366
driver = eeh_pcid_get(dev);
366-
if (driver && driver->err_handler)
367-
return NULL;
367+
if (driver) {
368+
eeh_pcid_put(dev);
369+
if (driver->err_handler)
370+
return NULL;
371+
}
368372

369373
/* Remove it from PCI subsystem */
370374
pr_debug("EEH: Removing %s without EEH sensitive driver\n",

arch/powerpc/kernel/iommu.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,14 @@ int iommu_take_ownership(struct iommu_table *tbl)
10881088
memset(tbl->it_map, 0xff, sz);
10891089
iommu_clear_tces_and_put_pages(tbl, tbl->it_offset, tbl->it_size);
10901090

1091+
/*
1092+
* Disable iommu bypass, otherwise the user can DMA to all of
1093+
* our physical memory via the bypass window instead of just
1094+
* the pages that has been explicitly mapped into the iommu
1095+
*/
1096+
if (tbl->set_bypass)
1097+
tbl->set_bypass(tbl, false);
1098+
10911099
return 0;
10921100
}
10931101
EXPORT_SYMBOL_GPL(iommu_take_ownership);
@@ -1102,6 +1110,10 @@ void iommu_release_ownership(struct iommu_table *tbl)
11021110
/* Restore bit#0 set by iommu_init_table() */
11031111
if (tbl->it_offset == 0)
11041112
set_bit(0, tbl->it_map);
1113+
1114+
/* The kernel owns the device now, we can restore the iommu bypass */
1115+
if (tbl->set_bypass)
1116+
tbl->set_bypass(tbl, true);
11051117
}
11061118
EXPORT_SYMBOL_GPL(iommu_release_ownership);
11071119

arch/powerpc/kernel/irq.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,13 @@ void exc_lvl_ctx_init(void)
559559
#ifdef CONFIG_PPC64
560560
cpu_nr = i;
561561
#else
562+
#ifdef CONFIG_SMP
562563
cpu_nr = get_hard_smp_processor_id(i);
564+
#else
565+
cpu_nr = 0;
563566
#endif
567+
#endif
568+
564569
memset((void *)critirq_ctx[cpu_nr], 0, THREAD_SIZE);
565570
tp = critirq_ctx[cpu_nr];
566571
tp->cpu = cpu_nr;

arch/powerpc/kernel/machine_kexec.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ int overlaps_crashkernel(unsigned long start, unsigned long size)
196196

197197
/* Values we need to export to the second kernel via the device tree. */
198198
static phys_addr_t kernel_end;
199+
static phys_addr_t crashk_base;
199200
static phys_addr_t crashk_size;
201+
static unsigned long long mem_limit;
200202

201203
static struct property kernel_end_prop = {
202204
.name = "linux,kernel-end",
@@ -207,7 +209,7 @@ static struct property kernel_end_prop = {
207209
static struct property crashk_base_prop = {
208210
.name = "linux,crashkernel-base",
209211
.length = sizeof(phys_addr_t),
210-
.value = &crashk_res.start,
212+
.value = &crashk_base
211213
};
212214

213215
static struct property crashk_size_prop = {
@@ -219,9 +221,11 @@ static struct property crashk_size_prop = {
219221
static struct property memory_limit_prop = {
220222
.name = "linux,memory-limit",
221223
.length = sizeof(unsigned long long),
222-
.value = &memory_limit,
224+
.value = &mem_limit,
223225
};
224226

227+
#define cpu_to_be_ulong __PASTE(cpu_to_be, BITS_PER_LONG)
228+
225229
static void __init export_crashk_values(struct device_node *node)
226230
{
227231
struct property *prop;
@@ -237,15 +241,17 @@ static void __init export_crashk_values(struct device_node *node)
237241
of_remove_property(node, prop);
238242

239243
if (crashk_res.start != 0) {
244+
crashk_base = cpu_to_be_ulong(crashk_res.start),
240245
of_add_property(node, &crashk_base_prop);
241-
crashk_size = resource_size(&crashk_res);
246+
crashk_size = cpu_to_be_ulong(resource_size(&crashk_res));
242247
of_add_property(node, &crashk_size_prop);
243248
}
244249

245250
/*
246251
* memory_limit is required by the kexec-tools to limit the
247252
* crash regions to the actual memory used.
248253
*/
254+
mem_limit = cpu_to_be_ulong(memory_limit);
249255
of_update_property(node, &memory_limit_prop);
250256
}
251257

@@ -264,7 +270,7 @@ static int __init kexec_setup(void)
264270
of_remove_property(node, prop);
265271

266272
/* information needed by userspace when using default_machine_kexec */
267-
kernel_end = __pa(_end);
273+
kernel_end = cpu_to_be_ulong(__pa(_end));
268274
of_add_property(node, &kernel_end_prop);
269275

270276
export_crashk_values(node);

arch/powerpc/kernel/machine_kexec_64.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ void default_machine_kexec(struct kimage *image)
369369

370370
/* Values we need to export to the second kernel via the device tree. */
371371
static unsigned long htab_base;
372+
static unsigned long htab_size;
372373

373374
static struct property htab_base_prop = {
374375
.name = "linux,htab-base",
@@ -379,7 +380,7 @@ static struct property htab_base_prop = {
379380
static struct property htab_size_prop = {
380381
.name = "linux,htab-size",
381382
.length = sizeof(unsigned long),
382-
.value = &htab_size_bytes,
383+
.value = &htab_size,
383384
};
384385

385386
static int __init export_htab_values(void)
@@ -403,8 +404,9 @@ static int __init export_htab_values(void)
403404
if (prop)
404405
of_remove_property(node, prop);
405406

406-
htab_base = __pa(htab_address);
407+
htab_base = cpu_to_be64(__pa(htab_address));
407408
of_add_property(node, &htab_base_prop);
409+
htab_size = cpu_to_be64(htab_size_bytes);
408410
of_add_property(node, &htab_size_prop);
409411

410412
of_node_put(node);

arch/powerpc/kernel/reloc_64.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ _GLOBAL(relocate)
6969
* R_PPC64_RELATIVE ones.
7070
*/
7171
mtctr r8
72-
5: lwz r0,12(9) /* ELF64_R_TYPE(reloc->r_info) */
73-
cmpwi r0,R_PPC64_RELATIVE
72+
5: ld r0,8(9) /* ELF64_R_TYPE(reloc->r_info) */
73+
cmpdi r0,R_PPC64_RELATIVE
7474
bne 6f
7575
ld r6,0(r9) /* reloc->r_offset */
7676
ld r0,16(r9) /* reloc->r_addend */

arch/powerpc/kernel/setup_32.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,12 @@ static void __init exc_lvl_early_init(void)
247247
/* interrupt stacks must be in lowmem, we get that for free on ppc32
248248
* as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
249249
for_each_possible_cpu(i) {
250+
#ifdef CONFIG_SMP
250251
hw_cpu = get_hard_smp_processor_id(i);
252+
#else
253+
hw_cpu = 0;
254+
#endif
255+
251256
critirq_ctx[hw_cpu] = (struct thread_info *)
252257
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
253258
#ifdef CONFIG_BOOKE

arch/powerpc/mm/hash_utils_64.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,20 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
207207
if (overlaps_kernel_text(vaddr, vaddr + step))
208208
tprot &= ~HPTE_R_N;
209209

210+
/*
211+
* If relocatable, check if it overlaps interrupt vectors that
212+
* are copied down to real 0. For relocatable kernel
213+
* (e.g. kdump case) we copy interrupt vectors down to real
214+
* address 0. Mark that region as executable. This is
215+
* because on p8 system with relocation on exception feature
216+
* enabled, exceptions are raised with MMU (IR=DR=1) ON. Hence
217+
* in order to execute the interrupt handlers in virtual
218+
* mode the vector region need to be marked as executable.
219+
*/
220+
if ((PHYSICAL_START > MEMORY_START) &&
221+
overlaps_interrupt_vector_text(vaddr, vaddr + step))
222+
tprot &= ~HPTE_R_N;
223+
210224
hash = hpt_hash(vpn, shift, ssize);
211225
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
212226

arch/powerpc/perf/core-book3s.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,9 @@ static void power_pmu_enable(struct pmu *pmu)
11471147
mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]);
11481148

11491149
mb();
1150+
if (cpuhw->bhrb_users)
1151+
ppmu->config_bhrb(cpuhw->bhrb_filter);
1152+
11501153
write_mmcr0(cpuhw, mmcr0);
11511154

11521155
/*
@@ -1158,8 +1161,6 @@ static void power_pmu_enable(struct pmu *pmu)
11581161
}
11591162

11601163
out:
1161-
if (cpuhw->bhrb_users)
1162-
ppmu->config_bhrb(cpuhw->bhrb_filter);
11631164

11641165
local_irq_restore(flags);
11651166
}

0 commit comments

Comments
 (0)