<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-dev/drivers/crypto/virtio, branch master</title>
<subtitle>Linux kernel development work - see feature branches</subtitle>
<id>https://git.zx2c4.com/linux-dev/atom/drivers/crypto/virtio?h=master</id>
<link rel='self' href='https://git.zx2c4.com/linux-dev/atom/drivers/crypto/virtio?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/'/>
<updated>2022-09-27T22:30:48Z</updated>
<entry>
<title>virtio-crypto: fix memory-leak</title>
<updated>2022-09-27T22:30:48Z</updated>
<author>
<name>lei he</name>
<email>helei.sig11@bytedance.com</email>
</author>
<published>2022-09-19T07:51:58Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=1bedcf22c081a6e9943f09937b2da8d3ef52d20d'/>
<id>urn:sha1:1bedcf22c081a6e9943f09937b2da8d3ef52d20d</id>
<content type='text'>
Fix memory-leak for virtio-crypto akcipher request, this problem is
introduced by 59ca6c93387d3(virtio-crypto: implement RSA algorithm).
The leak can be reproduced and tested with the following script
inside virtual machine:

#!/bin/bash

LOOP_TIMES=10000

# required module: pkcs8_key_parser, virtio_crypto
modprobe pkcs8_key_parser # if CONFIG_PKCS8_PRIVATE_KEY_PARSER=m
modprobe virtio_crypto # if CONFIG_CRYPTO_DEV_VIRTIO=m
rm -rf /tmp/data
dd if=/dev/random of=/tmp/data count=1 bs=230

# generate private key and self-signed cert
openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem \
		-outform der -out cert.der  \
		-subj "/C=CN/ST=GD/L=SZ/O=vihoo/OU=dev/CN=always.com/emailAddress=yy@always.com"
# convert private key from pem to der
openssl pkcs8 -in key.pem -topk8 -nocrypt -outform DER -out key.der

# add key
PRIV_KEY_ID=`cat key.der | keyctl padd asymmetric test_priv_key @s`
echo "priv key id = "$PRIV_KEY_ID
PUB_KEY_ID=`cat cert.der | keyctl padd asymmetric test_pub_key @s`
echo "pub key id = "$PUB_KEY_ID

# query key
keyctl pkey_query $PRIV_KEY_ID 0
keyctl pkey_query $PUB_KEY_ID 0

# here we only run pkey_encrypt becasuse it is the fastest interface
function bench_pub() {
	keyctl pkey_encrypt $PUB_KEY_ID 0 /tmp/data enc=pkcs1 &gt;/tmp/enc.pub
}

# do bench_pub in loop to obtain the memory leak
for (( i = 0; i &lt; ${LOOP_TIMES}; ++i )); do
	bench_pub
done

Signed-off-by: lei he &lt;helei.sig11@bytedance.com&gt;
Acked-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
Message-Id: &lt;20220919075158.3625-1-helei.sig11@bytedance.com&gt;
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>virtio-crypto: enable retry for virtio-crypto-dev</title>
<updated>2022-05-31T16:45:09Z</updated>
<author>
<name>lei he</name>
<email>helei.sig11@bytedance.com</email>
</author>
<published>2022-05-06T13:16:27Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=4e0d352af04cf4e019d3e45229eaaff9e8ffb33d'/>
<id>urn:sha1:4e0d352af04cf4e019d3e45229eaaff9e8ffb33d</id>
<content type='text'>
Enable retry for virtio-crypto-dev, so that crypto-engine
can process cipher-requests parallelly.

Cc: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Cc: Jason Wang &lt;jasowang@redhat.com&gt;
Cc: Gonglei &lt;arei.gonglei@huawei.com&gt;
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
Signed-off-by: lei he &lt;helei.sig11@bytedance.com&gt;
Signed-off-by: zhenwei pi &lt;pizhenwei@bytedance.com&gt;
Message-Id: &lt;20220506131627.180784-6-pizhenwei@bytedance.com&gt;
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>virtio-crypto: adjust dst_len at ops callback</title>
<updated>2022-05-31T16:45:09Z</updated>
<author>
<name>lei he</name>
<email>helei.sig11@bytedance.com</email>
</author>
<published>2022-05-06T13:16:26Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=a36bd0ad9fbf69d0d711b1c105954ce8d6cc144a'/>
<id>urn:sha1:a36bd0ad9fbf69d0d711b1c105954ce8d6cc144a</id>
<content type='text'>
For some akcipher operations(eg, decryption of pkcs1pad(rsa)),
the length of returned result maybe less than akcipher_req-&gt;dst_len,
we need to recalculate the actual dst_len through the virt-queue
protocol.

Cc: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Cc: Jason Wang &lt;jasowang@redhat.com&gt;
Cc: Gonglei &lt;arei.gonglei@huawei.com&gt;
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
Signed-off-by: lei he &lt;helei.sig11@bytedance.com&gt;
Signed-off-by: zhenwei pi &lt;pizhenwei@bytedance.com&gt;
Message-Id: &lt;20220506131627.180784-5-pizhenwei@bytedance.com&gt;
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>virtio-crypto: wait ctrl queue instead of busy polling</title>
<updated>2022-05-31T16:45:09Z</updated>
<author>
<name>zhenwei pi</name>
<email>pizhenwei@bytedance.com</email>
</author>
<published>2022-05-06T13:16:25Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=977231e8d45657871a86fe3c7bed94921d04e447'/>
<id>urn:sha1:977231e8d45657871a86fe3c7bed94921d04e447</id>
<content type='text'>
Originally, after submitting request into virtio crypto control
queue, the guest side polls the result from the virt queue. This
works like following:
    CPU0   CPU1               ...             CPUx  CPUy
     |      |                                  |     |
     \      \                                  /     /
      \--------spin_lock(&amp;vcrypto-&gt;ctrl_lock)-------/
                           |
                 virtqueue add &amp; kick
                           |
                  busy poll virtqueue
                           |
              spin_unlock(&amp;vcrypto-&gt;ctrl_lock)
                          ...

There are two problems:
1, The queue depth is always 1, the performance of a virtio crypto
   device gets limited. Multi user processes share a single control
   queue, and hit spin lock race from control queue. Test on Intel
   Platinum 8260, a single worker gets ~35K/s create/close session
   operations, and 8 workers get ~40K/s operations with 800% CPU
   utilization.
2, The control request is supposed to get handled immediately, but
   in the current implementation of QEMU(v6.2), the vCPU thread kicks
   another thread to do this work, the latency also gets unstable.
   Tracking latency of virtio_crypto_alg_akcipher_close_session in 5s:
        usecs               : count     distribution
         0 -&gt; 1          : 0        |                        |
         2 -&gt; 3          : 7        |                        |
         4 -&gt; 7          : 72       |                        |
         8 -&gt; 15         : 186485   |************************|
        16 -&gt; 31         : 687      |                        |
        32 -&gt; 63         : 5        |                        |
        64 -&gt; 127        : 3        |                        |
       128 -&gt; 255        : 1        |                        |
       256 -&gt; 511        : 0        |                        |
       512 -&gt; 1023       : 0        |                        |
      1024 -&gt; 2047       : 0        |                        |
      2048 -&gt; 4095       : 0        |                        |
      4096 -&gt; 8191       : 0        |                        |
      8192 -&gt; 16383      : 2        |                        |
This means that a CPU may hold vcrypto-&gt;ctrl_lock as long as 8192~16383us.

