mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
powerpc fixes for 5.5 #3
One fix for a regression introduced by our recent rework of cache flushing on memory hotunplug. Like several other arches, our VDSO clock_getres() needed a fix to match the semantics of posix_get_hrtimer_res(). A fix for a boot crash on Power9 LPARs using PCI LSI interrupts. A commit disabling use of the trace_imc PMU (not the core PMU) on Power9 systems, because it can lead to checkstops, until a workaround is developed. A handful of other minor fixes. Thanks to: Aneesh Kumar K.V, Anju T Sudhakar, Ard Biesheuvel, Christophe Leroy, Cédric Le Goater, Madhavan Srinivasan, Vincenzo Frascino. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAl3qRJcTHG1wZUBlbGxl cm1hbi5pZC5hdQAKCRBR6+o8yOGlgDymD/4lqWlFnXBUJA0MrYGa6PI7AA7W+oFC vVAFobQ0kCI7RiWv8UW1GKAOkQKIhIhCxl/TEv5DNevajelsvfaPeF/nlI5fL2y9 klrvpMvQmEvBVTDispKQy3+pIr8EDWlvVOhFzU8YQMSZirxACLCmM/XNSmboCSR8 Y3chFNgEL9nYpEVxX+IhN9oTJ8/eCJqfp8QhcVt1kG/jXnf8CVfSx7z/Qr1IarIT 3LiiDBCCJbtG4WWH3Ku9WaCBZ66QxcTz/3RonGffYhalguhQjXl2vSdz9gg/icos G0H372ONZ5MkUj+IkyTTs/tmg2QVEzn1ZsVkstJZphbJ+/5VmrpdiAH0FvuJ/CaN kJ0dww4I9IEC2bl9Ok9XKNZSoQaXckfkPdX6JcHqD52pCIaBCoG+MdOvi0eMfcBj SDKuCK2BiAz+aOt0buSaqlgUNA6wXneb96h3I0u7CcV/CuzKChkJMLC6aJYB32DB gPZsnaespvOHBtbcLFP6RFAlY/nwaeLHTfSlLrbvs6k+5w9+ZUHA81uMzEBhNLN6 ANPx57lDOzmlAQ/8fLyvGRWCdYZVGKmO4GaQXV9eDKn6lNV94hHkYMe0JX0bI0M9 1SZP20t+zBBBV80nO7+JHEAxpTnT4RA6GNJ8p/bPyawEo6xdD1IMIZQy+EKYg++Q BeK76ccKp7wtZg== =1Q9O -----END PGP SIGNATURE----- Merge tag 'powerpc-5.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux Pull powerpc fixes from Michael Ellerman: "One fix for a regression introduced by our recent rework of cache flushing on memory hotunplug. Like several other arches, our VDSO clock_getres() needed a fix to match the semantics of posix_get_hrtimer_res(). A fix for a boot crash on Power9 LPARs using PCI LSI interrupts. A commit disabling use of the trace_imc PMU (not the core PMU) on Power9 systems, because it can lead to checkstops, until a workaround is developed. A handful of other minor fixes. Thanks to: Aneesh Kumar K.V, Anju T Sudhakar, Ard Biesheuvel, Christophe Leroy, Cédric Le Goater, Madhavan Srinivasan, Vincenzo Frascino" * tag 'powerpc-5.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/perf: Disable trace_imc pmu powerpc/powernv: Avoid re-registration of imc debugfs directory powerpc/pmem: Convert to EXPORT_SYMBOL_GPL powerpc/archrandom: fix arch_get_random_seed_int() powerpc: Fix vDSO clock_getres() powerpc/pmem: Fix kernel crash due to wrong range value usage in flush_dcache_range powerpc/xive: Skip ioremap() of ESB pages for LSI interrupts powerpc/kasan: Fix boot failure with RELOCATABLE && FSL_BOOKE
This commit is contained in:
commit
f89d416a86
11 changed files with 55 additions and 38 deletions
|
@ -28,7 +28,7 @@ static inline int arch_get_random_seed_int(unsigned int *v)
|
|||
unsigned long val;
|
||||
int rc;
|
||||
|
||||
rc = arch_get_random_long(&val);
|
||||
rc = arch_get_random_seed_long(&val);
|
||||
if (rc)
|
||||
*v = val;
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ struct vdso_data {
|
|||
__s64 wtom_clock_sec; /* Wall to monotonic clock sec */
|
||||
__s64 stamp_xtime_sec; /* xtime secs as at tb_orig_stamp */
|
||||
__s64 stamp_xtime_nsec; /* xtime nsecs as at tb_orig_stamp */
|
||||
__u32 hrtimer_res; /* hrtimer resolution */
|
||||
__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
|
||||
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
|
||||
};
|
||||
|
@ -105,6 +106,7 @@ struct vdso_data {
|
|||
__s32 stamp_xtime_sec; /* xtime seconds as at tb_orig_stamp */
|
||||
__s32 stamp_xtime_nsec; /* xtime nsecs as at tb_orig_stamp */
|
||||
__u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */
|
||||
__u32 hrtimer_res; /* hrtimer resolution */
|
||||
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
|
||||
__u32 dcache_block_size; /* L1 d-cache block size */
|
||||
__u32 icache_block_size; /* L1 i-cache block size */
|
||||
|
|
|
@ -388,6 +388,7 @@ int main(void)
|
|||
OFFSET(STAMP_XTIME_SEC, vdso_data, stamp_xtime_sec);
|
||||
OFFSET(STAMP_XTIME_NSEC, vdso_data, stamp_xtime_nsec);
|
||||
OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction);
|
||||
OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res);
|
||||
OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size);
|
||||
OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size);
|
||||
OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size);
|
||||
|
@ -413,7 +414,6 @@ int main(void)
|
|||
DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
|
||||
DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
|
||||
DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
|
||||
DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
|
||||
|
|
|
@ -240,6 +240,9 @@ set_ivor:
|
|||
|
||||
bl early_init
|
||||
|
||||
#ifdef CONFIG_KASAN
|
||||
bl kasan_early_init
|
||||
#endif
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
mr r3,r30
|
||||
mr r4,r31
|
||||
|
@ -266,9 +269,6 @@ set_ivor:
|
|||
/*
|
||||
* Decide what sort of machine this is and initialize the MMU.
|
||||
*/
|
||||
#ifdef CONFIG_KASAN
|
||||
bl kasan_early_init
|
||||
#endif
|
||||
mr r3,r30
|
||||
mr r4,r31
|
||||
bl machine_init
|
||||
|
|
|
@ -960,6 +960,7 @@ void update_vsyscall(struct timekeeper *tk)
|
|||
vdso_data->stamp_xtime_sec = xt.tv_sec;
|
||||
vdso_data->stamp_xtime_nsec = xt.tv_nsec;
|
||||
vdso_data->stamp_sec_fraction = frac_sec;
|
||||
vdso_data->hrtimer_res = hrtimer_resolution;
|
||||
smp_wmb();
|
||||
++(vdso_data->tb_update_count);
|
||||
}
|
||||
|
|
|
@ -154,12 +154,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
|
|||
cror cr0*4+eq,cr0*4+eq,cr1*4+eq
|
||||
bne cr0,99f
|
||||
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
bl __get_datapage@local /* get data page */
|
||||
lwz r5, CLOCK_HRTIMER_RES(r3)
|
||||
mtlr r12
|
||||
li r3,0
|
||||
cmpli cr0,r4,0
|
||||
crclr cr0*4+so
|
||||
beqlr
|
||||
lis r5,CLOCK_REALTIME_RES@h
|
||||
ori r5,r5,CLOCK_REALTIME_RES@l
|
||||
stw r3,TSPC32_TV_SEC(r4)
|
||||
stw r5,TSPC32_TV_NSEC(r4)
|
||||
blr
|
||||
|
|
|
@ -186,12 +186,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
|
|||
cror cr0*4+eq,cr0*4+eq,cr1*4+eq
|
||||
bne cr0,99f
|
||||
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
bl V_LOCAL_FUNC(__get_datapage)
|
||||
lwz r5, CLOCK_HRTIMER_RES(r3)
|
||||
mtlr r12
|
||||
li r3,0
|
||||
cmpldi cr0,r4,0
|
||||
crclr cr0*4+so
|
||||
beqlr
|
||||
lis r5,CLOCK_REALTIME_RES@h
|
||||
ori r5,r5,CLOCK_REALTIME_RES@l
|
||||
std r3,TSPC64_TV_SEC(r4)
|
||||
std r5,TSPC64_TV_NSEC(r4)
|
||||
blr
|
||||
|
|
|
@ -17,14 +17,14 @@ void arch_wb_cache_pmem(void *addr, size_t size)
|
|||
unsigned long start = (unsigned long) addr;
|
||||
flush_dcache_range(start, start + size);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_wb_cache_pmem);
|
||||
EXPORT_SYMBOL_GPL(arch_wb_cache_pmem);
|
||||
|
||||
void arch_invalidate_pmem(void *addr, size_t size)
|
||||
{
|
||||
unsigned long start = (unsigned long) addr;
|
||||
flush_dcache_range(start, start + size);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_invalidate_pmem);
|
||||
EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
|
||||
|
||||
/*
|
||||
* CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE symbols
|
||||
|
|
|
@ -121,7 +121,7 @@ static void flush_dcache_range_chunked(unsigned long start, unsigned long stop,
|
|||
unsigned long i;
|
||||
|
||||
for (i = start; i < stop; i += chunk) {
|
||||
flush_dcache_range(i, min(stop, start + chunk));
|
||||
flush_dcache_range(i, min(stop, i + chunk));
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,10 +59,6 @@ static void export_imc_mode_and_cmd(struct device_node *node,
|
|||
|
||||
imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root);
|
||||
|
||||
/*
|
||||
* Return here, either because 'imc' directory already exists,
|
||||
* Or failed to create a new one.
|
||||
*/
|
||||
if (!imc_debugfs_parent)
|
||||
return;
|
||||
|
||||
|
@ -135,7 +131,6 @@ static int imc_get_mem_addr_nest(struct device_node *node,
|
|||
}
|
||||
|
||||
pmu_ptr->imc_counter_mmaped = true;
|
||||
export_imc_mode_and_cmd(node, pmu_ptr);
|
||||
kfree(base_addr_arr);
|
||||
kfree(chipid_arr);
|
||||
return 0;
|
||||
|
@ -151,7 +146,7 @@ static int imc_get_mem_addr_nest(struct device_node *node,
|
|||
* and domain as the inputs.
|
||||
* Allocates memory for the struct imc_pmu, sets up its domain, size and offsets
|
||||
*/
|
||||
static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
|
||||
static struct imc_pmu *imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
|
||||
{
|
||||
int ret = 0;
|
||||
struct imc_pmu *pmu_ptr;
|
||||
|
@ -159,27 +154,23 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
|
|||
|
||||
/* Return for unknown domain */
|
||||
if (domain < 0)
|
||||
return -EINVAL;
|
||||
return NULL;
|
||||
|
||||
/* memory for pmu */
|
||||
pmu_ptr = kzalloc(sizeof(*pmu_ptr), GFP_KERNEL);
|
||||
if (!pmu_ptr)
|
||||
return -ENOMEM;
|
||||
return NULL;
|
||||
|
||||
/* Set the domain */
|
||||
pmu_ptr->domain = domain;
|
||||
|
||||
ret = of_property_read_u32(parent, "size", &pmu_ptr->counter_mem_size);
|
||||
if (ret) {
|
||||
ret = -EINVAL;
|
||||
if (ret)
|
||||
goto free_pmu;
|
||||
}
|
||||
|
||||
if (!of_property_read_u32(parent, "offset", &offset)) {
|
||||
if (imc_get_mem_addr_nest(parent, pmu_ptr, offset)) {
|
||||
ret = -EINVAL;
|
||||
if (imc_get_mem_addr_nest(parent, pmu_ptr, offset))
|
||||
goto free_pmu;
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to register IMC pmu */
|
||||
|
@ -190,14 +181,14 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
|
|||
if (pmu_ptr->domain == IMC_DOMAIN_NEST)
|
||||
kfree(pmu_ptr->mem_info);
|
||||
kfree(pmu_ptr);
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return pmu_ptr;
|
||||
|
||||
free_pmu:
|
||||
kfree(pmu_ptr);
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void disable_nest_pmu_counters(void)
|
||||
|
@ -254,6 +245,7 @@ int get_max_nest_dev(void)
|
|||
static int opal_imc_counters_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *imc_dev = pdev->dev.of_node;
|
||||
struct imc_pmu *pmu;
|
||||
int pmu_count = 0, domain;
|
||||
bool core_imc_reg = false, thread_imc_reg = false;
|
||||
u32 type;
|
||||
|
@ -269,6 +261,7 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
for_each_compatible_node(imc_dev, NULL, IMC_DTB_UNIT_COMPAT) {
|
||||
pmu = NULL;
|
||||
if (of_property_read_u32(imc_dev, "type", &type)) {
|
||||
pr_warn("IMC Device without type property\n");
|
||||
continue;
|
||||
|
@ -285,7 +278,14 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
|
|||
domain = IMC_DOMAIN_THREAD;
|
||||
break;
|
||||
case IMC_TYPE_TRACE:
|
||||
domain = IMC_DOMAIN_TRACE;
|
||||
/*
|
||||
* FIXME. Using trace_imc events to monitor application
|
||||
* or KVM thread performance can cause a checkstop
|
||||
* (system crash).
|
||||
* Disable it for now.
|
||||
*/
|
||||
pr_info_once("IMC: disabling trace_imc PMU\n");
|
||||
domain = -1;
|
||||
break;
|
||||
default:
|
||||
pr_warn("IMC Unknown Device type \n");
|
||||
|
@ -293,9 +293,13 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!imc_pmu_create(imc_dev, pmu_count, domain)) {
|
||||
if (domain == IMC_DOMAIN_NEST)
|
||||
pmu = imc_pmu_create(imc_dev, pmu_count, domain);
|
||||
if (pmu != NULL) {
|
||||
if (domain == IMC_DOMAIN_NEST) {
|
||||
if (!imc_debugfs_parent)
|
||||
export_imc_mode_and_cmd(imc_dev, pmu);
|
||||
pmu_count++;
|
||||
}
|
||||
if (domain == IMC_DOMAIN_CORE)
|
||||
core_imc_reg = true;
|
||||
if (domain == IMC_DOMAIN_THREAD)
|
||||
|
@ -303,10 +307,6 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
/* If none of the nest units are registered, remove debugfs interface */
|
||||
if (pmu_count == 0)
|
||||
debugfs_remove_recursive(imc_debugfs_parent);
|
||||
|
||||
/* If core imc is not registered, unregister thread-imc */
|
||||
if (!core_imc_reg && thread_imc_reg)
|
||||
unregister_thread_imc();
|
||||
|
|
|
@ -392,20 +392,28 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
|
|||
data->esb_shift = esb_shift;
|
||||
data->trig_page = trig_page;
|
||||
|
||||
data->hw_irq = hw_irq;
|
||||
|
||||
/*
|
||||
* No chip-id for the sPAPR backend. This has an impact how we
|
||||
* pick a target. See xive_pick_irq_target().
|
||||
*/
|
||||
data->src_chip = XIVE_INVALID_CHIP_ID;
|
||||
|
||||
/*
|
||||
* When the H_INT_ESB flag is set, the H_INT_ESB hcall should
|
||||
* be used for interrupt management. Skip the remapping of the
|
||||
* ESB pages which are not available.
|
||||
*/
|
||||
if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB)
|
||||
return 0;
|
||||
|
||||
data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift);
|
||||
if (!data->eoi_mmio) {
|
||||
pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
data->hw_irq = hw_irq;
|
||||
|
||||
/* Full function page supports trigger */
|
||||
if (flags & XIVE_SRC_TRIGGER) {
|
||||
data->trig_mmio = data->eoi_mmio;
|
||||
|
|
Loading…
Reference in a new issue