Re: [PATCH 1/2] crypto: Make hwrng choose rng source by quality.
Hi Harald, Can you split this patch into two? One patch to choose rng based on the quality and another for not overriding user decided rng. Some more minor comments below. On 29 June 2017 at 15:33, Harald Freudenbergerwrote: > The hwrng core implementation currently doesn't consider the > quality field of the struct hwrng. So the first registered rng > is the winner and further rng sources even with much better > quality are ignored. > > The behavior should be that always the best rng with the highest > quality rate should be used as current rng source. Only if the > user explicitly chooses a rng source (via writing a rng name > to /sys/class/misc/hw_random) the decision for the best quality > should be suppressed. > > This patch makes hwrng always hold a list of registered rng > sources sorted decreasing by quality. On registration of a new > hwrng source the list is updated and if the current rng source > was not chosen by user and the new rng provides better quality > set as new current rng source. Similar on unregistration of an > rng, if it was the current used rng source the one with the > next highest quality is used. If a rng source has been set via > sysfs from userland as long as this one doesn't unregister > it is kept as current rng regardless of registration of 'better' > rng sources. Nice to see the patch. This is indeed required. > Signed-off-by: Harald Freudenberger > --- > drivers/char/hw_random/core.c | 31 +-- > 1 file changed, 25 insertions(+), 6 deletions(-) > > diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c > index 503a41d..7fe47f8 100644 > --- a/drivers/char/hw_random/core.c > +++ b/drivers/char/hw_random/core.c > @@ -28,7 +28,10 @@ > #define RNG_MODULE_NAME"hw_random" > > static struct hwrng *current_rng; > +/* the current rng has been explicitly chosen by user via sysfs */ > +static int cur_rng_set_by_user; Letting the user know that the current rng was selected based on user input would be a good option I guess. Any thoughts on this? > static struct task_struct *hwrng_fill; > +/* list of registered rngs, sorted decending by quality */ > static LIST_HEAD(rng_list); > /* Protects rng_list and current_rng */ > static DEFINE_MUTEX(rng_mutex); > @@ -308,6 +311,8 @@ static ssize_t hwrng_attr_current_store(struct device > *dev, > break; > } > } > + if (!err) > + cur_rng_set_by_user = 1; This can be put inside the loop. The if condition will go away in that case. > mutex_unlock(_mutex); > > return err ? : len; > @@ -417,6 +422,7 @@ int hwrng_register(struct hwrng *rng) > { > int err = -EINVAL; > struct hwrng *old_rng, *tmp; > + struct list_head *ptr; Any better name instead of ptr? > if (!rng->name || (!rng->data_read && !rng->read)) > goto out; > @@ -432,14 +438,26 @@ int hwrng_register(struct hwrng *rng) > init_completion(>cleanup_done); > complete(>cleanup_done); > > + /* rng_list is sorted by decreasing quality */ > + list_for_each(ptr, _list) { > + tmp = list_entry(ptr, struct hwrng, list); > + if (tmp->quality < rng->quality) > + break; > + } > + list_add_tail(>list, ptr); > + > old_rng = current_rng; > err = 0; > - if (!old_rng) { > + if (!old_rng || > + (!cur_rng_set_by_user && rng->quality > old_rng->quality)) { > + /* > +* Set new rng as current if no current rng or rng was > +* not chosen by user and the new one has better quality. > +*/ > err = set_current_rng(rng); > if (err) > goto out_unlock; > } > - list_add_tail(>list, _list); > > if (old_rng && !rng->init) { > /* > @@ -466,12 +484,13 @@ void hwrng_unregister(struct hwrng *rng) > list_del(>list); > if (current_rng == rng) { > drop_current_rng(); > + cur_rng_set_by_user = 0; > + /* rng_list is sorted by quality, use the best (=first) one */ > if (!list_empty(_list)) { > - struct hwrng *tail; > - > - tail = list_entry(rng_list.prev, struct hwrng, list); > + struct hwrng *new_rng; > > - set_current_rng(tail); > + new_rng = list_entry(rng_list.next, struct hwrng, > list); > + set_current_rng(new_rng); > } > } > > -- > 2.7.4 > This patch looks good. I am fine with this patch as is. Reviewed-by: PrasannaKumar Muralidharan If this patch is split into please go ahead and my reviewed-by tag. Regards, PrasannaKumar
[PATCH] crypto: arm64/gcm - implement native driver using v8 Crypto Extensions
Currently, the AES-GCM implementation for arm64 systems that support the ARMv8 Crypto Extensions is based on the generic GCM module, which combines the AES-CTR implementation using AES instructions with the PMULL based GHASH driver. This is suboptimal, given the fact that the input data needs to be loaded twice, once for the encryption and again for the MAC calculation. On Cortex-A57 (r1p2) and other recent cores that implement micro-op fusing for the AES instructions, AES executes at less than 1 cycle per byte, which means that any cycles wasted on loading the data twice hurt even more. So implement a new GCM driver that combines the AES and PMULL instructions at the block level. This improves performance on Cortex-A57 by ~27% (from 3.5 cpb to 2.6 cpb) Signed-off-by: Ard Biesheuvel--- Raw numbers measured on a 2GHz AMD Overdrive B1 can be found after he patch. arch/arm64/crypto/ghash-ce-core.S | 177 ++ arch/arm64/crypto/ghash-ce-glue.c | 348 +++- 2 files changed, 515 insertions(+), 10 deletions(-) diff --git a/arch/arm64/crypto/ghash-ce-core.S b/arch/arm64/crypto/ghash-ce-core.S index f0bb9f0b524f..7f0c7271c569 100644 --- a/arch/arm64/crypto/ghash-ce-core.S +++ b/arch/arm64/crypto/ghash-ce-core.S @@ -77,3 +77,180 @@ CPU_LE( rev64 T1.16b, T1.16b ) st1 {XL.2d}, [x1] ret ENDPROC(pmull_ghash_update) + + KS .reqv8 + CTR .reqv9 + INP .reqv10 + + .macro load_round_keys, rounds, rk + cmp \rounds, #12 + blo f /* 128 bits */ + beq f /* 192 bits */ + ld1 {v17.16b-v18.16b}, [\rk], #32 +: ld1 {v19.16b-v20.16b}, [\rk], #32 +: ld1 {v21.16b-v24.16b}, [\rk], #64 + ld1 {v25.16b-v28.16b}, [\rk], #64 + ld1 {v29.16b-v31.16b}, [\rk] + .endm + + .macro enc_round, state, key + aese\state\().16b, \key\().16b + aesmc \state\().16b, \state\().16b + .endm + + .macro enc_block, state, rounds + cmp \rounds, #12 + b.lof /* 128 bits */ + b.eqf /* 192 bits */ + enc_round \state, v17 + enc_round \state, v18 +: enc_round \state, v19 + enc_round \state, v20 +: .irpkey, v21, v22, v23, v24, v25, v26, v27, v28, v29 + enc_round \state, \key + .endr + aese\state\().16b, v30.16b + eor \state\().16b, \state\().16b, v31.16b + .endm + + .macro pmull_gcm_do_crypt, enc + load_round_keys w7, x6 + + ld1 {SHASH.2d}, [x4] + ld1 {XL.2d}, [x1] + ldr x8, [x5, #8]// load lower counter + + moviMASK.16b, #0xe1 + ext SHASH2.16b, SHASH.16b, SHASH.16b, #8 +CPU_LE(rev x8, x8 ) + shl MASK.2d, MASK.2d, #57 + eor SHASH2.16b, SHASH2.16b, SHASH.16b + + .if \enc == 1 + ldr x10, [sp] + ld1 {KS.16b}, [x10] + .endif + +0: ld1 {CTR.8b}, [x5] // load upper counter + ld1 {INP.16b}, [x3], #16 + rev x9, x8 + add x8, x8, #1 + sub w0, w0, #1 + ins CTR.d[1], x9// set lower counter + + .if \enc == 1 + eor INP.16b, INP.16b, KS.16b// encrypt input + st1 {INP.16b}, [x2], #16 + .endif + + rev64 T1.16b, INP.16b + + cmp w7, #12 + b.ge2f // AES-192/256? + +1: enc_round CTR, v21 + + ext T2.16b, XL.16b, XL.16b, #8 + ext IN1.16b, T1.16b, T1.16b, #8 + + enc_round CTR, v22 + + eor T1.16b, T1.16b, T2.16b + eor XL.16b, XL.16b, IN1.16b + + enc_round CTR, v23 + + pmull2 XH.1q, SHASH.2d, XL.2d // a1 * b1 + eor T1.16b, T1.16b, XL.16b + + enc_round CTR, v24 + + pmull XL.1q, SHASH.1d, XL.1d // a0 * b0 + pmull XM.1q, SHASH2.1d, T1.1d // (a1 + a0)(b1 + b0) + + enc_round CTR, v25 + + ext T1.16b, XL.16b, XH.16b, #8 + eor T2.16b, XL.16b, XH.16b + eor XM.16b, XM.16b, T1.16b + + enc_round CTR, v26 + + eor XM.16b, XM.16b, T2.16b + pmull T2.1q, XL.1d, MASK.1d + + enc_round CTR, v27 + + mov XH.d[0],
[PATCH v2] staging: ccree: Use __func__ instead of function name
From: Karthik TummalaFixed following checkpatch.pl warning: WARNING: Prefer using '"%s...", __func__' to using the function's name, in a string It is prefered to use '%s & __func__' instead of function name for logging. Signed-off-by: Karthik Tummala --- Changes for v2: v1 was a patch series, which consisted of two patches in which second one was already submitted by Gilad Ben-Yossef, so dropped that one. Patch generated on staging-testing as suggested by Greg-K H. --- drivers/staging/ccree/ssi_aead.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/ccree/ssi_aead.c b/drivers/staging/ccree/ssi_aead.c index 1fc0b05..1168161 100644 --- a/drivers/staging/ccree/ssi_aead.c +++ b/drivers/staging/ccree/ssi_aead.c @@ -1886,7 +1886,7 @@ static int config_gcm_context(struct aead_request *req) (req->cryptlen - ctx->authsize); __be32 counter = cpu_to_be32(2); - SSI_LOG_DEBUG("config_gcm_context() cryptlen = %d, req->assoclen = %d ctx->authsize = %d\n", cryptlen, req->assoclen, ctx->authsize); + SSI_LOG_DEBUG("%s() cryptlen = %d, req->assoclen = %d ctx->authsize = %d\n", __func__, cryptlen, req->assoclen, ctx->authsize); memset(req_ctx->hkey, 0, AES_BLOCK_SIZE); @@ -2198,7 +2198,7 @@ static int ssi_rfc4106_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsign struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); int rc = 0; - SSI_LOG_DEBUG("ssi_rfc4106_gcm_setkey() keylen %d, key %p\n", keylen, key); + SSI_LOG_DEBUG("%s() keylen %d, key %p\n", __func__, keylen, key); if (keylen < 4) return -EINVAL; @@ -2216,7 +2216,7 @@ static int ssi_rfc4543_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsign struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); int rc = 0; - SSI_LOG_DEBUG("ssi_rfc4543_gcm_setkey() keylen %d, key %p\n", keylen, key); + SSI_LOG_DEBUG("%s() keylen %d, key %p\n", __func__, keylen, key); if (keylen < 4) return -EINVAL; -- 1.9.1
[PATCH v3 RESEND 5/5] crypto: ccp - remove ccp_present() check from device initialize
Since SP device driver supports multiples devices (e.g CCP, PSP), we should not fail the driver init just because CCP device is not found. Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/sp-dev.c | 12 1 file changed, 12 deletions(-) diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c index edbf1bd9..a017233 100644 --- a/drivers/crypto/ccp/sp-dev.c +++ b/drivers/crypto/ccp/sp-dev.c @@ -244,12 +244,6 @@ static int __init sp_mod_init(void) if (ret) return ret; - /* Don't leave the driver loaded if init failed */ - if (ccp_present() != 0) { - sp_pci_exit(); - return -ENODEV; - } - return 0; #endif @@ -260,12 +254,6 @@ static int __init sp_mod_init(void) if (ret) return ret; - /* Don't leave the driver loaded if init failed */ - if (ccp_present() != 0) { - sp_platform_exit(); - return -ENODEV; - } - return 0; #endif -- 2.9.4
[PATCH v3 RESEND 4/5] crypto: ccp - rename ccp driver initialize files as sp device
CCP device initializes is now integerated into higher level SP device, to avoid the confusion lets rename the ccp driver initialization files (ccp-platform.c->sp-platform.c, ccp-pci.c->sp-pci.c). The patch does not make any functional changes other than renaming file and structures Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/Makefile| 4 +- drivers/crypto/ccp/ccp-dev.h | 6 -- drivers/crypto/ccp/sp-dev.c| 12 ++-- drivers/crypto/ccp/{ccp-pci.c => sp-pci.c} | 80 +++--- .../crypto/ccp/{ccp-platform.c => sp-platform.c} | 78 ++--- 5 files changed, 87 insertions(+), 93 deletions(-) rename drivers/crypto/ccp/{ccp-pci.c => sp-pci.c} (71%) rename drivers/crypto/ccp/{ccp-platform.c => sp-platform.c} (66%) diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index d2f1b52..5f2adc5 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -1,12 +1,12 @@ obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o -ccp-objs := sp-dev.o ccp-platform.o +ccp-objs := sp-dev.o sp-platform.o ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \ ccp-ops.o \ ccp-dev-v3.o \ ccp-dev-v5.o \ ccp-dmaengine.o \ ccp-debugfs.o -ccp-$(CONFIG_PCI) += ccp-pci.o +ccp-$(CONFIG_PCI) += sp-pci.o obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o ccp-crypto-objs := ccp-crypto-main.o \ diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index 193f309..b959e24 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -626,12 +626,6 @@ struct ccp5_desc { struct dword7 dw7; }; -int ccp_pci_init(void); -void ccp_pci_exit(void); - -int ccp_platform_init(void); -void ccp_platform_exit(void); - void ccp_add_device(struct ccp_device *ccp); void ccp_del_device(struct ccp_device *ccp); diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c index 44e76e5..edbf1bd9 100644 --- a/drivers/crypto/ccp/sp-dev.c +++ b/drivers/crypto/ccp/sp-dev.c @@ -240,13 +240,13 @@ static int __init sp_mod_init(void) #ifdef CONFIG_X86 int ret; - ret = ccp_pci_init(); + ret = sp_pci_init(); if (ret) return ret; /* Don't leave the driver loaded if init failed */ if (ccp_present() != 0) { - ccp_pci_exit(); + sp_pci_exit(); return -ENODEV; } @@ -256,13 +256,13 @@ static int __init sp_mod_init(void) #ifdef CONFIG_ARM64 int ret; - ret = ccp_platform_init(); + ret = sp_platform_init(); if (ret) return ret; /* Don't leave the driver loaded if init failed */ if (ccp_present() != 0) { - ccp_platform_exit(); + sp_platform_exit(); return -ENODEV; } @@ -275,11 +275,11 @@ static int __init sp_mod_init(void) static void __exit sp_mod_exit(void) { #ifdef CONFIG_X86 - ccp_pci_exit(); + sp_pci_exit(); #endif #ifdef CONFIG_ARM64 - ccp_platform_exit(); + sp_platform_exit(); #endif } diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/sp-pci.c similarity index 71% rename from drivers/crypto/ccp/ccp-pci.c rename to drivers/crypto/ccp/sp-pci.c index b29a093..9859aa6 100644 --- a/drivers/crypto/ccp/ccp-pci.c +++ b/drivers/crypto/ccp/sp-pci.c @@ -1,5 +1,5 @@ /* - * AMD Cryptographic Coprocessor (CCP) driver + * AMD Secure Processor device driver * * Copyright (C) 2013,2016 Advanced Micro Devices, Inc. * @@ -28,35 +28,35 @@ #define MSIX_VECTORS 2 -struct ccp_pci { +struct sp_pci { int msix_count; struct msix_entry msix_entry[MSIX_VECTORS]; }; -static int ccp_get_msix_irqs(struct sp_device *sp) +static int sp_get_msix_irqs(struct sp_device *sp) { - struct ccp_pci *ccp_pci = sp->dev_specific; + struct sp_pci *sp_pci = sp->dev_specific; struct device *dev = sp->dev; struct pci_dev *pdev = to_pci_dev(dev); int v, ret; - for (v = 0; v < ARRAY_SIZE(ccp_pci->msix_entry); v++) - ccp_pci->msix_entry[v].entry = v; + for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++) + sp_pci->msix_entry[v].entry = v; - ret = pci_enable_msix_range(pdev, ccp_pci->msix_entry, 1, v); + ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v); if (ret < 0) return ret; - ccp_pci->msix_count = ret; + sp_pci->msix_count = ret; sp->use_tasklet = true; - sp->psp_irq = ccp_pci->msix_entry[0].vector; - sp->ccp_irq = (ccp_pci->msix_count > 1) ? ccp_pci->msix_entry[1].vector - : ccp_pci->msix_entry[0].vector; + sp->psp_irq = sp_pci->msix_entry[0].vector; + sp->ccp_irq = (sp_pci->msix_count > 1) ?
[PATCH v3 RESEND 3/5] crypto: cpp - Abstract interrupt registeration
The CCP and PSP devices part of AMD Secure Procesor may share the same interrupt. Hence we expand the SP device to register a common interrupt handler and provide functions to CCP and PSP devices to register their interrupt callback which will be invoked upon interrupt. Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/ccp-dev-v3.c | 6 +-- drivers/crypto/ccp/ccp-dev-v5.c | 7 ++- drivers/crypto/ccp/ccp-dev.c | 3 +- drivers/crypto/ccp/ccp-dev.h | 2 - drivers/crypto/ccp/ccp-pci.c | 103 +++- drivers/crypto/ccp/ccp-platform.c | 57 ++-- drivers/crypto/ccp/sp-dev.c | 107 ++ drivers/crypto/ccp/sp-dev.h | 16 +- 8 files changed, 186 insertions(+), 115 deletions(-) diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 57179034..695fde8 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -453,7 +453,7 @@ static int ccp_init(struct ccp_device *ccp) iowrite32(ccp->qim, ccp->io_regs + IRQ_STATUS_REG); /* Request an irq */ - ret = ccp->get_irq(ccp); + ret = sp_request_ccp_irq(ccp->sp, ccp_irq_handler, ccp->name, ccp); if (ret) { dev_err(dev, "unable to allocate an IRQ\n"); goto e_pool; @@ -510,7 +510,7 @@ static int ccp_init(struct ccp_device *ccp) if (ccp->cmd_q[i].kthread) kthread_stop(ccp->cmd_q[i].kthread); - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -549,7 +549,7 @@ static void ccp_destroy(struct ccp_device *ccp) if (ccp->cmd_q[i].kthread) kthread_stop(ccp->cmd_q[i].kthread); - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); for (i = 0; i < ccp->cmd_q_count; i++) dma_pool_destroy(ccp->cmd_q[i].dma_pool); diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 8ed2b37..b0391f0 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -880,7 +880,7 @@ static int ccp5_init(struct ccp_device *ccp) dev_dbg(dev, "Requesting an IRQ...\n"); /* Request an irq */ - ret = ccp->get_irq(ccp); + ret = sp_request_ccp_irq(ccp->sp, ccp5_irq_handler, ccp->name, ccp); if (ret) { dev_err(dev, "unable to allocate an IRQ\n"); goto e_pool; @@ -986,7 +986,7 @@ static int ccp5_init(struct ccp_device *ccp) kthread_stop(ccp->cmd_q[i].kthread); e_irq: - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -1036,7 +1036,7 @@ static void ccp5_destroy(struct ccp_device *ccp) if (ccp->cmd_q[i].kthread) kthread_stop(ccp->cmd_q[i].kthread); - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); for (i = 0; i < ccp->cmd_q_count; i++) { cmd_q = >cmd_q[i]; @@ -1105,7 +1105,6 @@ static const struct ccp_actions ccp5_actions = { .init = ccp5_init, .destroy = ccp5_destroy, .get_free_slots = ccp5_get_free_slots, - .irqhandler = ccp5_irq_handler, }; const struct ccp_vdata ccpv5a = { diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 8a1674a..7c751bf 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -599,8 +599,7 @@ int ccp_dev_init(struct sp_device *sp) goto e_err; } - ccp->get_irq = sp->get_irq; - ccp->free_irq = sp->free_irq; + ccp->use_tasklet = sp->use_tasklet; ccp->io_regs = sp->io_map + ccp->vdata->offset; if (ccp->vdata->setup) diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index ca44821..193f309 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -351,8 +351,6 @@ struct ccp_device { /* Bus specific device information */ void *dev_specific; - int (*get_irq)(struct ccp_device *ccp); - void (*free_irq)(struct ccp_device *ccp); unsigned int qim; unsigned int irq; bool use_tasklet; diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c index ab2df96..b29a093 100644 --- a/drivers/crypto/ccp/ccp-pci.c +++ b/drivers/crypto/ccp/ccp-pci.c @@ -28,67 +28,37 @@ #define MSIX_VECTORS 2 -struct ccp_msix { - u32 vector; - char name[16]; -}; - struct ccp_pci { int msix_count; - struct ccp_msix msix[MSIX_VECTORS]; + struct msix_entry msix_entry[MSIX_VECTORS]; }; -static int ccp_get_msix_irqs(struct ccp_device *ccp) +static int ccp_get_msix_irqs(struct sp_device *sp) { - struct sp_device *sp = ccp->sp; struct
[PATCH v3 RESEND 2/5] crypto: ccp - Introduce the AMD Secure Processor device
The CCP device is part of the AMD Secure Processor. In order to expand the usage of the AMD Secure Processor, create a framework that allows functional components of the AMD Secure Processor to be initialized and handled appropriately. Signed-off-by: Brijesh Singh--- drivers/crypto/Kconfig| 6 +- drivers/crypto/ccp/Kconfig| 21 +++-- drivers/crypto/ccp/Makefile | 4 +- drivers/crypto/ccp/ccp-dev-v3.c | 4 +- drivers/crypto/ccp/ccp-dev-v5.c | 5 +- drivers/crypto/ccp/ccp-dev.c | 106 +- drivers/crypto/ccp/ccp-dev.h | 21 + drivers/crypto/ccp/ccp-pci.c | 81 +++-- drivers/crypto/ccp/ccp-platform.c | 70 --- drivers/crypto/ccp/sp-dev.c | 180 ++ drivers/crypto/ccp/sp-dev.h | 120 + include/linux/ccp.h | 7 +- 12 files changed, 461 insertions(+), 164 deletions(-) create mode 100644 drivers/crypto/ccp/sp-dev.c create mode 100644 drivers/crypto/ccp/sp-dev.h diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 0528a62..148b516 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -513,11 +513,11 @@ config CRYPTO_DEV_ATMEL_SHA will be called atmel-sha. config CRYPTO_DEV_CCP - bool "Support for AMD Cryptographic Coprocessor" + bool "Support for AMD Secure Processor" depends on ((X86 && PCI) || (ARM64 && (OF_ADDRESS || ACPI))) && HAS_IOMEM help - The AMD Cryptographic Coprocessor provides hardware offload support - for encryption, hashing and related operations. + The AMD Secure Processor provides hardware offload support for memory + encryption in virtualization and cryptographic hashing and related operations. if CRYPTO_DEV_CCP source "drivers/crypto/ccp/Kconfig" diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig index 2238f77..15b63fd 100644 --- a/drivers/crypto/ccp/Kconfig +++ b/drivers/crypto/ccp/Kconfig @@ -1,22 +1,29 @@ config CRYPTO_DEV_CCP_DD - tristate "Cryptographic Coprocessor device driver" - depends on CRYPTO_DEV_CCP + tristate "Secure Processor device driver" default m + help + Provides AMD Secure Processor device driver. + If you choose 'M' here, this module will be called ccp. + +config CRYPTO_DEV_SP_CCP + bool "Cryptographic Coprocessor device" + default y + depends on CRYPTO_DEV_CCP_DD select HW_RANDOM select DMA_ENGINE select DMADEVICES select CRYPTO_SHA1 select CRYPTO_SHA256 help - Provides the interface to use the AMD Cryptographic Coprocessor - which can be used to offload encryption operations such as SHA, - AES and more. If you choose 'M' here, this module will be called - ccp. + Provides the support for AMD Cryptographic Coprocessor (CCP) device + which can be used to offload encryption operations such as SHA, AES + and more. config CRYPTO_DEV_CCP_CRYPTO tristate "Encryption and hashing offload support" - depends on CRYPTO_DEV_CCP_DD default m + depends on CRYPTO_DEV_CCP_DD + depends on CRYPTO_DEV_SP_CCP select CRYPTO_HASH select CRYPTO_BLKCIPHER select CRYPTO_AUTHENC diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index 59493fd..d2f1b52 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -1,9 +1,9 @@ obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o -ccp-objs := ccp-dev.o \ +ccp-objs := sp-dev.o ccp-platform.o +ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \ ccp-ops.o \ ccp-dev-v3.o \ ccp-dev-v5.o \ - ccp-platform.o \ ccp-dmaengine.o \ ccp-debugfs.o ccp-$(CONFIG_PCI) += ccp-pci.o diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 52aa88b..57179034 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -359,8 +359,7 @@ static void ccp_irq_bh(unsigned long data) static irqreturn_t ccp_irq_handler(int irq, void *data) { - struct device *dev = data; - struct ccp_device *ccp = dev_get_drvdata(dev); + struct ccp_device *ccp = (struct ccp_device *)data; ccp_disable_queue_interrupts(ccp); if (ccp->use_tasklet) @@ -597,6 +596,5 @@ const struct ccp_vdata ccpv3 = { .version = CCP_VERSION(3, 0), .setup = NULL, .perform = _actions, - .bar = 2, .offset = 0x2, }; diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index b10d2d2..8ed2b37 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -769,8 +769,7 @@ static void ccp5_irq_bh(unsigned long data) static irqreturn_t ccp5_irq_handler(int irq, void *data) { -
[PATCH v3 RESEND 1/5] crypto: ccp - Use devres interface to allocate PCI/iomap and cleanup
Update pci and platform files to use devres interface to allocate the PCI and iomap resources. Also add helper functions to consolicate module init, exit and power mangagement code duplication. Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/ccp-dev-v3.c | 7 +++ drivers/crypto/ccp/ccp-dev.c | 61 drivers/crypto/ccp/ccp-dev.h | 6 ++ drivers/crypto/ccp/ccp-pci.c | 114 +- drivers/crypto/ccp/ccp-platform.c | 56 ++- 5 files changed, 106 insertions(+), 138 deletions(-) diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 367c2e3..52aa88b 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -586,6 +586,13 @@ static const struct ccp_actions ccp3_actions = { .irqhandler = ccp_irq_handler, }; +const struct ccp_vdata ccpv3_platform = { + .version = CCP_VERSION(3, 0), + .setup = NULL, + .perform = _actions, + .offset = 0, +}; + const struct ccp_vdata ccpv3 = { .version = CCP_VERSION(3, 0), .setup = NULL, diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 2506b50..abb3d68 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -538,8 +538,69 @@ bool ccp_queues_suspended(struct ccp_device *ccp) return ccp->cmd_q_count == suspended; } + +int ccp_dev_suspend(struct ccp_device *ccp, pm_message_t state) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(>cmd_lock, flags); + + ccp->suspending = 1; + + /* Wake all the queue kthreads to prepare for suspend */ + for (i = 0; i < ccp->cmd_q_count; i++) + wake_up_process(ccp->cmd_q[i].kthread); + + spin_unlock_irqrestore(>cmd_lock, flags); + + /* Wait for all queue kthreads to say they're done */ + while (!ccp_queues_suspended(ccp)) + wait_event_interruptible(ccp->suspend_queue, +ccp_queues_suspended(ccp)); + + return 0; +} + +int ccp_dev_resume(struct ccp_device *ccp) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(>cmd_lock, flags); + + ccp->suspending = 0; + + /* Wake up all the kthreads */ + for (i = 0; i < ccp->cmd_q_count; i++) { + ccp->cmd_q[i].suspended = 0; + wake_up_process(ccp->cmd_q[i].kthread); + } + + spin_unlock_irqrestore(>cmd_lock, flags); + + return 0; +} #endif +int ccp_dev_init(struct ccp_device *ccp) +{ + ccp->io_regs = ccp->io_map + ccp->vdata->offset; + + if (ccp->vdata->setup) + ccp->vdata->setup(ccp); + + return ccp->vdata->perform->init(ccp); +} + +void ccp_dev_destroy(struct ccp_device *ccp) +{ + if (!ccp) + return; + + ccp->vdata->perform->destroy(ccp); +} + static int __init ccp_mod_init(void) { #ifdef CONFIG_X86 diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index a70154a..df2e76e 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -652,6 +652,11 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp); void ccp5_debugfs_setup(struct ccp_device *ccp); void ccp5_debugfs_destroy(void); +int ccp_dev_init(struct ccp_device *ccp); +void ccp_dev_destroy(struct ccp_device *ccp); +int ccp_dev_suspend(struct ccp_device *ccp, pm_message_t state); +int ccp_dev_resume(struct ccp_device *ccp); + /* Structure for computation functions that are device-specific */ struct ccp_actions { int (*aes)(struct ccp_op *); @@ -679,6 +684,7 @@ struct ccp_vdata { const unsigned int offset; }; +extern const struct ccp_vdata ccpv3_platform; extern const struct ccp_vdata ccpv3; extern const struct ccp_vdata ccpv5a; extern const struct ccp_vdata ccpv5b; diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c index e880d4cf4..490ad0a 100644 --- a/drivers/crypto/ccp/ccp-pci.c +++ b/drivers/crypto/ccp/ccp-pci.c @@ -150,28 +150,13 @@ static void ccp_free_irqs(struct ccp_device *ccp) ccp->irq = 0; } -static int ccp_find_mmio_area(struct ccp_device *ccp) -{ - struct device *dev = ccp->dev; - struct pci_dev *pdev = to_pci_dev(dev); - resource_size_t io_len; - unsigned long io_flags; - - io_flags = pci_resource_flags(pdev, ccp->vdata->bar); - io_len = pci_resource_len(pdev, ccp->vdata->bar); - if ((io_flags & IORESOURCE_MEM) && - (io_len >= (ccp->vdata->offset + 0x800))) - return ccp->vdata->bar; - - return -EIO; -} - static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct ccp_device *ccp; struct ccp_pci *ccp_pci; struct device *dev = >dev; - unsigned int bar; + void __iomem * const *iomap_table; + int bar_mask; int ret;
[PATCH v3 RESEND 0/5] Introduce AMD Secure Processor device
(Copying Tom Lendacky) CCP device (drivers/crypto/ccp/ccp.ko) is part of AMD Secure Processor, which is not dedicated solely to crypto. The AMD Secure Processor includes CCP and PSP (Platform Secure Processor) devices. This patch series adds a framework that allows functional component of the AMD Secure Processor to be initialized and handled appropriately. The series does not makes any logic modification into CCP - it refactors the code to integerate CCP into AMD secure processor framework. --- Changes since v2: - move the ccp->io_regs initialization before device setup(). - maintain the original Kconfig hierarchy - rename ccp-{pci,platform}.c -> sp-{pci,platform}.c - do not fail the module_init() when ccp device is not found Changes since v1: - remove unused function [sp_get_device()] Brijesh Singh (5): crypto: ccp - Use devres interface to allocate PCI/iomap and cleanup crypto: ccp - Introduce the AMD Secure Processor device crypto: cpp - Abstract interrupt registeration crypto: ccp - rename ccp driver initialize files as sp device crypto: ccp - remove ccp_present() check from device initialize drivers/crypto/Kconfig| 6 +- drivers/crypto/ccp/Kconfig| 21 ++- drivers/crypto/ccp/Makefile | 6 +- drivers/crypto/ccp/ccp-dev-v3.c | 17 +- drivers/crypto/ccp/ccp-dev-v5.c | 12 +- drivers/crypto/ccp/ccp-dev.c | 124 - drivers/crypto/ccp/ccp-dev.h | 25 +-- drivers/crypto/ccp/ccp-pci.c | 356 -- drivers/crypto/ccp/ccp-platform.c | 293 --- drivers/crypto/ccp/sp-dev.c | 275 + drivers/crypto/ccp/sp-dev.h | 132 ++ drivers/crypto/ccp/sp-pci.c | 276 + drivers/crypto/ccp/sp-platform.c | 252 +++ include/linux/ccp.h | 7 +- 14 files changed, 1060 insertions(+), 742 deletions(-) delete mode 100644 drivers/crypto/ccp/ccp-pci.c delete mode 100644 drivers/crypto/ccp/ccp-platform.c create mode 100644 drivers/crypto/ccp/sp-dev.c create mode 100644 drivers/crypto/ccp/sp-dev.h create mode 100644 drivers/crypto/ccp/sp-pci.c create mode 100644 drivers/crypto/ccp/sp-platform.c -- 2.9.4
[PATCH v3 5/5] crypto: ccp - remove ccp_present() check from device initialize
Since SP device driver supports multiples devices (e.g CCP, PSP), we should not fail the driver init just because CCP device is not found. Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/sp-dev.c | 12 1 file changed, 12 deletions(-) diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c index edbf1bd9..a017233 100644 --- a/drivers/crypto/ccp/sp-dev.c +++ b/drivers/crypto/ccp/sp-dev.c @@ -244,12 +244,6 @@ static int __init sp_mod_init(void) if (ret) return ret; - /* Don't leave the driver loaded if init failed */ - if (ccp_present() != 0) { - sp_pci_exit(); - return -ENODEV; - } - return 0; #endif @@ -260,12 +254,6 @@ static int __init sp_mod_init(void) if (ret) return ret; - /* Don't leave the driver loaded if init failed */ - if (ccp_present() != 0) { - sp_platform_exit(); - return -ENODEV; - } - return 0; #endif -- 2.9.4
[PATCH v3 3/5] crypto: cpp - Abstract interrupt registeration
The CCP and PSP devices part of AMD Secure Procesor may share the same interrupt. Hence we expand the SP device to register a common interrupt handler and provide functions to CCP and PSP devices to register their interrupt callback which will be invoked upon interrupt. Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/ccp-dev-v3.c | 6 +-- drivers/crypto/ccp/ccp-dev-v5.c | 7 ++- drivers/crypto/ccp/ccp-dev.c | 3 +- drivers/crypto/ccp/ccp-dev.h | 2 - drivers/crypto/ccp/ccp-pci.c | 103 +++- drivers/crypto/ccp/ccp-platform.c | 57 ++-- drivers/crypto/ccp/sp-dev.c | 107 ++ drivers/crypto/ccp/sp-dev.h | 16 +- 8 files changed, 186 insertions(+), 115 deletions(-) diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 57179034..695fde8 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -453,7 +453,7 @@ static int ccp_init(struct ccp_device *ccp) iowrite32(ccp->qim, ccp->io_regs + IRQ_STATUS_REG); /* Request an irq */ - ret = ccp->get_irq(ccp); + ret = sp_request_ccp_irq(ccp->sp, ccp_irq_handler, ccp->name, ccp); if (ret) { dev_err(dev, "unable to allocate an IRQ\n"); goto e_pool; @@ -510,7 +510,7 @@ static int ccp_init(struct ccp_device *ccp) if (ccp->cmd_q[i].kthread) kthread_stop(ccp->cmd_q[i].kthread); - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -549,7 +549,7 @@ static void ccp_destroy(struct ccp_device *ccp) if (ccp->cmd_q[i].kthread) kthread_stop(ccp->cmd_q[i].kthread); - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); for (i = 0; i < ccp->cmd_q_count; i++) dma_pool_destroy(ccp->cmd_q[i].dma_pool); diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 8ed2b37..b0391f0 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -880,7 +880,7 @@ static int ccp5_init(struct ccp_device *ccp) dev_dbg(dev, "Requesting an IRQ...\n"); /* Request an irq */ - ret = ccp->get_irq(ccp); + ret = sp_request_ccp_irq(ccp->sp, ccp5_irq_handler, ccp->name, ccp); if (ret) { dev_err(dev, "unable to allocate an IRQ\n"); goto e_pool; @@ -986,7 +986,7 @@ static int ccp5_init(struct ccp_device *ccp) kthread_stop(ccp->cmd_q[i].kthread); e_irq: - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -1036,7 +1036,7 @@ static void ccp5_destroy(struct ccp_device *ccp) if (ccp->cmd_q[i].kthread) kthread_stop(ccp->cmd_q[i].kthread); - ccp->free_irq(ccp); + sp_free_ccp_irq(ccp->sp, ccp); for (i = 0; i < ccp->cmd_q_count; i++) { cmd_q = >cmd_q[i]; @@ -1105,7 +1105,6 @@ static const struct ccp_actions ccp5_actions = { .init = ccp5_init, .destroy = ccp5_destroy, .get_free_slots = ccp5_get_free_slots, - .irqhandler = ccp5_irq_handler, }; const struct ccp_vdata ccpv5a = { diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 8a1674a..7c751bf 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -599,8 +599,7 @@ int ccp_dev_init(struct sp_device *sp) goto e_err; } - ccp->get_irq = sp->get_irq; - ccp->free_irq = sp->free_irq; + ccp->use_tasklet = sp->use_tasklet; ccp->io_regs = sp->io_map + ccp->vdata->offset; if (ccp->vdata->setup) diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index ca44821..193f309 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -351,8 +351,6 @@ struct ccp_device { /* Bus specific device information */ void *dev_specific; - int (*get_irq)(struct ccp_device *ccp); - void (*free_irq)(struct ccp_device *ccp); unsigned int qim; unsigned int irq; bool use_tasklet; diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c index ab2df96..b29a093 100644 --- a/drivers/crypto/ccp/ccp-pci.c +++ b/drivers/crypto/ccp/ccp-pci.c @@ -28,67 +28,37 @@ #define MSIX_VECTORS 2 -struct ccp_msix { - u32 vector; - char name[16]; -}; - struct ccp_pci { int msix_count; - struct ccp_msix msix[MSIX_VECTORS]; + struct msix_entry msix_entry[MSIX_VECTORS]; }; -static int ccp_get_msix_irqs(struct ccp_device *ccp) +static int ccp_get_msix_irqs(struct sp_device *sp) { - struct sp_device *sp = ccp->sp; struct
[PATCH v3 0/5] Introduce AMD Secure Processor device
CCP device (drivers/crypto/ccp/ccp.ko) is part of AMD Secure Processor, which is not dedicated solely to crypto. The AMD Secure Processor includes CCP and PSP (Platform Secure Processor) devices. This patch series adds a framework that allows functional component of the AMD Secure Processor to be initialized and handled appropriately. The series does not makes any logic modification into CCP - it refactors the code to integerate CCP into AMD secure processor framework. --- Changes since v2: - move the ccp->io_regs initialization before device setup(). - maintain the original Kconfig hierarchy - rename ccp-{pci,platform}.c -> sp-{pci,platform}.c - do not fail the module_init() when ccp device is not found Changes since v1: - remove unused function [sp_get_device()] Brijesh Singh (5): crypto: ccp - Use devres interface to allocate PCI/iomap and cleanup crypto: ccp - Introduce the AMD Secure Processor device crypto: cpp - Abstract interrupt registeration crypto: ccp - rename ccp driver initialize files as sp device crypto: ccp - remove ccp_present() check from device initialize drivers/crypto/Kconfig| 6 +- drivers/crypto/ccp/Kconfig| 21 ++- drivers/crypto/ccp/Makefile | 6 +- drivers/crypto/ccp/ccp-dev-v3.c | 17 +- drivers/crypto/ccp/ccp-dev-v5.c | 12 +- drivers/crypto/ccp/ccp-dev.c | 124 - drivers/crypto/ccp/ccp-dev.h | 25 +-- drivers/crypto/ccp/ccp-pci.c | 356 -- drivers/crypto/ccp/ccp-platform.c | 293 --- drivers/crypto/ccp/sp-dev.c | 275 + drivers/crypto/ccp/sp-dev.h | 132 ++ drivers/crypto/ccp/sp-pci.c | 276 + drivers/crypto/ccp/sp-platform.c | 252 +++ include/linux/ccp.h | 7 +- 14 files changed, 1060 insertions(+), 742 deletions(-) delete mode 100644 drivers/crypto/ccp/ccp-pci.c delete mode 100644 drivers/crypto/ccp/ccp-platform.c create mode 100644 drivers/crypto/ccp/sp-dev.c create mode 100644 drivers/crypto/ccp/sp-dev.h create mode 100644 drivers/crypto/ccp/sp-pci.c create mode 100644 drivers/crypto/ccp/sp-platform.c -- 2.9.4
[PATCH v3 2/5] crypto: ccp - Introduce the AMD Secure Processor device
The CCP device is part of the AMD Secure Processor. In order to expand the usage of the AMD Secure Processor, create a framework that allows functional components of the AMD Secure Processor to be initialized and handled appropriately. Signed-off-by: Brijesh Singh--- drivers/crypto/Kconfig| 6 +- drivers/crypto/ccp/Kconfig| 21 +++-- drivers/crypto/ccp/Makefile | 4 +- drivers/crypto/ccp/ccp-dev-v3.c | 4 +- drivers/crypto/ccp/ccp-dev-v5.c | 5 +- drivers/crypto/ccp/ccp-dev.c | 106 +- drivers/crypto/ccp/ccp-dev.h | 21 + drivers/crypto/ccp/ccp-pci.c | 81 +++-- drivers/crypto/ccp/ccp-platform.c | 70 --- drivers/crypto/ccp/sp-dev.c | 180 ++ drivers/crypto/ccp/sp-dev.h | 120 + include/linux/ccp.h | 7 +- 12 files changed, 461 insertions(+), 164 deletions(-) create mode 100644 drivers/crypto/ccp/sp-dev.c create mode 100644 drivers/crypto/ccp/sp-dev.h diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 0528a62..148b516 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -513,11 +513,11 @@ config CRYPTO_DEV_ATMEL_SHA will be called atmel-sha. config CRYPTO_DEV_CCP - bool "Support for AMD Cryptographic Coprocessor" + bool "Support for AMD Secure Processor" depends on ((X86 && PCI) || (ARM64 && (OF_ADDRESS || ACPI))) && HAS_IOMEM help - The AMD Cryptographic Coprocessor provides hardware offload support - for encryption, hashing and related operations. + The AMD Secure Processor provides hardware offload support for memory + encryption in virtualization and cryptographic hashing and related operations. if CRYPTO_DEV_CCP source "drivers/crypto/ccp/Kconfig" diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig index 2238f77..15b63fd 100644 --- a/drivers/crypto/ccp/Kconfig +++ b/drivers/crypto/ccp/Kconfig @@ -1,22 +1,29 @@ config CRYPTO_DEV_CCP_DD - tristate "Cryptographic Coprocessor device driver" - depends on CRYPTO_DEV_CCP + tristate "Secure Processor device driver" default m + help + Provides AMD Secure Processor device driver. + If you choose 'M' here, this module will be called ccp. + +config CRYPTO_DEV_SP_CCP + bool "Cryptographic Coprocessor device" + default y + depends on CRYPTO_DEV_CCP_DD select HW_RANDOM select DMA_ENGINE select DMADEVICES select CRYPTO_SHA1 select CRYPTO_SHA256 help - Provides the interface to use the AMD Cryptographic Coprocessor - which can be used to offload encryption operations such as SHA, - AES and more. If you choose 'M' here, this module will be called - ccp. + Provides the support for AMD Cryptographic Coprocessor (CCP) device + which can be used to offload encryption operations such as SHA, AES + and more. config CRYPTO_DEV_CCP_CRYPTO tristate "Encryption and hashing offload support" - depends on CRYPTO_DEV_CCP_DD default m + depends on CRYPTO_DEV_CCP_DD + depends on CRYPTO_DEV_SP_CCP select CRYPTO_HASH select CRYPTO_BLKCIPHER select CRYPTO_AUTHENC diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index 59493fd..d2f1b52 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -1,9 +1,9 @@ obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o -ccp-objs := ccp-dev.o \ +ccp-objs := sp-dev.o ccp-platform.o +ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \ ccp-ops.o \ ccp-dev-v3.o \ ccp-dev-v5.o \ - ccp-platform.o \ ccp-dmaengine.o \ ccp-debugfs.o ccp-$(CONFIG_PCI) += ccp-pci.o diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 52aa88b..57179034 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -359,8 +359,7 @@ static void ccp_irq_bh(unsigned long data) static irqreturn_t ccp_irq_handler(int irq, void *data) { - struct device *dev = data; - struct ccp_device *ccp = dev_get_drvdata(dev); + struct ccp_device *ccp = (struct ccp_device *)data; ccp_disable_queue_interrupts(ccp); if (ccp->use_tasklet) @@ -597,6 +596,5 @@ const struct ccp_vdata ccpv3 = { .version = CCP_VERSION(3, 0), .setup = NULL, .perform = _actions, - .bar = 2, .offset = 0x2, }; diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index b10d2d2..8ed2b37 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -769,8 +769,7 @@ static void ccp5_irq_bh(unsigned long data) static irqreturn_t ccp5_irq_handler(int irq, void *data) { -
[PATCH v3 4/5] crypto: ccp - rename ccp driver initialize files as sp device
CCP device initializes is now integerated into higher level SP device, to avoid the confusion lets rename the ccp driver initialization files (ccp-platform.c->sp-platform.c, ccp-pci.c->sp-pci.c). The patch does not make any functional changes other than renaming file and structures Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/Makefile| 4 +- drivers/crypto/ccp/ccp-dev.h | 6 -- drivers/crypto/ccp/sp-dev.c| 12 ++-- drivers/crypto/ccp/{ccp-pci.c => sp-pci.c} | 80 +++--- .../crypto/ccp/{ccp-platform.c => sp-platform.c} | 78 ++--- 5 files changed, 87 insertions(+), 93 deletions(-) rename drivers/crypto/ccp/{ccp-pci.c => sp-pci.c} (71%) rename drivers/crypto/ccp/{ccp-platform.c => sp-platform.c} (66%) diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index d2f1b52..5f2adc5 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -1,12 +1,12 @@ obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o -ccp-objs := sp-dev.o ccp-platform.o +ccp-objs := sp-dev.o sp-platform.o ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \ ccp-ops.o \ ccp-dev-v3.o \ ccp-dev-v5.o \ ccp-dmaengine.o \ ccp-debugfs.o -ccp-$(CONFIG_PCI) += ccp-pci.o +ccp-$(CONFIG_PCI) += sp-pci.o obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o ccp-crypto-objs := ccp-crypto-main.o \ diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index 193f309..b959e24 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -626,12 +626,6 @@ struct ccp5_desc { struct dword7 dw7; }; -int ccp_pci_init(void); -void ccp_pci_exit(void); - -int ccp_platform_init(void); -void ccp_platform_exit(void); - void ccp_add_device(struct ccp_device *ccp); void ccp_del_device(struct ccp_device *ccp); diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c index 44e76e5..edbf1bd9 100644 --- a/drivers/crypto/ccp/sp-dev.c +++ b/drivers/crypto/ccp/sp-dev.c @@ -240,13 +240,13 @@ static int __init sp_mod_init(void) #ifdef CONFIG_X86 int ret; - ret = ccp_pci_init(); + ret = sp_pci_init(); if (ret) return ret; /* Don't leave the driver loaded if init failed */ if (ccp_present() != 0) { - ccp_pci_exit(); + sp_pci_exit(); return -ENODEV; } @@ -256,13 +256,13 @@ static int __init sp_mod_init(void) #ifdef CONFIG_ARM64 int ret; - ret = ccp_platform_init(); + ret = sp_platform_init(); if (ret) return ret; /* Don't leave the driver loaded if init failed */ if (ccp_present() != 0) { - ccp_platform_exit(); + sp_platform_exit(); return -ENODEV; } @@ -275,11 +275,11 @@ static int __init sp_mod_init(void) static void __exit sp_mod_exit(void) { #ifdef CONFIG_X86 - ccp_pci_exit(); + sp_pci_exit(); #endif #ifdef CONFIG_ARM64 - ccp_platform_exit(); + sp_platform_exit(); #endif } diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/sp-pci.c similarity index 71% rename from drivers/crypto/ccp/ccp-pci.c rename to drivers/crypto/ccp/sp-pci.c index b29a093..9859aa6 100644 --- a/drivers/crypto/ccp/ccp-pci.c +++ b/drivers/crypto/ccp/sp-pci.c @@ -1,5 +1,5 @@ /* - * AMD Cryptographic Coprocessor (CCP) driver + * AMD Secure Processor device driver * * Copyright (C) 2013,2016 Advanced Micro Devices, Inc. * @@ -28,35 +28,35 @@ #define MSIX_VECTORS 2 -struct ccp_pci { +struct sp_pci { int msix_count; struct msix_entry msix_entry[MSIX_VECTORS]; }; -static int ccp_get_msix_irqs(struct sp_device *sp) +static int sp_get_msix_irqs(struct sp_device *sp) { - struct ccp_pci *ccp_pci = sp->dev_specific; + struct sp_pci *sp_pci = sp->dev_specific; struct device *dev = sp->dev; struct pci_dev *pdev = to_pci_dev(dev); int v, ret; - for (v = 0; v < ARRAY_SIZE(ccp_pci->msix_entry); v++) - ccp_pci->msix_entry[v].entry = v; + for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++) + sp_pci->msix_entry[v].entry = v; - ret = pci_enable_msix_range(pdev, ccp_pci->msix_entry, 1, v); + ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v); if (ret < 0) return ret; - ccp_pci->msix_count = ret; + sp_pci->msix_count = ret; sp->use_tasklet = true; - sp->psp_irq = ccp_pci->msix_entry[0].vector; - sp->ccp_irq = (ccp_pci->msix_count > 1) ? ccp_pci->msix_entry[1].vector - : ccp_pci->msix_entry[0].vector; + sp->psp_irq = sp_pci->msix_entry[0].vector; + sp->ccp_irq = (sp_pci->msix_count > 1) ?
[PATCH v3 1/5] crypto: ccp - Use devres interface to allocate PCI/iomap and cleanup
Update pci and platform files to use devres interface to allocate the PCI and iomap resources. Also add helper functions to consolicate module init, exit and power mangagement code duplication. Signed-off-by: Brijesh Singh--- drivers/crypto/ccp/ccp-dev-v3.c | 7 +++ drivers/crypto/ccp/ccp-dev.c | 61 drivers/crypto/ccp/ccp-dev.h | 6 ++ drivers/crypto/ccp/ccp-pci.c | 114 +- drivers/crypto/ccp/ccp-platform.c | 56 ++- 5 files changed, 106 insertions(+), 138 deletions(-) diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 367c2e3..52aa88b 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -586,6 +586,13 @@ static const struct ccp_actions ccp3_actions = { .irqhandler = ccp_irq_handler, }; +const struct ccp_vdata ccpv3_platform = { + .version = CCP_VERSION(3, 0), + .setup = NULL, + .perform = _actions, + .offset = 0, +}; + const struct ccp_vdata ccpv3 = { .version = CCP_VERSION(3, 0), .setup = NULL, diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 2506b50..abb3d68 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -538,8 +538,69 @@ bool ccp_queues_suspended(struct ccp_device *ccp) return ccp->cmd_q_count == suspended; } + +int ccp_dev_suspend(struct ccp_device *ccp, pm_message_t state) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(>cmd_lock, flags); + + ccp->suspending = 1; + + /* Wake all the queue kthreads to prepare for suspend */ + for (i = 0; i < ccp->cmd_q_count; i++) + wake_up_process(ccp->cmd_q[i].kthread); + + spin_unlock_irqrestore(>cmd_lock, flags); + + /* Wait for all queue kthreads to say they're done */ + while (!ccp_queues_suspended(ccp)) + wait_event_interruptible(ccp->suspend_queue, +ccp_queues_suspended(ccp)); + + return 0; +} + +int ccp_dev_resume(struct ccp_device *ccp) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(>cmd_lock, flags); + + ccp->suspending = 0; + + /* Wake up all the kthreads */ + for (i = 0; i < ccp->cmd_q_count; i++) { + ccp->cmd_q[i].suspended = 0; + wake_up_process(ccp->cmd_q[i].kthread); + } + + spin_unlock_irqrestore(>cmd_lock, flags); + + return 0; +} #endif +int ccp_dev_init(struct ccp_device *ccp) +{ + ccp->io_regs = ccp->io_map + ccp->vdata->offset; + + if (ccp->vdata->setup) + ccp->vdata->setup(ccp); + + return ccp->vdata->perform->init(ccp); +} + +void ccp_dev_destroy(struct ccp_device *ccp) +{ + if (!ccp) + return; + + ccp->vdata->perform->destroy(ccp); +} + static int __init ccp_mod_init(void) { #ifdef CONFIG_X86 diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index a70154a..df2e76e 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -652,6 +652,11 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp); void ccp5_debugfs_setup(struct ccp_device *ccp); void ccp5_debugfs_destroy(void); +int ccp_dev_init(struct ccp_device *ccp); +void ccp_dev_destroy(struct ccp_device *ccp); +int ccp_dev_suspend(struct ccp_device *ccp, pm_message_t state); +int ccp_dev_resume(struct ccp_device *ccp); + /* Structure for computation functions that are device-specific */ struct ccp_actions { int (*aes)(struct ccp_op *); @@ -679,6 +684,7 @@ struct ccp_vdata { const unsigned int offset; }; +extern const struct ccp_vdata ccpv3_platform; extern const struct ccp_vdata ccpv3; extern const struct ccp_vdata ccpv5a; extern const struct ccp_vdata ccpv5b; diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c index e880d4cf4..490ad0a 100644 --- a/drivers/crypto/ccp/ccp-pci.c +++ b/drivers/crypto/ccp/ccp-pci.c @@ -150,28 +150,13 @@ static void ccp_free_irqs(struct ccp_device *ccp) ccp->irq = 0; } -static int ccp_find_mmio_area(struct ccp_device *ccp) -{ - struct device *dev = ccp->dev; - struct pci_dev *pdev = to_pci_dev(dev); - resource_size_t io_len; - unsigned long io_flags; - - io_flags = pci_resource_flags(pdev, ccp->vdata->bar); - io_len = pci_resource_len(pdev, ccp->vdata->bar); - if ((io_flags & IORESOURCE_MEM) && - (io_len >= (ccp->vdata->offset + 0x800))) - return ccp->vdata->bar; - - return -EIO; -} - static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct ccp_device *ccp; struct ccp_pci *ccp_pci; struct device *dev = >dev; - unsigned int bar; + void __iomem * const *iomap_table; + int bar_mask; int ret;
Re: wait in atomic context for an i2c crypto device to finish its execution
On 29.06.2017 13:12, Gilad Ben-Yossef wrote: Perhaps I missed something but it sounds like a classic case to use a work queue: Makes sense, thanks! ta
[PATCH v3 0/4] make io{read|write}64 more globally usable
Hi, Here's my third attempt. This time we add functions to io-64-nonatomic-* which call io{read|write}32 twice so that the pio is done correctly. I've also included a patch that adds these functions to the generic iomap library so that readq/writeq can be used while still splitting pio operations (when appropriate). Thanks, Logan Horia Geantă (1): crypto: caam: cleanup CONFIG_64BIT ifdefs when using io{read|write}64 Logan Gunthorpe (3): iomap: introduce io{read|write}64_{lo_hi|hi_lo} io-64-nonatomic: add io{read|write}64[be]{_lo_hi|_hi_lo} macros ntb: ntb_hw_intel: use io-64-nonatomic instead of in-driver hacks drivers/crypto/caam/regs.h| 35 ++--- drivers/ntb/hw/intel/ntb_hw_intel.c | 31 +--- include/asm-generic/iomap.h | 26 +-- include/linux/io-64-nonatomic-hi-lo.h | 62 include/linux/io-64-nonatomic-lo-hi.h | 60 lib/iomap.c | 132 ++ 6 files changed, 280 insertions(+), 66 deletions(-) -- 2.11.0
[PATCH v3 1/4] iomap: introduce io{read|write}64_{lo_hi|hi_lo}
In order to provide non-atomic functions for io{read|write}64 that will use readq and writeq when appropriate. We define a number of variants of these functions in the generic iomap that will do non-atomic operations on pio but atomic operations on mmio. These functions are only defined if readq and writeq are defined. If they are not, then the wrappers that always use non-atomic operations from include/linux/io-64-nonatomic*.h will be used. Signed-off-by: Logan GunthorpeCc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Arnd Bergmann Cc: Suresh Warrier Cc: Nicholas Piggin --- include/asm-generic/iomap.h | 26 +++-- lib/iomap.c | 132 2 files changed, 152 insertions(+), 6 deletions(-) diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h index 650fede33c25..e4601455ac4a 100644 --- a/include/asm-generic/iomap.h +++ b/include/asm-generic/iomap.h @@ -30,9 +30,16 @@ extern unsigned int ioread16(void __iomem *); extern unsigned int ioread16be(void __iomem *); extern unsigned int ioread32(void __iomem *); extern unsigned int ioread32be(void __iomem *); -#ifdef CONFIG_64BIT -extern u64 ioread64(void __iomem *); -extern u64 ioread64be(void __iomem *); + +#ifdef readq +#define ioread64_lo_hi ioread64_lo_hi +#define ioread64_hi_lo ioread64_hi_lo +#define ioread64be_lo_hi ioread64be_lo_hi +#define ioread64be_hi_lo ioread64be_hi_lo +extern u64 ioread64_lo_hi(void __iomem *addr); +extern u64 ioread64_hi_lo(void __iomem *addr); +extern u64 ioread64be_lo_hi(void __iomem *addr); +extern u64 ioread64be_hi_lo(void __iomem *addr); #endif extern void iowrite8(u8, void __iomem *); @@ -40,9 +47,16 @@ extern void iowrite16(u16, void __iomem *); extern void iowrite16be(u16, void __iomem *); extern void iowrite32(u32, void __iomem *); extern void iowrite32be(u32, void __iomem *); -#ifdef CONFIG_64BIT -extern void iowrite64(u64, void __iomem *); -extern void iowrite64be(u64, void __iomem *); + +#ifdef writeq +#define iowrite64_lo_hi iowrite64_lo_hi +#define iowrite64_hi_lo iowrite64_hi_lo +#define iowrite64be_lo_hi iowrite64be_lo_hi +#define iowrite64be_hi_lo iowrite64be_hi_lo +void iowrite64_lo_hi(u64 val, void __iomem *addr); +void iowrite64_hi_lo(u64 val, void __iomem *addr); +void iowrite64be_lo_hi(u64 val, void __iomem *addr); +void iowrite64be_hi_lo(u64 val, void __iomem *addr); #endif /* diff --git a/lib/iomap.c b/lib/iomap.c index fc3dcb4b238e..b993400d60bd 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -66,6 +66,7 @@ static void bad_io_access(unsigned long port, const char *access) #ifndef mmio_read16be #define mmio_read16be(addr) be16_to_cpu(__raw_readw(addr)) #define mmio_read32be(addr) be32_to_cpu(__raw_readl(addr)) +#define mmio_read64be(addr) be64_to_cpu(__raw_readq(addr)) #endif unsigned int ioread8(void __iomem *addr) @@ -99,6 +100,80 @@ EXPORT_SYMBOL(ioread16be); EXPORT_SYMBOL(ioread32); EXPORT_SYMBOL(ioread32be); +#ifdef readq +static u64 pio_read64_lo_hi(unsigned long port) +{ + u64 lo, hi; + + lo = inl(port); + hi = inl(port + sizeof(u32)); + + return lo | (hi << 32); +} + +static u64 pio_read64_hi_lo(unsigned long port) +{ + u64 lo, hi; + + hi = inl(port + sizeof(u32)); + lo = inl(port); + + return lo | (hi << 32); +} + +static u64 pio_read64be_lo_hi(unsigned long port) +{ + u64 lo, hi; + + lo = pio_read32be(port + sizeof(u32)); + hi = pio_read32be(port); + + return lo | (hi << 32); +} + +static u64 pio_read64be_hi_lo(unsigned long port) +{ + u64 lo, hi; + + hi = pio_read32be(port); + lo = pio_read32be(port + sizeof(u32)); + + return lo | (hi << 32); +} + +u64 ioread64_lo_hi(void __iomem *addr) +{ + IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr)); + return 0xLL; +} + +u64 ioread64_hi_lo(void __iomem *addr) +{ + IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr)); + return 0xLL; +} + +u64 ioread64be_lo_hi(void __iomem *addr) +{ + IO_COND(addr, return pio_read64be_lo_hi(port), + return mmio_read64be(addr)); + return 0xLL; +} + +u64 ioread64be_hi_lo(void __iomem *addr) +{ + IO_COND(addr, return pio_read64be_hi_lo(port), + return mmio_read64be(addr)); + return 0xLL; +} + +EXPORT_SYMBOL(ioread64_lo_hi); +EXPORT_SYMBOL(ioread64_hi_lo); +EXPORT_SYMBOL(ioread64be_lo_hi); +EXPORT_SYMBOL(ioread64be_hi_lo); + +#endif /* readq */ + #ifndef pio_write16be #define pio_write16be(val,port) outw(swab16(val),port) #define pio_write32be(val,port) outl(swab32(val),port) @@ -107,6 +182,7 @@ EXPORT_SYMBOL(ioread32be); #ifndef mmio_write16be #define mmio_write16be(val,port)
[PATCH v3 2/4] io-64-nonatomic: add io{read|write}64[be]{_lo_hi|_hi_lo} macros
This patch adds generic io{read|write}64[be]{_lo_hi|_hi_lo} macros if they are not already defined by the architecture. (As they are provided by the generic iomap library). The patch also points io{read|write}64[be] to the variant specified by the header name. This is because new drivers are encouraged to use ioreadXX, et al instead of readX[1], et al -- and mixing ioreadXX with readq is pretty ugly. [1] ldd3: section 9.4.2 Signed-off-by: Logan Gunthorpecc: Christoph Hellwig cc: Arnd Bergmann cc: Alan Cox cc: Greg Kroah-Hartman squash! io-64-nonatomic: add io{read|write}64[be] macros --- include/linux/io-64-nonatomic-hi-lo.h | 62 +++ include/linux/io-64-nonatomic-lo-hi.h | 60 + 2 files changed, 122 insertions(+) diff --git a/include/linux/io-64-nonatomic-hi-lo.h b/include/linux/io-64-nonatomic-hi-lo.h index defcc4644ce3..845e67d4b1d2 100644 --- a/include/linux/io-64-nonatomic-hi-lo.h +++ b/include/linux/io-64-nonatomic-hi-lo.h @@ -54,4 +54,66 @@ static inline void hi_lo_writeq_relaxed(__u64 val, volatile void __iomem *addr) #define writeq_relaxed hi_lo_writeq_relaxed #endif +#ifndef ioread64_hi_lo +#define ioread64_hi_lo ioread64_hi_lo +static inline u64 ioread64_hi_lo(void __iomem *addr) +{ + const u32 __iomem *p = addr; + u32 low, high; + + high = ioread32(p + 1); + low = ioread32(p); + + return low + ((u64)high << 32); +} +#endif + +#ifndef iowrite64_hi_lo +#define iowrite64_hi_lo iowrite64_hi_lo +static inline void iowrite64_hi_lo(u64 val, void __iomem *addr) +{ + iowrite32(val >> 32, addr + sizeof(u32)); + iowrite32(val, addr); +} +#endif + +#ifndef ioread64be_hi_lo +#define ioread64be_hi_lo ioread64be_hi_lo +static inline u64 ioread64be_hi_lo(void __iomem *addr) +{ + const u32 __iomem *p = addr; + u32 low, high; + + high = ioread32be(p); + low = ioread32be(p + 1); + + return low + ((u64)high << 32); +} +#endif + +#ifndef iowrite64be_hi_lo +#define iowrite64be_hi_lo iowrite64be_hi_lo +static inline void iowrite64be_hi_lo(u64 val, void __iomem *addr) +{ + iowrite32be(val >> 32, addr); + iowrite32be(val, addr + sizeof(u32)); +} +#endif + +#ifndef ioread64 +#define ioread64 ioread64_hi_lo +#endif + +#ifndef iowrite64 +#define iowrite64 iowrite64_hi_lo +#endif + +#ifndef ioread64be +#define ioread64be(p) ioread64be_hi_lo +#endif + +#ifndef iowrite64be +#define iowrite64be(v, p) iowrite64be_hi_lo +#endif + #endif /* _LINUX_IO_64_NONATOMIC_HI_LO_H_ */ diff --git a/include/linux/io-64-nonatomic-lo-hi.h b/include/linux/io-64-nonatomic-lo-hi.h index 084461a4e5ab..7ffa928a07fb 100644 --- a/include/linux/io-64-nonatomic-lo-hi.h +++ b/include/linux/io-64-nonatomic-lo-hi.h @@ -54,4 +54,64 @@ static inline void lo_hi_writeq_relaxed(__u64 val, volatile void __iomem *addr) #define writeq_relaxed lo_hi_writeq_relaxed #endif +#ifndef ioread64_lo_hi +#define ioread64_lo_hi ioread64_lo_hi +static inline u64 ioread64_lo_hi(void __iomem *addr) +{ + u32 low, high; + + low = ioread32(addr); + high = ioread32(addr + sizeof(u32)); + + return low + ((u64)high << 32); +} +#endif + +#ifndef iowrite64_lo_hi +#define iowrite64_lo_hi iowrite64_lo_hi +static inline void iowrite64_lo_hi(u64 val, void __iomem *addr) +{ + iowrite32(val, addr); + iowrite32(val >> 32, addr + sizeof(u32)); +} +#endif + +#ifndef ioread64be_lo_hi +#define ioread64be_lo_hi ioread64be_lo_hi +static inline u64 ioread64be_lo_hi(void __iomem *addr) +{ + u32 low, high; + + low = ioread32be(addr + sizeof(u32)); + high = ioread32be(addr); + + return low + ((u64)high << 32); +} +#endif + +#ifndef iowrite64be_lo_hi +#define iowrite64be_lo_hi iowrite64be_lo_hi +static inline void iowrite64be_lo_hi(u64 val, void __iomem *addr) +{ + iowrite32be(val, addr + sizeof(u32)); + iowrite32be(val >> 32, addr); +} +#endif + +#ifndef ioread64 +#define ioread64 ioread64_lo_hi +#endif + +#ifndef iowrite64 +#define iowrite64 iowrite64_lo_hi +#endif + +#ifndef ioread64be +#define ioread64be(p) ioread64be_lo_hi +#endif + +#ifndef iowrite64be +#define iowrite64be(v, p) iowrite64be_lo_hi +#endif + #endif /* _LINUX_IO_64_NONATOMIC_LO_HI_H_ */ -- 2.11.0
[PATCH v3 3/4] ntb: ntb_hw_intel: use io-64-nonatomic instead of in-driver hacks
Now that ioread64 and iowrite64 are available in io-64-nonatomic, we can remove the hack at the top of ntb_hw_intel.c and replace it with an include. Signed-off-by: Logan GunthorpeCc: Jon Mason Cc: Allen Hubbe Acked-by: Dave Jiang --- drivers/ntb/hw/intel/ntb_hw_intel.c | 31 +-- 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/drivers/ntb/hw/intel/ntb_hw_intel.c b/drivers/ntb/hw/intel/ntb_hw_intel.c index 7b3b6fd63d7d..13978bca47b8 100644 --- a/drivers/ntb/hw/intel/ntb_hw_intel.c +++ b/drivers/ntb/hw/intel/ntb_hw_intel.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "ntb_hw_intel.h" @@ -153,35 +154,6 @@ MODULE_PARM_DESC(xeon_b2b_dsd_bar5_addr32, static inline enum ntb_topo xeon_ppd_topo(struct intel_ntb_dev *ndev, u8 ppd); static int xeon_init_isr(struct intel_ntb_dev *ndev); -#ifndef ioread64 -#ifdef readq -#define ioread64 readq -#else -#define ioread64 _ioread64 -static inline u64 _ioread64(void __iomem *mmio) -{ - u64 low, high; - - low = ioread32(mmio); - high = ioread32(mmio + sizeof(u32)); - return low | (high << 32); -} -#endif -#endif - -#ifndef iowrite64 -#ifdef writeq -#define iowrite64 writeq -#else -#define iowrite64 _iowrite64 -static inline void _iowrite64(u64 val, void __iomem *mmio) -{ - iowrite32(val, mmio); - iowrite32(val >> 32, mmio + sizeof(u32)); -} -#endif -#endif - static inline int pdev_is_atom(struct pci_dev *pdev) { switch (pdev->device) { @@ -3008,4 +2980,3 @@ static void __exit intel_ntb_pci_driver_exit(void) debugfs_remove_recursive(debugfs_dir); } module_exit(intel_ntb_pci_driver_exit); - -- 2.11.0
[PATCH v3 4/4] crypto: caam: cleanup CONFIG_64BIT ifdefs when using io{read|write}64
From: Horia GeantăWe can now make use of the io-64-nonatomic-hi-lo header to always provide 64 bit IO operations. So this patch cleans up the extra CONFIG_64BIT ifdefs. To be consistent with CAAM engine HW spec: in case of 64-bit registers, irrespective of device endianness, the lower address should be read from / written to first, followed by the upper address. Indeed the I/O accessors in CAAM driver currently don't follow the spec, however this is a good opportunity to fix the code. Signed-off-by: Horia Geantă Signed-off-by: Logan Gunthorpe Cc: Horia Geantă Cc: Dan Douglass Cc: Herbert Xu Cc: "David S. Miller" --- drivers/crypto/caam/regs.h | 35 +-- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index 84d2f838a063..0c45505458e7 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -9,7 +9,7 @@ #include #include -#include +#include /* * Architecture-specific register access methods @@ -134,50 +134,25 @@ static inline void clrsetbits_32(void __iomem *reg, u32 clear, u32 set) *base + 0x : least-significant 32 bits *base + 0x0004 : most-significant 32 bits */ -#ifdef CONFIG_64BIT static inline void wr_reg64(void __iomem *reg, u64 data) { +#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX if (caam_little_end) iowrite64(data, reg); else - iowrite64be(data, reg); -} - -static inline u64 rd_reg64(void __iomem *reg) -{ - if (caam_little_end) - return ioread64(reg); - else - return ioread64be(reg); -} - -#else /* CONFIG_64BIT */ -static inline void wr_reg64(void __iomem *reg, u64 data) -{ -#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX - if (caam_little_end) { - wr_reg32((u32 __iomem *)(reg) + 1, data >> 32); - wr_reg32((u32 __iomem *)(reg), data); - } else #endif - { - wr_reg32((u32 __iomem *)(reg), data >> 32); - wr_reg32((u32 __iomem *)(reg) + 1, data); - } + iowrite64be(data, reg); } static inline u64 rd_reg64(void __iomem *reg) { #ifndef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX if (caam_little_end) - return ((u64)rd_reg32((u32 __iomem *)(reg) + 1) << 32 | - (u64)rd_reg32((u32 __iomem *)(reg))); + return ioread64(reg); else #endif - return ((u64)rd_reg32((u32 __iomem *)(reg)) << 32 | - (u64)rd_reg32((u32 __iomem *)(reg) + 1)); + return ioread64be(reg); } -#endif /* CONFIG_64BIT */ #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT #ifdef CONFIG_SOC_IMX7D -- 2.11.0
Re: [PATCH 14/14] staging: ccree: fix block comment style
On Tue, Jun 27, 2017 at 9:27 AM, Gilad Ben-Yossefwrote: > Align block comments according to coding style. > > Signed-off-by: Gilad Ben-Yossef > --- > drivers/staging/ccree/cc_hw_queue_defs.h | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/staging/ccree/cc_hw_queue_defs.h > b/drivers/staging/ccree/cc_hw_queue_defs.h > index f11487a..e6b8cea 100644 > --- a/drivers/staging/ccree/cc_hw_queue_defs.h > +++ b/drivers/staging/ccree/cc_hw_queue_defs.h > @@ -23,8 +23,8 @@ > #include > > > /** > -* DEFINITIONS > -**/ > + * DEFINITIONS > + > **/ I think if you change to the preferred block comment format, you should also drop these lines full of asterisks. I'm not sure why a multi-line comment is warranted here, anyway. Frans
Re: [PATCH] Stagingdriver cctree: Fix for checkpatch warning
On Tue, Jun 27, 2017 at 11:47:56AM +0530, bincy_k_phi...@yahoo.co.in wrote: > From: Bincy K Philip> > Trivial fix for Line over 80 characters > > Moved the comment to top of the definition > --- > drivers/staging/ccree/cc_hw_queue_defs.h | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) Always use scripts/checkpatch.pl on your patch so you don't get a grumpy maintaner telling you to run scripts/checkpatch.pl on your patch :(
Re: [PATCH 0/2] staging: ccree: Fix coding style and remove warnings
On Thu, Jun 29, 2017 at 04:13:38PM +0530, karthik wrote: > On Wednesday 28 June 2017 03:15 PM, Gilad Ben-Yossef wrote: > > Thank you Karthik, > > > > On Wed, Jun 28, 2017 at 12:37 PM,wrote: > > > From: Karthik Tummala > > > > > > This patch series fixes coding style and removes the following > > > checkpatch.pl warnings: > > > > > > Prefer using '"%s...", __func__' to using the function's name, > > > in a string. > > > > This one is good. > > > > > > Braces {} are not necessary for single statement blocks. > > > > I have already sent a patch addressing this and some other things > > yesterday/ > > > > > > > > Rebased on top of next-20170627. > > > Patches were tested and built on next-20170627 > > > > Can you please check patch 1 still applies after yesterdays patch series? > Hi, I have applied your patch series and then tried to apply patch 1 and it > failed. Should I wait until the patch series gets accepted and then continue > my work on the new linux-next release ? or is there any other option ? You need to rebased on top of these changes. All of them are now in staging-testing, soon to move to staging-next in a day or so. Rebase on there and resend. thanks, greg k-h
Re: [PATCH 0/2] staging: ccree: Fix coding style and remove warnings
On Wednesday 28 June 2017 03:15 PM, Gilad Ben-Yossef wrote: Thank you Karthik, On Wed, Jun 28, 2017 at 12:37 PM,wrote: From: Karthik Tummala This patch series fixes coding style and removes the following checkpatch.pl warnings: Prefer using '"%s...", __func__' to using the function's name, in a string. This one is good. Braces {} are not necessary for single statement blocks. I have already sent a patch addressing this and some other things yesterday/ Rebased on top of next-20170627. Patches were tested and built on next-20170627 Can you please check patch 1 still applies after yesterdays patch series? Hi, I have applied your patch series and then tried to apply patch 1 and it failed. Should I wait until the patch series gets accepted and then continue my work on the new linux-next release ? or is there any other option ? Karthik Tummala (2): staging: ccree: Use __func__ instead of function name staging: ccree: Remove braces {} for single statement blocks drivers/staging/ccree/ssi_aead.c | 48 1 file changed, 19 insertions(+), 29 deletions(-) -- 1.9.1 Thanks, Gilad Thanks karthik
Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
On 6/28/2017 4:42 PM, Horia Geantă wrote: > On 6/28/2017 4:27 PM, David Gstir wrote: >> Certain cipher modes like CTS expect the IV (req->info) of >> ablkcipher_request (or equivalently req->iv of skcipher_request) to >> contain the last ciphertext block when the {en,de}crypt operation is done. >> This is currently not the case for the CAAM driver which in turn breaks >> e.g. cts(cbc(aes)) when the CAAM driver is enabled. >> >> This patch fixes the CAAM driver to properly set the IV after the >> {en,de}crypt operation of ablkcipher finishes. >> >> This issue was revealed by the changes in the SW CTS mode in commit >> 0605c41cc53ca ("crypto: cts - Convert to skcipher") >> >> Cc:# 4.8+ >> Signed-off-by: David Gstir > Reviewed-by: Horia Geantă > Btw, instead of updating the IV in SW, CAAM engine could be programmed to do it - by saving the Context Register of the AES accelerator. Unfortunately this would require changes in quite a few places: shared descriptor, HW S/G generation logic, IV dma (un)mapping and maybe others. So it's better to have this fix now (which, considering size, is appropriate for -stable) and later, if needed, offload IV updating in HW. Regards, Horia
Re: wait in atomic context for an i2c crypto device to finish its execution
On Thu, Jun 29, 2017 at 1:05 PM, Tudor Ambaruswrote: > Hi, Herbert, all, > > I need an advice. I'm writing a driver for a crypto device that > communicates over I2C. Reads and writes from/to the i2c device are > sequential, I use a lock to synchronize the requests. > > There are no interrupts for the i2c client. Each request has to send > a command, to wait for an estimated time so that the device finishes to > execute the command and then to read the result. > > The crypto requests can be in atomic context. The maximum execution time > of a command in my crypto device is 115 milliseconds. Using a spinlock > to synchronize the requests and udelay for waiting the device to finish > the execution will block the core for at least 115 milliseconds. > If someone floods me with requests in atomic context, the core will be > doomed. > > As of now I see two possibilities when treating requests in atomic > context: > 1. fallback to the software implementation and hope that it's faster >than my hw. My device is capable of doing ecc privkey generation, >ecdh and ecdsa. > 2. use spinlock and udelay and block the core. > Perhaps I missed something but it sounds like a classic case to use a work queue: Have the crypto request API post a work queue item and return with -EINPROGRESS Run all interaction with the I2C device in a work item that has no problem sleeping for as long as you need it. Call the completion callback from the work item. Unless I've missed something this should work. Hope it helps, Gilad -- Gilad Ben-Yossef Chief Coffee Drinker "If you take a class in large-scale robotics, can you end up in a situation where the homework eats your dog?" -- Jean-Baptiste Queru
wait in atomic context for an i2c crypto device to finish its execution
Hi, Herbert, all, I need an advice. I'm writing a driver for a crypto device that communicates over I2C. Reads and writes from/to the i2c device are sequential, I use a lock to synchronize the requests. There are no interrupts for the i2c client. Each request has to send a command, to wait for an estimated time so that the device finishes to execute the command and then to read the result. The crypto requests can be in atomic context. The maximum execution time of a command in my crypto device is 115 milliseconds. Using a spinlock to synchronize the requests and udelay for waiting the device to finish the execution will block the core for at least 115 milliseconds. If someone floods me with requests in atomic context, the core will be doomed. As of now I see two possibilities when treating requests in atomic context: 1. fallback to the software implementation and hope that it's faster than my hw. My device is capable of doing ecc privkey generation, ecdh and ecdsa. 2. use spinlock and udelay and block the core. What would you advise me, how should I treat requests in atomic context? Thanks, ta
[PATCH 1/2] crypto: Make hwrng choose rng source by quality.
The hwrng core implementation currently doesn't consider the quality field of the struct hwrng. So the first registered rng is the winner and further rng sources even with much better quality are ignored. The behavior should be that always the best rng with the highest quality rate should be used as current rng source. Only if the user explicitly chooses a rng source (via writing a rng name to /sys/class/misc/hw_random) the decision for the best quality should be suppressed. This patch makes hwrng always hold a list of registered rng sources sorted decreasing by quality. On registration of a new hwrng source the list is updated and if the current rng source was not chosen by user and the new rng provides better quality set as new current rng source. Similar on unregistration of an rng, if it was the current used rng source the one with the next highest quality is used. If a rng source has been set via sysfs from userland as long as this one doesn't unregister it is kept as current rng regardless of registration of 'better' rng sources. Signed-off-by: Harald Freudenberger--- drivers/char/hw_random/core.c | 31 +-- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 503a41d..7fe47f8 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -28,7 +28,10 @@ #define RNG_MODULE_NAME"hw_random" static struct hwrng *current_rng; +/* the current rng has been explicitly chosen by user via sysfs */ +static int cur_rng_set_by_user; static struct task_struct *hwrng_fill; +/* list of registered rngs, sorted decending by quality */ static LIST_HEAD(rng_list); /* Protects rng_list and current_rng */ static DEFINE_MUTEX(rng_mutex); @@ -308,6 +311,8 @@ static ssize_t hwrng_attr_current_store(struct device *dev, break; } } + if (!err) + cur_rng_set_by_user = 1; mutex_unlock(_mutex); return err ? : len; @@ -417,6 +422,7 @@ int hwrng_register(struct hwrng *rng) { int err = -EINVAL; struct hwrng *old_rng, *tmp; + struct list_head *ptr; if (!rng->name || (!rng->data_read && !rng->read)) goto out; @@ -432,14 +438,26 @@ int hwrng_register(struct hwrng *rng) init_completion(>cleanup_done); complete(>cleanup_done); + /* rng_list is sorted by decreasing quality */ + list_for_each(ptr, _list) { + tmp = list_entry(ptr, struct hwrng, list); + if (tmp->quality < rng->quality) + break; + } + list_add_tail(>list, ptr); + old_rng = current_rng; err = 0; - if (!old_rng) { + if (!old_rng || + (!cur_rng_set_by_user && rng->quality > old_rng->quality)) { + /* +* Set new rng as current if no current rng or rng was +* not chosen by user and the new one has better quality. +*/ err = set_current_rng(rng); if (err) goto out_unlock; } - list_add_tail(>list, _list); if (old_rng && !rng->init) { /* @@ -466,12 +484,13 @@ void hwrng_unregister(struct hwrng *rng) list_del(>list); if (current_rng == rng) { drop_current_rng(); + cur_rng_set_by_user = 0; + /* rng_list is sorted by quality, use the best (=first) one */ if (!list_empty(_list)) { - struct hwrng *tail; - - tail = list_entry(rng_list.prev, struct hwrng, list); + struct hwrng *new_rng; - set_current_rng(tail); + new_rng = list_entry(rng_list.next, struct hwrng, list); + set_current_rng(new_rng); } } -- 2.7.4
Re: [PATCH v2 3/3] crypto: caam: cleanup CONFIG_64BIT ifdefs when using io{read|write}64
On 6/28/2017 7:51 PM, Logan Gunthorpe wrote: > > > On 28/06/17 04:20 AM, Arnd Bergmann wrote: >> On Wed, Jun 28, 2017 at 1:02 AM, Logan Gunthorpewrote: >>> #include >>> #include >>> -#include >>> +#include >> >> Here you include the hi-lo variant unconditionally. >> Arnd, thanks for spotting this. This was not in the patch I signed off. The lo-hi variant should be used instead for CAAM, see further below. >>> -#else /* CONFIG_64BIT */ >>> -static inline void wr_reg64(void __iomem *reg, u64 data) >>> -{ >>> -#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX >>> - if (caam_little_end) { >>> - wr_reg32((u32 __iomem *)(reg) + 1, data >> 32); >>> - wr_reg32((u32 __iomem *)(reg), data); >>> - } else >>> #endif >>> - { >>> - wr_reg32((u32 __iomem *)(reg), data >> 32); >>> - wr_reg32((u32 __iomem *)(reg) + 1, data); >>> - } >>> + iowrite64be(data, reg); >>> } >> >> However, the #else path here uses lo-hi instead. I guess we have >> to decide how to define iowrite64be_lo_hi() first: it could >> either byteswap the 64-bit value first, then write the two halves, >> or it could write the two halves, doing a 32-bit byte swap on >> each. > > Ok, I studied this a bit more: > > The lo_hi/hi_lo functions seem to always refer to the data being written > or read not to the address operated on. So, in the v3 version of this > set, which I'm working on, I've defined: > > static inline void iowrite64_hi_lo(u64 val, void __iomem *addr) > { > iowrite32(val >> 32, addr + sizeof(u32)); > iowrite32(val, addr); > } > > static inline void iowrite64be_hi_lo(u64 val, void __iomem *addr) > { > iowrite32be(val >> 32, addr); > iowrite32be(val, addr + sizeof(u32)); > } > > So the two hi_lo functions match both paths of the #if and thus, I > believe, the patch will be correct in v3 without changes. > To be consistent with CAAM engine HW spec: in case of 64-bit registers, irrespective of device endianness, the lower address should be read from / written to first, followed by the upper address. Indeed the I/O accessors in CAAM driver currently don't follow the spec, however this is a good opportunity to fix the code. I don't consider this requires a separate patch, as we haven't noticed any problem. I'd say a simple note in the commit message mentioning the change (lo-hi r/w order replacing hi-lo for little endian case) is enough. Thanks, Horia