To improve the performance of control queue, a request on control queue
waits completion instead of busy polling to reduce lock racing, and gets
completed by control queue callback.
    CPU0   CPU1               ...             CPUx  CPUy
     |      |                                  |     |
     \      \                                  /     /
      \--------spin_lock(&amp;vcrypto-&gt;ctrl_lock)-------/
                           |
                 virtqueue add &amp; kick
                           |
      ---------spin_unlock(&amp;vcrypto-&gt;ctrl_lock)------
     /      /                                  \     \
     |      |                                  |     |
    wait   wait                               wait  wait

Test this patch, the guest side get ~200K/s operations with 300% CPU
utilization.

Cc: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Cc: Jason Wang &lt;jasowang@redhat.com&gt;
Cc: Gonglei &lt;arei.gonglei@huawei.com&gt;
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
Signed-off-by: zhenwei pi &lt;pizhenwei@bytedance.com&gt;
Message-Id: &lt;20220506131627.180784-4-pizhenwei@bytedance.com&gt;
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>virtio-crypto: use private buffer for control request</title>
<updated>2022-05-31T16:45:09Z</updated>
<author>
<name>zhenwei pi</name>
<email>pizhenwei@bytedance.com</email>
</author>
<published>2022-05-06T13:16:24Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=0756ad15b1fef287d4d8fa11bc36ea77a5c42e4a'/>
<id>urn:sha1:0756ad15b1fef287d4d8fa11bc36ea77a5c42e4a</id>
<content type='text'>
Originally, all of the control requests share a single buffer(
ctrl &amp; input &amp; ctrl_status fields in struct virtio_crypto), this
allows queue depth 1 only, the performance of control queue gets
limited by this design.

In this patch, each request allocates request buffer dynamically, and
free buffer after request, so the scope protected by ctrl_lock also
get optimized here.
It's possible to optimize control queue depth in the next step.

A necessary comment is already in code, still describe it again:
/*
 * Note: there are padding fields in request, clear them to zero before
 * sending to host to avoid to divulge any information.
 * Ex, virtio_crypto_ctrl_request::ctrl::u::destroy_session::padding[48]
 */
So use kzalloc to allocate buffer of struct virtio_crypto_ctrl_request.

Potentially dereferencing uninitialized variables:
Reported-by: kernel test robot &lt;lkp@intel.com&gt;
Reported-by: Dan Carpenter &lt;dan.carpenter@oracle.com&gt;

Cc: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Cc: Jason Wang &lt;jasowang@redhat.com&gt;
Cc: Gonglei &lt;arei.gonglei@huawei.com&gt;
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
Signed-off-by: zhenwei pi &lt;pizhenwei@bytedance.com&gt;
Message-Id: &lt;20220506131627.180784-3-pizhenwei@bytedance.com&gt;
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>virtio-crypto: change code style</title>
<updated>2022-05-31T16:45:08Z</updated>
<author>
<name>zhenwei pi</name>
<email>pizhenwei@bytedance.com</email>
</author>
<published>2022-05-06T13:16:23Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=6fd763d155860eb7ea3a93c8b3bf926940ffa3fb'/>
<id>urn:sha1:6fd763d155860eb7ea3a93c8b3bf926940ffa3fb</id>
<content type='text'>
Use temporary variable to make code easy to read and maintain.
	/* Pad cipher's parameters */
        vcrypto-&gt;ctrl.u.sym_create_session.op_type =
                cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER);
        vcrypto-&gt;ctrl.u.sym_create_session.u.cipher.para.algo =
                vcrypto-&gt;ctrl.header.algo;
        vcrypto-&gt;ctrl.u.sym_create_session.u.cipher.para.keylen =
                cpu_to_le32(keylen);
        vcrypto-&gt;ctrl.u.sym_create_session.u.cipher.para.op =
                cpu_to_le32(op);
--&gt;
	sym_create_session = &amp;ctrl-&gt;u.sym_create_session;
	sym_create_session-&gt;op_type = cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER);
	sym_create_session-&gt;u.cipher.para.algo = ctrl-&gt;header.algo;
	sym_create_session-&gt;u.cipher.para.keylen = cpu_to_le32(keylen);
	sym_create_session-&gt;u.cipher.para.op = cpu_to_le32(op);

