Commit 218ea310 authored by Michael Ellerman's avatar Michael Ellerman

Merge branch 'fixes' into next

Merge our fixes branch, a few of them are tripping people up while
working on top of next, and we also have a dependency between the CXL
fixes and new CXL code we want to merge into next.
parents 5405c92b d6bd8194
...@@ -866,6 +866,15 @@ ...@@ -866,6 +866,15 @@
dscc4.setup= [NET] dscc4.setup= [NET]
dt_cpu_ftrs= [PPC]
Format: {"off" | "known"}
Control how the dt_cpu_ftrs device-tree binding is
used for CPU feature discovery and setup (if it
exists).
off: Do not use it, fall back to legacy cpu table.
known: Do not pass through unknown features to guests
or userspace, only those that the kernel is aware of.
dump_apple_properties [X86] dump_apple_properties [X86]
Dump name and content of EFI device properties on Dump name and content of EFI device properties on
x86 Macs. Useful for driver authors to determine x86 Macs. Useful for driver authors to determine
......
...@@ -374,22 +374,6 @@ source "arch/powerpc/platforms/Kconfig" ...@@ -374,22 +374,6 @@ source "arch/powerpc/platforms/Kconfig"
menu "Kernel options" menu "Kernel options"
config PPC_DT_CPU_FTRS
bool "Device-tree based CPU feature discovery & setup"
depends on PPC_BOOK3S_64
default n
help
This enables code to use a new device tree binding for describing CPU
compatibility and features. Saying Y here will attempt to use the new
binding if the firmware provides it. Currently only the skiboot
firmware provides this binding.
If you're not sure say Y.
config PPC_CPUFEATURES_ENABLE_UNKNOWN
bool "cpufeatures pass through unknown features to guest/userspace"
depends on PPC_DT_CPU_FTRS
default y
config HIGHMEM config HIGHMEM
bool "High memory support" bool "High memory support"
depends on PPC32 depends on PPC32
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define H_PTE_INDEX_SIZE 9 #define H_PTE_INDEX_SIZE 9
#define H_PMD_INDEX_SIZE 7 #define H_PMD_INDEX_SIZE 7
#define H_PUD_INDEX_SIZE 9 #define H_PUD_INDEX_SIZE 9
#define H_PGD_INDEX_SIZE 12 #define H_PGD_INDEX_SIZE 9
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE) #define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE)
......
...@@ -104,7 +104,7 @@ ...@@ -104,7 +104,7 @@
"1: "PPC_TLNEI" %4,0\n" \ "1: "PPC_TLNEI" %4,0\n" \
_EMIT_BUG_ENTRY \ _EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), \ : : "i" (__FILE__), "i" (__LINE__), \
"i" (BUGFLAG_TAINT(TAINT_WARN)), \ "i" (BUGFLAG_WARNING|BUGFLAG_TAINT(TAINT_WARN)),\
"i" (sizeof(struct bug_entry)), \ "i" (sizeof(struct bug_entry)), \
"r" (__ret_warn_on)); \ "r" (__ret_warn_on)); \
} \ } \
......
...@@ -214,7 +214,6 @@ enum { ...@@ -214,7 +214,6 @@ enum {
#define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000)
#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) #define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000)
#define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000) #define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000)
#define CPU_FTR_SUBCORE LONG_ASM_CONST(0x2000000000000000)
#define CPU_FTR_POWER9_DD1 LONG_ASM_CONST(0x4000000000000000) #define CPU_FTR_POWER9_DD1 LONG_ASM_CONST(0x4000000000000000)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
...@@ -463,7 +462,7 @@ enum { ...@@ -463,7 +462,7 @@ enum {
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_SUBCORE) CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG) #define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL) #define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL)
#define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ #define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
......
...@@ -103,6 +103,7 @@ extern int kprobe_exceptions_notify(struct notifier_block *self, ...@@ -103,6 +103,7 @@ extern int kprobe_exceptions_notify(struct notifier_block *self,
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
extern int kprobe_handler(struct pt_regs *regs); extern int kprobe_handler(struct pt_regs *regs);
extern int kprobe_post_handler(struct pt_regs *regs); extern int kprobe_post_handler(struct pt_regs *regs);
extern int is_current_kprobe_addr(unsigned long addr);
#ifdef CONFIG_KPROBES_ON_FTRACE #ifdef CONFIG_KPROBES_ON_FTRACE
extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs, extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
struct kprobe_ctlblk *kcb); struct kprobe_ctlblk *kcb);
......
...@@ -110,13 +110,18 @@ void release_thread(struct task_struct *); ...@@ -110,13 +110,18 @@ void release_thread(struct task_struct *);
#define TASK_SIZE_128TB (0x0000800000000000UL) #define TASK_SIZE_128TB (0x0000800000000000UL)
#define TASK_SIZE_512TB (0x0002000000000000UL) #define TASK_SIZE_512TB (0x0002000000000000UL)
#ifdef CONFIG_PPC_BOOK3S_64 /*
* For now 512TB is only supported with book3s and 64K linux page size.
*/
#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_64K_PAGES)
/* /*
* Max value currently used: * Max value currently used:
*/ */
#define TASK_SIZE_USER64 TASK_SIZE_512TB #define TASK_SIZE_USER64 TASK_SIZE_512TB
#define DEFAULT_MAP_WINDOW_USER64 TASK_SIZE_128TB
#else #else
#define TASK_SIZE_USER64 TASK_SIZE_64TB #define TASK_SIZE_USER64 TASK_SIZE_64TB
#define DEFAULT_MAP_WINDOW_USER64 TASK_SIZE_64TB
#endif #endif
/* /*
...@@ -132,7 +137,7 @@ void release_thread(struct task_struct *); ...@@ -132,7 +137,7 @@ void release_thread(struct task_struct *);
* space during mmap's. * space during mmap's.
*/ */
#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4)) #define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_128TB / 4)) #define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(DEFAULT_MAP_WINDOW_USER64 / 4))
#define TASK_UNMAPPED_BASE ((is_32bit_task()) ? \ #define TASK_UNMAPPED_BASE ((is_32bit_task()) ? \
TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 ) TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
...@@ -143,21 +148,15 @@ void release_thread(struct task_struct *); ...@@ -143,21 +148,15 @@ void release_thread(struct task_struct *);
* with 128TB and conditionally enable upto 512TB * with 128TB and conditionally enable upto 512TB
*/ */
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
#define DEFAULT_MAP_WINDOW ((is_32bit_task()) ? \ #define DEFAULT_MAP_WINDOW ((is_32bit_task()) ? \
TASK_SIZE_USER32 : TASK_SIZE_128TB) TASK_SIZE_USER32 : DEFAULT_MAP_WINDOW_USER64)
#else #else
#define DEFAULT_MAP_WINDOW TASK_SIZE #define DEFAULT_MAP_WINDOW TASK_SIZE
#endif #endif
#ifdef __powerpc64__ #ifdef __powerpc64__
#ifdef CONFIG_PPC_BOOK3S_64 #define STACK_TOP_USER64 DEFAULT_MAP_WINDOW_USER64
/* Limit stack to 128TB */
#define STACK_TOP_USER64 TASK_SIZE_128TB
#else
#define STACK_TOP_USER64 TASK_SIZE_USER64
#endif
#define STACK_TOP_USER32 TASK_SIZE_USER32 #define STACK_TOP_USER32 TASK_SIZE_USER32
#define STACK_TOP (is_32bit_task() ? \ #define STACK_TOP (is_32bit_task() ? \
......
...@@ -44,8 +44,22 @@ extern void __init dump_numa_cpu_topology(void); ...@@ -44,8 +44,22 @@ extern void __init dump_numa_cpu_topology(void);
extern int sysfs_add_device_to_node(struct device *dev, int nid); extern int sysfs_add_device_to_node(struct device *dev, int nid);
extern void sysfs_remove_device_from_node(struct device *dev, int nid); extern void sysfs_remove_device_from_node(struct device *dev, int nid);
static inline int early_cpu_to_node(int cpu)
{
int nid;
nid = numa_cpu_lookup_table[cpu];
/*
* Fall back to node 0 if nid is unset (it should be, except bugs).
* This allows callers to safely do NODE_DATA(early_cpu_to_node(cpu)).
*/
return (nid < 0) ? 0 : nid;
}
#else #else
static inline int early_cpu_to_node(int cpu) { return 0; }
static inline void dump_numa_cpu_topology(void) {} static inline void dump_numa_cpu_topology(void) {}
static inline int sysfs_add_device_to_node(struct device *dev, int nid) static inline int sysfs_add_device_to_node(struct device *dev, int nid)
......
...@@ -267,13 +267,7 @@ do { \ ...@@ -267,13 +267,7 @@ do { \
extern unsigned long __copy_tofrom_user(void __user *to, extern unsigned long __copy_tofrom_user(void __user *to,
const void __user *from, unsigned long size); const void __user *from, unsigned long size);
#ifndef __powerpc64__ #ifdef __powerpc64__
#define INLINE_COPY_FROM_USER
#define INLINE_COPY_TO_USER
#else /* __powerpc64__ */
static inline unsigned long static inline unsigned long
raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
{ {
......
...@@ -94,11 +94,13 @@ struct xive_q { ...@@ -94,11 +94,13 @@ struct xive_q {
* store at 0 and some ESBs support doing a trigger via a * store at 0 and some ESBs support doing a trigger via a
* separate trigger page. * separate trigger page.
*/ */
#define XIVE_ESB_GET 0x800 #define XIVE_ESB_STORE_EOI 0x400 /* Store */
#define XIVE_ESB_SET_PQ_00 0xc00 #define XIVE_ESB_LOAD_EOI 0x000 /* Load */
#define XIVE_ESB_SET_PQ_01 0xd00 #define XIVE_ESB_GET 0x800 /* Load */
#define XIVE_ESB_SET_PQ_10 0xe00 #define XIVE_ESB_SET_PQ_00 0xc00 /* Load */
#define XIVE_ESB_SET_PQ_11 0xf00 #define XIVE_ESB_SET_PQ_01 0xd00 /* Load */
#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */
#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */
#define XIVE_ESB_VAL_P 0x2 #define XIVE_ESB_VAL_P 0x2
#define XIVE_ESB_VAL_Q 0x1 #define XIVE_ESB_VAL_Q 0x1
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <linux/libfdt.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -642,7 +643,6 @@ static struct dt_cpu_feature_match __initdata ...@@ -642,7 +643,6 @@ static struct dt_cpu_feature_match __initdata
{"processor-control-facility", feat_enable_dbell, CPU_FTR_DBELL}, {"processor-control-facility", feat_enable_dbell, CPU_FTR_DBELL},
{"processor-control-facility-v3", feat_enable_dbell, CPU_FTR_DBELL}, {"processor-control-facility-v3", feat_enable_dbell, CPU_FTR_DBELL},
{"processor-utilization-of-resources-register", feat_enable_purr, 0}, {"processor-utilization-of-resources-register", feat_enable_purr, 0},
{"subcore", feat_enable, CPU_FTR_SUBCORE},
{"no-execute", feat_enable, 0}, {"no-execute", feat_enable, 0},
{"strong-access-ordering", feat_enable, CPU_FTR_SAO}, {"strong-access-ordering", feat_enable, CPU_FTR_SAO},
{"cache-inhibited-large-page", feat_enable_large_ci, 0}, {"cache-inhibited-large-page", feat_enable_large_ci, 0},
...@@ -671,12 +671,24 @@ static struct dt_cpu_feature_match __initdata ...@@ -671,12 +671,24 @@ static struct dt_cpu_feature_match __initdata
{"wait-v3", feat_enable, 0}, {"wait-v3", feat_enable, 0},
}; };
/* XXX: how to configure this? Default + boot time? */ static bool __initdata using_dt_cpu_ftrs;
#ifdef CONFIG_PPC_CPUFEATURES_ENABLE_UNKNOWN static bool __initdata enable_unknown = true;
#define CPU_FEATURE_ENABLE_UNKNOWN 1
#else static int __init dt_cpu_ftrs_parse(char *str)
#define CPU_FEATURE_ENABLE_UNKNOWN 0 {
#endif if (!str)
return 0;
if (!strcmp(str, "off"))
using_dt_cpu_ftrs = false;
else if (!strcmp(str, "known"))
enable_unknown = false;
else
return 1;
return 0;
}
early_param("dt_cpu_ftrs", dt_cpu_ftrs_parse);
static void __init cpufeatures_setup_start(u32 isa) static void __init cpufeatures_setup_start(u32 isa)
{ {
...@@ -707,7 +719,7 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) ...@@ -707,7 +719,7 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
} }
} }
if (!known && CPU_FEATURE_ENABLE_UNKNOWN) { if (!known && enable_unknown) {
if (!feat_try_enable_unknown(f)) { if (!feat_try_enable_unknown(f)) {
pr_info("not enabling: %s (unknown and unsupported by kernel)\n", pr_info("not enabling: %s (unknown and unsupported by kernel)\n",
f->name); f->name);
...@@ -756,6 +768,26 @@ static void __init cpufeatures_setup_finished(void) ...@@ -756,6 +768,26 @@ static void __init cpufeatures_setup_finished(void)
cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features); cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features);
} }
static int __init disabled_on_cmdline(void)
{
unsigned long root, chosen;
const char *p;
root = of_get_flat_dt_root();
chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
if (chosen == -FDT_ERR_NOTFOUND)
return false;
p = of_get_flat_dt_prop(chosen, "bootargs", NULL);
if (!p)
return false;
if (strstr(p, "dt_cpu_ftrs=off"))
return true;
return false;
}
static int __init fdt_find_cpu_features(unsigned long node, const char *uname, static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
int depth, void *data) int depth, void *data)
{ {
...@@ -766,8 +798,6 @@ static int __init fdt_find_cpu_features(unsigned long node, const char *uname, ...@@ -766,8 +798,6 @@ static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
return 0; return 0;
} }
static bool __initdata using_dt_cpu_ftrs = false;
bool __init dt_cpu_ftrs_in_use(void) bool __init dt_cpu_ftrs_in_use(void)
{ {
return using_dt_cpu_ftrs; return using_dt_cpu_ftrs;
...@@ -775,6 +805,8 @@ bool __init dt_cpu_ftrs_in_use(void) ...@@ -775,6 +805,8 @@ bool __init dt_cpu_ftrs_in_use(void)
bool __init dt_cpu_ftrs_init(void *fdt) bool __init dt_cpu_ftrs_init(void *fdt)
{ {
using_dt_cpu_ftrs = false;
/* Setup and verify the FDT, if it fails we just bail */ /* Setup and verify the FDT, if it fails we just bail */
if (!early_init_dt_verify(fdt)) if (!early_init_dt_verify(fdt))
return false; return false;
...@@ -782,6 +814,9 @@ bool __init dt_cpu_ftrs_init(void *fdt) ...@@ -782,6 +814,9 @@ bool __init dt_cpu_ftrs_init(void *fdt)
if (!of_scan_flat_dt(fdt_find_cpu_features, NULL)) if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))
return false; return false;
if (disabled_on_cmdline())
return false;
cpufeatures_setup_cpu(); cpufeatures_setup_cpu();
using_dt_cpu_ftrs = true; using_dt_cpu_ftrs = true;
...@@ -1027,5 +1062,8 @@ static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char ...@@ -1027,5 +1062,8 @@ static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char
void __init dt_cpu_ftrs_scan(void) void __init dt_cpu_ftrs_scan(void)
{ {
if (!using_dt_cpu_ftrs)
return;
of_scan_flat_dt(dt_cpu_ftrs_scan_callback, NULL); of_scan_flat_dt(dt_cpu_ftrs_scan_callback, NULL);
} }
...@@ -1452,10 +1452,8 @@ USE_TEXT_SECTION() ...@@ -1452,10 +1452,8 @@ USE_TEXT_SECTION()
.balign IFETCH_ALIGN_BYTES .balign IFETCH_ALIGN_BYTES
do_hash_page: do_hash_page:
#ifdef CONFIG_PPC_STD_MMU_64 #ifdef CONFIG_PPC_STD_MMU_64
andis. r0,r4,0xa410 /* weird error? */ andis. r0,r4,0xa450 /* weird error? */
bne- handle_page_fault /* if not, try to insert a HPTE */ bne- handle_page_fault /* if not, try to insert a HPTE */
andis. r0,r4,DSISR_DABRMATCH@h
bne- handle_dabr_fault
CURRENT_THREAD_INFO(r11, r1) CURRENT_THREAD_INFO(r11, r1)
lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */
andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */
...@@ -1479,11 +1477,16 @@ do_hash_page: ...@@ -1479,11 +1477,16 @@ do_hash_page:
/* Error */ /* Error */
blt- 13f blt- 13f
/* Reload DSISR into r4 for the DABR check below */
ld r4,_DSISR(r1)
#endif /* CONFIG_PPC_STD_MMU_64 */ #endif /* CONFIG_PPC_STD_MMU_64 */
/* Here we have a page fault that hash_page can't handle. */ /* Here we have a page fault that hash_page can't handle. */
handle_page_fault: handle_page_fault:
11: ld r4,_DAR(r1) 11: andis. r0,r4,DSISR_DABRMATCH@h
bne- handle_dabr_fault
ld r4,_DAR(r1)
ld r5,_DSISR(r1) ld r5,_DSISR(r1)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl do_page_fault bl do_page_fault
......
...@@ -43,6 +43,12 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); ...@@ -43,6 +43,12 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
int is_current_kprobe_addr(unsigned long addr)
{
struct kprobe *p = kprobe_running();
return (p && (unsigned long)p->addr == addr) ? 1 : 0;
}
bool arch_within_kprobe_blacklist(unsigned long addr) bool arch_within_kprobe_blacklist(unsigned long addr)
{ {
return (addr >= (unsigned long)__kprobes_text_start && return (addr >= (unsigned long)__kprobes_text_start &&
...@@ -617,6 +623,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -617,6 +623,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
#endif #endif
/*
* jprobes use jprobe_return() which skips the normal return
* path of the function, and this messes up the accounting of the
* function graph tracer.
*
* Pause function graph tracing while performing the jprobe function.
*/
pause_graph_tracing();
return 1; return 1;
} }
NOKPROBE_SYMBOL(setjmp_pre_handler); NOKPROBE_SYMBOL(setjmp_pre_handler);
...@@ -642,6 +657,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -642,6 +657,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
* saved regs... * saved regs...
*/ */
memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs)); memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
/* It's OK to start function graph tracing again */
unpause_graph_tracing();
preempt_enable_no_resched(); preempt_enable_no_resched();
return 1; return 1;
} }
......
...@@ -1697,6 +1697,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) ...@@ -1697,6 +1697,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
#ifdef CONFIG_VSX #ifdef CONFIG_VSX
current->thread.used_vsr = 0; current->thread.used_vsr = 0;
#endif #endif
current->thread.load_fp = 0;
memset(&current->thread.fp_state, 0, sizeof(current->thread.fp_state)); memset(&current->thread.fp_state, 0, sizeof(current->thread.fp_state));
current->thread.fp_save_area = NULL; current->thread.fp_save_area = NULL;
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
...@@ -1705,6 +1706,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) ...@@ -1705,6 +1706,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
current->thread.vr_save_area = NULL; current->thread.vr_save_area = NULL;
current->thread.vrsave = 0; current->thread.vrsave = 0;
current->thread.used_vr = 0; current->thread.used_vr = 0;
current->thread.load_vec = 0;
#endif /* CONFIG_ALTIVEC */ #endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_SPE #ifdef CONFIG_SPE
memset(current->thread.evr, 0, sizeof(current->thread.evr)); memset(current->thread.evr, 0, sizeof(current->thread.evr));
...@@ -1716,6 +1718,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) ...@@ -1716,6 +1718,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
current->thread.tm_tfhar = 0; current->thread.tm_tfhar = 0;
current->thread.tm_texasr = 0; current->thread.tm_texasr = 0;
current->thread.tm_tfiar = 0; current->thread.tm_tfiar = 0;
current->thread.load_tm = 0;
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
} }
EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(start_thread);
......
...@@ -932,7 +932,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -932,7 +932,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_PPC_MM_SLICES #ifdef CONFIG_PPC_MM_SLICES
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
init_mm.context.addr_limit = TASK_SIZE_128TB; init_mm.context.addr_limit = DEFAULT_MAP_WINDOW_USER64;
#else #else
#error "context.addr_limit not initialized." #error "context.addr_limit not initialized."
#endif #endif
......
...@@ -615,6 +615,24 @@ void __init exc_lvl_early_init(void) ...@@ -615,6 +615,24 @@ void __init exc_lvl_early_init(void)
} }
#endif #endif
/*
* Emergency stacks are used for a range of things, from asynchronous
* NMIs (system reset, machine check) to synchronous, process context.
* We set preempt_count to zero, even though that isn't necessarily correct. To
* get the right value we'd need to copy it from the previous thread_info, but
* doing that might fault causing more problems.
* TODO: what to do with accounting?
*/
static void emerg_stack_init_thread_info(struct thread_info *ti, int cpu)
{
ti->task = NULL;
ti->cpu = cpu;
ti->preempt_count = 0;
ti->local_flags = 0;
ti->flags = 0;
klp_init_thread_info(ti);
}
/* /*
* Stack space used when we detect a bad kernel stack pointer, and * Stack space used when we detect a bad kernel stack pointer, and
* early in SMP boots before relocation is enabled. Exclusive emergency * early in SMP boots before relocation is enabled. Exclusive emergency
...@@ -633,24 +651,31 @@ void __init emergency_stack_init(void) ...@@ -633,24 +651,31 @@ void __init emergency_stack_init(void)
* Since we use these as temporary stacks during secondary CPU * Since we use these as temporary stacks during secondary CPU
* bringup, we need to get at them in real mode. This means they * bringup, we need to get at them in real mode. This means they
* must also be within the RMO region. * must also be within the RMO region.
*
* The IRQ stacks allocated elsewhere in this file are zeroed and
* initialized in kernel/irq.c. These are initialized here in order
* to have emergency stacks available as early as possible.
*/ */
limit = min(safe_stack_limit(), ppc64_rma_size); limit = min(safe_stack_limit(), ppc64_rma_size);
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
struct thread_info *ti; struct thread_info *ti;
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
klp_init_thread_info(ti); memset(ti, 0, THREAD_SIZE);
emerg_stack_init_thread_info(ti, i);
paca[i].emergency_sp = (void *)ti + THREAD_SIZE; paca[i].emergency_sp = (void *)ti + THREAD_SIZE;
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
/* emergency stack for NMI exception handling. */ /* emergency stack for NMI exception handling. */
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
klp_init_thread_info(ti); memset(ti, 0, THREAD_SIZE);
emerg_stack_init_thread_info(ti, i);
paca[i].nmi_emergency_sp = (void *)ti + THREAD_SIZE; paca[i].nmi_emergency_sp = (void *)ti + THREAD_SIZE;
/* emergency stack for machine check exception handling. */ /* emergency stack for machine check exception handling. */
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
klp_init_thread_info(ti); memset(ti, 0, THREAD_SIZE);
emerg_stack_init_thread_info(ti, i);
paca[i].mc_emergency_sp = (void *)ti + THREAD_SIZE; paca[i].mc_emergency_sp = (void *)ti + THREAD_SIZE;
#endif #endif
} }
...@@ -661,7 +686,7 @@ void __init emergency_stack_init(void) ...@@ -661,7 +686,7 @@ void __init emergency_stack_init(void)
static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align) static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
{ {
return __alloc_bootmem_node(NODE_DATA(cpu_to_node(cpu)), size, align, return __alloc_bootmem_node(NODE_DATA(early_cpu_to_node(cpu)), size, align,
__pa(MAX_DMA_ADDRESS)); __pa(MAX_DMA_ADDRESS));
} }
...@@ -672,7 +697,7 @@ static void __init pcpu_fc_free(void *ptr, size_t size) ...@@ -672,7 +697,7 @@ static void __init pcpu_fc_free(void *ptr, size_t size)
static int pcpu_cpu_distance(unsigned int from, unsigned int to) static int pcpu_cpu_distance(unsigned int from, unsigned int to)
{ {
if (cpu_to_node(from) == cpu_to_node(to)) if (early_cpu_to_node(from) == early_cpu_to_node(to))
return LOCAL_DISTANCE; return LOCAL_DISTANCE;
else else
return REMOTE_DISTANCE; return REMOTE_DISTANCE;
......
...@@ -45,10 +45,14 @@ _GLOBAL(ftrace_caller) ...@@ -45,10 +45,14 @@ _GLOBAL(ftrace_caller)
stdu r1,-SWITCH_FRAME_SIZE(r1) stdu r1,-SWITCH_FRAME_SIZE(r1)
/* Save all gprs to pt_regs */ /* Save all gprs to pt_regs */
SAVE_8GPRS(0,r1) SAVE_GPR(0, r1)
SAVE_8GPRS(8,r1) SAVE_10GPRS(2, r1)
SAVE_8GPRS(16,r1) SAVE_10GPRS(12, r1)
SAVE_8GPRS(24,r1) SAVE_10GPRS(22, r1)
/* Save previous stack pointer (r1) */
addi r8, r1, SWITCH_FRAME_SIZE
std r8, GPR1(r1)
/* Load special regs for save below */ /* Load special regs for save below */
mfmsr r8 mfmsr r8
...@@ -95,18 +99,44 @@ ftrace_call: ...@@ -95,18 +99,44 @@ ftrace_call:
bl ftrace_stub bl ftrace_stub
nop nop
/* Load ctr with the possibly modified NIP */ /* Load the possibly modified NIP */
ld r3, _NIP(r1) ld r15, _NIP(r1)
mtctr r3
#ifdef CONFIG_LIVEPATCH #ifdef CONFIG_LIVEPATCH
cmpd r14,r3 /* has NIP been altered? */ cmpd r14, r15 /* has NIP been altered? */
#endif
#if defined(CONFIG_LIVEPATCH) && defined(CONFIG_KPROBES_ON_FTRACE)
/* NIP has not been altered, skip over further checks */
beq 1f
/* Check if there is an active kprobe on us */
subi r3, r14, 4
bl is_current_kprobe_addr
nop
/*
* If r3 == 1, then this is a kprobe/jprobe.
* else, this is livepatched function.
*
* The conditional branch for livepatch_handler below will use the
* result of this comparison. For kprobe/jprobe, we just need to branch to
* the new NIP, not call livepatch_handler. The branch below is bne, so we
* want CR0[EQ] to be true if this is a kprobe/jprobe. Which means we want
* CR0[EQ] = (r3 == 1).
*/
cmpdi r3, 1
1:
#endif #endif
/* Load CTR with the possibly modified NIP */
mtctr r15
/* Restore gprs */ /* Restore gprs */
REST_8GPRS(0,r1) REST_GPR(0,r1)
REST_8GPRS(8,r1) REST_10GPRS(2,r1)
REST_8GPRS(16,r1) REST_10GPRS(12,r1)
REST_8GPRS(24,r1) REST_10GPRS(22,r1)
/* Restore possibly modified LR */ /* Restore possibly modified LR */
ld r0, _LINK(r1) ld r0, _LINK(r1)
...@@ -119,7 +149,10 @@ ftrace_call: ...@@ -119,7 +149,10 @@ ftrace_call:
addi r1, r1, SWITCH_FRAME_SIZE addi r1, r1, SWITCH_FRAME_SIZE
#ifdef CONFIG_LIVEPATCH #ifdef CONFIG_LIVEPATCH
/* Based on the cmpd above, if the NIP was altered handle livepatch */ /*
* Based on the cmpd or cmpdi above, if the NIP was altered and we're
* not on a kprobe/jprobe, then handle livepatch.
*/
bne- livepatch_handler bne- livepatch_handler
#endif #endif
......
...@@ -69,7 +69,7 @@ static void GLUE(X_PFX,source_eoi)(u32 hw_irq, struct xive_irq_data *xd) ...@@ -69,7 +69,7 @@ static void GLUE(X_PFX,source_eoi)(u32 hw_irq, struct xive_irq_data *xd)
{ {
/* If the XIVE supports the new "store EOI facility, use it */ /* If the XIVE supports the new "store EOI facility, use it */
if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
__x_writeq(0, __x_eoi_page(xd)); __x_writeq(0, __x_eoi_page(xd) + XIVE_ESB_STORE_EOI);
else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) { else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) {
opal_int_eoi(hw_irq); opal_int_eoi(hw_irq);
} else { } else {
...@@ -89,7 +89,7 @@ static void GLUE(X_PFX,source_eoi)(u32 hw_irq, struct xive_irq_data *xd) ...@@ -89,7 +89,7 @@ static void GLUE(X_PFX,source_eoi)(u32 hw_irq, struct xive_irq_data *xd)
* properly. * properly.
*/ */
if (xd->flags & XIVE_IRQ_FLAG_LSI) if (xd->flags & XIVE_IRQ_FLAG_LSI)
__x_readq(__x_eoi_page(xd)); __x_readq(__x_eoi_page(xd) + XIVE_ESB_LOAD_EOI);
else { else {
eoi_val = GLUE(X_PFX,esb_load)(xd, XIVE_ESB_SET_PQ_00); eoi_val = GLUE(X_PFX,esb_load)(xd, XIVE_ESB_SET_PQ_00);
......
...@@ -99,7 +99,7 @@ static int hash__init_new_context(struct mm_struct *mm) ...@@ -99,7 +99,7 @@ static int hash__init_new_context(struct mm_struct *mm)
* mm->context.addr_limit. Default to max task size so that we copy the * mm->context.addr_limit. Default to max task size so that we copy the
* default values to paca which will help us to handle slb miss early. * default values to paca which will help us to handle slb miss early.
*/ */
mm->context.addr_limit = TASK_SIZE_128TB; mm->context.addr_limit = DEFAULT_MAP_WINDOW_USER64;
/* /*
* The old code would re-promote on fork, we don't do that when using * The old code would re-promote on fork, we don't do that when using
......
...@@ -101,5 +101,6 @@ void perf_get_regs_user(struct perf_regs *regs_user, ...@@ -101,5 +101,6 @@ void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs_user_copy) struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = perf_reg_abi(current); regs_user->abi = (regs_user->regs) ? perf_reg_abi(current) :
PERF_SAMPLE_REGS_ABI_NONE;
} }
...@@ -402,7 +402,7 @@ static struct power_pmu power9_isa207_pmu = { ...@@ -402,7 +402,7 @@ static struct power_pmu power9_isa207_pmu = {
.name = "POWER9", .name = "POWER9",
.n_counter = MAX_PMU_COUNTERS, .n_counter = MAX_PMU_COUNTERS,
.add_fields = ISA207_ADD_FIELDS, .add_fields = ISA207_ADD_FIELDS,
.test_adder = ISA207_TEST_ADDER, .test_adder = P9_DD1_TEST_ADDER,
.compute_mmcr = isa207_compute_mmcr, .compute_mmcr = isa207_compute_mmcr,
.config_bhrb = power9_config_bhrb, .config_bhrb = power9_config_bhrb,
.bhrb_filter_map = power9_bhrb_filter_map, .bhrb_filter_map = power9_bhrb_filter_map,
...@@ -421,7 +421,7 @@ static struct power_pmu power9_pmu = { ...@@ -421,7 +421,7 @@ static struct power_pmu power9_pmu = {
.name = "POWER9", .name = "POWER9",
.n_counter = MAX_PMU_COUNTERS, .n_counter = MAX_PMU_COUNTERS,
.add_fields = ISA207_ADD_FIELDS, .add_fields = ISA207_ADD_FIELDS,
.test_adder = P9_DD1_TEST_ADDER, .test_adder = ISA207_TEST_ADDER,
.compute_mmcr = isa207_compute_mmcr, .compute_mmcr = isa207_compute_mmcr,
.config_bhrb = power9_config_bhrb, .config_bhrb = power9_config_bhrb,
.bhrb_filter_map = power9_bhrb_filter_map, .bhrb_filter_map = power9_bhrb_filter_map,
......
...@@ -59,6 +59,17 @@ config PPC_OF_BOOT_TRAMPOLINE ...@@ -59,6 +59,17 @@ config PPC_OF_BOOT_TRAMPOLINE
In case of doubt, say Y In case of doubt, say Y
config PPC_DT_CPU_FTRS
bool "Device-tree based CPU feature discovery & setup"
depends on PPC_BOOK3S_64
default y
help
This enables code to use a new device tree binding for describing CPU
compatibility and features. Saying Y here will attempt to use the new
binding if the firmware provides it. Currently only the skiboot
firmware provides this binding.
If you're not sure say Y.
config UDBG_RTAS_CONSOLE config UDBG_RTAS_CONSOLE
bool "RTAS based debug console" bool "RTAS based debug console"
depends on PPC_RTAS depends on PPC_RTAS
......
...@@ -175,6 +175,8 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i, ...@@ -175,6 +175,8 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i,
skip = roundup(cprm->pos - total + sz, 4) - cprm->pos; skip = roundup(cprm->pos - total + sz, 4) - cprm->pos;
if (!dump_skip(cprm, skip)) if (!dump_skip(cprm, skip))
goto Eio; goto Eio;
rc = 0;
out: out:
free_page((unsigned long)buf); free_page((unsigned long)buf);
return rc; return rc;
......
...@@ -75,7 +75,8 @@ struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index) ...@@ -75,7 +75,8 @@ struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index)
if (WARN_ON(!gpdev)) if (WARN_ON(!gpdev))
return NULL; return NULL;
if (WARN_ON(!gpdev->dev.of_node)) /* Not all PCI devices have device-tree nodes */
if (!gpdev->dev.of_node)
return NULL; return NULL;
/* Get assoicated PCI device */ /* Get assoicated PCI device */
...@@ -448,7 +449,7 @@ static int mmio_launch_invalidate(struct npu *npu, unsigned long launch, ...@@ -448,7 +449,7 @@ static int mmio_launch_invalidate(struct npu *npu, unsigned long launch,
return mmio_atsd_reg; return mmio_atsd_reg;
} }
static int mmio_invalidate_pid(struct npu *npu, unsigned long pid) static int mmio_invalidate_pid(struct npu *npu, unsigned long pid, bool flush)
{ {
unsigned long launch; unsigned long launch;
...@@ -464,12 +465,15 @@ static int mmio_invalidate_pid(struct npu *npu, unsigned long pid) ...@@ -464,12 +465,15 @@ static int mmio_invalidate_pid(struct npu *npu, unsigned long pid)
/* PID */ /* PID */
launch |= pid << PPC_BITLSHIFT(38); launch |= pid << PPC_BITLSHIFT(38);
/* No flush */
launch |= !flush << PPC_BITLSHIFT(39);
/* Invalidating the entire process doesn't use a va */ /* Invalidating the entire process doesn't use a va */
return mmio_launch_invalidate(npu, launch, 0); return mmio_launch_invalidate(npu, launch, 0);
} }
static int mmio_invalidate_va(struct npu *npu, unsigned long va, static int mmio_invalidate_va(struct npu *npu, unsigned long va,
unsigned long pid) unsigned long pid, bool flush)
{ {
unsigned long launch; unsigned long launch;
...@@ -485,26 +489,60 @@ static int mmio_invalidate_va(struct npu *npu, unsigned long va, ...@@ -485,26 +489,60 @@ static int mmio_invalidate_va(struct npu *npu, unsigned long va,
/* PID */ /* PID */
launch |= pid << PPC_BITLSHIFT(38); launch |= pid << PPC_BITLSHIFT(38);
/* No flush */
launch |= !flush << PPC_BITLSHIFT(39);
return mmio_launch_invalidate(npu, launch, va); return mmio_launch_invalidate(npu, launch, va);
} }
#define mn_to_npu_context(x) container_of(x, struct npu_context, mn) #define mn_to_npu_context(x) container_of(x, struct npu_context, mn)
struct mmio_atsd_reg {
struct npu *npu;
int reg;
};
static void mmio_invalidate_wait(
struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS], bool flush)
{
struct npu *npu;
int i, reg;
/* Wait for all invalidations to complete */
for (i = 0; i <= max_npu2_index; i++) {
if (mmio_atsd_reg[i].reg < 0)
continue;
/* Wait for completion */
npu = mmio_atsd_reg[i].npu;
reg = mmio_atsd_reg[i].reg;
while (__raw_readq(npu->mmio_atsd_regs[reg] + XTS_ATSD_STAT))
cpu_relax();
put_mmio_atsd_reg(npu, reg);
/*
* The GPU requires two flush ATSDs to ensure all entries have
* been flushed. We use PID 0 as it will never be used for a
* process on the GPU.
*/
if (flush)
mmio_invalidate_pid(npu, 0, true);
}
}
/* /*
* Invalidate either a single address or an entire PID depending on * Invalidate either a single address or an entire PID depending on
* the value of va. * the value of va.
*/ */
static void mmio_invalidate(struct npu_context *npu_context, int va, static void mmio_invalidate(struct npu_context *npu_context, int va,
unsigned long address) unsigned long address, bool flush)
{ {
int i, j, reg; int i, j;
struct npu *npu; struct npu *npu;
struct pnv_phb *nphb; struct pnv_phb *nphb;
struct pci_dev *npdev; struct pci_dev *npdev;
struct { struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS];
struct npu *npu;
int reg;
} mmio_atsd_reg[NV_MAX_NPUS];
unsigned long pid = npu_context->mm->context.id; unsigned long pid = npu_context->mm->context.id;
/* /*
...@@ -524,10 +562,11 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, ...@@ -524,10 +562,11 @@ static void mmio_invalidate(struct npu_context *npu_context, int va,
if (va) if (va)
mmio_atsd_reg[i].reg = mmio_atsd_reg[i].reg =
mmio_invalidate_va(npu, address, pid); mmio_invalidate_va(npu, address, pid,
flush);
else else
mmio_atsd_reg[i].reg = mmio_atsd_reg[i].reg =
mmio_invalidate_pid(npu, pid); mmio_invalidate_pid(npu, pid, flush);
/* /*
* The NPU hardware forwards the shootdown to all GPUs * The NPU hardware forwards the shootdown to all GPUs
...@@ -543,18 +582,10 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, ...@@ -543,18 +582,10 @@ static void mmio_invalidate(struct npu_context *npu_context, int va,
*/ */
flush_tlb_mm(npu_context->mm); flush_tlb_mm(npu_context->mm);
/* Wait for all invalidations to complete */ mmio_invalidate_wait(mmio_atsd_reg, flush);
for (i = 0; i <= max_npu2_index; i++) { if (flush)
if (mmio_atsd_reg[i].reg < 0) /* Wait for the flush to complete */
continue; mmio_invalidate_wait(mmio_atsd_reg, false);
/* Wait for completion */
npu = mmio_atsd_reg[i].npu;
reg = mmio_atsd_reg[i].reg;
while (__raw_readq(npu->mmio_atsd_regs[reg] + XTS_ATSD_STAT))
cpu_relax();
put_mmio_atsd_reg(npu, reg);
}
} }
static void pnv_npu2_mn_release(struct mmu_notifier *mn, static void pnv_npu2_mn_release(struct mmu_notifier *mn,
...@@ -570,7 +601,7 @@ static void pnv_npu2_mn_release(struct mmu_notifier *mn, ...@@ -570,7 +601,7 @@ static void pnv_npu2_mn_release(struct mmu_notifier *mn,
* There should be no more translation requests for this PID, but we * There should be no more translation requests for this PID, but we
* need to ensure any entries for it are removed from the TLB. * need to ensure any entries for it are removed from the TLB.
*/ */
mmio_invalidate(npu_context, 0, 0); mmio_invalidate(npu_context, 0, 0, true);
} }
static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn, static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn,
...@@ -580,7 +611,7 @@ static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn, ...@@ -580,7 +611,7 @@ static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn,
{ {
struct npu_context *npu_context = mn_to_npu_context(mn); struct npu_context *npu_context = mn_to_npu_context(mn);
mmio_invalidate(npu_context, 1, address); mmio_invalidate(npu_context, 1, address, true);
} }
static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn, static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn,
...@@ -589,7 +620,7 @@ static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn, ...@@ -589,7 +620,7 @@ static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn,
{ {
struct npu_context *npu_context = mn_to_npu_context(mn); struct npu_context *npu_context = mn_to_npu_context(mn);
mmio_invalidate(npu_context, 1, address); mmio_invalidate(npu_context, 1, address, true);
} }
static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
...@@ -599,8 +630,11 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, ...@@ -599,8 +630,11 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
struct npu_context *npu_context = mn_to_npu_context(mn); struct npu_context *npu_context = mn_to_npu_context(mn);
unsigned long address; unsigned long address;
for (address = start; address <= end; address += PAGE_SIZE) for (address = start; address < end; address += PAGE_SIZE)
mmio_invalidate(npu_context, 1, address); mmio_invalidate(npu_context, 1, address, false);
/* Do the flush only on the final addess == end */
mmio_invalidate(npu_context, 1, address, true);
} }
static const struct mmu_notifier_ops nv_nmmu_notifier_ops = { static const struct mmu_notifier_ops nv_nmmu_notifier_ops = {
...@@ -650,8 +684,11 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, ...@@ -650,8 +684,11 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
/* No nvlink associated with this GPU device */ /* No nvlink associated with this GPU device */
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
if (!mm) { if (!mm || mm->context.id == 0) {
/* kernel thread contexts are not supported */ /*
* Kernel thread contexts are not supported and context id 0 is
* reserved on the GPU.
*/
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
......
...@@ -408,7 +408,13 @@ static DEVICE_ATTR(subcores_per_core, 0644, ...@@ -408,7 +408,13 @@ static DEVICE_ATTR(subcores_per_core, 0644,
static int subcore_init(void) static int subcore_init(void)
{ {
if (!cpu_has_feature(CPU_FTR_SUBCORE)) unsigned pvr_ver;
pvr_ver = PVR_VER(mfspr(SPRN_PVR));
if (pvr_ver != PVR_POWER8 &&
pvr_ver != PVR_POWER8E &&
pvr_ver != PVR_POWER8NVL)
return 0; return 0;
/* /*
......
...@@ -125,6 +125,7 @@ static struct property *dlpar_clone_drconf_property(struct device_node *dn) ...@@ -125,6 +125,7 @@ static struct property *dlpar_clone_drconf_property(struct device_node *dn)
for (i = 0; i < num_lmbs; i++) { for (i = 0; i < num_lmbs; i++) {
lmbs[i].base_addr = be64_to_cpu(lmbs[i].base_addr); lmbs[i].base_addr = be64_to_cpu(lmbs[i].base_addr);
lmbs[i].drc_index = be32_to_cpu(lmbs[i].drc_index); lmbs[i].drc_index = be32_to_cpu(lmbs[i].drc_index);
lmbs[i].aa_index = be32_to_cpu(lmbs[i].aa_index);
lmbs[i].flags = be32_to_cpu(lmbs[i].flags); lmbs[i].flags = be32_to_cpu(lmbs[i].flags);
} }
...@@ -148,6 +149,7 @@ static void dlpar_update_drconf_property(struct device_node *dn, ...@@ -148,6 +149,7 @@ static void dlpar_update_drconf_property(struct device_node *dn,
for (i = 0; i < num_lmbs; i++) { for (i = 0; i < num_lmbs; i++) {
lmbs[i].base_addr = cpu_to_be64(lmbs[i].base_addr); lmbs[i].base_addr = cpu_to_be64(lmbs[i].base_addr);
lmbs[i].drc_index = cpu_to_be32(lmbs[i].drc_index); lmbs[i].drc_index = cpu_to_be32(lmbs[i].drc_index);
lmbs[i].aa_index = cpu_to_be32(lmbs[i].aa_index);
lmbs[i].flags = cpu_to_be32(lmbs[i].flags); lmbs[i].flags = cpu_to_be32(lmbs[i].flags);
} }
......
...@@ -75,7 +75,8 @@ static int u8_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) ...@@ -75,7 +75,8 @@ static int u8_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
static void u8_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) static void u8_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
{ {
struct u8_gpio_chip *u8_gc = gpiochip_get_data(&mm_gc->gc); struct u8_gpio_chip *u8_gc =
container_of(mm_gc, struct u8_gpio_chip, mm_gc);
u8_gc->data = in_8(mm_gc->regs); u8_gc->data = in_8(mm_gc->regs);
} }
......
...@@ -297,7 +297,7 @@ void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd) ...@@ -297,7 +297,7 @@ void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd)
{ {
/* If the XIVE supports the new "store EOI facility, use it */ /* If the XIVE supports the new "store EOI facility, use it */
if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
out_be64(xd->eoi_mmio, 0); out_be64(xd->eoi_mmio + XIVE_ESB_STORE_EOI, 0);
else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) { else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) {
/* /*
* The FW told us to call it. This happens for some * The FW told us to call it. This happens for some
......
...@@ -45,7 +45,7 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master) ...@@ -45,7 +45,7 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
mutex_init(&ctx->mapping_lock); mutex_init(&ctx->mapping_lock);
ctx->mapping = NULL; ctx->mapping = NULL;
if (cxl_is_psl8(afu)) { if (cxl_is_power8()) {
spin_lock_init(&ctx->sste_lock); spin_lock_init(&ctx->sste_lock);
/* /*
...@@ -189,7 +189,7 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma) ...@@ -189,7 +189,7 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
if (start + len > ctx->afu->adapter->ps_size) if (start + len > ctx->afu->adapter->ps_size)
return -EINVAL; return -EINVAL;
if (cxl_is_psl9(ctx->afu)) { if (cxl_is_power9()) {
/* /*
* Make sure there is a valid problem state * Make sure there is a valid problem state
* area space for this AFU. * area space for this AFU.
...@@ -324,7 +324,7 @@ static void reclaim_ctx(struct rcu_head *rcu) ...@@ -324,7 +324,7 @@ static void reclaim_ctx(struct rcu_head *rcu)
{ {
struct cxl_context *ctx = container_of(rcu, struct cxl_context, rcu); struct cxl_context *ctx = container_of(rcu, struct cxl_context, rcu);
if (cxl_is_psl8(ctx->afu)) if (cxl_is_power8())
free_page((u64)ctx->sstp); free_page((u64)ctx->sstp);
if (ctx->ff_page) if (ctx->ff_page)
__free_page(ctx->ff_page); __free_page(ctx->ff_page);
......
...@@ -357,6 +357,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; ...@@ -357,6 +357,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
#define CXL_PSL9_DSISR_An_PF_RGP 0x0000000000000090ULL /* PTE not found (Radix Guest (parent)) 0b10010000 */ #define CXL_PSL9_DSISR_An_PF_RGP 0x0000000000000090ULL /* PTE not found (Radix Guest (parent)) 0b10010000 */
#define CXL_PSL9_DSISR_An_PF_HRH 0x0000000000000094ULL /* PTE not found (HPT/Radix Host) 0b10010100 */ #define CXL_PSL9_DSISR_An_PF_HRH 0x0000000000000094ULL /* PTE not found (HPT/Radix Host) 0b10010100 */
#define CXL_PSL9_DSISR_An_PF_STEG 0x000000000000009CULL /* PTE not found (STEG VA) 0b10011100 */ #define CXL_PSL9_DSISR_An_PF_STEG 0x000000000000009CULL /* PTE not found (STEG VA) 0b10011100 */
#define CXL_PSL9_DSISR_An_URTCH 0x00000000000000B4ULL /* Unsupported Radix Tree Configuration 0b10110100 */
/****** CXL_PSL_TFC_An ******************************************************/ /****** CXL_PSL_TFC_An ******************************************************/
#define CXL_PSL_TFC_An_A (1ull << (63-28)) /* Acknowledge non-translation fault */ #define CXL_PSL_TFC_An_A (1ull << (63-28)) /* Acknowledge non-translation fault */
...@@ -844,24 +845,15 @@ static inline bool cxl_is_power8(void) ...@@ -844,24 +845,15 @@ static inline bool cxl_is_power8(void)
static inline bool cxl_is_power9(void) static inline bool cxl_is_power9(void)
{ {
/* intermediate solution */ if (pvr_version_is(PVR_POWER9))
if (!cxl_is_power8() &&
(cpu_has_feature(CPU_FTRS_POWER9) ||
cpu_has_feature(CPU_FTR_POWER9_DD1)))
return true; return true;
return false; return false;
} }
static inline bool cxl_is_psl8(struct cxl_afu *afu) static inline bool cxl_is_power9_dd1(void)
{ {
if (afu->adapter->caia_major == 1) if ((pvr_version_is(PVR_POWER9)) &&
return true; cpu_has_feature(CPU_FTR_POWER9_DD1))
return false;
}
static inline bool cxl_is_psl9(struct cxl_afu *afu)
{
if (afu->adapter->caia_major == 2)
return true; return true;
return false; return false;
} }
......
...@@ -187,7 +187,7 @@ static struct mm_struct *get_mem_context(struct cxl_context *ctx) ...@@ -187,7 +187,7 @@ static struct mm_struct *get_mem_context(struct cxl_context *ctx)
static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr) static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr)
{ {
if ((cxl_is_psl8(ctx->afu)) && (dsisr & CXL_PSL_DSISR_An_DS)) if ((cxl_is_power8() && (dsisr & CXL_PSL_DSISR_An_DS)))
return true; return true;
return false; return false;
...@@ -195,16 +195,23 @@ static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr) ...@@ -195,16 +195,23 @@ static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr)
static bool cxl_is_page_fault(struct cxl_context *ctx, u64 dsisr) static bool cxl_is_page_fault(struct cxl_context *ctx, u64 dsisr)
{ {
if ((cxl_is_psl8(ctx->afu)) && (dsisr & CXL_PSL_DSISR_An_DM)) u64 crs; /* Translation Checkout Response Status */
return true;
if ((cxl_is_psl9(ctx->afu)) && if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_An_DM))
((dsisr & CXL_PSL9_DSISR_An_CO_MASK) &
(CXL_PSL9_DSISR_An_PF_SLR | CXL_PSL9_DSISR_An_PF_RGC |
CXL_PSL9_DSISR_An_PF_RGP | CXL_PSL9_DSISR_An_PF_HRH |
CXL_PSL9_DSISR_An_PF_STEG)))
return true; return true;
if (cxl_is_power9()) {
crs = (dsisr & CXL_PSL9_DSISR_An_CO_MASK);
if ((crs == CXL_PSL9_DSISR_An_PF_SLR) ||
(crs == CXL_PSL9_DSISR_An_PF_RGC) ||
(crs == CXL_PSL9_DSISR_An_PF_RGP) ||
(crs == CXL_PSL9_DSISR_An_PF_HRH) ||
(crs == CXL_PSL9_DSISR_An_PF_STEG) ||
(crs == CXL_PSL9_DSISR_An_URTCH)) {
return true;
}
}
return false; return false;
} }
......
...@@ -159,11 +159,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, ...@@ -159,11 +159,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
/* Do this outside the status_mutex to avoid a circular dependency with /* Do this outside the status_mutex to avoid a circular dependency with
* the locking in cxl_mmap_fault() */ * the locking in cxl_mmap_fault() */
if (copy_from_user(&work, uwork, if (copy_from_user(&work, uwork, sizeof(work)))
sizeof(struct cxl_ioctl_start_work))) { return -EFAULT;
rc = -EFAULT;
goto out;
}
mutex_lock(&ctx->status_mutex); mutex_lock(&ctx->status_mutex);
if (ctx->status != OPENED) { if (ctx->status != OPENED) {
......
...@@ -329,8 +329,15 @@ static int __init init_cxl(void) ...@@ -329,8 +329,15 @@ static int __init init_cxl(void)
cxl_debugfs_init(); cxl_debugfs_init();
if ((rc = register_cxl_calls(&cxl_calls))) /*
goto err; * we don't register the callback on P9. slb callack is only
* used for the PSL8 MMU and CX4.
*/
if (cxl_is_power8()) {
rc = register_cxl_calls(&cxl_calls);
if (rc)
goto err;
}
if (cpu_has_feature(CPU_FTR_HVMODE)) { if (cpu_has_feature(CPU_FTR_HVMODE)) {
cxl_ops = &cxl_native_ops; cxl_ops = &cxl_native_ops;
...@@ -347,7 +354,8 @@ static int __init init_cxl(void) ...@@ -347,7 +354,8 @@ static int __init init_cxl(void)
return 0; return 0;
err1: err1:
unregister_cxl_calls(&cxl_calls); if (cxl_is_power8())
unregister_cxl_calls(&cxl_calls);
err: err:
cxl_debugfs_exit(); cxl_debugfs_exit();
cxl_file_exit(); cxl_file_exit();
...@@ -366,7 +374,8 @@ static void exit_cxl(void) ...@@ -366,7 +374,8 @@ static void exit_cxl(void)
cxl_debugfs_exit(); cxl_debugfs_exit();
cxl_file_exit(); cxl_file_exit();
unregister_cxl_calls(&cxl_calls); if (cxl_is_power8())
unregister_cxl_calls(&cxl_calls);
idr_destroy(&cxl_adapter_idr); idr_destroy(&cxl_adapter_idr);
} }
......
...@@ -105,11 +105,16 @@ static int native_afu_reset(struct cxl_afu *afu) ...@@ -105,11 +105,16 @@ static int native_afu_reset(struct cxl_afu *afu)
CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK, CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK,
false); false);
/* Re-enable any masked interrupts */ /*
serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); * Re-enable any masked interrupts when the AFU is not
serr &= ~CXL_PSL_SERR_An_IRQ_MASKS; * activated to avoid side effects after attaching a process
cxl_p1n_write(afu, CXL_PSL_SERR_An, serr); * in dedicated mode.
*/
if (afu->current_mode == 0) {
serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
serr &= ~CXL_PSL_SERR_An_IRQ_MASKS;
cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
}
return rc; return rc;
} }
...@@ -139,9 +144,9 @@ int cxl_psl_purge(struct cxl_afu *afu) ...@@ -139,9 +144,9 @@ int cxl_psl_purge(struct cxl_afu *afu)
pr_devel("PSL purge request\n"); pr_devel("PSL purge request\n");
if (cxl_is_psl8(afu)) if (cxl_is_power8())
trans_fault = CXL_PSL_DSISR_TRANS; trans_fault = CXL_PSL_DSISR_TRANS;
if (cxl_is_psl9(afu)) if (cxl_is_power9())
trans_fault = CXL_PSL9_DSISR_An_TF; trans_fault = CXL_PSL9_DSISR_An_TF;
if (!cxl_ops->link_ok(afu->adapter, afu)) { if (!cxl_ops->link_ok(afu->adapter, afu)) {
...@@ -603,7 +608,7 @@ static u64 calculate_sr(struct cxl_context *ctx) ...@@ -603,7 +608,7 @@ static u64 calculate_sr(struct cxl_context *ctx)
if (!test_tsk_thread_flag(current, TIF_32BIT)) if (!test_tsk_thread_flag(current, TIF_32BIT))
sr |= CXL_PSL_SR_An_SF; sr |= CXL_PSL_SR_An_SF;
} }
if (cxl_is_psl9(ctx->afu)) { if (cxl_is_power9()) {
if (radix_enabled()) if (radix_enabled())
sr |= CXL_PSL_SR_An_XLAT_ror; sr |= CXL_PSL_SR_An_XLAT_ror;
else else
...@@ -1117,10 +1122,10 @@ static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx, ...@@ -1117,10 +1122,10 @@ static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,
static bool cxl_is_translation_fault(struct cxl_afu *afu, u64 dsisr) static bool cxl_is_translation_fault(struct cxl_afu *afu, u64 dsisr)
{ {
if ((cxl_is_psl8(afu)) && (dsisr & CXL_PSL_DSISR_TRANS)) if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_TRANS))
return true; return true;
if ((cxl_is_psl9(afu)) && (dsisr & CXL_PSL9_DSISR_An_TF)) if ((cxl_is_power9()) && (dsisr & CXL_PSL9_DSISR_An_TF))
return true; return true;
return false; return false;
...@@ -1194,10 +1199,10 @@ static void native_irq_wait(struct cxl_context *ctx) ...@@ -1194,10 +1199,10 @@ static void native_irq_wait(struct cxl_context *ctx)
if (ph != ctx->pe) if (ph != ctx->pe)
return; return;
dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An); dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An);
if (cxl_is_psl8(ctx->afu) && if (cxl_is_power8() &&
((dsisr & CXL_PSL_DSISR_PENDING) == 0)) ((dsisr & CXL_PSL_DSISR_PENDING) == 0))
return; return;
if (cxl_is_psl9(ctx->afu) && if (cxl_is_power9() &&
((dsisr & CXL_PSL9_DSISR_PENDING) == 0)) ((dsisr & CXL_PSL9_DSISR_PENDING) == 0))
return; return;
/* /*
...@@ -1302,13 +1307,16 @@ int cxl_native_register_psl_err_irq(struct cxl *adapter) ...@@ -1302,13 +1307,16 @@ int cxl_native_register_psl_err_irq(struct cxl *adapter)
void cxl_native_release_psl_err_irq(struct cxl *adapter) void cxl_native_release_psl_err_irq(struct cxl *adapter)
{ {
if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq)) if (adapter->native->err_virq == 0 ||
adapter->native->err_virq !=
irq_find_mapping(NULL, adapter->native->err_hwirq))
return; return;
cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
cxl_unmap_irq(adapter->native->err_virq, adapter); cxl_unmap_irq(adapter->native->err_virq, adapter);
cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq); cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq);
kfree(adapter->irq_name); kfree(adapter->irq_name);
adapter->native->err_virq = 0;
} }
int cxl_native_register_serr_irq(struct cxl_afu *afu) int cxl_native_register_serr_irq(struct cxl_afu *afu)
...@@ -1346,13 +1354,15 @@ int cxl_native_register_serr_irq(struct cxl_afu *afu) ...@@ -1346,13 +1354,15 @@ int cxl_native_register_serr_irq(struct cxl_afu *afu)
void cxl_native_release_serr_irq(struct cxl_afu *afu) void cxl_native_release_serr_irq(struct cxl_afu *afu)
{ {
if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq)) if (afu->serr_virq == 0 ||
afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
return; return;
cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000); cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
cxl_unmap_irq(afu->serr_virq, afu); cxl_unmap_irq(afu->serr_virq, afu);
cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq); cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
kfree(afu->err_irq_name); kfree(afu->err_irq_name);
afu->serr_virq = 0;
} }
int cxl_native_register_psl_irq(struct cxl_afu *afu) int cxl_native_register_psl_irq(struct cxl_afu *afu)
...@@ -1375,12 +1385,15 @@ int cxl_native_register_psl_irq(struct cxl_afu *afu) ...@@ -1375,12 +1385,15 @@ int cxl_native_register_psl_irq(struct cxl_afu *afu)
void cxl_native_release_psl_irq(struct cxl_afu *afu) void cxl_native_release_psl_irq(struct cxl_afu *afu)
{ {
if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq)) if (afu->native->psl_virq == 0 ||
afu->native->psl_virq !=
irq_find_mapping(NULL, afu->native->psl_hwirq))
return; return;
cxl_unmap_irq(afu->native->psl_virq, afu); cxl_unmap_irq(afu->native->psl_virq, afu);
cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq); cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq);
kfree(afu->psl_irq_name); kfree(afu->psl_irq_name);
afu->native->psl_virq = 0;
} }
static void recover_psl_err(struct cxl_afu *afu, u64 errstat) static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
......
...@@ -436,7 +436,7 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter, struct pci ...@@ -436,7 +436,7 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter, struct pci
/* nMMU_ID Defaults to: b’000001001’*/ /* nMMU_ID Defaults to: b’000001001’*/
xsl_dsnctl |= ((u64)0x09 << (63-28)); xsl_dsnctl |= ((u64)0x09 << (63-28));
if (cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1)) { if (!(cxl_is_power9_dd1())) {
/* /*
* Used to identify CAPI packets which should be sorted into * Used to identify CAPI packets which should be sorted into
* the Non-Blocking queues by the PHB. This field should match * the Non-Blocking queues by the PHB. This field should match
...@@ -491,7 +491,7 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter, struct pci ...@@ -491,7 +491,7 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter, struct pci
cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000003FFFF0000ULL); cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000003FFFF0000ULL);
/* Disable vc dd1 fix */ /* Disable vc dd1 fix */
if ((cxl_is_power9() && cpu_has_feature(CPU_FTR_POWER9_DD1))) if (cxl_is_power9_dd1())
cxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0400000000000001ULL); cxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0400000000000001ULL);
return 0; return 0;
...@@ -1439,8 +1439,7 @@ int cxl_pci_reset(struct cxl *adapter) ...@@ -1439,8 +1439,7 @@ int cxl_pci_reset(struct cxl *adapter)
* The adapter is about to be reset, so ignore errors. * The adapter is about to be reset, so ignore errors.
* Not supported on P9 DD1 * Not supported on P9 DD1
*/ */
if ((cxl_is_power8()) || if ((cxl_is_power8()) || (!(cxl_is_power9_dd1())))
((cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1))))
cxl_data_cache_flush(adapter); cxl_data_cache_flush(adapter);
/* pcie_warm_reset requests a fundamental pci reset which includes a /* pcie_warm_reset requests a fundamental pci reset which includes a
...@@ -1750,7 +1749,6 @@ static const struct cxl_service_layer_ops psl9_ops = { ...@@ -1750,7 +1749,6 @@ static const struct cxl_service_layer_ops psl9_ops = {
.debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl9, .debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl9,
.debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl9, .debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl9,
.psl_irq_dump_registers = cxl_native_irq_dump_regs_psl9, .psl_irq_dump_registers = cxl_native_irq_dump_regs_psl9,
.err_irq_dump_registers = cxl_native_err_irq_dump_regs,
.debugfs_stop_trace = cxl_stop_trace_psl9, .debugfs_stop_trace = cxl_stop_trace_psl9,
.write_timebase_ctrl = write_timebase_ctrl_psl9, .write_timebase_ctrl = write_timebase_ctrl_psl9,
.timebase_read = timebase_read_psl9, .timebase_read = timebase_read_psl9,
...@@ -1889,8 +1887,7 @@ static void cxl_pci_remove_adapter(struct cxl *adapter) ...@@ -1889,8 +1887,7 @@ static void cxl_pci_remove_adapter(struct cxl *adapter)
* Flush adapter datacache as its about to be removed. * Flush adapter datacache as its about to be removed.
* Not supported on P9 DD1. * Not supported on P9 DD1.
*/ */
if ((cxl_is_power8()) || if ((cxl_is_power8()) || (!(cxl_is_power9_dd1())))
((cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1))))
cxl_data_cache_flush(adapter); cxl_data_cache_flush(adapter);
cxl_deconfigure_adapter(adapter); cxl_deconfigure_adapter(adapter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment