From 9227f0431435c9d664771b112c230e75ca4f9b52 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 25 Jul 2017 00:10:15 +1000 Subject: powerpc/udbg: Reduce the footgun potential of EARLY_DEBUG_LPAR(_HVSI) For debugging very early boot problems we have CONFIG_PPC_EARLY_DEBUG, which allows configuring the kernel such that it unconditionally writes to a particular type of console, regardless of whether that console exists or not. This is useful sometimes when the kernel crashes before it can even determine what platform it's on, and therefore what consoles exist. However if you boot a kernel built this way on a different platform, it will generally crash because it writes to a console that doesn't exist. A particularly nasty instance of this is if you enable the hypervisor console early debug, and then boot that kernel on bare metal. The result is that the kernel calls "the hypervisor" very early in boot, but the kernel *is* the hypervisor, so we jump to the system call handler and start executing all sorts of code that isn't ready to be run. This may lead to a machine check or check stop depending on how lucky you are. Luckily there is an easy way to avoid this particular case. We simply read the MSR before installing the hooks, and if we see MSR_HV is set then we are the hypervisor and we definitely should not use the hypervisor console. Signed-off-by: Michael Ellerman --- drivers/tty/hvc/hvc_vio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index b05dc5086627..6ffbdd8d50c5 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -442,6 +442,14 @@ void __init hvc_vio_init_early(void) #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR void __init udbg_init_debug_lpar(void) { + /* + * If we're running as a hypervisor then we definitely can't call the + * hypervisor to print debug output (we *are* the hypervisor), so don't + * register if we detect that MSR_HV=1. + */ + if (mfmsr() & MSR_HV) + return; + hvterm_privs[0] = &hvterm_priv0; hvterm_priv0.termno = 0; hvterm_priv0.proto = HV_PROTOCOL_RAW; @@ -455,6 +463,10 @@ void __init udbg_init_debug_lpar(void) #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR_HVSI void __init udbg_init_debug_lpar_hvsi(void) { + /* See comment above in udbg_init_debug_lpar() */ + if (mfmsr() & MSR_HV) + return; + hvterm_privs[0] = &hvterm_priv0; hvterm_priv0.termno = CONFIG_PPC_EARLY_DEBUG_HVSI_VTERMNO; hvterm_priv0.proto = HV_PROTOCOL_HVSI; -- cgit From 1ad35f6e2864d9b52fe9705ede1730468c25f692 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Fri, 11 Aug 2017 23:08:45 +0530 Subject: drivers/macintosh: Make wf_control_ops and wf_pid_param const Make wf_control_ops const as they are only stored in the ops field of a wf_control structure, which is const. Make wf_pid_param const as they are only used during a copy operation. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Michael Ellerman --- drivers/macintosh/windfarm_cpufreq_clamp.c | 2 +- drivers/macintosh/windfarm_rm31.c | 4 ++-- drivers/macintosh/windfarm_smu_controls.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c index 72d1fdfe02a5..2626990331dc 100644 --- a/drivers/macintosh/windfarm_cpufreq_clamp.c +++ b/drivers/macintosh/windfarm_cpufreq_clamp.c @@ -63,7 +63,7 @@ static s32 clamp_max(struct wf_control *ct) return 1; } -static struct wf_control_ops clamp_ops = { +static const struct wf_control_ops clamp_ops = { .set_value = clamp_set, .get_value = clamp_get, .get_min = clamp_min, diff --git a/drivers/macintosh/windfarm_rm31.c b/drivers/macintosh/windfarm_rm31.c index bdfcb8a8bfbb..a0cd9c7f9835 100644 --- a/drivers/macintosh/windfarm_rm31.c +++ b/drivers/macintosh/windfarm_rm31.c @@ -338,7 +338,7 @@ static int cpu_setup_pid(int cpu) } /* Backside/U3 fan */ -static struct wf_pid_param backside_param = { +static const struct wf_pid_param backside_param = { .interval = 1, .history_len = 2, .gd = 0x00500000, @@ -351,7 +351,7 @@ static struct wf_pid_param backside_param = { }; /* DIMMs temperature (clamp the backside fan) */ -static struct wf_pid_param dimms_param = { +static const struct wf_pid_param dimms_param = { .interval = 1, .history_len = 20, .gd = 0, diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index c155a54e8638..d174c7437337 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c @@ -145,7 +145,7 @@ static s32 smu_fan_max(struct wf_control *ct) return fct->max; } -static struct wf_control_ops smu_fan_ops = { +static const struct wf_control_ops smu_fan_ops = { .set_value = smu_fan_set, .get_value = smu_fan_get, .get_min = smu_fan_min, -- cgit From fd1335e048a961ef63f7da1a0c8f395eb7bddc22 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 7 Aug 2017 20:09:20 +0000 Subject: block/ps3vram: Delete an error message for a failed memory allocation in ps3vram_cache_init() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Cc: Jim Paris Cc: Jens Axboe Signed-off-by: Geoff Levand Signed-off-by: Michael Ellerman --- drivers/block/ps3vram.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index e0e81cacd781..ba97d037279e 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -409,10 +409,8 @@ static int ps3vram_cache_init(struct ps3_system_bus_device *dev) priv->cache.page_size = CACHE_PAGE_SIZE; priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * CACHE_PAGE_COUNT, GFP_KERNEL); - if (priv->cache.tags == NULL) { - dev_err(&dev->core, "Could not allocate cache tags\n"); + if (!priv->cache.tags) return -ENOMEM; - } dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n", CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); -- cgit From 00e7c259e9c44f414ead5fc9bb3c459d8235045c Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Mon, 7 Aug 2017 20:09:20 +0000 Subject: block/ps3vram: Check return of ps3vram_cache_init Cc: Markus Elfring Cc: Jim Paris Cc: Jens Axboe Signed-off-by: Geoff Levand Signed-off-by: Michael Ellerman --- drivers/block/ps3vram.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index ba97d037279e..6a55959cbf78 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -741,7 +741,11 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev) goto out_unmap_reports; } - ps3vram_cache_init(dev); + error = ps3vram_cache_init(dev); + if (error < 0) { + goto out_unmap_reports; + } + ps3vram_proc_init(dev); queue = blk_alloc_queue(GFP_KERNEL); -- cgit From 0f4bc0932e51817105fdee77a4668069a89581d5 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Thu, 27 Jul 2017 11:54:55 +0530 Subject: powerpc/mm/cxl: Add the fault handling cpu to mm cpumask We use mm cpumask for serializing against lockless page table walk. Anybody who is doing a lockless page table walk is expected to disable irq and only cpus in mm cpumask is expected do the lockless walk. This ensure that a THP split can send IPI to only cpus in the mm cpumask, to make sure there are no parallel lockless page table walk. Add the CAPI fault handling cpu to the mm cpumask so that we can do the lockless page table walk while inserting hash page table entries. Reviewed-by: Frederic Barrat Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- drivers/misc/cxl/fault.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index 6eed7d03e2b5..ab507e4ed69b 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c @@ -138,6 +138,12 @@ int cxl_handle_mm_fault(struct mm_struct *mm, u64 dsisr, u64 dar) int result; unsigned long access, flags, inv_flags = 0; + /* + * Add the fault handling cpu to task mm cpumask so that we + * can do a safe lockless page table walk when inserting the + * hash page table entry. + */ + cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); if ((result = copro_handle_mm_fault(mm, dar, dsisr, &flt))) { pr_devel("copro_handle_mm_fault failed: %#x\n", result); return result; -- cgit From 516fa8d0e19d854253460ea7692551e836e7e2b5 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 19 Jun 2017 11:14:25 +0530 Subject: macintosh/rack-meter: Make of_device_ids const of_device_ids are not supposed to change at runtime. All functions working with of_device_ids provided by work with const of_device_ids. So mark the non-const structs as const. File size before: text data bss dec hex filename 407 576 0 983 3d7 drivers/macintosh/rack-meter.o File size after constify rackmeter_match. text data bss dec hex filename 807 176 0 983 3d7 drivers/macintosh/rack-meter.o Signed-off-by: Arvind Yadav Signed-off-by: Michael Ellerman --- drivers/macintosh/rack-meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index e199fd6c71ce..35582eb271e9 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -579,7 +579,7 @@ static int rackmeter_shutdown(struct macio_dev* mdev) return 0; } -static struct of_device_id rackmeter_match[] = { +static const struct of_device_id rackmeter_match[] = { { .name = "i2s" }, { } }; -- cgit From b6622a339e8670a1025d4dd84be473c76dabed33 Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Mon, 28 Aug 2017 23:23:32 -0700 Subject: powerpc/powernv: Move GET_FIELD/SET_FIELD to vas.h Move the GET_FIELD and SET_FIELD macros to vas.h as VAS and other users of VAS, including NX-842 can use those macros. There is a lot of related code between the VAS/NX kernel drivers and skiboot. For consistency, switch the order of parameters in SET_FIELD to match the order in skiboot. Signed-off-by: Sukadev Bhattiprolu Reviewed-by: Dan Streetman Signed-off-by: Michael Ellerman --- drivers/crypto/nx/nx-842-powernv.c | 7 ++++--- drivers/crypto/nx/nx-842.h | 5 ----- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 1710f80a09ec..3abb045cdba7 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -22,6 +22,7 @@ #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Dan Streetman "); @@ -424,9 +425,9 @@ static int nx842_powernv_function(const unsigned char *in, unsigned int inlen, /* set up CCW */ ccw = 0; - ccw = SET_FIELD(ccw, CCW_CT, nx842_ct); - ccw = SET_FIELD(ccw, CCW_CI_842, 0); /* use 0 for hw auto-selection */ - ccw = SET_FIELD(ccw, CCW_FC_842, fc); + ccw = SET_FIELD(CCW_CT, ccw, nx842_ct); + ccw = SET_FIELD(CCW_CI_842, ccw, 0); /* use 0 for hw auto-selection */ + ccw = SET_FIELD(CCW_FC_842, ccw, fc); /* set up CRB's CSB addr */ csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS; diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h index a4eee3bba937..30929bd7d1a9 100644 --- a/drivers/crypto/nx/nx-842.h +++ b/drivers/crypto/nx/nx-842.h @@ -100,11 +100,6 @@ static inline unsigned long nx842_get_pa(void *addr) return page_to_phys(vmalloc_to_page(addr)) + offset_in_page(addr); } -/* Get/Set bit fields */ -#define MASK_LSH(m) (__builtin_ffsl(m) - 1) -#define GET_FIELD(v, m) (((v) & (m)) >> MASK_LSH(m)) -#define SET_FIELD(v, m, val) (((v) & ~(m)) | (((val) << MASK_LSH(m)) & (m))) - /** * This provides the driver's constraints. Different nx842 implementations * may have varying requirements. The constraints are: -- cgit From 22259a6e800cdb8e06e65432fcd019983214be0c Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 28 Aug 2017 14:05:44 +0530 Subject: powerpc/mm/cxl: Add barrier when setting mm cpumask We need to add memory barrier so that the page table walk doesn't happen before the cpumask is set and made visible to the other cpus. We need to use a sync here instead of lwsync because lwsync is not sufficient for store/load ordering. We also need to add an if (mm) check so that we do the right thing when called with a kernel context. For kernel context, we have mm = NULL. W.r.t kernel address we can skip setting the mm cpumask. Fixes: 0f4bc0932e ("powerpc/mm/cxl: Add the fault handling cpu to mm cpumask") Cc: Andrew Donnellan Reported-by: Benjamin Herrenschmidt Reported-by: Dan Carpenter Signed-off-by: Aneesh Kumar K.V Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- drivers/misc/cxl/fault.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index ab507e4ed69b..f17f72ea0545 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c @@ -141,9 +141,19 @@ int cxl_handle_mm_fault(struct mm_struct *mm, u64 dsisr, u64 dar) /* * Add the fault handling cpu to task mm cpumask so that we * can do a safe lockless page table walk when inserting the - * hash page table entry. + * hash page table entry. This function get called with a + * valid mm for user space addresses. Hence using the if (mm) + * check is sufficient here. */ - cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); + if (mm && !cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) { + cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); + /* + * We need to make sure we walk the table only after + * we update the cpumask. The other side of the barrier + * is explained in serialize_against_pte_lookup() + */ + smp_mb(); + } if ((result = copro_handle_mm_fault(mm, dar, dsisr, &flt))) { pr_devel("copro_handle_mm_fault failed: %#x\n", result); return result; -- cgit From 197267d0356004a31c4d6b6336598f5dff3301e1 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Wed, 30 Aug 2017 12:15:49 +0200 Subject: cxl: Fix driver use count cxl keeps a driver use count, which is used with the hash memory model on p8 to know when to upgrade local TLBIs to global and to trigger callbacks to manage the MMU for PSL8. If a process opens a context and closes without attaching or fails the attachment, the driver use count is never decremented. As a consequence, TLB invalidations remain global, even if there are no active cxl contexts. We should increment the driver use count when the process is attaching to the cxl adapter, and not on open. It's not needed before the adapter starts using the context and the use count is decremented on the detach path, so it makes more sense. It affects only the user api. The kernel api is already doing The Right Thing. Signed-off-by: Frederic Barrat Cc: stable@vger.kernel.org # v4.2+ Fixes: 7bb5d91a4dda ("cxl: Rework context lifetimes") Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 4 ++++ drivers/misc/cxl/file.c | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index 1a138c83f877..a0c44d16bf30 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -336,6 +336,10 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, mmput(ctx->mm); } + /* + * Increment driver use count. Enables global TLBIs for hash + * and callbacks to handle the segment table + */ cxl_ctx_get(); if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) { diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 0761271d68c5..4bfad9f6dc9f 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -95,7 +95,6 @@ static int __afu_open(struct inode *inode, struct file *file, bool master) pr_devel("afu_open pe: %i\n", ctx->pe); file->private_data = ctx; - cxl_ctx_get(); /* indicate success */ rc = 0; @@ -225,6 +224,12 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, if (ctx->mm) mmput(ctx->mm); + /* + * Increment driver use count. Enables global TLBIs for hash + * and callbacks to handle the segment table + */ + cxl_ctx_get(); + trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor, @@ -233,6 +238,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, cxl_adapter_context_put(ctx->afu->adapter); put_pid(ctx->pid); ctx->pid = NULL; + cxl_ctx_put(); cxl_context_mm_count_put(ctx); goto out; } -- cgit From c97f8169fb227cae5adeac56cafa980f25978031 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Thu, 31 Aug 2017 00:11:29 -0700 Subject: crypto/nx: Rename nx842_powernv_function as icswx function Rename nx842_powernv_function to nx842_powernv_exec. nx842_powernv_exec points to nx842_exec_icswx and will be point to VAS exec function which will be added later for P9 NX support. Signed-off-by: Haren Myneni Signed-off-by: Michael Ellerman --- drivers/crypto/nx/nx-842-powernv.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 3abb045cdba7..161987698bbc 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -54,7 +54,11 @@ struct nx842_coproc { /* no cpu hotplug on powernv, so this list never changes after init */ static LIST_HEAD(nx842_coprocs); -static unsigned int nx842_ct; +static unsigned int nx842_ct; /* used in icswx function */ + +static int (*nx842_powernv_exec)(const unsigned char *in, + unsigned int inlen, unsigned char *out, + unsigned int *outlenp, void *workmem, int fc); /** * setup_indirect_dde - Setup an indirect DDE @@ -355,7 +359,7 @@ static int wait_for_csb(struct nx842_workmem *wmem, } /** - * nx842_powernv_function - compress/decompress data using the 842 algorithm + * nx842_exec_icswx - compress/decompress data using the 842 algorithm * * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems. * This compresses or decompresses the provided input buffer into the provided @@ -385,7 +389,7 @@ static int wait_for_csb(struct nx842_workmem *wmem, * -ETIMEDOUT hardware did not complete operation in reasonable time * -EINTR operation was aborted */ -static int nx842_powernv_function(const unsigned char *in, unsigned int inlen, +static int nx842_exec_icswx(const unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlenp, void *workmem, int fc) { @@ -489,13 +493,13 @@ static int nx842_powernv_function(const unsigned char *in, unsigned int inlen, * @workmem: working memory buffer pointer, size determined by * nx842_powernv_driver.workmem_size * - * Returns: see @nx842_powernv_function() + * Returns: see @nx842_powernv_exec() */ static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlenp, void *wmem) { - return nx842_powernv_function(in, inlen, out, outlenp, + return nx842_powernv_exec(in, inlen, out, outlenp, wmem, CCW_FC_842_COMP_CRC); } @@ -517,13 +521,13 @@ static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen, * @workmem: working memory buffer pointer, size determined by * nx842_powernv_driver.workmem_size * - * Returns: see @nx842_powernv_function() + * Returns: see @nx842_powernv_exec() */ static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlenp, void *wmem) { - return nx842_powernv_function(in, inlen, out, outlenp, + return nx842_powernv_exec(in, inlen, out, outlenp, wmem, CCW_FC_842_DECOMP_CRC); } @@ -625,6 +629,8 @@ static __init int nx842_powernv_init(void) if (!nx842_ct) return -ENODEV; + nx842_powernv_exec = nx842_exec_icswx; + ret = crypto_register_alg(&nx842_powernv_alg); if (ret) { struct nx842_coproc *coproc, *n; -- cgit From 56c10d5ea68b9a1425df0dedbe5d2710cc7d8bfa Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Thu, 31 Aug 2017 00:12:22 -0700 Subject: crypto/nx: Create nx842_configure_crb function Configure CRB is moved to nx842_configure_crb() so that it can be used for icswx and VAS exec functions. VAS function will be added later with P9 support. Signed-off-by: Haren Myneni Signed-off-by: Michael Ellerman --- drivers/crypto/nx/nx-842-powernv.c | 57 +++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 161987698bbc..1bd19e03eb7d 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -358,6 +358,40 @@ static int wait_for_csb(struct nx842_workmem *wmem, return 0; } +static int nx842_config_crb(const unsigned char *in, unsigned int inlen, + unsigned char *out, unsigned int outlen, + struct nx842_workmem *wmem) +{ + struct coprocessor_request_block *crb; + struct coprocessor_status_block *csb; + u64 csb_addr; + int ret; + + crb = &wmem->crb; + csb = &crb->csb; + + /* Clear any previous values */ + memset(crb, 0, sizeof(*crb)); + + /* set up DDLs */ + ret = setup_ddl(&crb->source, wmem->ddl_in, + (unsigned char *)in, inlen, true); + if (ret) + return ret; + + ret = setup_ddl(&crb->target, wmem->ddl_out, + out, outlen, false); + if (ret) + return ret; + + /* set up CRB's CSB addr */ + csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS; + csb_addr |= CRB_CSB_AT; /* Addrs are phys */ + crb->csb_addr = cpu_to_be64(csb_addr); + + return 0; +} + /** * nx842_exec_icswx - compress/decompress data using the 842 algorithm * @@ -397,7 +431,6 @@ static int nx842_exec_icswx(const unsigned char *in, unsigned int inlen, struct coprocessor_status_block *csb; struct nx842_workmem *wmem; int ret; - u64 csb_addr; u32 ccw; unsigned int outlen = *outlenp; @@ -411,33 +444,19 @@ static int nx842_exec_icswx(const unsigned char *in, unsigned int inlen, return -ENODEV; } - crb = &wmem->crb; - csb = &crb->csb; - - /* Clear any previous values */ - memset(crb, 0, sizeof(*crb)); - - /* set up DDLs */ - ret = setup_ddl(&crb->source, wmem->ddl_in, - (unsigned char *)in, inlen, true); - if (ret) - return ret; - ret = setup_ddl(&crb->target, wmem->ddl_out, - out, outlen, false); + ret = nx842_config_crb(in, inlen, out, outlen, wmem); if (ret) return ret; + crb = &wmem->crb; + csb = &crb->csb; + /* set up CCW */ ccw = 0; ccw = SET_FIELD(CCW_CT, ccw, nx842_ct); ccw = SET_FIELD(CCW_CI_842, ccw, 0); /* use 0 for hw auto-selection */ ccw = SET_FIELD(CCW_FC_842, ccw, fc); - /* set up CRB's CSB addr */ - csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS; - csb_addr |= CRB_CSB_AT; /* Addrs are phys */ - crb->csb_addr = cpu_to_be64(csb_addr); - wmem->start = ktime_get(); /* do ICSWX */ -- cgit From 1ee51b28ee6ad7919da4fbe9672263dd274dcbfe Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Thu, 31 Aug 2017 00:13:15 -0700 Subject: crypto/nx: Create nx842_delete_coprocs function Move deleting coprocessors info upon exit or failure to nx842_delete_coprocs(). Signed-off-by: Haren Myneni Signed-off-by: Michael Ellerman --- drivers/crypto/nx/nx-842-powernv.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 1bd19e03eb7d..67dc06f9b557 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -593,6 +593,16 @@ static int __init nx842_powernv_probe(struct device_node *dn) return 0; } +static void nx842_delete_coprocs(void) +{ + struct nx842_coproc *coproc, *n; + + list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) { + list_del(&coproc->list); + kfree(coproc); + } +} + static struct nx842_constraints nx842_powernv_constraints = { .alignment = DDE_BUFFER_ALIGN, .multiple = DDE_BUFFER_LAST_MULT, @@ -652,13 +662,7 @@ static __init int nx842_powernv_init(void) ret = crypto_register_alg(&nx842_powernv_alg); if (ret) { - struct nx842_coproc *coproc, *n; - - list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) { - list_del(&coproc->list); - kfree(coproc); - } - + nx842_delete_coprocs(); return ret; } @@ -668,13 +672,8 @@ module_init(nx842_powernv_init); static void __exit nx842_powernv_exit(void) { - struct nx842_coproc *coproc, *n; - crypto_unregister_alg(&nx842_powernv_alg); - list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) { - list_del(&coproc->list); - kfree(coproc); - } + nx842_delete_coprocs(); } module_exit(nx842_powernv_exit); -- cgit From cd38a8a8a2ab95e43a031410db6a32f2d84e3fc0 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Thu, 31 Aug 2017 00:14:06 -0700 Subject: crypto/nx: Add nx842_add_coprocs_list function Updating coprocessor list is moved to nx842_add_coprocs_list(). This function will be used for both icswx and VAS functions. Signed-off-by: Haren Myneni Signed-off-by: Michael Ellerman --- drivers/crypto/nx/nx-842-powernv.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 67dc06f9b557..829b5cad0043 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -550,6 +550,14 @@ static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen, wmem, CCW_FC_842_DECOMP_CRC); } +static inline void nx842_add_coprocs_list(struct nx842_coproc *coproc, + int chipid) +{ + coproc->chip_id = chipid; + INIT_LIST_HEAD(&coproc->list); + list_add(&coproc->list, &nx842_coprocs); +} + static int __init nx842_powernv_probe(struct device_node *dn) { struct nx842_coproc *coproc; @@ -576,11 +584,9 @@ static int __init nx842_powernv_probe(struct device_node *dn) if (!coproc) return -ENOMEM; - coproc->chip_id = chip_id; coproc->ct = ct; coproc->ci = ci; - INIT_LIST_HEAD(&coproc->list); - list_add(&coproc->list, &nx842_coprocs); + nx842_add_coprocs_list(coproc, chip_id); pr_info("coprocessor found on chip %d, CT %d CI %d\n", chip_id, ct, ci); -- cgit From f05368336b3ae399f66cf511c52c6d69c7bc6b39 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Thu, 31 Aug 2017 00:17:25 -0700 Subject: crypto/nx: Use kzalloc for workmem allocation Send window is opened / closed for each crypto session. So initializes txwin in workmem. Signed-off-by: Haren Myneni Signed-off-by: Michael Ellerman --- drivers/crypto/nx/nx-842.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index d94e25df503b..da3cb8c35ec7 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c @@ -116,7 +116,7 @@ int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver) spin_lock_init(&ctx->lock); ctx->driver = driver; - ctx->wmem = kmalloc(driver->workmem_size, GFP_KERNEL); + ctx->wmem = kzalloc(driver->workmem_size, GFP_KERNEL); ctx->sbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER); ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER); if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) { -- cgit From 146e9f1b65478643f2729a97ccb8be60bb4492e5 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Thu, 31 Aug 2017 00:18:18 -0700 Subject: crypto/nx: Add P9 NX specific error codes for 842 engine This patch adds changes for checking P9 specific 842 engine error codes. These errros are reported in coprocessor status block (CSB) for failures. Signed-off-by: Haren Myneni Signed-off-by: Michael Ellerman --- drivers/crypto/nx/nx-842-powernv.c | 18 ++++++++++++++++++ drivers/crypto/nx/nx-842.h | 8 ++++++++ 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 829b5cad0043..c0dd4c7e17d3 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -243,6 +243,13 @@ static int wait_for_csb(struct nx842_workmem *wmem, case CSB_CC_TEMPL_OVERFLOW: CSB_ERR(csb, "Compressed data template shows data past end"); return -EINVAL; + case CSB_CC_EXCEED_BYTE_COUNT: /* P9 or later */ + /* + * DDE byte count exceeds the limit specified in Maximum + * byte count register. + */ + CSB_ERR(csb, "DDE byte count exceeds the limit"); + return -EINVAL; /* these should not happen */ case CSB_CC_INVALID_ALIGN: @@ -284,9 +291,17 @@ static int wait_for_csb(struct nx842_workmem *wmem, CSB_ERR(csb, "Too many DDEs in DDL"); return -EINVAL; case CSB_CC_TRANSPORT: + case CSB_CC_INVALID_CRB: /* P9 or later */ /* shouldn't happen, we setup CRB correctly */ CSB_ERR(csb, "Invalid CRB"); return -EINVAL; + case CSB_CC_INVALID_DDE: /* P9 or later */ + /* + * shouldn't happen, setup_direct/indirect_dde creates + * DDE right + */ + CSB_ERR(csb, "Invalid DDE"); + return -EINVAL; case CSB_CC_SEGMENTED_DDL: /* shouldn't happen, setup_ddl creates DDL right */ CSB_ERR(csb, "Segmented DDL error"); @@ -330,6 +345,9 @@ static int wait_for_csb(struct nx842_workmem *wmem, case CSB_CC_HW: CSB_ERR(csb, "Correctable hardware error"); return -EPROTO; + case CSB_CC_HW_EXPIRED_TIMER: /* P9 or later */ + CSB_ERR(csb, "Job did not finish within allowed time"); + return -EPROTO; default: CSB_ERR(csb, "Invalid CC %d", csb->cc); diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h index 30929bd7d1a9..bb2f31792683 100644 --- a/drivers/crypto/nx/nx-842.h +++ b/drivers/crypto/nx/nx-842.h @@ -76,9 +76,17 @@ #define CSB_CC_DECRYPT_OVERFLOW (64) /* asym crypt codes */ #define CSB_CC_MINV_OVERFLOW (128) +/* + * HW error - Job did not finish in the maximum time allowed. + * Job terminated. + */ +#define CSB_CC_HW_EXPIRED_TIMER (224) /* These are reserved for hypervisor use */ #define CSB_CC_HYP_RESERVE_START (240) #define CSB_CC_HYP_RESERVE_END (253) +#define CSB_CC_HYP_RESERVE_P9_END (251) +/* No valid interrupt server (P9 or later). */ +#define CSB_CC_HYP_RESERVE_NO_INTR_SERVER (252) #define CSB_CC_HYP_NO_HW (254) #define CSB_CC_HYP_HANG_ABORTED (255) -- cgit From b0d6c9bab5e41d07f2bece1ef8c81cd2175b5f88 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Thu, 31 Aug 2017 00:19:07 -0700 Subject: crypto/nx: Add P9 NX support for 842 compression engine This patch adds P9 NX support for 842 compression engine. Virtual Accelerator Switchboard (VAS) is used to access 842 engine on P9. For each NX engine per chip, setup receive window using vas_rx_win_open() which configures RxFIFo with FIFO address, lpid, pid and tid values. This unique (lpid, pid, tid) combination will be used to identify the target engine. For crypto open request, open send window on the NX engine for the corresponding chip / cpu where the open request is executed. This send window will be closed upon crypto close request. NX provides high and normal priority FIFOs. For compression / decompression requests, we use only hight priority FIFOs in kernel. Each NX request will be communicated to VAS using copy/paste instructions with vas_copy_crb() / vas_paste_crb() functions. Signed-off-by: Haren Myneni Reviewed-by: Ram Pai Signed-off-by: Michael Ellerman --- drivers/crypto/nx/Kconfig | 1 + drivers/crypto/nx/nx-842-powernv.c | 377 ++++++++++++++++++++++++++++++++++++- 2 files changed, 372 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/nx/Kconfig b/drivers/crypto/nx/Kconfig index ad7552a6998c..cd5dda9c48f4 100644 --- a/drivers/crypto/nx/Kconfig +++ b/drivers/crypto/nx/Kconfig @@ -38,6 +38,7 @@ config CRYPTO_DEV_NX_COMPRESS_PSERIES config CRYPTO_DEV_NX_COMPRESS_POWERNV tristate "Compression acceleration support on PowerNV platform" depends on PPC_POWERNV + depends on PPC_VAS default y help Support for PowerPC Nest (NX) compression acceleration. This diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index c0dd4c7e17d3..874ddf5e9087 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -23,6 +23,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Dan Streetman "); @@ -32,6 +33,9 @@ MODULE_ALIAS_CRYPTO("842-nx"); #define WORKMEM_ALIGN (CRB_ALIGN) #define CSB_WAIT_MAX (5000) /* ms */ +#define VAS_RETRIES (10) +/* # of requests allowed per RxFIFO at a time. 0 for unlimited */ +#define MAX_CREDITS_PER_RXFIFO (1024) struct nx842_workmem { /* Below fields must be properly aligned */ @@ -42,16 +46,27 @@ struct nx842_workmem { ktime_t start; + struct vas_window *txwin; /* Used with VAS function */ char padding[WORKMEM_ALIGN]; /* unused, to allow alignment */ } __packed __aligned(WORKMEM_ALIGN); struct nx842_coproc { unsigned int chip_id; unsigned int ct; - unsigned int ci; + unsigned int ci; /* Coprocessor instance, used with icswx */ + struct { + struct vas_window *rxwin; + int id; + } vas; struct list_head list; }; +/* + * Send the request to NX engine on the chip for the corresponding CPU + * where the process is executing. Use with VAS function. + */ +static DEFINE_PER_CPU(struct nx842_coproc *, coproc_inst); + /* no cpu hotplug on powernv, so this list never changes after init */ static LIST_HEAD(nx842_coprocs); static unsigned int nx842_ct; /* used in icswx function */ @@ -512,6 +527,104 @@ static int nx842_exec_icswx(const unsigned char *in, unsigned int inlen, return ret; } +/** + * nx842_exec_vas - compress/decompress data using the 842 algorithm + * + * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems. + * This compresses or decompresses the provided input buffer into the provided + * output buffer. + * + * Upon return from this function @outlen contains the length of the + * output data. If there is an error then @outlen will be 0 and an + * error will be specified by the return code from this function. + * + * The @workmem buffer should only be used by one function call at a time. + * + * @in: input buffer pointer + * @inlen: input buffer size + * @out: output buffer pointer + * @outlenp: output buffer size pointer + * @workmem: working memory buffer pointer, size determined by + * nx842_powernv_driver.workmem_size + * @fc: function code, see CCW Function Codes in nx-842.h + * + * Returns: + * 0 Success, output of length @outlenp stored in the buffer + * at @out + * -ENODEV Hardware unavailable + * -ENOSPC Output buffer is to small + * -EMSGSIZE Input buffer too large + * -EINVAL buffer constraints do not fix nx842_constraints + * -EPROTO hardware error during operation + * -ETIMEDOUT hardware did not complete operation in reasonable time + * -EINTR operation was aborted + */ +static int nx842_exec_vas(const unsigned char *in, unsigned int inlen, + unsigned char *out, unsigned int *outlenp, + void *workmem, int fc) +{ + struct coprocessor_request_block *crb; + struct coprocessor_status_block *csb; + struct nx842_workmem *wmem; + struct vas_window *txwin; + int ret, i = 0; + u32 ccw; + unsigned int outlen = *outlenp; + + wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN); + + *outlenp = 0; + + crb = &wmem->crb; + csb = &crb->csb; + + ret = nx842_config_crb(in, inlen, out, outlen, wmem); + if (ret) + return ret; + + ccw = 0; + ccw = SET_FIELD(CCW_FC_842, ccw, fc); + crb->ccw = cpu_to_be32(ccw); + + txwin = wmem->txwin; + /* shoudn't happen, we don't load without a coproc */ + if (!txwin) { + pr_err_ratelimited("NX-842 coprocessor is not available"); + return -ENODEV; + } + + do { + wmem->start = ktime_get(); + preempt_disable(); + /* + * VAS copy CRB into L2 cache. Refer . + * @crb and @offset. + */ + vas_copy_crb(crb, 0); + + /* + * VAS paste previously copied CRB to NX. + * @txwin, @offset and @last (must be true). + */ + ret = vas_paste_crb(txwin, 0, 1); + preempt_enable(); + /* + * Retry copy/paste function for VAS failures. + */ + } while (ret && (i++ < VAS_RETRIES)); + + if (ret) { + pr_err_ratelimited("VAS copy/paste failed\n"); + return ret; + } + + ret = wait_for_csb(wmem, csb); + if (!ret) + *outlenp = be32_to_cpu(csb->count); + + return ret; +} + /** * nx842_powernv_compress - Compress data using the 842 algorithm * @@ -576,6 +689,201 @@ static inline void nx842_add_coprocs_list(struct nx842_coproc *coproc, list_add(&coproc->list, &nx842_coprocs); } +/* + * Identify chip ID for each CPU and save coprocesor adddress for the + * corresponding NX engine in percpu coproc_inst. + * coproc_inst is used in crypto_init to open send window on the NX instance + * for the corresponding CPU / chip where the open request is executed. + */ +static void nx842_set_per_cpu_coproc(struct nx842_coproc *coproc) +{ + unsigned int i, chip_id; + + for_each_possible_cpu(i) { + chip_id = cpu_to_chip_id(i); + + if (coproc->chip_id == chip_id) + per_cpu(coproc_inst, i) = coproc; + } +} + + +static struct vas_window *nx842_alloc_txwin(struct nx842_coproc *coproc) +{ + struct vas_window *txwin = NULL; + struct vas_tx_win_attr txattr; + + /* + * Kernel requests will be high priority. So open send + * windows only for high priority RxFIFO entries. + */ + vas_init_tx_win_attr(&txattr, coproc->ct); + txattr.lpid = 0; /* lpid is 0 for kernel requests */ + txattr.pid = 0; /* pid is 0 for kernel requests */ + + /* + * Open a VAS send window which is used to send request to NX. + */ + txwin = vas_tx_win_open(coproc->vas.id, coproc->ct, &txattr); + if (IS_ERR(txwin)) { + pr_err("ibm,nx-842: Can not open TX window: %ld\n", + PTR_ERR(txwin)); + return NULL; + } + + return txwin; +} + +static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id, + int vasid) +{ + struct vas_window *rxwin = NULL; + struct vas_rx_win_attr rxattr; + struct nx842_coproc *coproc; + u32 lpid, pid, tid, fifo_size; + u64 rx_fifo; + const char *priority; + int ret; + + ret = of_property_read_u64(dn, "rx-fifo-address", &rx_fifo); + if (ret) { + pr_err("Missing rx-fifo-address property\n"); + return ret; + } + + ret = of_property_read_u32(dn, "rx-fifo-size", &fifo_size); + if (ret) { + pr_err("Missing rx-fifo-size property\n"); + return ret; + } + + ret = of_property_read_u32(dn, "lpid", &lpid); + if (ret) { + pr_err("Missing lpid property\n"); + return ret; + } + + ret = of_property_read_u32(dn, "pid", &pid); + if (ret) { + pr_err("Missing pid property\n"); + return ret; + } + + ret = of_property_read_u32(dn, "tid", &tid); + if (ret) { + pr_err("Missing tid property\n"); + return ret; + } + + ret = of_property_read_string(dn, "priority", &priority); + if (ret) { + pr_err("Missing priority property\n"); + return ret; + } + + coproc = kzalloc(sizeof(*coproc), GFP_KERNEL); + if (!coproc) + return -ENOMEM; + + if (!strcmp(priority, "High")) + coproc->ct = VAS_COP_TYPE_842_HIPRI; + else if (!strcmp(priority, "Normal")) + coproc->ct = VAS_COP_TYPE_842; + else { + pr_err("Invalid RxFIFO priority value\n"); + ret = -EINVAL; + goto err_out; + } + + vas_init_rx_win_attr(&rxattr, coproc->ct); + rxattr.rx_fifo = (void *)rx_fifo; + rxattr.rx_fifo_size = fifo_size; + rxattr.lnotify_lpid = lpid; + rxattr.lnotify_pid = pid; + rxattr.lnotify_tid = tid; + rxattr.wcreds_max = MAX_CREDITS_PER_RXFIFO; + + /* + * Open a VAS receice window which is used to configure RxFIFO + * for NX. + */ + rxwin = vas_rx_win_open(vasid, coproc->ct, &rxattr); + if (IS_ERR(rxwin)) { + ret = PTR_ERR(rxwin); + pr_err("setting RxFIFO with VAS failed: %d\n", + ret); + goto err_out; + } + + coproc->vas.rxwin = rxwin; + coproc->vas.id = vasid; + nx842_add_coprocs_list(coproc, chip_id); + + /* + * Kernel requests use only high priority FIFOs. So save coproc + * info in percpu coproc_inst which will be used to open send + * windows for crypto open requests later. + */ + if (coproc->ct == VAS_COP_TYPE_842_HIPRI) + nx842_set_per_cpu_coproc(coproc); + + return 0; + +err_out: + kfree(coproc); + return ret; +} + + +static int __init nx842_powernv_probe_vas(struct device_node *pn) +{ + struct device_node *dn; + int chip_id, vasid, ret = 0; + int nx_fifo_found = 0; + + chip_id = of_get_ibm_chip_id(pn); + if (chip_id < 0) { + pr_err("ibm,chip-id missing\n"); + return -EINVAL; + } + + for_each_compatible_node(dn, NULL, "ibm,power9-vas-x") { + if (of_get_ibm_chip_id(dn) == chip_id) + break; + } + + if (!dn) { + pr_err("Missing VAS device node\n"); + return -EINVAL; + } + + if (of_property_read_u32(dn, "ibm,vas-id", &vasid)) { + pr_err("Missing ibm,vas-id device property\n"); + of_node_put(dn); + return -EINVAL; + } + + of_node_put(dn); + + for_each_child_of_node(pn, dn) { + if (of_device_is_compatible(dn, "ibm,p9-nx-842")) { + ret = vas_cfg_coproc_info(dn, chip_id, vasid); + if (ret) { + of_node_put(dn); + return ret; + } + nx_fifo_found++; + } + } + + if (!nx_fifo_found) { + pr_err("NX842 FIFO nodes are missing\n"); + ret = -EINVAL; + } + + return ret; +} + static int __init nx842_powernv_probe(struct device_node *dn) { struct nx842_coproc *coproc; @@ -622,6 +930,9 @@ static void nx842_delete_coprocs(void) struct nx842_coproc *coproc, *n; list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) { + if (coproc->vas.rxwin) + vas_win_close(coproc->vas.rxwin); + list_del(&coproc->list); kfree(coproc); } @@ -643,6 +954,46 @@ static struct nx842_driver nx842_powernv_driver = { .decompress = nx842_powernv_decompress, }; +static int nx842_powernv_crypto_init_vas(struct crypto_tfm *tfm) +{ + struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm); + struct nx842_workmem *wmem; + struct nx842_coproc *coproc; + int ret; + + ret = nx842_crypto_init(tfm, &nx842_powernv_driver); + + if (ret) + return ret; + + wmem = PTR_ALIGN((struct nx842_workmem *)ctx->wmem, WORKMEM_ALIGN); + coproc = per_cpu(coproc_inst, smp_processor_id()); + + ret = -EINVAL; + if (coproc && coproc->vas.rxwin) { + wmem->txwin = nx842_alloc_txwin(coproc); + if (!IS_ERR(wmem->txwin)) + return 0; + + ret = PTR_ERR(wmem->txwin); + } + + return ret; +} + +void nx842_powernv_crypto_exit_vas(struct crypto_tfm *tfm) +{ + struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm); + struct nx842_workmem *wmem; + + wmem = PTR_ALIGN((struct nx842_workmem *)ctx->wmem, WORKMEM_ALIGN); + + if (wmem && wmem->txwin) + vas_win_close(wmem->txwin); + + nx842_crypto_exit(tfm); +} + static int nx842_powernv_crypto_init(struct crypto_tfm *tfm) { return nx842_crypto_init(tfm, &nx842_powernv_driver); @@ -676,13 +1027,27 @@ static __init int nx842_powernv_init(void) BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT); BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT); - for_each_compatible_node(dn, NULL, "ibm,power-nx") - nx842_powernv_probe(dn); + for_each_compatible_node(dn, NULL, "ibm,power9-nx") { + ret = nx842_powernv_probe_vas(dn); + if (ret) { + nx842_delete_coprocs(); + return ret; + } + } - if (!nx842_ct) - return -ENODEV; + if (list_empty(&nx842_coprocs)) { + for_each_compatible_node(dn, NULL, "ibm,power-nx") + nx842_powernv_probe(dn); + + if (!nx842_ct) + return -ENODEV; - nx842_powernv_exec = nx842_exec_icswx; + nx842_powernv_exec = nx842_exec_icswx; + } else { + nx842_powernv_exec = nx842_exec_vas; + nx842_powernv_alg.cra_init = nx842_powernv_crypto_init_vas; + nx842_powernv_alg.cra_exit = nx842_powernv_crypto_exit_vas; + } ret = crypto_register_alg(&nx842_powernv_alg); if (ret) { -- cgit From 859420e3155d8192b31a93cd92d32c85151bf8da Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:07 -0500 Subject: ide: pmac: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Cc: "David S. Miller" Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: linux-ide@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Acked-by: David S. Miller Signed-off-by: Michael Ellerman --- drivers/ide/pmac.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 0c5d3a99468e..c5b902b86b44 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -1145,8 +1145,8 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, return -ENOMEM; if (macio_resource_count(mdev) == 0) { - printk(KERN_WARNING "ide-pmac: no address for %s\n", - mdev->ofdev.dev.of_node->full_name); + printk(KERN_WARNING "ide-pmac: no address for %pOF\n", + mdev->ofdev.dev.of_node); rc = -ENXIO; goto out_free_pmif; } @@ -1154,7 +1154,7 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, /* Request memory resource for IO ports */ if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { printk(KERN_ERR "ide-pmac: can't request MMIO resource for " - "%s!\n", mdev->ofdev.dev.of_node->full_name); + "%pOF!\n", mdev->ofdev.dev.of_node); rc = -EBUSY; goto out_free_pmif; } @@ -1165,8 +1165,8 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, * where that happens though... */ if (macio_irq_count(mdev) == 0) { - printk(KERN_WARNING "ide-pmac: no intrs for device %s, using " - "13\n", mdev->ofdev.dev.of_node->full_name); + printk(KERN_WARNING "ide-pmac: no intrs for device %pOF, using " + "13\n", mdev->ofdev.dev.of_node); irq = irq_create_mapping(NULL, 13); } else irq = macio_irq(mdev, 0); @@ -1183,8 +1183,8 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, if (macio_resource_count(mdev) >= 2) { if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) printk(KERN_WARNING "ide-pmac: can't request DMA " - "resource for %s!\n", - mdev->ofdev.dev.of_node->full_name); + "resource for %pOF!\n", + mdev->ofdev.dev.of_node); else pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); } else @@ -1274,7 +1274,7 @@ static int pmac_ide_pci_attach(struct pci_dev *pdev, if (pci_enable_device(pdev)) { printk(KERN_WARNING "ide-pmac: Can't enable PCI device for " - "%s\n", np->full_name); + "%pOF\n", np); rc = -ENXIO; goto out_free_pmif; } @@ -1282,7 +1282,7 @@ static int pmac_ide_pci_attach(struct pci_dev *pdev, if (pci_request_regions(pdev, "Kauai ATA")) { printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources for " - "%s\n", np->full_name); + "%pOF\n", np); rc = -ENXIO; goto out_free_pmif; } -- cgit From b6a945ae03fd3962b51b27ecedf4f1dd7e034229 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:12 -0500 Subject: macintosh: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring [mpe: Also convert the two cases inside #if 0] Signed-off-by: Michael Ellerman --- drivers/macintosh/macio_sysfs.c | 2 +- drivers/macintosh/rack-meter.c | 12 ++++++------ drivers/macintosh/smu.c | 8 ++++---- drivers/macintosh/via-cuda.c | 4 ++-- drivers/macintosh/windfarm_fcu_controls.c | 4 ++-- drivers/macintosh/windfarm_lm87_sensor.c | 4 ++-- drivers/macintosh/windfarm_smu_sat.c | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 2445274f7e4b..281f5345661e 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -52,7 +52,7 @@ static ssize_t devspec_show(struct device *dev, struct platform_device *ofdev; ofdev = to_platform_device(dev); - return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); + return sprintf(buf, "%pOF\n", ofdev->dev.of_node); } static DEVICE_ATTR_RO(modalias); static DEVICE_ATTR_RO(devspec); diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 35582eb271e9..910b5b6f96b1 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -411,16 +411,16 @@ static int rackmeter_probe(struct macio_dev* mdev, #if 0 /* Use that when i2s-a is finally an mdev per-se */ if (macio_resource_count(mdev) < 2 || macio_irq_count(mdev) < 2) { printk(KERN_ERR - "rackmeter: found match but lacks resources: %s" + "rackmeter: found match but lacks resources: %pOF" " (%d resources, %d interrupts)\n", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node); rc = -ENXIO; goto bail_free; } if (macio_request_resources(mdev, "rackmeter")) { printk(KERN_ERR - "rackmeter: failed to request resources: %s\n", - mdev->ofdev.node->full_name); + "rackmeter: failed to request resources: %pOF\n", + mdev->ofdev.dev.of_node); rc = -EBUSY; goto bail_free; } @@ -431,8 +431,8 @@ static int rackmeter_probe(struct macio_dev* mdev, of_address_to_resource(i2s, 0, &ri2s) || of_address_to_resource(i2s, 1, &rdma)) { printk(KERN_ERR - "rackmeter: found match but lacks resources: %s", - mdev->ofdev.dev.of_node->full_name); + "rackmeter: found match but lacks resources: %pOF", + mdev->ofdev.dev.of_node); rc = -ENXIO; goto bail_free; } diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 1ac66421877a..ea9bdc85a21d 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -589,14 +589,14 @@ static int smu_late_init(void) if (smu->db_node) { smu->db_irq = irq_of_parse_and_map(smu->db_node, 0); if (!smu->db_irq) - printk(KERN_ERR "smu: failed to map irq for node %s\n", - smu->db_node->full_name); + printk(KERN_ERR "smu: failed to map irq for node %pOF\n", + smu->db_node); } if (smu->msg_node) { smu->msg_irq = irq_of_parse_and_map(smu->msg_node, 0); if (!smu->msg_irq) - printk(KERN_ERR "smu: failed to map irq for node %s\n", - smu->msg_node->full_name); + printk(KERN_ERR "smu: failed to map irq for node %pOF\n", + smu->msg_node); } /* diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index c60415958dfe..147da4edd021 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -297,8 +297,8 @@ static int __init via_cuda_start(void) #else cuda_irq = irq_of_parse_and_map(vias, 0); if (!cuda_irq) { - printk(KERN_ERR "via-cuda: can't map interrupts for %s\n", - vias->full_name); + printk(KERN_ERR "via-cuda: can't map interrupts for %pOF\n", + vias); return -ENODEV; } #endif diff --git a/drivers/macintosh/windfarm_fcu_controls.c b/drivers/macintosh/windfarm_fcu_controls.c index 0226b796a21c..fab7a21e9577 100644 --- a/drivers/macintosh/windfarm_fcu_controls.c +++ b/drivers/macintosh/windfarm_fcu_controls.c @@ -470,8 +470,8 @@ static void wf_fcu_lookup_fans(struct wf_fcu_priv *pv) id = ((*reg) - 0x30) / 2; if (id > 7) { pr_warning("wf_fcu: Can't parse " - "fan ID in device-tree for %s\n", - np->full_name); + "fan ID in device-tree for %pOF\n", + np); break; } wf_fcu_add_fan(pv, name, type, id); diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c index c071aab79dd1..913c4bfeef94 100644 --- a/drivers/macintosh/windfarm_lm87_sensor.c +++ b/drivers/macintosh/windfarm_lm87_sensor.c @@ -126,8 +126,8 @@ static int wf_lm87_probe(struct i2c_client *client, } } if (!name) { - pr_warning("wf_lm87: Unsupported sensor %s\n", - client->dev.of_node->full_name); + pr_warning("wf_lm87: Unsupported sensor %pOF\n", + client->dev.of_node); return -ENODEV; } diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index ad6223e88340..e9c828bf171b 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -248,7 +248,7 @@ static int wf_sat_probe(struct i2c_client *client, core = loc[5] - '0'; if (chip > 1 || core > 1) { printk(KERN_ERR "wf_sat_create: don't understand " - "location %s for %s\n", loc, child->full_name); + "location %s for %pOF\n", loc, child); continue; } cpu = 2 * chip + core; -- cgit From de854e54d79bc0ad5c45c5be50821b1c0639cb75 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 2 Aug 2017 23:01:45 +0200 Subject: powerpc/macintosh: constify wf_sensor_ops structures The wf_sensor_ops structures are only stored in the ops field of a wf_sensor structure, which is declared as const. Thus the wf_sensor_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct wf_sensor_ops i@p = { ... }; @ok1@ identifier r.i; struct wf_sensor s; position p; @@ s.ops = &i@p @ok2@ identifier r.i; struct wf_sat_sensor s; position p; @@ s.sens.ops = &i@p @bad@ position p != {r.p,ok1.p,ok2.p}; identifier r.i; struct wf_sensor_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct wf_sensor_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Michael Ellerman --- drivers/macintosh/windfarm_lm75_sensor.c | 2 +- drivers/macintosh/windfarm_lm87_sensor.c | 2 +- drivers/macintosh/windfarm_max6690_sensor.c | 2 +- drivers/macintosh/windfarm_smu_sat.c | 2 +- drivers/macintosh/windfarm_smu_sensors.c | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 590214ba736c..6cdfe714901d 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -82,7 +82,7 @@ static void wf_lm75_release(struct wf_sensor *sr) kfree(lm); } -static struct wf_sensor_ops wf_lm75_ops = { +static const struct wf_sensor_ops wf_lm75_ops = { .get_value = wf_lm75_get, .release = wf_lm75_release, .owner = THIS_MODULE, diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c index 913c4bfeef94..35aa571d498a 100644 --- a/drivers/macintosh/windfarm_lm87_sensor.c +++ b/drivers/macintosh/windfarm_lm87_sensor.c @@ -91,7 +91,7 @@ static void wf_lm87_release(struct wf_sensor *sr) kfree(lm); } -static struct wf_sensor_ops wf_lm87_ops = { +static const struct wf_sensor_ops wf_lm87_ops = { .get_value = wf_lm87_get, .release = wf_lm87_release, .owner = THIS_MODULE, diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index 87e439b10318..6ad035e13c08 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -55,7 +55,7 @@ static void wf_max6690_release(struct wf_sensor *sr) kfree(max); } -static struct wf_sensor_ops wf_max6690_ops = { +static const struct wf_sensor_ops wf_max6690_ops = { .get_value = wf_max6690_get, .release = wf_max6690_release, .owner = THIS_MODULE, diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index e9c828bf171b..da7f4fc1a51d 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -195,7 +195,7 @@ static void wf_sat_sensor_release(struct wf_sensor *sr) kref_put(&sat->ref, wf_sat_release); } -static struct wf_sensor_ops wf_sat_ops = { +static const struct wf_sensor_ops wf_sat_ops = { .get_value = wf_sat_sensor_get, .release = wf_sat_sensor_release, .owner = THIS_MODULE, diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index 1cc4e4953d89..172fd267dcf6 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c @@ -172,22 +172,22 @@ static int smu_slotspow_get(struct wf_sensor *sr, s32 *value) } -static struct wf_sensor_ops smu_cputemp_ops = { +static const struct wf_sensor_ops smu_cputemp_ops = { .get_value = smu_cputemp_get, .release = smu_ads_release, .owner = THIS_MODULE, }; -static struct wf_sensor_ops smu_cpuamp_ops = { +static const struct wf_sensor_ops smu_cpuamp_ops = { .get_value = smu_cpuamp_get, .release = smu_ads_release, .owner = THIS_MODULE, }; -static struct wf_sensor_ops smu_cpuvolt_ops = { +static const struct wf_sensor_ops smu_cpuvolt_ops = { .get_value = smu_cpuvolt_get, .release = smu_ads_release, .owner = THIS_MODULE, }; -static struct wf_sensor_ops smu_slotspow_ops = { +static const struct wf_sensor_ops smu_slotspow_ops = { .get_value = smu_slotspow_get, .release = smu_ads_release, .owner = THIS_MODULE, @@ -327,7 +327,7 @@ static int smu_cpu_power_get(struct wf_sensor *sr, s32 *value) return 0; } -static struct wf_sensor_ops smu_cpu_power_ops = { +static const struct wf_sensor_ops smu_cpu_power_ops = { .get_value = smu_cpu_power_get, .release = smu_cpu_power_release, .owner = THIS_MODULE, -- cgit