The new style shows more obviously:
- the variable we want to operate.
- an assignment statement in a single line.

Cc: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Cc: Jason Wang &lt;jasowang@redhat.com&gt;
Cc: Gonglei &lt;arei.gonglei@huawei.com&gt;
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
Signed-off-by: zhenwei pi &lt;pizhenwei@bytedance.com&gt;
Message-Id: &lt;20220506131627.180784-2-pizhenwei@bytedance.com&gt;
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>virtio-crypto: rename skcipher algs</title>
<updated>2022-03-28T20:52:58Z</updated>
<author>
<name>zhenwei pi</name>
<email>pizhenwei@bytedance.com</email>
</author>
<published>2022-03-02T03:39:17Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=ea993de113b85557ed34da8f7b4af0629550e023'/>
<id>urn:sha1:ea993de113b85557ed34da8f7b4af0629550e023</id>
<content type='text'>
Suggested by Gonglei, rename virtio_crypto_algs.c to
virtio_crypto_skcipher_algs.c. Also minor changes for function name.
Thus the function of source files get clear: skcipher services in
virtio_crypto_skcipher_algs.c and akcipher services in
virtio_crypto_akcipher_algs.c.

Signed-off-by: zhenwei pi &lt;pizhenwei@bytedance.com&gt;
Link: https://lore.kernel.org/r/20220302033917.1295334-5-pizhenwei@bytedance.com
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
</content>
</entry>
<entry>
<title>virtio-crypto: implement RSA algorithm</title>
<updated>2022-03-28T20:52:58Z</updated>
<author>
<name>zhenwei pi</name>
<email>pizhenwei@bytedance.com</email>
</author>
<published>2022-03-02T03:39:16Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=59ca6c93387d325e96577d8bd4c23c78c1491c11'/>
<id>urn:sha1:59ca6c93387d325e96577d8bd4c23c78c1491c11</id>
<content type='text'>
Support rsa &amp; pkcs1pad(rsa,sha1) with priority 150.

Test with QEMU built-in backend, it works fine.
1, The self-test framework of crypto layer works fine in guest kernel
2, Test with Linux guest(with asym support), the following script
test(note that pkey_XXX is supported only in a newer version of keyutils):
  - both public key &amp; private key
  - create/close session
  - encrypt/decrypt/sign/verify basic driver operation
  - also test with kernel crypto layer(pkey add/query)

All the cases work fine.

rm -rf *.der *.pem *.pfx
modprobe pkcs8_key_parser # if CONFIG_PKCS8_PRIVATE_KEY_PARSER=m
rm -rf /tmp/data
dd if=/dev/random of=/tmp/data count=1 bs=226

openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -subj "/C=CN/ST=BJ/L=HD/O=qemu/OU=dev/CN=qemu/emailAddress=qemu@qemu.org"
openssl pkcs8 -in key.pem -topk8 -nocrypt -outform DER -out key.der
openssl x509 -in cert.pem -inform PEM -outform DER -out cert.der

PRIV_KEY_ID=`cat key.der | keyctl padd asymmetric test_priv_key @s`
echo "priv key id = "$PRIV_KEY_ID
PUB_KEY_ID=`cat cert.der | keyctl padd asymmetric test_pub_key @s`
echo "pub key id = "$PUB_KEY_ID

keyctl pkey_query $PRIV_KEY_ID 0
keyctl pkey_query $PUB_KEY_ID 0

echo "Enc with priv key..."
keyctl pkey_encrypt $PRIV_KEY_ID 0 /tmp/data enc=pkcs1 &gt;/tmp/enc.priv
echo "Dec with pub key..."
keyctl pkey_decrypt $PRIV_KEY_ID 0 /tmp/enc.priv enc=pkcs1 &gt;/tmp/dec
cmp /tmp/data /tmp/dec

