diff options
86 files changed, 2106 insertions, 280 deletions
diff --git a/Documentation/dev-tools/sparse.rst b/Documentation/dev-tools/sparse.rst index 8c250e8a2105..78aa00a604a0 100644 --- a/Documentation/dev-tools/sparse.rst +++ b/Documentation/dev-tools/sparse.rst @@ -51,13 +51,6 @@ sure that bitwise types don't get mixed up (little-endian vs big-endian vs cpu-endian vs whatever), and there the constant "0" really _is_ special. -__bitwise__ - to be used for relatively compact stuff (gfp_t, etc.) that -is mostly warning-free and is supposed to stay that way. Warnings will -be generated without __CHECK_ENDIAN__. - -__bitwise - noisy stuff; in particular, __le*/__be* are that. We really -don't want to drown in noise unless we'd explicitly asked for it. - Using sparse for lock checking ------------------------------ @@ -109,9 +102,4 @@ be recompiled or not. The latter is a fast way to check the whole tree if you have already built it. The optional make variable CF can be used to pass arguments to sparse. The -build system passes -Wbitwise to sparse automatically. To perform endianness -checks, you may define __CHECK_ENDIAN__:: - - make C=2 CF="-D__CHECK_ENDIAN__" - -These checks are disabled by default as they generate a host of warnings. +build system passes -Wbitwise to sparse automatically. diff --git a/Documentation/translations/zh_CN/sparse.txt b/Documentation/translations/zh_CN/sparse.txt index cc144e581515..e41dc940e162 100644 --- a/Documentation/translations/zh_CN/sparse.txt +++ b/Documentation/translations/zh_CN/sparse.txt @@ -92,9 +92,4 @@ DaveJ 把每小时自动生成的 git 源码树 tar 包放在以下地址: 如果你已经编译了内核,用后一种方式可以很快地检查整个源码树。 make 的可选变量 CHECKFLAGS 可以用来向 sparse 工具传递参数。编译系统会自 -动向 sparse 工具传递 -Wbitwise 参数。你可以定义 __CHECK_ENDIAN__ 来进行 -大小尾检查。 - - make C=2 CHECKFLAGS="-D__CHECK_ENDIAN__" - -这些检查默认都是被关闭的,因为他们通常会产生大量的警告。 +动向 sparse 工具传递 -Wbitwise 参数。 diff --git a/MAINTAINERS b/MAINTAINERS index 7dc766390b73..299ee500f8fd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13013,6 +13013,7 @@ F: drivers/net/virtio_net.c F: drivers/block/virtio_blk.c F: include/linux/virtio_*.h F: include/uapi/linux/virtio_*.h +F: drivers/crypto/virtio/ VIRTIO DRIVERS FOR S390 M: Christian Borntraeger <borntraeger@de.ibm.com> @@ -13049,6 +13050,14 @@ S: Maintained F: drivers/virtio/virtio_input.c F: include/uapi/linux/virtio_input.h +VIRTIO CRYPTO DRIVER +M: Gonglei <arei.gonglei@huawei.com> +L: virtualization@lists.linux-foundation.org +L: linux-crypto@vger.kernel.org +S: Maintained +F: drivers/crypto/virtio/ +F: include/uapi/linux/virtio_crypto.h + VIA RHINE NETWORK DRIVER S: Orphan F: drivers/net/ethernet/via/via-rhine.c diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 21391faab068..e55d1f597db8 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -26,7 +26,7 @@ #include <linux/types.h> -typedef unsigned int __bitwise__ samsung_gpio_pull_t; +typedef unsigned int __bitwise samsung_gpio_pull_t; /* forward declaration if gpio-core.h hasn't been included */ struct samsung_gpio_chip; diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index b1fc29a697b7..80627187c8b6 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -40,5 +40,3 @@ hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci_qca.o hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o hci_uart-$(CONFIG_BT_HCIUART_MRVL) += hci_mrvl.o hci_uart-objs := $(hci_uart-y) - -ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 5649234b7316..8b00e79c2683 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -152,8 +152,8 @@ struct ports_device { spinlock_t c_ivq_lock; spinlock_t c_ovq_lock; - /* The current config space is stored here */ - struct virtio_console_config config; + /* max. number of ports this device can hold */ + u32 max_nr_ports; /* The virtio device we're associated with */ struct virtio_device *vdev; @@ -1649,11 +1649,11 @@ static void handle_control_message(struct virtio_device *vdev, break; } if (virtio32_to_cpu(vdev, cpkt->id) >= - portdev->config.max_nr_ports) { + portdev->max_nr_ports) { dev_warn(&portdev->vdev->dev, "Request for adding port with " "out-of-bound id %u, max. supported id: %u\n", - cpkt->id, portdev->config.max_nr_ports - 1); + cpkt->id, portdev->max_nr_ports - 1); break; } add_port(portdev, virtio32_to_cpu(vdev, cpkt->id)); @@ -1894,7 +1894,7 @@ static int init_vqs(struct ports_device *portdev) u32 i, j, nr_ports, nr_queues; int err; - nr_ports = portdev->config.max_nr_ports; + nr_ports = portdev->max_nr_ports; nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2; vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL); @@ -2047,13 +2047,13 @@ static int virtcons_probe(struct virtio_device *vdev) } multiport = false; - portdev->config.max_nr_ports = 1; + portdev->max_nr_ports = 1; /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */ if (!is_rproc_serial(vdev) && virtio_cread_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT, struct virtio_console_config, max_nr_ports, - &portdev->config.max_nr_ports) == 0) { + &portdev->max_nr_ports) == 0) { multiport = true; } diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 4d2b81f2b223..79564785ae30 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -555,4 +555,6 @@ config CRYPTO_DEV_ROCKCHIP source "drivers/crypto/chelsio/Kconfig" +source "drivers/crypto/virtio/Kconfig" + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index ad7250fa1348..bc53cb833a06 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -32,3 +32,4 @@ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sunxi-ss/ obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chelsio/ +obj-$(CONFIG_CRYPTO_DEV_VIRTIO) += virtio/ diff --git a/drivers/crypto/virtio/Kconfig b/drivers/crypto/virtio/Kconfig new file mode 100644 index 000000000000..d80f73366ae2 --- /dev/null +++ b/drivers/crypto/virtio/Kconfig @@ -0,0 +1,10 @@ +config CRYPTO_DEV_VIRTIO + tristate "VirtIO crypto driver" + depends on VIRTIO + select CRYPTO_AEAD + select CRYPTO_AUTHENC + select CRYPTO_BLKCIPHER + default m + help + This driver provides support for virtio crypto device. If you + choose 'M' here, this module will be called virtio_crypto. diff --git a/drivers/crypto/virtio/Makefile b/drivers/crypto/virtio/Makefile new file mode 100644 index 000000000000..dd342c947ff9 --- /dev/null +++ b/drivers/crypto/virtio/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_CRYPTO_DEV_VIRTIO) += virtio_crypto.o +virtio_crypto-objs := \ + virtio_crypto_algs.o \ + virtio_crypto_mgr.o \ + virtio_crypto_core.o diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c b/drivers/crypto/virtio/virtio_crypto_algs.c new file mode 100644 index 000000000000..c2374df9abae --- /dev/null +++ b/drivers/crypto/virtio/virtio_crypto_algs.c @@ -0,0 +1,540 @@ + /* Algorithms supported by virtio crypto device + * + * Authors: Gonglei <arei.gonglei@huawei.com> + * + * Copyright 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/scatterlist.h> +#include <crypto/algapi.h> +#include <linux/err.h> +#include <crypto/scatterwalk.h> +#include <linux/atomic.h> + +#include <uapi/linux/virtio_crypto.h> +#include "virtio_crypto_common.h" + +/* + * The algs_lock protects the below global virtio_crypto_active_devs + * and crypto algorithms registion. + */ +static DEFINE_MUTEX(algs_lock); +static unsigned int virtio_crypto_active_devs; + +static u64 virtio_crypto_alg_sg_nents_length(struct scatterlist *sg) +{ + u64 total = 0; + + for (total = 0; sg; sg = sg_next(sg)) + total += sg->length; + + return total; +} + +static int +virtio_crypto_alg_validate_key(int key_len, uint32_t *alg) +{ + switch (key_len) { + case AES_KEYSIZE_128: + case AES_KEYSIZE_192: + case AES_KEYSIZE_256: + *alg = VIRTIO_CRYPTO_CIPHER_AES_CBC; + break; + default: + pr_err("virtio_crypto: Unsupported key length: %d\n", + key_len); + return -EINVAL; + } + return 0; +} + +static int virtio_crypto_alg_ablkcipher_init_session( + struct virtio_crypto_ablkcipher_ctx *ctx, + uint32_t alg, const uint8_t *key, + unsigned int keylen, + int encrypt) +{ + struct scatterlist outhdr, key_sg, inhdr, *sgs[3]; + unsigned int tmp; + struct virtio_crypto *vcrypto = ctx->vcrypto; + int op = encrypt ? VIRTIO_CRYPTO_OP_ENCRYPT : VIRTIO_CRYPTO_OP_DECRYPT; + int err; + unsigned int num_out = 0, num_in = 0; + + /* + * Avoid to do DMA from the stack, switch to using + * dynamically-allocated for the key + */ + uint8_t *cipher_key = kmalloc(keylen, GFP_ATOMIC); + + if (!cipher_key) + return -ENOMEM; + + memcpy(cipher_key, key, keylen); + + spin_lock(&vcrypto->ctrl_lock); + /* Pad ctrl header */ + vcrypto->ctrl.header.opcode = + cpu_to_le32(VIRTIO_CRYPTO_CIPHER_CREATE_SESSION); + vcrypto->ctrl.header.algo = cpu_to_le32(alg); + /* Set the default dataqueue id to 0 */ + vcrypto->ctrl.header.queue_id = 0; + + vcrypto->input.status = cpu_to_le32(VIRTIO_CRYPTO_ERR); + /* Pad cipher's parameters */ + vcrypto->ctrl.u.sym_create_session.op_type = + cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER); + vcrypto->ctrl.u.sym_create_session.u.cipher.para.algo = + vcrypto->ctrl.header.algo; + vcrypto->ctrl.u.sym_create_session.u.cipher.para.keylen = + cpu_to_le32(keylen); + vcrypto->ctrl.u.sym_create_session.u.cipher.para.op = + cpu_to_le32(op); + + sg_init_one(&outhdr, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); + sgs[num_out++] = &outhdr; + + /* Set key */ + sg_init_one(&key_sg, cipher_key, keylen); + sgs[num_out++] = &key_sg; + + /* Return status and session id back */ + sg_init_one(&inhdr, &vcrypto->input, sizeof(vcrypto->input)); + sgs[num_out + num_in++] = &inhdr; + + err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, + num_in, vcrypto, GFP_ATOMIC); + if (err < 0) { + spin_unlock(&vcrypto->ctrl_lock); + kzfree(cipher_key); + return err; + } + virtqueue_kick(vcrypto->ctrl_vq); + + /* + * Trapping into the hypervisor, so the request should be + * handled immediately. + */ + while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && + !virtqueue_is_broken(vcrypto->ctrl_vq)) + cpu_relax(); + + if (le32_to_cpu(vcrypto->input.status) != VIRTIO_CRYPTO_OK) { + spin_unlock(&vcrypto->ctrl_lock); + pr_err("virtio_crypto: Create session failed status: %u\n", + le32_to_cpu(vcrypto->input.status)); + kzfree(cipher_key); + return -EINVAL; + } + + if (encrypt) + ctx->enc_sess_info.session_id = + le64_to_cpu(vcrypto->input.session_id); + else + ctx->dec_sess_info.session_id = + le64_to_cpu(vcrypto->input.session_id); + + spin_unlock(&vcrypto->ctrl_lock); + + kzfree(cipher_key); + return 0; +} + +static int virtio_crypto_alg_ablkcipher_close_session( + struct virtio_crypto_ablkcipher_ctx *ctx, + int encrypt) +{ + struct scatterlist outhdr, status_sg, *sgs[2]; + unsigned int tmp; + struct virtio_crypto_destroy_session_req *destroy_session; + struct virtio_crypto *vcrypto = ctx->vcrypto; + int err; + unsigned int num_out = 0, num_in = 0; + + spin_lock(&vcrypto->ctrl_lock); + vcrypto->ctrl_status.status = VIRTIO_CRYPTO_ERR; + /* Pad ctrl header */ + vcrypto->ctrl.header.opcode = + cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION); + /* Set the default virtqueue id to 0 */ + vcrypto->ctrl.header.queue_id = 0; + + destroy_session = &vcrypto->ctrl.u.destroy_session; + + if (encrypt) + destroy_session->session_id = + cpu_to_le64(ctx->enc_sess_info.session_id); + else + destroy_session->session_id = + cpu_to_le64(ctx->dec_sess_info.session_id); + + sg_init_one(&outhdr, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); + sgs[num_out++] = &outhdr; + + /* Return status and session id back */ + sg_init_one(&status_sg, &vcrypto->ctrl_status.status, + sizeof(vcrypto->ctrl_status.status)); + sgs[num_out + num_in++] = &status_sg; + + err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, + num_in, vcrypto, GFP_ATOMIC); + if (err < 0) { + spin_unlock(&vcrypto->ctrl_lock); + return err; + } + virtqueue_kick(vcrypto->ctrl_vq); + + while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && + !virtqueue_is_broken(vcrypto->ctrl_vq)) + cpu_relax(); + + if (vcrypto->ctrl_status.status != VIRTIO_CRYPTO_OK) { + spin_unlock(&vcrypto->ctrl_lock); + pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", + vcrypto->ctrl_status.status, + destroy_session->session_id); + + return -EINVAL; + } |