echo "Sign with priv key..."
keyctl pkey_sign $PRIV_KEY_ID 0 /tmp/data enc=pkcs1 hash=sha1 &gt; /tmp/sig
echo "Verify with pub key..."
keyctl pkey_verify $PRIV_KEY_ID 0 /tmp/data /tmp/sig enc=pkcs1 hash=sha1

echo "Enc with pub key..."
keyctl pkey_encrypt $PUB_KEY_ID 0 /tmp/data enc=pkcs1 &gt;/tmp/enc.pub
echo "Dec with priv key..."
keyctl pkey_decrypt $PRIV_KEY_ID 0 /tmp/enc.pub enc=pkcs1 &gt;/tmp/dec
cmp /tmp/data /tmp/dec

echo "Verify with pub key..."
keyctl pkey_verify $PUB_KEY_ID 0 /tmp/data /tmp/sig enc=pkcs1 hash=sha1

[1 compiling warning during development]
Reported-by: kernel test robot &lt;lkp@intel.com&gt;

Co-developed-by: lei he &lt;helei.sig11@bytedance.com&gt;
Signed-off-by: lei he &lt;helei.sig11@bytedance.com&gt;
Signed-off-by: zhenwei pi &lt;pizhenwei@bytedance.com&gt;
Link: https://lore.kernel.org/r/20220302033917.1295334-4-pizhenwei@bytedance.com
Reviewed-by: Gonglei &lt;arei.gonglei@huawei.com&gt;
Signed-off-by: Nathan Chancellor &lt;nathan@kernel.org&gt; #Kconfig tweaks
Link: https://lore.kernel.org/r/20220308205309.2192502-1-nathan@kernel.org
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>virtio: wrap config-&gt;reset calls</title>
<updated>2022-01-14T23:50:52Z</updated>
<author>
<name>Michael S. Tsirkin</name>
<email>mst@redhat.com</email>
</author>
<published>2021-10-13T10:55:44Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=d9679d0013a66849f23057978f92e76b255c50aa'/>
<id>urn:sha1:d9679d0013a66849f23057978f92e76b255c50aa</id>
<content type='text'>
This will enable cleanups down the road.
The idea is to disable cbs, then add "flush_queued_cbs" callback
as a parameter, this way drivers can flush any work
queued after callbacks have been disabled.

Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Link: https://lore.kernel.org/r/20211013105226.20225-1-mst@redhat.com
Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
</content>
</entry>
<entry>
<title>crypto: virtio - Replace deprecated CPU-hotplug functions.</title>
<updated>2021-08-12T11:16:58Z</updated>
<author>
<name>Sebastian Andrzej Siewior</name>
<email>bigeasy@linutronix.de</email>
</author>
<published>2021-08-03T14:15:55Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/linux-dev/commit/?id=d01a9f7009c3812a8955b7ae5798470cd6ab3590'/>
<id>urn:sha1:d01a9f7009c3812a8955b7ae5798470cd6ab3590</id>
<content type='text'>
The functions get_online_cpus() and put_online_cpus() have been
deprecated during the CPU hotplug rework. They map directly to
cpus_read_lock() and cpus_read_unlock().

Replace deprecated CPU-hotplug functions with the official version.
The behavior remains unchanged.

Cc: Gonglei &lt;arei.gonglei@huawei.com&gt;
Cc: "Michael S. Tsirkin" &lt;mst@redhat.com&gt;
Cc: Jason Wang &lt;jasowang@redhat.com&gt;
Cc: Herbert Xu &lt;herbert@gondor.apana.org.au&gt;
Cc: "David S. Miller" &lt;davem@davemloft.net&gt;
Cc: virtualization@lists.linux-foundation.org
Cc: linux-crypto@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior &lt;bigeasy@linutronix.de&gt;
Signed-off-by: Herbert Xu &lt;herbert@gondor.apana.org.au&gt;
</content>
</entry>
</feed>
