* Re: [PATCH v2 net 5/7] virtio_net: Don't process redirected XDP frames when XDP is disabled
From: Michael S. Tsirkin @ 2019-01-29 22:50 UTC (permalink / raw)
To: Toshiaki Makita
Cc: netdev, Jesper Dangaard Brouer, David S. Miller, virtualization
In-Reply-To: <1548722759-2470-6-git-send-email-makita.toshiaki@lab.ntt.co.jp>
On Tue, Jan 29, 2019 at 09:45:57AM +0900, Toshiaki Makita wrote:
> Commit 8dcc5b0ab0ec ("virtio_net: fix ndo_xdp_xmit crash towards dev not
> ready for XDP") tried to avoid access to unexpected sq while XDP is
> disabled, but was not complete.
>
> There was a small window which causes out of bounds sq access in
> virtnet_xdp_xmit() while disabling XDP.
>
> An example case of
> - curr_queue_pairs = 6 (2 for SKB and 4 for XDP)
> - online_cpu_num = xdp_queue_paris = 4
> when XDP is enabled:
>
> CPU 0 CPU 1
> (Disabling XDP) (Processing redirected XDP frames)
>
> virtnet_xdp_xmit()
> virtnet_xdp_set()
> _virtnet_set_queues()
> set curr_queue_pairs (2)
> check if rq->xdp_prog is not NULL
> virtnet_xdp_sq(vi)
> qp = curr_queue_pairs -
> xdp_queue_pairs +
> smp_processor_id()
> = 2 - 4 + 1 = -1
> sq = &vi->sq[qp] // out of bounds access
> set xdp_queue_pairs (0)
> rq->xdp_prog = NULL
>
> Basically we should not change curr_queue_pairs and xdp_queue_pairs
> while someone can read the values. Thus, when disabling XDP, assign NULL
> to rq->xdp_prog first, and wait for RCU grace period, then change
> xxx_queue_pairs.
> Note that we need to keep the current order when enabling XDP though.
>
> - v2: Make rcu_assign_pointer/synchronize_net conditional instead of
> _virtnet_set_queues.
>
> Fixes: 186b3c998c50 ("virtio-net: support XDP_REDIRECT")
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> drivers/net/virtio_net.c | 33 ++++++++++++++++++++++++++-------
> 1 file changed, 26 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 669b65c..cea52e4 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -2410,6 +2410,10 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> return -ENOMEM;
> }
>
> + old_prog = rtnl_dereference(vi->rq[0].xdp_prog);
> + if (!prog && !old_prog)
> + return 0;
> +
> if (prog) {
> prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
> if (IS_ERR(prog))
> @@ -2424,21 +2428,30 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> }
> }
>
> + if (!prog) {
> + for (i = 0; i < vi->max_queue_pairs; i++) {
> + rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
> + if (i == 0)
> + virtnet_restore_guest_offloads(vi);
> + }
> + synchronize_net();
> + }
> +
> err = _virtnet_set_queues(vi, curr_qp + xdp_qp);
> if (err)
> goto err;
> netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp);
> vi->xdp_queue_pairs = xdp_qp;
>
> - for (i = 0; i < vi->max_queue_pairs; i++) {
> - old_prog = rtnl_dereference(vi->rq[i].xdp_prog);
> - rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
> - if (i == 0) {
> - if (!old_prog)
> + if (prog) {
> + for (i = 0; i < vi->max_queue_pairs; i++) {
> + rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
> + if (i == 0 && !old_prog)
> virtnet_clear_guest_offloads(vi);
> - if (!prog)
> - virtnet_restore_guest_offloads(vi);
> }
> + }
> +
> + for (i = 0; i < vi->max_queue_pairs; i++) {
> if (old_prog)
> bpf_prog_put(old_prog);
> if (netif_running(dev)) {
> @@ -2451,6 +2464,12 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> return 0;
>
> err:
> + if (!prog) {
> + virtnet_clear_guest_offloads(vi);
> + for (i = 0; i < vi->max_queue_pairs; i++)
> + rcu_assign_pointer(vi->rq[i].xdp_prog, old_prog);
> + }
> +
> if (netif_running(dev)) {
> for (i = 0; i < vi->max_queue_pairs; i++) {
> virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi);
> --
> 1.8.3.1
>
^ permalink raw reply
* Re: [PATCH v2 net 7/7] virtio_net: Differentiate sk_buff and xdp_frame on freeing
From: Michael S. Tsirkin @ 2019-01-29 22:51 UTC (permalink / raw)
To: Toshiaki Makita; +Cc: netdev, David S. Miller, virtualization
In-Reply-To: <1548722759-2470-8-git-send-email-makita.toshiaki@lab.ntt.co.jp>
On Tue, Jan 29, 2019 at 09:45:59AM +0900, Toshiaki Makita wrote:
> We do not reset or free up unused buffers when enabling/disabling XDP,
> so it can happen that xdp_frames are freed after disabling XDP or
> sk_buffs are freed after enabling XDP on xdp tx queues.
> Thus we need to handle both forms (xdp_frames and sk_buffs) regardless
> of XDP setting.
> One way to trigger this problem is to disable XDP when napi_tx is
> enabled. In that case, virtnet_xdp_set() calls virtnet_napi_enable()
> which kicks NAPI. The NAPI handler will call virtnet_poll_cleantx()
> which invokes free_old_xmit_skbs() for queues which have been used by
> XDP.
>
> Note that even with this change we need to keep skipping
> free_old_xmit_skbs() from NAPI handlers when XDP is enabled, because XDP
> tx queues do not aquire queue locks.
>
> - v2: Use napi_consume_skb() instead of dev_consume_skb_any()
>
> Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set")
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> NOTE: Dropped Acked-by because of the v2 change.
>
> drivers/net/virtio_net.c | 54 +++++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 42 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 1d454ce..2594481 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -57,6 +57,8 @@
> #define VIRTIO_XDP_TX BIT(0)
> #define VIRTIO_XDP_REDIR BIT(1)
>
> +#define VIRTIO_XDP_FLAG BIT(0)
> +
> /* RX packet size EWMA. The average packet size is used to determine the packet
> * buffer size when refilling RX rings. As the entire RX ring may be refilled
> * at once, the weight is chosen so that the EWMA will be insensitive to short-
> @@ -252,6 +254,21 @@ struct padded_vnet_hdr {
> char padding[4];
> };
>
> +static bool is_xdp_frame(void *ptr)
> +{
> + return (unsigned long)ptr & VIRTIO_XDP_FLAG;
> +}
> +
> +static void *xdp_to_ptr(struct xdp_frame *ptr)
> +{
> + return (void *)((unsigned long)ptr | VIRTIO_XDP_FLAG);
> +}
> +
> +static struct xdp_frame *ptr_to_xdp(void *ptr)
> +{
> + return (struct xdp_frame *)((unsigned long)ptr & ~VIRTIO_XDP_FLAG);
> +}
> +
> /* Converting between virtqueue no. and kernel tx/rx queue no.
> * 0:rx0 1:tx0 2:rx1 3:tx1 ... 2N:rxN 2N+1:txN 2N+2:cvq
> */
> @@ -462,7 +479,8 @@ static int __virtnet_xdp_xmit_one(struct virtnet_info *vi,
>
> sg_init_one(sq->sg, xdpf->data, xdpf->len);
>
> - err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdpf, GFP_ATOMIC);
> + err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdp_to_ptr(xdpf),
> + GFP_ATOMIC);
> if (unlikely(err))
> return -ENOSPC; /* Caller handle free/refcnt */
>
> @@ -482,13 +500,13 @@ static int virtnet_xdp_xmit(struct net_device *dev,
> {
> struct virtnet_info *vi = netdev_priv(dev);
> struct receive_queue *rq = vi->rq;
> - struct xdp_frame *xdpf_sent;
> struct bpf_prog *xdp_prog;
> struct send_queue *sq;
> unsigned int len;
> int drops = 0;
> int kicks = 0;
> int ret, err;
> + void *ptr;
> int i;
>
> /* Only allow ndo_xdp_xmit if XDP is loaded on dev, as this
> @@ -507,8 +525,12 @@ static int virtnet_xdp_xmit(struct net_device *dev,
> }
>
> /* Free up any pending old buffers before queueing new ones. */
> - while ((xdpf_sent = virtqueue_get_buf(sq->vq, &len)) != NULL)
> - xdp_return_frame(xdpf_sent);
> + while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> + if (likely(is_xdp_frame(ptr)))
> + xdp_return_frame(ptr_to_xdp(ptr));
> + else
> + napi_consume_skb(ptr, false);
> + }
>
> for (i = 0; i < n; i++) {
> struct xdp_frame *xdpf = frames[i];
> @@ -1329,18 +1351,26 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
>
> static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi)
> {
> - struct sk_buff *skb;
> unsigned int len;
> unsigned int packets = 0;
> unsigned int bytes = 0;
> + void *ptr;
>
> - while ((skb = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> - pr_debug("Sent skb %p\n", skb);
> + while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> + if (likely(!is_xdp_frame(ptr))) {
> + struct sk_buff *skb = ptr;
>
> - bytes += skb->len;
> - packets++;
> + pr_debug("Sent skb %p\n", skb);
>
> - napi_consume_skb(skb, in_napi);
> + bytes += skb->len;
> + napi_consume_skb(skb, in_napi);
> + } else {
> + struct xdp_frame *frame = ptr_to_xdp(ptr);
> +
> + bytes += frame->len;
> + xdp_return_frame(frame);
> + }
> + packets++;
> }
>
> /* Avoid overhead when no packets have been processed
> @@ -2666,10 +2696,10 @@ static void free_unused_bufs(struct virtnet_info *vi)
> for (i = 0; i < vi->max_queue_pairs; i++) {
> struct virtqueue *vq = vi->sq[i].vq;
> while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
> - if (!is_xdp_raw_buffer_queue(vi, i))
> + if (!is_xdp_frame(buf))
> dev_kfree_skb(buf);
> else
> - xdp_return_frame(buf);
> + xdp_return_frame(ptr_to_xdp(buf));
> }
> }
>
> --
> 1.8.3.1
>
^ permalink raw reply
* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: Michael S. Tsirkin @ 2019-01-29 22:54 UTC (permalink / raw)
To: David Miller; +Cc: kvm, netdev, linux-kernel, virtualization, stefanha
In-Reply-To: <20190128.225444.1929870241029842289.davem@davemloft.net>
On Mon, Jan 28, 2019 at 10:54:44PM -0800, David Miller wrote:
> From: Jason Wang <jasowang@redhat.com>
> Date: Mon, 28 Jan 2019 15:05:05 +0800
>
> > After batched used ring updating was introduced in commit e2b3b35eb989
> > ("vhost_net: batch used ring update in rx"). We tend to batch heads in
> > vq->heads for more than one packet. But the quota passed to
> > get_rx_bufs() was not correctly limited, which can result a OOB write
> > in vq->heads.
> >
> > headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
> > vhost_len, &in, vq_log, &log,
> > likely(mergeable) ? UIO_MAXIOV : 1);
> >
> > UIO_MAXIOV was still used which is wrong since we could have batched
> > used in vq->heads, this will cause OOB if the next buffer needs more
> > than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
> > batched 64 (VHOST_NET_BATCH) heads:
> ...
> > Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
> > vhost-net. This is done through set the limitation through
> > vhost_dev_init(), then set_owner can allocate the number of iov in a
> > per device manner.
> >
> > This fixes CVE-2018-16880.
> >
> > Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
>
> Applied and queued up for -stable, thanks!
Wow it seems we are down to hours round time post to queue.
It would be hard to keep up that rate generally.
However, I am guessing this was already in downstreams, and it's a CVE,
so I guess it's a no brainer and review wasn't really necessary - was
that the idea? Just checking.
--
MST
^ permalink raw reply
* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: David Miller @ 2019-01-29 23:10 UTC (permalink / raw)
To: mst; +Cc: kvm, netdev, linux-kernel, virtualization, stefanha
In-Reply-To: <20190129175145-mutt-send-email-mst@kernel.org>
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Tue, 29 Jan 2019 17:54:44 -0500
> On Mon, Jan 28, 2019 at 10:54:44PM -0800, David Miller wrote:
>> From: Jason Wang <jasowang@redhat.com>
>> Date: Mon, 28 Jan 2019 15:05:05 +0800
>>
>> > After batched used ring updating was introduced in commit e2b3b35eb989
>> > ("vhost_net: batch used ring update in rx"). We tend to batch heads in
>> > vq->heads for more than one packet. But the quota passed to
>> > get_rx_bufs() was not correctly limited, which can result a OOB write
>> > in vq->heads.
>> >
>> > headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
>> > vhost_len, &in, vq_log, &log,
>> > likely(mergeable) ? UIO_MAXIOV : 1);
>> >
>> > UIO_MAXIOV was still used which is wrong since we could have batched
>> > used in vq->heads, this will cause OOB if the next buffer needs more
>> > than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
>> > batched 64 (VHOST_NET_BATCH) heads:
>> ...
>> > Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
>> > vhost-net. This is done through set the limitation through
>> > vhost_dev_init(), then set_owner can allocate the number of iov in a
>> > per device manner.
>> >
>> > This fixes CVE-2018-16880.
>> >
>> > Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
>> > Signed-off-by: Jason Wang <jasowang@redhat.com>
>>
>> Applied and queued up for -stable, thanks!
>
> Wow it seems we are down to hours round time post to queue.
> It would be hard to keep up that rate generally.
> However, I am guessing this was already in downstreams, and it's a CVE,
> so I guess it's a no brainer and review wasn't really necessary - was
> that the idea? Just checking.
Yeah the CVE pushed my hand a little bit, and I knew I was going to send Linus
a pull request today because David Watson needs some TLS changes in net-next.
^ permalink raw reply
* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: David Miller @ 2019-01-29 23:38 UTC (permalink / raw)
To: mst; +Cc: kvm, netdev, linux-kernel, virtualization, stefanha
In-Reply-To: <20190129.151026.358327408932275252.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Tue, 29 Jan 2019 15:10:26 -0800 (PST)
> Yeah the CVE pushed my hand a little bit, and I knew I was going to
> send Linus a pull request today because David Watson needs some TLS
> changes in net-next.
I also want to make a general comment.... for the record.
If I let patches slip consistently past 24 hours my backlog is
unmanageable. Even with aggressively applying things quickly I'm
right now at 70-75. If I do not do what I am doing, then it's in the
100-150 range.
So I am at the point where I often must move forward with patches that
I think I personally can verify and vet on my own.
^ permalink raw reply
* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: Michael S. Tsirkin @ 2019-01-30 1:36 UTC (permalink / raw)
To: David Miller; +Cc: kvm, netdev, linux-kernel, virtualization, stefanha
In-Reply-To: <20190129.153810.493942539151548676.davem@davemloft.net>
On Tue, Jan 29, 2019 at 03:38:10PM -0800, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Tue, 29 Jan 2019 15:10:26 -0800 (PST)
>
> > Yeah the CVE pushed my hand a little bit, and I knew I was going to
> > send Linus a pull request today because David Watson needs some TLS
> > changes in net-next.
>
> I also want to make a general comment.... for the record.
>
> If I let patches slip consistently past 24 hours my backlog is
> unmanageable. Even with aggressively applying things quickly I'm
> right now at 70-75. If I do not do what I am doing, then it's in the
> 100-150 range.
>
> So I am at the point where I often must move forward with patches that
> I think I personally can verify and vet on my own.
If it helps I can include most virtio stuff in my pull requests instead.
Or if that can't work since there's too often a dependency on net-next,
maybe Jason wants to create a tree and send pull requests to you. Let
us know if that will help, and which of the options looks better from
your POV.
--
MST
^ permalink raw reply
* Re: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
From: Jason Wang @ 2019-01-30 2:24 UTC (permalink / raw)
To: Michael S. Tsirkin, Thiago Jung Bauermann
Cc: Jean-Philippe Brucker, Benjamin Herrenschmidt,
Alexey Kardashevskiy, Ram Pai, linux-kernel, virtualization,
Paul Mackerras, iommu, linuxppc-dev, Christoph Hellwig,
David Gibson
In-Reply-To: <20190129134750-mutt-send-email-mst@kernel.org>
On 2019/1/30 上午3:02, Michael S. Tsirkin wrote:
> On Tue, Jan 29, 2019 at 03:42:44PM -0200, Thiago Jung Bauermann wrote:
>> Fixing address of powerpc mailing list.
>>
>> Thiago Jung Bauermann <bauerman@linux.ibm.com> writes:
>>
>>> Hello,
>>>
>>> With Christoph's rework of the DMA API that recently landed, the patch
>>> below is the only change needed in virtio to make it work in a POWER
>>> secure guest under the ultravisor.
>>>
>>> The other change we need (making sure the device's dma_map_ops is NULL
>>> so that the dma-direct/swiotlb code is used) can be made in
>>> powerpc-specific code.
>>>
>>> Of course, I also have patches (soon to be posted as RFC) which hook up
>>> <linux/mem_encrypt.h> to the powerpc secure guest support code.
>>>
>>> What do you think?
>>>
>>> From d0629a36a75c678b4a72b853f8f7f8c17eedd6b3 Mon Sep 17 00:00:00 2001
>>> From: Thiago Jung Bauermann <bauerman@linux.ibm.com>
>>> Date: Thu, 24 Jan 2019 22:08:02 -0200
>>> Subject: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
>>>
>>> The host can't access the guest memory when it's encrypted, so using
>>> regular memory pages for the ring isn't an option. Go through the DMA API.
>>>
>>> Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> Well I think this will come back to bite us (witness xen which is now
> reworking precisely this path - but at least they aren't to blame, xen
> came before ACCESS_PLATFORM).
>
> I also still think the right thing would have been to set
> ACCESS_PLATFORM for all systems where device can't access all memory.
>
> But I also think I don't have the energy to argue about power secure
> guest anymore. So be it for power secure guest since the involved
> engineers disagree with me. Hey I've been wrong in the past ;).
>
> But the name "sev_active" makes me scared because at least AMD guys who
> were doing the sensible thing and setting ACCESS_PLATFORM (unless I'm
> wrong? I reemember distinctly that's so) will likely be affected too.
> We don't want that.
>
> So let's find a way to make sure it's just power secure guest for now
> pls.
>
> I also think we should add a dma_api near features under virtio_device
> such that these hacks can move off data path.
Anyway the current Xen code is conflict with spec which said:
"If this feature bit is set to 0, then the device has same access to
memory addresses supplied to it as the driver has. In particular, the
device will always use physical addresses matching addresses used by the
driver (typically meaning physical addresses used by the CPU) and not
translated further, and can access any address supplied to it by the
driver. When clear, this overrides any platform-specific description of
whether device access is limited or translated in any way, e.g. whether
an IOMMU may be present. "
I wonder how much value that the above description can give us. It's
kind of odd that the behavior of "when the feature is not negotiated" is
described in the spec. Personally I think we can remove the above and
then we can switch to use DMA API unconditionally in guest driver. It
may have single digit regression probably, we can try to overcome it.
Thanks
>
> By the way could you please respond about virtio-iommu and
> why there's no support for ACCESS_PLATFORM on power?
>
> I have Cc'd you on these discussions.
>
>
> Thanks!
>
>
>>> ---
>>> drivers/virtio/virtio_ring.c | 5 ++++-
>>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
>>> index cd7e755484e3..321a27075380 100644
>>> --- a/drivers/virtio/virtio_ring.c
>>> +++ b/drivers/virtio/virtio_ring.c
>>> @@ -259,8 +259,11 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
>>> * not work without an even larger kludge. Instead, enable
>>> * the DMA API if we're a Xen guest, which at least allows
>>> * all of the sensible Xen configurations to work correctly.
>>> + *
>>> + * Also, if guest memory is encrypted the host can't access
>>> + * it directly. In this case, we'll need to use the DMA API.
>>> */
>>> - if (xen_domain())
>>> + if (xen_domain() || sev_active())
>>> return true;
>>>
>>> return false;
>>
>> --
>> Thiago Jung Bauermann
>> IBM Linux Technology Center
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
From: Michael S. Tsirkin @ 2019-01-30 2:36 UTC (permalink / raw)
To: Jason Wang
Cc: Jean-Philippe Brucker, Benjamin Herrenschmidt,
Alexey Kardashevskiy, Ram Pai, linux-kernel, virtualization,
Paul Mackerras, iommu, linuxppc-dev, Christoph Hellwig,
Thiago Jung Bauermann, David Gibson
In-Reply-To: <6c68f7f7-1b28-6eba-9b8b-2c32efac9701@redhat.com>
On Wed, Jan 30, 2019 at 10:24:01AM +0800, Jason Wang wrote:
>
> On 2019/1/30 上午3:02, Michael S. Tsirkin wrote:
> > On Tue, Jan 29, 2019 at 03:42:44PM -0200, Thiago Jung Bauermann wrote:
> > > Fixing address of powerpc mailing list.
> > >
> > > Thiago Jung Bauermann <bauerman@linux.ibm.com> writes:
> > >
> > > > Hello,
> > > >
> > > > With Christoph's rework of the DMA API that recently landed, the patch
> > > > below is the only change needed in virtio to make it work in a POWER
> > > > secure guest under the ultravisor.
> > > >
> > > > The other change we need (making sure the device's dma_map_ops is NULL
> > > > so that the dma-direct/swiotlb code is used) can be made in
> > > > powerpc-specific code.
> > > >
> > > > Of course, I also have patches (soon to be posted as RFC) which hook up
> > > > <linux/mem_encrypt.h> to the powerpc secure guest support code.
> > > >
> > > > What do you think?
> > > >
> > > > From d0629a36a75c678b4a72b853f8f7f8c17eedd6b3 Mon Sep 17 00:00:00 2001
> > > > From: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> > > > Date: Thu, 24 Jan 2019 22:08:02 -0200
> > > > Subject: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
> > > >
> > > > The host can't access the guest memory when it's encrypted, so using
> > > > regular memory pages for the ring isn't an option. Go through the DMA API.
> > > >
> > > > Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> > Well I think this will come back to bite us (witness xen which is now
> > reworking precisely this path - but at least they aren't to blame, xen
> > came before ACCESS_PLATFORM).
> >
> > I also still think the right thing would have been to set
> > ACCESS_PLATFORM for all systems where device can't access all memory.
> >
> > But I also think I don't have the energy to argue about power secure
> > guest anymore. So be it for power secure guest since the involved
> > engineers disagree with me. Hey I've been wrong in the past ;).
> >
> > But the name "sev_active" makes me scared because at least AMD guys who
> > were doing the sensible thing and setting ACCESS_PLATFORM (unless I'm
> > wrong? I reemember distinctly that's so) will likely be affected too.
> > We don't want that.
> >
> > So let's find a way to make sure it's just power secure guest for now
> > pls.
> >
> > I also think we should add a dma_api near features under virtio_device
> > such that these hacks can move off data path.
>
>
> Anyway the current Xen code is conflict with spec which said:
>
> "If this feature bit is set to 0, then the device has same access to memory
> addresses supplied to it as the driver has. In particular, the device will
> always use physical addresses matching addresses used by the driver
> (typically meaning physical addresses used by the CPU) and not translated
> further, and can access any address supplied to it by the driver. When
> clear, this overrides any platform-specific description of whether device
> access is limited or translated in any way, e.g. whether an IOMMU may be
> present. "
>
> I wonder how much value that the above description can give us. It's kind of
> odd that the behavior of "when the feature is not negotiated" is described
> in the spec.
Hmm what's odd about it? We need to describe the behaviour is all cases.
> Personally I think we can remove the above and then we can
> switch to use DMA API unconditionally in guest driver. It may have single
> digit regression probably, we can try to overcome it.
>
> Thanks
This has been discussed ad nauseum. virtio is all about compatibility.
Losing a couple of lines of code isn't worth breaking working setups.
People that want "just use DMA API no tricks" now have the option.
Setting a flag in a feature bit map is literally a single line
of code in the hypervisor. So stop pushing for breaking working
legacy setups and just fix it in the right place.
>
> >
> > By the way could you please respond about virtio-iommu and
> > why there's no support for ACCESS_PLATFORM on power?
> >
> > I have Cc'd you on these discussions.
> >
> >
> > Thanks!
> >
> >
> > > > ---
> > > > drivers/virtio/virtio_ring.c | 5 ++++-
> > > > 1 file changed, 4 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > > > index cd7e755484e3..321a27075380 100644
> > > > --- a/drivers/virtio/virtio_ring.c
> > > > +++ b/drivers/virtio/virtio_ring.c
> > > > @@ -259,8 +259,11 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
> > > > * not work without an even larger kludge. Instead, enable
> > > > * the DMA API if we're a Xen guest, which at least allows
> > > > * all of the sensible Xen configurations to work correctly.
> > > > + *
> > > > + * Also, if guest memory is encrypted the host can't access
> > > > + * it directly. In this case, we'll need to use the DMA API.
> > > > */
> > > > - if (xen_domain())
> > > > + if (xen_domain() || sev_active())
> > > > return true;
> > > >
> > > > return false;
> > >
> > > --
> > > Thiago Jung Bauermann
> > > IBM Linux Technology Center
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
From: Jason Wang @ 2019-01-30 3:05 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Jean-Philippe Brucker, Benjamin Herrenschmidt,
Alexey Kardashevskiy, Ram Pai, linux-kernel, virtualization,
Paul Mackerras, iommu, linuxppc-dev, Christoph Hellwig,
Thiago Jung Bauermann, David Gibson
In-Reply-To: <20190129213137-mutt-send-email-mst@kernel.org>
On 2019/1/30 上午10:36, Michael S. Tsirkin wrote:
> On Wed, Jan 30, 2019 at 10:24:01AM +0800, Jason Wang wrote:
>> On 2019/1/30 上午3:02, Michael S. Tsirkin wrote:
>>> On Tue, Jan 29, 2019 at 03:42:44PM -0200, Thiago Jung Bauermann wrote:
>>>> Fixing address of powerpc mailing list.
>>>>
>>>> Thiago Jung Bauermann <bauerman@linux.ibm.com> writes:
>>>>
>>>>> Hello,
>>>>>
>>>>> With Christoph's rework of the DMA API that recently landed, the patch
>>>>> below is the only change needed in virtio to make it work in a POWER
>>>>> secure guest under the ultravisor.
>>>>>
>>>>> The other change we need (making sure the device's dma_map_ops is NULL
>>>>> so that the dma-direct/swiotlb code is used) can be made in
>>>>> powerpc-specific code.
>>>>>
>>>>> Of course, I also have patches (soon to be posted as RFC) which hook up
>>>>> <linux/mem_encrypt.h> to the powerpc secure guest support code.
>>>>>
>>>>> What do you think?
>>>>>
>>>>> From d0629a36a75c678b4a72b853f8f7f8c17eedd6b3 Mon Sep 17 00:00:00 2001
>>>>> From: Thiago Jung Bauermann <bauerman@linux.ibm.com>
>>>>> Date: Thu, 24 Jan 2019 22:08:02 -0200
>>>>> Subject: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
>>>>>
>>>>> The host can't access the guest memory when it's encrypted, so using
>>>>> regular memory pages for the ring isn't an option. Go through the DMA API.
>>>>>
>>>>> Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
>>> Well I think this will come back to bite us (witness xen which is now
>>> reworking precisely this path - but at least they aren't to blame, xen
>>> came before ACCESS_PLATFORM).
>>>
>>> I also still think the right thing would have been to set
>>> ACCESS_PLATFORM for all systems where device can't access all memory.
>>>
>>> But I also think I don't have the energy to argue about power secure
>>> guest anymore. So be it for power secure guest since the involved
>>> engineers disagree with me. Hey I've been wrong in the past ;).
>>>
>>> But the name "sev_active" makes me scared because at least AMD guys who
>>> were doing the sensible thing and setting ACCESS_PLATFORM (unless I'm
>>> wrong? I reemember distinctly that's so) will likely be affected too.
>>> We don't want that.
>>>
>>> So let's find a way to make sure it's just power secure guest for now
>>> pls.
>>>
>>> I also think we should add a dma_api near features under virtio_device
>>> such that these hacks can move off data path.
>>
>> Anyway the current Xen code is conflict with spec which said:
>>
>> "If this feature bit is set to 0, then the device has same access to memory
>> addresses supplied to it as the driver has. In particular, the device will
>> always use physical addresses matching addresses used by the driver
>> (typically meaning physical addresses used by the CPU) and not translated
>> further, and can access any address supplied to it by the driver. When
>> clear, this overrides any platform-specific description of whether device
>> access is limited or translated in any way, e.g. whether an IOMMU may be
>> present. "
>>
>> I wonder how much value that the above description can give us. It's kind of
>> odd that the behavior of "when the feature is not negotiated" is described
>> in the spec.
> Hmm what's odd about it? We need to describe the behaviour is all cases.
Well, try to limit the behavior of 'legacy' driver is tricky or even
impossible. Xen is an exact example for this.
>
>> Personally I think we can remove the above and then we can
>> switch to use DMA API unconditionally in guest driver. It may have single
>> digit regression probably, we can try to overcome it.
>>
>> Thanks
> This has been discussed ad nauseum. virtio is all about compatibility.
> Losing a couple of lines of code isn't worth breaking working setups.
> People that want "just use DMA API no tricks" now have the option.
> Setting a flag in a feature bit map is literally a single line
> of code in the hypervisor. So stop pushing for breaking working
> legacy setups and just fix it in the right place.
I may miss soemthing, which kind of legacy setup is broken? Do you mean
using virtio without IOMMU_PLATFORM on platform with IOMMU? We actually
unbreak this setup.
Thanks
>
>>> By the way could you please respond about virtio-iommu and
>>> why there's no support for ACCESS_PLATFORM on power?
>>>
>>> I have Cc'd you on these discussions.
>>>
>>>
>>> Thanks!
>>>
>>>
>>>>> ---
>>>>> drivers/virtio/virtio_ring.c | 5 ++++-
>>>>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
>>>>> index cd7e755484e3..321a27075380 100644
>>>>> --- a/drivers/virtio/virtio_ring.c
>>>>> +++ b/drivers/virtio/virtio_ring.c
>>>>> @@ -259,8 +259,11 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
>>>>> * not work without an even larger kludge. Instead, enable
>>>>> * the DMA API if we're a Xen guest, which at least allows
>>>>> * all of the sensible Xen configurations to work correctly.
>>>>> + *
>>>>> + * Also, if guest memory is encrypted the host can't access
>>>>> + * it directly. In this case, we'll need to use the DMA API.
>>>>> */
>>>>> - if (xen_domain())
>>>>> + if (xen_domain() || sev_active())
>>>>> return true;
>>>>>
>>>>> return false;
>>>> --
>>>> Thiago Jung Bauermann
>>>> IBM Linux Technology Center
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
From: Michael S. Tsirkin @ 2019-01-30 3:26 UTC (permalink / raw)
To: Jason Wang
Cc: Jean-Philippe Brucker, Benjamin Herrenschmidt,
Alexey Kardashevskiy, Ram Pai, linux-kernel, virtualization,
Paul Mackerras, iommu, linuxppc-dev, Christoph Hellwig,
Thiago Jung Bauermann, David Gibson
In-Reply-To: <94ab8910-594e-a056-c799-5536d8ae2b0e@redhat.com>
On Wed, Jan 30, 2019 at 11:05:42AM +0800, Jason Wang wrote:
>
> On 2019/1/30 上午10:36, Michael S. Tsirkin wrote:
> > On Wed, Jan 30, 2019 at 10:24:01AM +0800, Jason Wang wrote:
> > > On 2019/1/30 上午3:02, Michael S. Tsirkin wrote:
> > > > On Tue, Jan 29, 2019 at 03:42:44PM -0200, Thiago Jung Bauermann wrote:
> > > > > Fixing address of powerpc mailing list.
> > > > >
> > > > > Thiago Jung Bauermann <bauerman@linux.ibm.com> writes:
> > > > >
> > > > > > Hello,
> > > > > >
> > > > > > With Christoph's rework of the DMA API that recently landed, the patch
> > > > > > below is the only change needed in virtio to make it work in a POWER
> > > > > > secure guest under the ultravisor.
> > > > > >
> > > > > > The other change we need (making sure the device's dma_map_ops is NULL
> > > > > > so that the dma-direct/swiotlb code is used) can be made in
> > > > > > powerpc-specific code.
> > > > > >
> > > > > > Of course, I also have patches (soon to be posted as RFC) which hook up
> > > > > > <linux/mem_encrypt.h> to the powerpc secure guest support code.
> > > > > >
> > > > > > What do you think?
> > > > > >
> > > > > > From d0629a36a75c678b4a72b853f8f7f8c17eedd6b3 Mon Sep 17 00:00:00 2001
> > > > > > From: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> > > > > > Date: Thu, 24 Jan 2019 22:08:02 -0200
> > > > > > Subject: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
> > > > > >
> > > > > > The host can't access the guest memory when it's encrypted, so using
> > > > > > regular memory pages for the ring isn't an option. Go through the DMA API.
> > > > > >
> > > > > > Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> > > > Well I think this will come back to bite us (witness xen which is now
> > > > reworking precisely this path - but at least they aren't to blame, xen
> > > > came before ACCESS_PLATFORM).
> > > >
> > > > I also still think the right thing would have been to set
> > > > ACCESS_PLATFORM for all systems where device can't access all memory.
> > > >
> > > > But I also think I don't have the energy to argue about power secure
> > > > guest anymore. So be it for power secure guest since the involved
> > > > engineers disagree with me. Hey I've been wrong in the past ;).
> > > >
> > > > But the name "sev_active" makes me scared because at least AMD guys who
> > > > were doing the sensible thing and setting ACCESS_PLATFORM (unless I'm
> > > > wrong? I reemember distinctly that's so) will likely be affected too.
> > > > We don't want that.
> > > >
> > > > So let's find a way to make sure it's just power secure guest for now
> > > > pls.
> > > >
> > > > I also think we should add a dma_api near features under virtio_device
> > > > such that these hacks can move off data path.
> > >
> > > Anyway the current Xen code is conflict with spec which said:
> > >
> > > "If this feature bit is set to 0, then the device has same access to memory
> > > addresses supplied to it as the driver has. In particular, the device will
> > > always use physical addresses matching addresses used by the driver
> > > (typically meaning physical addresses used by the CPU) and not translated
> > > further, and can access any address supplied to it by the driver. When
> > > clear, this overrides any platform-specific description of whether device
> > > access is limited or translated in any way, e.g. whether an IOMMU may be
> > > present. "
> > >
> > > I wonder how much value that the above description can give us. It's kind of
> > > odd that the behavior of "when the feature is not negotiated" is described
> > > in the spec.
> > Hmm what's odd about it? We need to describe the behaviour is all cases.
>
>
> Well, try to limit the behavior of 'legacy' driver is tricky or even
> impossible. Xen is an exact example for this.
So don't. Xen got grand-fathered in because when that came
along we thought it's a one off thing. Was easier to just
add that as a special case. But really >99% of people
have a hypervisor device with direct guest memory access.
All else is esoterica.
>
> >
> > > Personally I think we can remove the above and then we can
> > > switch to use DMA API unconditionally in guest driver. It may have single
> > > digit regression probably, we can try to overcome it.
> > >
> > > Thanks
> > This has been discussed ad nauseum. virtio is all about compatibility.
> > Losing a couple of lines of code isn't worth breaking working setups.
> > People that want "just use DMA API no tricks" now have the option.
> > Setting a flag in a feature bit map is literally a single line
> > of code in the hypervisor. So stop pushing for breaking working
> > legacy setups and just fix it in the right place.
>
>
> I may miss soemthing, which kind of legacy setup is broken? Do you mean
> using virtio without IOMMU_PLATFORM on platform with IOMMU? We actually
> unbreak this setup.
>
> Thanks
Legacy setups by definition are working setups. The rules are pretty
simple. By default virtio == full guest memory access.
If your access is limited or translated in any way, you use a device
with ACCESS_PLATFORM. When in doubt use ACCESS_PLATFORM.
Xen was there before, and it does not have a flag and it still
wants ACCESS_PLATFORM semantics without setting ACCESS_PLATFORM
sometimes. So we don't want to break existing setups,
and we make an exception in that case.
I don't really see any good reason to make more exceptions.
Nor IMHO should we trust all platform people to know about virtio
and have special kind of DMA API just for virtio.
>
> >
> > > > By the way could you please respond about virtio-iommu and
> > > > why there's no support for ACCESS_PLATFORM on power?
> > > >
> > > > I have Cc'd you on these discussions.
> > > >
> > > >
> > > > Thanks!
> > > >
> > > >
> > > > > > ---
> > > > > > drivers/virtio/virtio_ring.c | 5 ++++-
> > > > > > 1 file changed, 4 insertions(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > > > > > index cd7e755484e3..321a27075380 100644
> > > > > > --- a/drivers/virtio/virtio_ring.c
> > > > > > +++ b/drivers/virtio/virtio_ring.c
> > > > > > @@ -259,8 +259,11 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
> > > > > > * not work without an even larger kludge. Instead, enable
> > > > > > * the DMA API if we're a Xen guest, which at least allows
> > > > > > * all of the sensible Xen configurations to work correctly.
> > > > > > + *
> > > > > > + * Also, if guest memory is encrypted the host can't access
> > > > > > + * it directly. In this case, we'll need to use the DMA API.
> > > > > > */
> > > > > > - if (xen_domain())
> > > > > > + if (xen_domain() || sev_active())
> > > > > > return true;
> > > > > >
> > > > > > return false;
> > > > > --
> > > > > Thiago Jung Bauermann
> > > > > IBM Linux Technology Center
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
From: Christoph Hellwig @ 2019-01-30 7:44 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Jean-Philippe Brucker, Benjamin Herrenschmidt,
Alexey Kardashevskiy, Ram Pai, linux-kernel, virtualization,
Paul Mackerras, iommu, linuxppc-dev, Christoph Hellwig,
Thiago Jung Bauermann, David Gibson
In-Reply-To: <20190129213137-mutt-send-email-mst@kernel.org>
On Tue, Jan 29, 2019 at 09:36:08PM -0500, Michael S. Tsirkin wrote:
> This has been discussed ad nauseum. virtio is all about compatibility.
> Losing a couple of lines of code isn't worth breaking working setups.
> People that want "just use DMA API no tricks" now have the option.
> Setting a flag in a feature bit map is literally a single line
> of code in the hypervisor. So stop pushing for breaking working
> legacy setups and just fix it in the right place.
I agree with the legacy aspect. What I am missing is an extremely
strong wording that says you SHOULD always set this flag for new
hosts, including an explanation why.
^ permalink raw reply
* Re: INFO: task hung in vhost_init_device_iotlb
From: Dmitry Vyukov via Virtualization @ 2019-01-30 8:12 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: KVM list, syzbot, netdev, syzkaller-bugs, LKML, virtualization
In-Reply-To: <20190129105957-mutt-send-email-mst@kernel.org>
On Tue, Jan 29, 2019 at 5:06 PM Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Tue, Jan 29, 2019 at 01:22:02AM -0800, syzbot wrote:
> > Hello,
> >
> > syzbot found the following crash on:
> >
> > HEAD commit: 983542434e6b Merge tag 'edac_fix_for_5.0' of git://git.ker..
> > git tree: upstream
> > console output: https://syzkaller.appspot.com/x/log.txt?x=17476498c00000
> > kernel config: https://syzkaller.appspot.com/x/.config?x=505743eba4e4f68
> > dashboard link: https://syzkaller.appspot.com/bug?extid=40e28a8bd59d10ed0c42
> > compiler: gcc (GCC) 9.0.0 20181231 (experimental)
> >
> > Unfortunately, I don't have any reproducer for this crash yet.
>
> Hmm nothing obvious below. Generic corruption elsewhere?
Hard to say, a silent memory corruption is definitely possible.
If there is nothing obvious let's wait, maybe syzbot will come up with
a repro or we get more such hangs so that it will be possible to rule
out flakes/corruptions.
> > IMPORTANT: if you fix the bug, please add the following tag to the commit:
> > Reported-by: syzbot+40e28a8bd59d10ed0c42@syzkaller.appspotmail.com
> >
> > protocol 88fb is buggy, dev hsr_slave_1
> > protocol 88fb is buggy, dev hsr_slave_0
> > protocol 88fb is buggy, dev hsr_slave_1
> > protocol 88fb is buggy, dev hsr_slave_0
> > protocol 88fb is buggy, dev hsr_slave_1
> > INFO: task syz-executor5:9417 blocked for more than 140 seconds.
> > Not tainted 5.0.0-rc3+ #48
> > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > syz-executor5 D27576 9417 8469 0x00000004
> > Call Trace:
> > context_switch kernel/sched/core.c:2831 [inline]
> > __schedule+0x897/0x1e60 kernel/sched/core.c:3472
> > schedule+0xfe/0x350 kernel/sched/core.c:3516
> > protocol 88fb is buggy, dev hsr_slave_0
> > protocol 88fb is buggy, dev hsr_slave_1
> > schedule_preempt_disabled+0x13/0x20 kernel/sched/core.c:3574
> > __mutex_lock_common kernel/locking/mutex.c:1002 [inline]
> > __mutex_lock+0xa3b/0x1670 kernel/locking/mutex.c:1072
> > mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:1087
> > vhost_init_device_iotlb+0x124/0x280 drivers/vhost/vhost.c:1606
> > vhost_net_set_features drivers/vhost/net.c:1674 [inline]
> > vhost_net_ioctl+0x1282/0x1c00 drivers/vhost/net.c:1739
> > vfs_ioctl fs/ioctl.c:46 [inline]
> > file_ioctl fs/ioctl.c:509 [inline]
> > do_vfs_ioctl+0x107b/0x17d0 fs/ioctl.c:696
> > ksys_ioctl+0xab/0xd0 fs/ioctl.c:713
> > __do_sys_ioctl fs/ioctl.c:720 [inline]
> > __se_sys_ioctl fs/ioctl.c:718 [inline]
> > __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718
> > do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290
> > protocol 88fb is buggy, dev hsr_slave_0
> > protocol 88fb is buggy, dev hsr_slave_1
> > entry_SYSCALL_64_after_hwframe+0x49/0xbe
> > RIP: 0033:0x458099
> > Code: Bad RIP value.
> > RSP: 002b:00007efd7ca9bc78 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> > RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000458099
> > RDX: 0000000020000080 RSI: 000000004008af00 RDI: 0000000000000003
> > RBP: 000000000073bfa0 R08: 0000000000000000 R09: 0000000000000000
> > R10: 0000000000000000 R11: 0000000000000246 R12: 00007efd7ca9c6d4
> > R13: 00000000004c295b R14: 00000000004d5280 R15: 00000000ffffffff
> > INFO: task syz-executor5:9418 blocked for more than 140 seconds.
> > Not tainted 5.0.0-rc3+ #48
> > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > syz-executor5 D27800 9418 8469 0x00000004
> > Call Trace:
> > context_switch kernel/sched/core.c:2831 [inline]
> > __schedule+0x897/0x1e60 kernel/sched/core.c:3472
> > schedule+0xfe/0x350 kernel/sched/core.c:3516
> > schedule_preempt_disabled+0x13/0x20 kernel/sched/core.c:3574
> > __mutex_lock_common kernel/locking/mutex.c:1002 [inline]
> > __mutex_lock+0xa3b/0x1670 kernel/locking/mutex.c:1072
> > mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:1087
> > vhost_net_set_owner drivers/vhost/net.c:1697 [inline]
> > vhost_net_ioctl+0x426/0x1c00 drivers/vhost/net.c:1754
> > vfs_ioctl fs/ioctl.c:46 [inline]
> > file_ioctl fs/ioctl.c:509 [inline]
> > do_vfs_ioctl+0x107b/0x17d0 fs/ioctl.c:696
> > ksys_ioctl+0xab/0xd0 fs/ioctl.c:713
> > __do_sys_ioctl fs/ioctl.c:720 [inline]
> > __se_sys_ioctl fs/ioctl.c:718 [inline]
> > __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718
> > do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290
> > entry_SYSCALL_64_after_hwframe+0x49/0xbe
> > RIP: 0033:0x458099
> > Code: Bad RIP value.
> > RSP: 002b:00007efd7ca7ac78 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> > RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000458099
> > RDX: 0000000000000000 RSI: 000040010000af01 RDI: 0000000000000003
> > RBP: 000000000073c040 R08: 0000000000000000 R09: 0000000000000000
> > R10: 0000000000000000 R11: 0000000000000246 R12: 00007efd7ca7b6d4
> > R13: 00000000004c33a4 R14: 00000000004d5e80 R15: 00000000ffffffff
> >
> > Showing all locks held in the system:
> > 1 lock held by khungtaskd/1040:
> > #0: 00000000b7479fbe (rcu_read_lock){....}, at:
> > debug_show_all_locks+0xc6/0x41d kernel/locking/lockdep.c:4389
> > 1 lock held by rsyslogd/8285:
> > #0: 000000006d9ccf7d (&f->f_pos_lock){+.+.}, at: __fdget_pos+0x1b3/0x1f0
> > fs/file.c:795
> > 2 locks held by getty/8406:
> > #0: 00000000052e805b (&tty->ldisc_sem){++++}, at: ldsem_down_read+0x33/0x40
> > drivers/tty/tty_ldsem.c:341
> > #1: 00000000b90dc267 (&ldata->atomic_read_lock){+.+.}, at:
> > n_tty_read+0x30a/0x1eb0 drivers/tty/n_tty.c:2154
> > 2 locks held by getty/8407:
> > #0: 000000009fdef632 (&tty->ldisc_sem){++++}, at: ldsem_down_read+0x33/0x40
> > drivers/tty/tty_ldsem.c:341
> > #1: 00000000ff2b1a16 (&ldata->atomic_read_lock){+.+.}, at:
> > n_tty_read+0x30a/0x1eb0 drivers/tty/n_tty.c:2154
> > 2 locks held by getty/8408:
> > #0: 00000000e48a8e78 (&tty->ldisc_sem){++++}, at: ldsem_down_read+0x33/0x40
> > drivers/tty/tty_ldsem.c:341
> > #1: 000000008fcf2060 (&ldata->atomic_read_lock){+.+.}, at:
> > n_tty_read+0x30a/0x1eb0 drivers/tty/n_tty.c:2154
> > 2 locks held by getty/8409:
> > #0: 0000000063f3f4f5 (&tty->ldisc_sem){++++}, at: ldsem_down_read+0x33/0x40
> > drivers/tty/tty_ldsem.c:341
> > #1: 000000001dc973ca (&ldata->atomic_read_lock){+.+.}, at:
> > n_tty_read+0x30a/0x1eb0 drivers/tty/n_tty.c:2154
> > 2 locks held by getty/8410:
> > #0: 00000000f3c14150 (&tty->ldisc_sem){++++}, at: ldsem_down_read+0x33/0x40
> > drivers/tty/tty_ldsem.c:341
> > #1: 000000007987cec5 (&ldata->atomic_read_lock){+.+.}, at:
> > n_tty_read+0x30a/0x1eb0 drivers/tty/n_tty.c:2154
> > 2 locks held by getty/8411:
> > #0: 00000000d04f4305 (&tty->ldisc_sem){++++}, at: ldsem_down_read+0x33/0x40
> > drivers/tty/tty_ldsem.c:341
> > #1: 000000003f47e3a6 (&ldata->atomic_read_lock){+.+.}, at:
> > n_tty_read+0x30a/0x1eb0 drivers/tty/n_tty.c:2154
> > 2 locks held by getty/8412:
> > #0: 0000000082430560 (&tty->ldisc_sem){++++}, at: ldsem_down_read+0x33/0x40
> > drivers/tty/tty_ldsem.c:341
> > #1: 0000000094609d81 (&ldata->atomic_read_lock){+.+.}, at:
> > n_tty_read+0x30a/0x1eb0 drivers/tty/n_tty.c:2154
> > 2 locks held by syz-executor5/9417:
> > #0: 0000000020a0f0a1 (&dev->mutex#4){+.+.}, at: vhost_net_set_features
> > drivers/vhost/net.c:1668 [inline]
> > #0: 0000000020a0f0a1 (&dev->mutex#4){+.+.}, at:
> > vhost_net_ioctl+0x204/0x1c00 drivers/vhost/net.c:1739
> > #1: 00000000a7b5872b (&vq->mutex){+.+.}, at:
> > vhost_init_device_iotlb+0x124/0x280 drivers/vhost/vhost.c:1606
> > 1 lock held by syz-executor5/9418:
> > #0: 0000000020a0f0a1 (&dev->mutex#4){+.+.}, at: vhost_net_set_owner
> > drivers/vhost/net.c:1697 [inline]
> > #0: 0000000020a0f0a1 (&dev->mutex#4){+.+.}, at:
> > vhost_net_ioctl+0x426/0x1c00 drivers/vhost/net.c:1754
> > 1 lock held by vhost-9408/9413:
> >
> > =============================================
> >
> > NMI backtrace for cpu 0
> > CPU: 0 PID: 1040 Comm: khungtaskd Not tainted 5.0.0-rc3+ #48
> > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> > Google 01/01/2011
> > Call Trace:
> > __dump_stack lib/dump_stack.c:77 [inline]
> > dump_stack+0x1db/0x2d0 lib/dump_stack.c:113
> > nmi_cpu_backtrace.cold+0x63/0xa4 lib/nmi_backtrace.c:101
> > nmi_trigger_cpumask_backtrace+0x1be/0x236 lib/nmi_backtrace.c:62
> > arch_trigger_cpumask_backtrace+0x14/0x20 arch/x86/kernel/apic/hw_nmi.c:38
> > trigger_all_cpu_backtrace include/linux/nmi.h:146 [inline]
> > check_hung_uninterruptible_tasks kernel/hung_task.c:203 [inline]
> > watchdog+0xbbb/0x1170 kernel/hung_task.c:287
> > kthread+0x357/0x430 kernel/kthread.c:246
> > ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
> > Sending NMI from CPU 0 to CPUs 1:
> > NMI backtrace for cpu 1
> > CPU: 1 PID: 7 Comm: kworker/u4:0 Not tainted 5.0.0-rc3+ #48
> > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> > Google 01/01/2011
> > Workqueue: bat_events batadv_nc_worker
> > RIP: 0010:__sanitizer_cov_trace_const_cmp1+0x15/0x20 kernel/kcov.c:174
> > Code: 00 48 89 e5 48 8b 4d 08 e8 18 ff ff ff 5d c3 66 0f 1f 44 00 00 55 40
> > 0f b6 d6 40 0f b6 f7 bf 01 00 00 00 48 89 e5 48 8b 4d 08 <e8> f6 fe ff ff 5d
> > c3 0f 1f 40 00 55 0f b7 d6 0f b7 f7 bf 03 00 00
> > RSP: 0018:ffff8880a947f8a8 EFLAGS: 00000246
> > RAX: ffff8880a94701c0 RBX: ffff8880a05efc40 RCX: ffffffff87d36c97
> > RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000001
> > RBP: ffff8880a947f8a8 R08: ffff8880a94701c0 R09: ffffed1015ce5b90
> > R10: ffffed1015ce5b8f R11: ffff8880ae72dc7b R12: 0000000000000000
> > R13: 0000000000000000 R14: 000000000000019e R15: dffffc0000000000
> > FS: 0000000000000000(0000) GS:ffff8880ae700000(0000) knlGS:0000000000000000
> > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > CR2: ffffffffff600400 CR3: 00000000a005a000 CR4: 00000000001426e0
> > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> > DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> > Call Trace:
> > rcu_read_unlock include/linux/rcupdate.h:657 [inline]
> > batadv_nc_purge_orig_hash net/batman-adv/network-coding.c:423 [inline]
> > batadv_nc_worker+0x2f7/0x920 net/batman-adv/network-coding.c:730
> > process_one_work+0xd0c/0x1ce0 kernel/workqueue.c:2153
> > worker_thread+0x143/0x14a0 kernel/workqueue.c:2296
> > kthread+0x357/0x430 kernel/kthread.c:246
> > ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
> >
> >
> > ---
> > This bug is generated by a bot. It may contain errors.
> > See https://goo.gl/tpsmEJ for more information about syzbot.
> > syzbot engineers can be reached at syzkaller@googlegroups.com.
> >
> > syzbot will keep track of this bug report. See:
> > https://goo.gl/tpsmEJ#bug-status-tracking for how to communicate with
> > syzbot.
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller-bugs" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller-bugs+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller-bugs/20190129105957-mutt-send-email-mst%40kernel.org.
> For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* [PATCH v2 1/6] drm/virtio: move virtio_gpu_object_{attach, detach} calls.
From: Gerd Hoffmann @ 2019-01-30 9:43 UTC (permalink / raw)
To: dri-devel
Cc: David Airlie, open list, Daniel Vetter,
open list:VIRTIO GPU DRIVER
In-Reply-To: <20190130094338.14203-1-kraxel@redhat.com>
Drop the dummy ttm backend implementation, add a real one for
TTM_PL_FLAG_TT objects. The bin/unbind callbacks will call
virtio_gpu_object_{attach,detach}, to update the object state
on the host side, instead of invoking those calls from the
move_notify() callback.
With that in place the move and move_notify callbacks are not
needed any more, so drop them.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
drivers/gpu/drm/virtio/virtgpu_ttm.c | 92 ++++++++++--------------------------
1 file changed, 24 insertions(+), 68 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c
index 4bfbf25fab..77407976c7 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ttm.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c
@@ -194,42 +194,45 @@ static void virtio_gpu_ttm_io_mem_free(struct ttm_bo_device *bdev,
*/
struct virtio_gpu_ttm_tt {
struct ttm_dma_tt ttm;
- struct virtio_gpu_device *vgdev;
- u64 offset;
+ struct virtio_gpu_object *obj;
};
-static int virtio_gpu_ttm_backend_bind(struct ttm_tt *ttm,
- struct ttm_mem_reg *bo_mem)
+static int virtio_gpu_ttm_tt_bind(struct ttm_tt *ttm,
+ struct ttm_mem_reg *bo_mem)
{
- struct virtio_gpu_ttm_tt *gtt = (void *)ttm;
+ struct virtio_gpu_ttm_tt *gtt =
+ container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm);
+ struct virtio_gpu_device *vgdev =
+ virtio_gpu_get_vgdev(gtt->obj->tbo.bdev);
- gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT);
- if (!ttm->num_pages)
- WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
- ttm->num_pages, bo_mem, ttm);
-
- /* Not implemented */
+ virtio_gpu_object_attach(vgdev, gtt->obj, NULL);
return 0;
}
-static int virtio_gpu_ttm_backend_unbind(struct ttm_tt *ttm)
+static int virtio_gpu_ttm_tt_unbind(struct ttm_tt *ttm)
{
- /* Not implemented */
+ struct virtio_gpu_ttm_tt *gtt =
+ container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm);
+ struct virtio_gpu_device *vgdev =
+ virtio_gpu_get_vgdev(gtt->obj->tbo.bdev);
+
+ virtio_gpu_object_detach(vgdev, gtt->obj);
return 0;
}
-static void virtio_gpu_ttm_backend_destroy(struct ttm_tt *ttm)
+static void virtio_gpu_ttm_tt_destroy(struct ttm_tt *ttm)
{
- struct virtio_gpu_ttm_tt *gtt = (void *)ttm;
+ struct virtio_gpu_ttm_tt *gtt =
+ container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm);
ttm_dma_tt_fini(>t->ttm);
kfree(gtt);
}
-static struct ttm_backend_func virtio_gpu_backend_func = {
- .bind = &virtio_gpu_ttm_backend_bind,
- .unbind = &virtio_gpu_ttm_backend_unbind,
- .destroy = &virtio_gpu_ttm_backend_destroy,
+static struct ttm_backend_func virtio_gpu_tt_func = {
+ .bind = &virtio_gpu_ttm_tt_bind,
+ .unbind = &virtio_gpu_ttm_tt_unbind,
+ .destroy = &virtio_gpu_ttm_tt_destroy,
};
static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo,
@@ -242,8 +245,8 @@ static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo,
gtt = kzalloc(sizeof(struct virtio_gpu_ttm_tt), GFP_KERNEL);
if (gtt == NULL)
return NULL;
- gtt->ttm.ttm.func = &virtio_gpu_backend_func;
- gtt->vgdev = vgdev;
+ gtt->ttm.ttm.func = &virtio_gpu_tt_func;
+ gtt->obj = container_of(bo, struct virtio_gpu_object, tbo);
if (ttm_dma_tt_init(>t->ttm, bo, page_flags)) {
kfree(gtt);
return NULL;
@@ -251,51 +254,6 @@ static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo,
return >t->ttm.ttm;
}
-static void virtio_gpu_move_null(struct ttm_buffer_object *bo,
- struct ttm_mem_reg *new_mem)
-{
- struct ttm_mem_reg *old_mem = &bo->mem;
-
- BUG_ON(old_mem->mm_node != NULL);
- *old_mem = *new_mem;
- new_mem->mm_node = NULL;
-}
-
-static int virtio_gpu_bo_move(struct ttm_buffer_object *bo, bool evict,
- struct ttm_operation_ctx *ctx,
- struct ttm_mem_reg *new_mem)
-{
- int ret;
-
- ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);
- if (ret)
- return ret;
-
- virtio_gpu_move_null(bo, new_mem);
- return 0;
-}
-
-static void virtio_gpu_bo_move_notify(struct ttm_buffer_object *tbo,
- bool evict,
- struct ttm_mem_reg *new_mem)
-{
- struct virtio_gpu_object *bo;
- struct virtio_gpu_device *vgdev;
-
- bo = container_of(tbo, struct virtio_gpu_object, tbo);
- vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private;
-
- if (!new_mem || (new_mem->placement & TTM_PL_FLAG_SYSTEM)) {
- if (bo->hw_res_handle)
- virtio_gpu_object_detach(vgdev, bo);
-
- } else if (new_mem->placement & TTM_PL_FLAG_TT) {
- if (bo->hw_res_handle) {
- virtio_gpu_object_attach(vgdev, bo, NULL);
- }
- }
-}
-
static void virtio_gpu_bo_swap_notify(struct ttm_buffer_object *tbo)
{
struct virtio_gpu_object *bo;
@@ -314,11 +272,9 @@ static struct ttm_bo_driver virtio_gpu_bo_driver = {
.init_mem_type = &virtio_gpu_init_mem_type,
.eviction_valuable = ttm_bo_eviction_valuable,
.evict_flags = &virtio_gpu_evict_flags,
- .move = &virtio_gpu_bo_move,
.verify_access = &virtio_gpu_verify_access,
.io_mem_reserve = &virtio_gpu_ttm_io_mem_reserve,
.io_mem_free = &virtio_gpu_ttm_io_mem_free,
- .move_notify = &virtio_gpu_bo_move_notify,
.swap_notify = &virtio_gpu_bo_swap_notify,
};
--
2.9.3
^ permalink raw reply related
* [PATCH v2 2/6] drm/virtio: use struct to pass params to virtio_gpu_object_create()
From: Gerd Hoffmann @ 2019-01-30 9:43 UTC (permalink / raw)
To: dri-devel
Cc: David Airlie, open list, Daniel Vetter,
open list:VIRTIO GPU DRIVER
In-Reply-To: <20190130094338.14203-1-kraxel@redhat.com>
Create virtio_gpu_object_params, use that to pass object parameters to
virtio_gpu_object_create. This is just the first step, followup patches
will add more parameters to the struct. The plan is to use the struct
for all object parameters.
Also drop unused "kernel" parameter for virtio_gpu_alloc_object(), it is
unused and always false.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
drivers/gpu/drm/virtio/virtgpu_drv.h | 15 ++++++++++-----
drivers/gpu/drm/virtio/virtgpu_gem.c | 17 ++++++++++-------
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 11 ++++++-----
drivers/gpu/drm/virtio/virtgpu_object.c | 22 +++++++++-------------
4 files changed, 35 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index d577cb76f5..40928980a2 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -50,6 +50,11 @@
#define DRIVER_MINOR 1
#define DRIVER_PATCHLEVEL 0
+struct virtio_gpu_object_params {
+ unsigned long size;
+ bool pinned;
+};
+
struct virtio_gpu_object {
struct drm_gem_object gem_base;
uint32_t hw_res_handle;
@@ -217,16 +222,16 @@ int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev);
void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev);
int virtio_gpu_gem_create(struct drm_file *file,
struct drm_device *dev,
- uint64_t size,
+ struct virtio_gpu_object_params *params,
struct drm_gem_object **obj_p,
uint32_t *handle_p);
int virtio_gpu_gem_object_open(struct drm_gem_object *obj,
struct drm_file *file);
void virtio_gpu_gem_object_close(struct drm_gem_object *obj,
struct drm_file *file);
-struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
- size_t size, bool kernel,
- bool pinned);
+struct virtio_gpu_object*
+virtio_gpu_alloc_object(struct drm_device *dev,
+ struct virtio_gpu_object_params *params);
int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -342,7 +347,7 @@ void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev,
/* virtio_gpu_object */
int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
- unsigned long size, bool kernel, bool pinned,
+ struct virtio_gpu_object_params *params,
struct virtio_gpu_object **bo_ptr);
void virtio_gpu_object_kunmap(struct virtio_gpu_object *bo);
int virtio_gpu_object_kmap(struct virtio_gpu_object *bo);
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index f065863939..b5f2d94ce5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -34,15 +34,15 @@ void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj)
virtio_gpu_object_unref(&obj);
}
-struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
- size_t size, bool kernel,
- bool pinned)
+struct virtio_gpu_object*
+virtio_gpu_alloc_object(struct drm_device *dev,
+ struct virtio_gpu_object_params *params)
{
struct virtio_gpu_device *vgdev = dev->dev_private;
struct virtio_gpu_object *obj;
int ret;
- ret = virtio_gpu_object_create(vgdev, size, kernel, pinned, &obj);
+ ret = virtio_gpu_object_create(vgdev, params, &obj);
if (ret)
return ERR_PTR(ret);
@@ -51,7 +51,7 @@ struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
int virtio_gpu_gem_create(struct drm_file *file,
struct drm_device *dev,
- uint64_t size,
+ struct virtio_gpu_object_params *params,
struct drm_gem_object **obj_p,
uint32_t *handle_p)
{
@@ -59,7 +59,7 @@ int virtio_gpu_gem_create(struct drm_file *file,
int ret;
u32 handle;
- obj = virtio_gpu_alloc_object(dev, size, false, false);
+ obj = virtio_gpu_alloc_object(dev, params);
if (IS_ERR(obj))
return PTR_ERR(obj);
@@ -85,6 +85,7 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
struct virtio_gpu_device *vgdev = dev->dev_private;
struct drm_gem_object *gobj;
struct virtio_gpu_object *obj;
+ struct virtio_gpu_object_params params = { 0 };
int ret;
uint32_t pitch;
uint32_t format;
@@ -96,7 +97,9 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
args->size = pitch * args->height;
args->size = ALIGN(args->size, PAGE_SIZE);
- ret = virtio_gpu_gem_create(file_priv, dev, args->size, &gobj,
+ params.pinned = false,
+ params.size = args->size;
+ ret = virtio_gpu_gem_create(file_priv, dev, ¶ms, &gobj,
&args->handle);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 14ce8188c0..fa7b958ca2 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -279,12 +279,12 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
struct virtio_gpu_object *qobj;
struct drm_gem_object *obj;
uint32_t handle = 0;
- uint32_t size;
struct list_head validate_list;
struct ttm_validate_buffer mainbuf;
struct virtio_gpu_fence *fence = NULL;
struct ww_acquire_ctx ticket;
struct virtio_gpu_resource_create_3d rc_3d;
+ struct virtio_gpu_object_params params = { 0 };
if (vgdev->has_virgl_3d == false) {
if (rc->depth > 1)
@@ -302,13 +302,14 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
INIT_LIST_HEAD(&validate_list);
memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer));
- size = rc->size;
+ params.pinned = false,
+ params.size = rc->size;
/* allocate a single page size object */
- if (size == 0)
- size = PAGE_SIZE;
+ if (params.size == 0)
+ params.size = PAGE_SIZE;
- qobj = virtio_gpu_alloc_object(dev, size, false, false);
+ qobj = virtio_gpu_alloc_object(dev, ¶ms);
if (IS_ERR(qobj))
return PTR_ERR(qobj);
obj = &qobj->gem_base;
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index f39a183d59..62367e3f80 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -79,21 +79,16 @@ static void virtio_gpu_init_ttm_placement(struct virtio_gpu_object *vgbo,
}
int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
- unsigned long size, bool kernel, bool pinned,
+ struct virtio_gpu_object_params *params,
struct virtio_gpu_object **bo_ptr)
{
struct virtio_gpu_object *bo;
- enum ttm_bo_type type;
size_t acc_size;
int ret;
- if (kernel)
- type = ttm_bo_type_kernel;
- else
- type = ttm_bo_type_device;
*bo_ptr = NULL;
- acc_size = ttm_bo_dma_acc_size(&vgdev->mman.bdev, size,
+ acc_size = ttm_bo_dma_acc_size(&vgdev->mman.bdev, params->size,
sizeof(struct virtio_gpu_object));
bo = kzalloc(sizeof(struct virtio_gpu_object), GFP_KERNEL);
@@ -104,19 +99,20 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
kfree(bo);
return ret;
}
- size = roundup(size, PAGE_SIZE);
- ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size);
+ params->size = roundup(params->size, PAGE_SIZE);
+ ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, params->size);
if (ret != 0) {
virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
kfree(bo);
return ret;
}
bo->dumb = false;
- virtio_gpu_init_ttm_placement(bo, pinned);
+ virtio_gpu_init_ttm_placement(bo, params->pinned);
- ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, size, type,
- &bo->placement, 0, !kernel, acc_size,
- NULL, NULL, &virtio_gpu_ttm_bo_destroy);
+ ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, params->size,
+ ttm_bo_type_device, &bo->placement, 0,
+ true, acc_size, NULL, NULL,
+ &virtio_gpu_ttm_bo_destroy);
/* ttm_bo_init failure will call the destroy */
if (ret != 0)
return ret;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 3/6] drm/virtio: params struct for virtio_gpu_cmd_create_resource()
From: Gerd Hoffmann @ 2019-01-30 9:43 UTC (permalink / raw)
To: dri-devel
Cc: David Airlie, open list, Daniel Vetter,
open list:VIRTIO GPU DRIVER
In-Reply-To: <20190130094338.14203-1-kraxel@redhat.com>
Add format, width and height fields to the virtio_gpu_object_params
struct. With that in place we can use the parameter struct for
virtio_gpu_cmd_create_resource() calls too.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
drivers/gpu/drm/virtio/virtgpu_drv.h | 7 ++++---
drivers/gpu/drm/virtio/virtgpu_gem.c | 8 ++++----
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 6 ++++--
drivers/gpu/drm/virtio/virtgpu_vq.c | 10 ++++------
4 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 40928980a2..a40215c10e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -51,6 +51,9 @@
#define DRIVER_PATCHLEVEL 0
struct virtio_gpu_object_params {
+ uint32_t format;
+ uint32_t width;
+ uint32_t height;
unsigned long size;
bool pinned;
};
@@ -248,9 +251,7 @@ int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev);
void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo,
- uint32_t format,
- uint32_t width,
- uint32_t height);
+ struct virtio_gpu_object_params *params);
void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,
uint32_t resource_id);
void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index b5f2d94ce5..3a63ffcd4b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -88,7 +88,6 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
struct virtio_gpu_object_params params = { 0 };
int ret;
uint32_t pitch;
- uint32_t format;
if (args->bpp != 32)
return -EINVAL;
@@ -98,16 +97,17 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
args->size = ALIGN(args->size, PAGE_SIZE);
params.pinned = false,
+ params.format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB8888);
+ params.width = args->width;
+ params.height = args->height;
params.size = args->size;
ret = virtio_gpu_gem_create(file_priv, dev, ¶ms, &gobj,
&args->handle);
if (ret)
goto fail;
- format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB8888);
obj = gem_to_virtio_gpu_obj(gobj);
- virtio_gpu_cmd_create_resource(vgdev, obj, format,
- args->width, args->height);
+ virtio_gpu_cmd_create_resource(vgdev, obj, ¶ms);
/* attach the object to the resource */
ret = virtio_gpu_object_attach(vgdev, obj, NULL);
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index fa7b958ca2..84c2216fd4 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -303,6 +303,9 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer));
params.pinned = false,
+ params.format = rc->format;
+ params.width = rc->width;
+ params.height = rc->height;
params.size = rc->size;
/* allocate a single page size object */
@@ -315,8 +318,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
obj = &qobj->gem_base;
if (!vgdev->has_virgl_3d) {
- virtio_gpu_cmd_create_resource(vgdev, qobj, rc->format,
- rc->width, rc->height);
+ virtio_gpu_cmd_create_resource(vgdev, qobj, ¶ms);
ret = virtio_gpu_object_attach(vgdev, qobj, NULL);
} else {
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 6bc2008b0d..363b8b8577 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -376,9 +376,7 @@ static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev,
/* create a basic resource */
void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo,
- uint32_t format,
- uint32_t width,
- uint32_t height)
+ struct virtio_gpu_object_params *params)
{
struct virtio_gpu_resource_create_2d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
@@ -388,9 +386,9 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_2D);
cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
- cmd_p->format = cpu_to_le32(format);
- cmd_p->width = cpu_to_le32(width);
- cmd_p->height = cpu_to_le32(height);
+ cmd_p->format = cpu_to_le32(params->format);
+ cmd_p->width = cpu_to_le32(params->width);
+ cmd_p->height = cpu_to_le32(params->height);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
bo->created = true;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 4/6] drm/virtio: params struct for virtio_gpu_cmd_create_resource_3d()
From: Gerd Hoffmann @ 2019-01-30 9:43 UTC (permalink / raw)
To: dri-devel
Cc: David Airlie, open list, Daniel Vetter,
open list:VIRTIO GPU DRIVER
In-Reply-To: <20190130094338.14203-1-kraxel@redhat.com>
Add 3d resource parameters to virtio_gpu_object_params struct. With
that in place we can use it for virtio_gpu_cmd_resource_create_3d()
calls.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
drivers/gpu/drm/virtio/virtgpu_drv.h | 10 +++++++++-
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 25 ++++++++++---------------
drivers/gpu/drm/virtio/virtgpu_vq.c | 16 +++++++++++++---
3 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index a40215c10e..3265e62725 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -56,6 +56,14 @@ struct virtio_gpu_object_params {
uint32_t height;
unsigned long size;
bool pinned;
+ /* 3d */
+ uint32_t target;
+ uint32_t bind;
+ uint32_t depth;
+ uint32_t array_size;
+ uint32_t last_level;
+ uint32_t nr_samples;
+ uint32_t flags;
};
struct virtio_gpu_object {
@@ -310,7 +318,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
void
virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo,
- struct virtio_gpu_resource_create_3d *rc_3d);
+ struct virtio_gpu_object_params *params);
void virtio_gpu_ctrl_ack(struct virtqueue *vq);
void virtio_gpu_cursor_ack(struct virtqueue *vq);
void virtio_gpu_fence_ack(struct virtqueue *vq);
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 84c2216fd4..431e5d767e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -283,7 +283,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
struct ttm_validate_buffer mainbuf;
struct virtio_gpu_fence *fence = NULL;
struct ww_acquire_ctx ticket;
- struct virtio_gpu_resource_create_3d rc_3d;
struct virtio_gpu_object_params params = { 0 };
if (vgdev->has_virgl_3d == false) {
@@ -307,7 +306,15 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
params.width = rc->width;
params.height = rc->height;
params.size = rc->size;
-
+ if (vgdev->has_virgl_3d) {
+ params.target = rc->target;
+ params.bind = rc->bind;
+ params.depth = rc->depth;
+ params.array_size = rc->array_size;
+ params.last_level = rc->last_level;
+ params.nr_samples = rc->nr_samples;
+ params.flags = rc->flags;
+ }
/* allocate a single page size object */
if (params.size == 0)
params.size = PAGE_SIZE;
@@ -333,25 +340,13 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
goto fail_unref;
}
- rc_3d.resource_id = cpu_to_le32(qobj->hw_res_handle);
- rc_3d.target = cpu_to_le32(rc->target);
- rc_3d.format = cpu_to_le32(rc->format);
- rc_3d.bind = cpu_to_le32(rc->bind);
- rc_3d.width = cpu_to_le32(rc->width);
- rc_3d.height = cpu_to_le32(rc->height);
- rc_3d.depth = cpu_to_le32(rc->depth);
- rc_3d.array_size = cpu_to_le32(rc->array_size);
- rc_3d.last_level = cpu_to_le32(rc->last_level);
- rc_3d.nr_samples = cpu_to_le32(rc->nr_samples);
- rc_3d.flags = cpu_to_le32(rc->flags);
-
fence = virtio_gpu_fence_alloc(vgdev);
if (!fence) {
ret = -ENOMEM;
goto fail_backoff;
}
- virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d);
+ virtio_gpu_cmd_resource_create_3d(vgdev, qobj, ¶ms);
ret = virtio_gpu_object_attach(vgdev, qobj, fence);
if (ret) {
dma_fence_put(&fence->f);
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 363b8b8577..ca93ec6ca3 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -826,7 +826,7 @@ void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev,
void
virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo,
- struct virtio_gpu_resource_create_3d *rc_3d)
+ struct virtio_gpu_object_params *params)
{
struct virtio_gpu_resource_create_3d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
@@ -834,9 +834,19 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,
cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
memset(cmd_p, 0, sizeof(*cmd_p));
- *cmd_p = *rc_3d;
cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_3D);
- cmd_p->hdr.flags = 0;
+ cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
+ cmd_p->format = cpu_to_le32(params->format);
+ cmd_p->width = cpu_to_le32(params->width);
+ cmd_p->height = cpu_to_le32(params->height);
+
+ cmd_p->target = cpu_to_le32(params->target);
+ cmd_p->bind = cpu_to_le32(params->bind);
+ cmd_p->depth = cpu_to_le32(params->depth);
+ cmd_p->array_size = cpu_to_le32(params->array_size);
+ cmd_p->last_level = cpu_to_le32(params->last_level);
+ cmd_p->nr_samples = cpu_to_le32(params->nr_samples);
+ cmd_p->flags = cpu_to_le32(params->flags);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
bo->created = true;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 5/6] drm/virtio: drop fencing in virtio_gpu_resource_create_ioctl
From: Gerd Hoffmann @ 2019-01-30 9:43 UTC (permalink / raw)
To: dri-devel
Cc: David Airlie, open list, Daniel Vetter,
open list:VIRTIO GPU DRIVER
In-Reply-To: <20190130094338.14203-1-kraxel@redhat.com>
There is no need to wait for completion here.
The host will process commands in submit order, so commands can
reference the new resource just fine even when queued up before
completion.
On the guest side there is no need to wait for completion too. Which
btw is different from resource destroy, where we have to make sure the
host has seen the destroy and thus doesn't use it any more before
releasing the pages backing the resource.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 51 +---------------------------------
1 file changed, 1 insertion(+), 50 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 431e5d767e..da06ebbb3a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -279,10 +279,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
struct virtio_gpu_object *qobj;
struct drm_gem_object *obj;
uint32_t handle = 0;
- struct list_head validate_list;
- struct ttm_validate_buffer mainbuf;
- struct virtio_gpu_fence *fence = NULL;
- struct ww_acquire_ctx ticket;
struct virtio_gpu_object_params params = { 0 };
if (vgdev->has_virgl_3d == false) {
@@ -298,9 +294,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
- INIT_LIST_HEAD(&validate_list);
- memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer));
-
params.pinned = false,
params.format = rc->format;
params.width = rc->width;
@@ -329,62 +322,20 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
ret = virtio_gpu_object_attach(vgdev, qobj, NULL);
} else {
- /* use a gem reference since unref list undoes them */
- drm_gem_object_get(&qobj->gem_base);
- mainbuf.bo = &qobj->tbo;
- list_add(&mainbuf.head, &validate_list);
-
- ret = virtio_gpu_object_list_validate(&ticket, &validate_list);
- if (ret) {
- DRM_DEBUG("failed to validate\n");
- goto fail_unref;
- }
-
- fence = virtio_gpu_fence_alloc(vgdev);
- if (!fence) {
- ret = -ENOMEM;
- goto fail_backoff;
- }
-
virtio_gpu_cmd_resource_create_3d(vgdev, qobj, ¶ms);
- ret = virtio_gpu_object_attach(vgdev, qobj, fence);
- if (ret) {
- dma_fence_put(&fence->f);
- goto fail_backoff;
- }
- ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f);
+ ret = virtio_gpu_object_attach(vgdev, qobj, NULL);
}
ret = drm_gem_handle_create(file_priv, obj, &handle);
if (ret) {
-
drm_gem_object_release(obj);
- if (vgdev->has_virgl_3d) {
- virtio_gpu_unref_list(&validate_list);
- dma_fence_put(&fence->f);
- }
return ret;
}
drm_gem_object_put_unlocked(obj);
rc->res_handle = qobj->hw_res_handle; /* similiar to a VM address */
rc->bo_handle = handle;
-
- if (vgdev->has_virgl_3d) {
- virtio_gpu_unref_list(&validate_list);
- dma_fence_put(&fence->f);
- }
return 0;
-fail_backoff:
- ttm_eu_backoff_reservation(&ticket, &validate_list);
-fail_unref:
- if (vgdev->has_virgl_3d) {
- virtio_gpu_unref_list(&validate_list);
- dma_fence_put(&fence->f);
- }
-//fail_obj:
-// drm_gem_object_handle_unreference_unlocked(obj);
- return ret;
}
static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data,
--
2.9.3
^ permalink raw reply related
* [PATCH v2 6/6] drm/virtio: move virtio_gpu_cmd_create_resource call into virtio_gpu_object_create
From: Gerd Hoffmann @ 2019-01-30 9:43 UTC (permalink / raw)
To: dri-devel
Cc: David Airlie, open list, Daniel Vetter,
open list:VIRTIO GPU DRIVER
In-Reply-To: <20190130094338.14203-1-kraxel@redhat.com>
Specifically call virtio_gpu_object_create() before ttm_bo_init(), so
the object is already created when ttm calls the
virtio_gpu_ttm_tt_bind() callback (which in turn calls
virtio_gpu_object_attach()).
With that in place virtio_gpu_object_attach() will never be called with
an object which is not yet created, so the extra
virtio_gpu_object_attach() calls done after
virtio_gpu_cmd_create_resource() is not needed any more.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
drivers/gpu/drm/virtio/virtgpu_drv.h | 2 ++
drivers/gpu/drm/virtio/virtgpu_gem.c | 12 +-----------
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 10 +---------
drivers/gpu/drm/virtio/virtgpu_object.c | 10 ++++++++--
drivers/gpu/drm/virtio/virtgpu_vq.c | 4 ++--
5 files changed, 14 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 3265e62725..52f3950f82 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -56,7 +56,9 @@ struct virtio_gpu_object_params {
uint32_t height;
unsigned long size;
bool pinned;
+ bool dumb;
/* 3d */
+ bool virgl;
uint32_t target;
uint32_t bind;
uint32_t depth;
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 3a63ffcd4b..b5d7df17ac 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -82,9 +82,7 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args)
{
- struct virtio_gpu_device *vgdev = dev->dev_private;
struct drm_gem_object *gobj;
- struct virtio_gpu_object *obj;
struct virtio_gpu_object_params params = { 0 };
int ret;
uint32_t pitch;
@@ -101,20 +99,12 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
params.width = args->width;
params.height = args->height;
params.size = args->size;
+ params.dumb = true;
ret = virtio_gpu_gem_create(file_priv, dev, ¶ms, &gobj,
&args->handle);
if (ret)
goto fail;
- obj = gem_to_virtio_gpu_obj(gobj);
- virtio_gpu_cmd_create_resource(vgdev, obj, ¶ms);
-
- /* attach the object to the resource */
- ret = virtio_gpu_object_attach(vgdev, obj, NULL);
- if (ret)
- goto fail;
-
- obj->dumb = true;
args->pitch = pitch;
return ret;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index da06ebbb3a..3a1c447098 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -300,6 +300,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
params.height = rc->height;
params.size = rc->size;
if (vgdev->has_virgl_3d) {
+ params.virgl = true;
params.target = rc->target;
params.bind = rc->bind;
params.depth = rc->depth;
@@ -317,15 +318,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
return PTR_ERR(qobj);
obj = &qobj->gem_base;
- if (!vgdev->has_virgl_3d) {
- virtio_gpu_cmd_create_resource(vgdev, qobj, ¶ms);
-
- ret = virtio_gpu_object_attach(vgdev, qobj, NULL);
- } else {
- virtio_gpu_cmd_resource_create_3d(vgdev, qobj, ¶ms);
- ret = virtio_gpu_object_attach(vgdev, qobj, NULL);
- }
-
ret = drm_gem_handle_create(file_priv, obj, &handle);
if (ret) {
drm_gem_object_release(obj);
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 62367e3f80..94da9e68d2 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -106,9 +106,15 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
kfree(bo);
return ret;
}
- bo->dumb = false;
+ bo->dumb = params->dumb;
+
+ if (params->virgl) {
+ virtio_gpu_cmd_resource_create_3d(vgdev, bo, params);
+ } else {
+ virtio_gpu_cmd_create_resource(vgdev, bo, params);
+ }
+
virtio_gpu_init_ttm_placement(bo, params->pinned);
-
ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, params->size,
ttm_bo_type_device, &bo->placement, 0,
true, acc_size, NULL, NULL,
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index ca93ec6ca3..292663c192 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -932,8 +932,8 @@ int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
struct scatterlist *sg;
int si, nents;
- if (!obj->created)
- return 0;
+ if (WARN_ON_ONCE(!obj->created))
+ return -EINVAL;
if (!obj->pages) {
int ret;
--
2.9.3
^ permalink raw reply related
* Re: [PATCH 3/5] dma: Introduce dma_max_mapping_size()
From: Lendacky, Thomas @ 2019-01-30 15:09 UTC (permalink / raw)
To: Joerg Roedel, Michael S . Tsirkin, Jason Wang,
Konrad Rzeszutek Wilk, Christoph Hellwig
Cc: Jens Axboe, jroedel@suse.de, Singh, Brijesh, Grimm, Jon,
jfehlig@suse.com, linux-kernel@vger.kernel.org,
linux-block@vger.kernel.org, iommu@lists.linux-foundation.org,
virtualization@lists.linux-foundation.org
In-Reply-To: <20190129084342.26030-4-joro@8bytes.org>
On 1/29/19 2:43 AM, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
>
> The function returns the maximum size that can be mapped
> using DMA-API functions. The patch also adds the
> implementation for direct DMA and a new dma_map_ops pointer
> so that other implementations can expose their limit.
>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
> Documentation/DMA-API.txt | 8 ++++++++
> include/linux/dma-mapping.h | 16 ++++++++++++++++
> kernel/dma/direct.c | 11 +++++++++++
> 3 files changed, 35 insertions(+)
>
> diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
> index e133ccd60228..acfe3d0f78d1 100644
> --- a/Documentation/DMA-API.txt
> +++ b/Documentation/DMA-API.txt
> @@ -195,6 +195,14 @@ Requesting the required mask does not alter the current mask. If you
> wish to take advantage of it, you should issue a dma_set_mask()
> call to set the mask to the value returned.
>
> +::
> +
> + size_t
> + dma_direct_max_mapping_size(struct device *dev);
> +
> +Returns the maximum size of a mapping for the device. The size parameter
> +of the mapping functions like dma_map_single(), dma_map_page() and
> +others should not be larger than the returned value.
>
> Part Id - Streaming DMA mappings
> --------------------------------
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index f6ded992c183..a3ca8a71a704 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -130,6 +130,7 @@ struct dma_map_ops {
> enum dma_data_direction direction);
> int (*dma_supported)(struct device *dev, u64 mask);
> u64 (*get_required_mask)(struct device *dev);
> + size_t (*max_mapping_size)(struct device *dev);
> };
>
> #define DMA_MAPPING_ERROR (~(dma_addr_t)0)
> @@ -257,6 +258,8 @@ static inline void dma_direct_sync_sg_for_cpu(struct device *dev,
> }
> #endif
>
> +size_t dma_direct_max_mapping_size(struct device *dev);
> +
> #ifdef CONFIG_HAS_DMA
> #include <asm/dma-mapping.h>
>
> @@ -440,6 +443,19 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
> return 0;
> }
>
> +static inline size_t dma_max_mapping_size(struct device *dev)
> +{
> + const struct dma_map_ops *ops = get_dma_ops(dev);
> + size_t size = SIZE_MAX;
> +
> + if (dma_is_direct(ops))
> + size = dma_direct_max_mapping_size(dev);
> + else if (ops && ops->max_mapping_size)
> + size = ops->max_mapping_size(dev);
> +
> + return size;
> +}
> +
> void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
> gfp_t flag, unsigned long attrs);
> void dma_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 355d16acee6d..6310ad01f915 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -380,3 +380,14 @@ int dma_direct_supported(struct device *dev, u64 mask)
> */
> return mask >= __phys_to_dma(dev, min_mask);
> }
> +
> +size_t dma_direct_max_mapping_size(struct device *dev)
> +{
> + size_t size = SIZE_MAX;
> +
> + /* If SWIOTLB is active, use its maximum mapping size */
> + if (is_swiotlb_active())
> + size = swiotlb_max_mapping_size(dev);
> +
> + return size;
> +}
When I build with these patches and with the virtio devices as modules I
get a build failure. Looks like this needs an EXPORT_SYMBOL() (I'm
assuming EXPORT_SYMBOL for DMA functions and not EXPORT_SYMBOL_GPL?).
Thanks,
Tom
>
^ permalink raw reply
* Re: [PATCH 4/5] virtio: Introduce virtio_max_dma_size()
From: Lendacky, Thomas @ 2019-01-30 15:10 UTC (permalink / raw)
To: Joerg Roedel, Michael S . Tsirkin, Jason Wang,
Konrad Rzeszutek Wilk, Christoph Hellwig
Cc: Jens Axboe, jroedel@suse.de, Singh, Brijesh, Grimm, Jon,
jfehlig@suse.com, linux-kernel@vger.kernel.org,
linux-block@vger.kernel.org, iommu@lists.linux-foundation.org,
virtualization@lists.linux-foundation.org
In-Reply-To: <20190129084342.26030-5-joro@8bytes.org>
On 1/29/19 2:43 AM, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
>
> This function returns the maximum segment size for a single
> dma transaction of a virtio device. The possible limit comes
> from the SWIOTLB implementation in the Linux kernel, that
> has an upper limit of (currently) 256kb of contiguous
> memory it can map. Other DMA-API implementations might also
> have limits.
>
> Use the new dma_max_mapping_size() function to determine the
> maximum mapping size when DMA-API is in use for virtio.
>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
> drivers/virtio/virtio_ring.c | 10 ++++++++++
> include/linux/virtio.h | 2 ++
> 2 files changed, 12 insertions(+)
>
> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> index cd7e755484e3..9ca3fe6af9fa 100644
> --- a/drivers/virtio/virtio_ring.c
> +++ b/drivers/virtio/virtio_ring.c
> @@ -266,6 +266,16 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
> return false;
> }
>
> +size_t virtio_max_dma_size(struct virtio_device *vdev)
> +{
> + size_t max_segment_size = SIZE_MAX;
> +
> + if (vring_use_dma_api(vdev))
> + max_segment_size = dma_max_mapping_size(&vdev->dev);
> +
> + return max_segment_size;
> +}
When I build with these patches and with the virtio devices as modules I
get a build failure. Looks like this needs an EXPORT_SYMBOL_GPL().
Thanks,
Tom
> +
> static void *vring_alloc_queue(struct virtio_device *vdev, size_t size,
> dma_addr_t *dma_handle, gfp_t flag)
> {
> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> index fa1b5da2804e..673fe3ef3607 100644
> --- a/include/linux/virtio.h
> +++ b/include/linux/virtio.h
> @@ -157,6 +157,8 @@ int virtio_device_freeze(struct virtio_device *dev);
> int virtio_device_restore(struct virtio_device *dev);
> #endif
>
> +size_t virtio_max_dma_size(struct virtio_device *vdev);
> +
> #define virtio_device_for_each_vq(vdev, vq) \
> list_for_each_entry(vq, &vdev->vqs, list)
>
>
^ permalink raw reply
* Re: [PATCH 4/5] virtio: Introduce virtio_max_dma_size()
From: Joerg Roedel @ 2019-01-30 15:49 UTC (permalink / raw)
To: Lendacky, Thomas
Cc: Jens Axboe, Grimm, Jon, Singh, Brijesh, Konrad Rzeszutek Wilk,
Michael S . Tsirkin, jfehlig@suse.com,
linux-kernel@vger.kernel.org,
virtualization@lists.linux-foundation.org,
linux-block@vger.kernel.org, iommu@lists.linux-foundation.org,
jroedel@suse.de, Christoph Hellwig
In-Reply-To: <e138b703-188c-59d2-edec-65fe3e76d229@amd.com>
Hi Tom,
On Wed, Jan 30, 2019 at 03:10:29PM +0000, Lendacky, Thomas wrote:
> On 1/29/19 2:43 AM, Joerg Roedel wrote:
> > +size_t virtio_max_dma_size(struct virtio_device *vdev)
> > +{
> > + size_t max_segment_size = SIZE_MAX;
> > +
> > + if (vring_use_dma_api(vdev))
> > + max_segment_size = dma_max_mapping_size(&vdev->dev);
> > +
> > + return max_segment_size;
> > +}
>
> When I build with these patches and with the virtio devices as modules I
> get a build failure. Looks like this needs an EXPORT_SYMBOL_GPL().
Thanks for pointing that out, I added the missing EXPORTs and will send
a new version shortly.
Regards,
Joerg
^ permalink raw reply
* Re: [PATCH] virtio_net: Introduce extended RSC feature
From: Michael S. Tsirkin @ 2019-01-30 16:28 UTC (permalink / raw)
To: Yuri Benditovich; +Cc: Yan Vugenfirer, linux-kernel, virtualization
In-Reply-To: <CAOEp5OfBWVcSnVEm2S3VhOYH3uv+vdUvT5z2yss9v8wvriiKtA@mail.gmail.com>
On Wed, Jan 30, 2019 at 09:42:07AM +0200, Yuri Benditovich wrote:
>
>
> On Tue, Jan 29, 2019 at 6:07 PM Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Tue, Jan 29, 2019 at 02:52:36PM +0200, Yuri Benditovich wrote:
> > VIRTIO_NET_F_RSC_EXT feature bit indicates that the device
> > is able to provide extended RSC information. When the feature
> > is active and 'gso_type' field in received packet is not GSO_NONE,
> > the device reports number of coalesced packets in 'csum_start'
> > field and number of duplicated acks in 'csum_offset' field
> > and sets VIRTIO_NET_HDR_F_RSC_INFO in 'flags' field.
> >
> > Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
> > ---
> > include/uapi/linux/virtio_net.h | 15 ++++++++++++++-
> > 1 file changed, 14 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/
> virtio_net.h
> > index a3715a3224c1..93c71d714475 100644
> > --- a/include/uapi/linux/virtio_net.h
> > +++ b/include/uapi/linux/virtio_net.h
> > @@ -56,7 +56,7 @@
> > #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
> > * Steering */
> > #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
> > -
> > +#define VIRTIO_NET_F_RSC_EXT 61 /* Provides extended RSC info */
> > #define VIRTIO_NET_F_STANDBY 62 /* Act as standby for another
> device
> > * with the same MAC.
> > */
> > @@ -104,6 +104,7 @@ struct virtio_net_config {
> > struct virtio_net_hdr_v1 {
> > #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start,
> csum_offset */
> > #define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */
> > +#define VIRTIO_NET_HDR_F_RSC_INFO 4 /* rsc_ext data in csum_ fields
> */
> > __u8 flags;
> > #define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame
> */
> > #define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP
> (TSO) */
> > @@ -140,6 +141,18 @@ struct virtio_net_hdr_mrg_rxbuf {
> > struct virtio_net_hdr hdr;
> > __virtio16 num_buffers; /* Number of merged rx buffers */
> > };
> > +
> > +static inline __virtio16 *virtio_net_rsc_ext_num_packets(
> > + struct virtio_net_hdr *hdr)
> > +{
> > + return &hdr->csum_start;
> > +}
> > +
> > +static inline __virtio16 *virtio_net_rsc_ext_num_dupacks(
> > + struct virtio_net_hdr *hdr)
> > +{
> > + return &hdr->csum_offset;
> > +}
> > #endif /* ...VIRTIO_NET_NO_LEGACY */
I also wonder why do we want to put this code in the legacy section
and use the legacy virtio_net_hdr as opposed to the new virtio_net_hdr_v1.
>
> Coding style is off here. But really I don't think these inlines are
> needed here. Put them in qemu or something.
>
>
>
> The are copied from qemu as is (what exactly is wrong?).
coding style says:
Descendants are always substantially shorter than the parent and
are placed substantially to the right.
placing a line to the left of ( doesn't count as substantially to the
right :)
Maybe start a new line at virtio_net_rsc_ext_num_dupacks.
Lack of documentation is also a problem.
> The reason I place these inlines here is following:
> We pull this include sometimes to virtio-win repo exactly as qemu do.
> If I place them into qemu, then we'll have these inlines in virtio-win and in
> qemu and they are not synchronized.
>
> So, I suggest to keep them in one common header and fix style problems, if they
> present.
> Please respond if you still disagree.
Okay but this assumes specific usage. E.g. someone might want
an offset and not a pointer. Or have a struct instance on stack.
Given all above issues (and also header version issues
described above) I'm inclined to say macros are better:
#define virtio_net_rsc_ext_num_packets csum_start
#define virtio_net_rsc_ext_num_dupacks csum_offset
But please in any case also add documentation same as we have for
fields.
>
> > /*
> > --
> > 2.17.1
>
^ permalink raw reply
* Re: [PATCH] mic: vop: Fix broken virtqueues
From: Sudeep Dutt @ 2019-01-30 16:29 UTC (permalink / raw)
To: Vincent Whitchurch
Cc: arnd, gregkh, Sudeep Dutt, virtualization, ashutosh.dixit, luto,
linux-kernel, Vincent Whitchurch
In-Reply-To: <20190129102207.9577-1-vincent.whitchurch@axis.com>
On Tue, 2019-01-29 at 11:22 +0100, Vincent Whitchurch wrote:
> VOP is broken in mainline since commit 1ce9e6055fa0a9043 ("virtio_ring:
> introduce packed ring support"); attempting to use the virtqueues leads
> to various kernel crashes. I'm testing it with my not-yet-merged
> loopback patches, but even the in-tree MIC hardware cannot work.
>
> The problem is not in the referenced commit per se, but is due to the
> following hack in vop_find_vq() which depends on the layout of private
> structures in other source files, which that commit happened to change:
>
> /*
> * To reassign the used ring here we are directly accessing
> * struct vring_virtqueue which is a private data structure
> * in virtio_ring.c. At the minimum, a BUILD_BUG_ON() in
> * vring_new_virtqueue() would ensure that
> * (&vq->vring == (struct vring *) (&vq->vq + 1));
> */
> vr = (struct vring *)(vq + 1);
> vr->used = used;
>
> Fix vop by using __vring_new_virtqueue() to create the needed vring
> layout from the start, instead of attempting to patch in the used ring
> later. __vring_new_virtqueue() was added way back in commit
> 2a2d1382fe9dcc ("virtio: Add improved queue allocation API") in order to
> address mic's usecase, according to the commit message.
>
Thank you for fixing this up Vincent.
Reviewed-by: Sudeep Dutt <sudeep.dutt@intel.com>
> Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
> ---
> drivers/misc/mic/vop/vop_main.c | 60 +++++++++++++++++++--------------
> 1 file changed, 34 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c
> index d2b9782eee87..fef45bf6d519 100644
> --- a/drivers/misc/mic/vop/vop_main.c
> +++ b/drivers/misc/mic/vop/vop_main.c
> @@ -284,6 +284,26 @@ static void vop_del_vqs(struct virtio_device *dev)
> vop_del_vq(vq, idx++);
> }
>
> +static struct virtqueue *vop_new_virtqueue(unsigned int index,
> + unsigned int num,
> + struct virtio_device *vdev,
> + bool context,
> + void *pages,
> + bool (*notify)(struct virtqueue *vq),
> + void (*callback)(struct virtqueue *vq),
> + const char *name,
> + void *used)
> +{
> + bool weak_barriers = false;
> + struct vring vring;
> +
> + vring_init(&vring, num, pages, MIC_VIRTIO_RING_ALIGN);
> + vring.used = used;
> +
> + return __vring_new_virtqueue(index, vring, vdev, weak_barriers, context,
> + notify, callback, name);
> +}
> +
> /*
> * This routine will assign vring's allocated in host/io memory. Code in
> * virtio_ring.c however continues to access this io memory as if it were local
> @@ -303,7 +323,6 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
> struct _mic_vring_info __iomem *info;
> void *used;
> int vr_size, _vr_size, err, magic;
> - struct vring *vr;
> u8 type = ioread8(&vdev->desc->type);
>
> if (index >= ioread8(&vdev->desc->num_vq))
> @@ -322,17 +341,7 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
> return ERR_PTR(-ENOMEM);
> vdev->vr[index] = va;
> memset_io(va, 0x0, _vr_size);
> - vq = vring_new_virtqueue(
> - index,
> - le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN,
> - dev,
> - false,
> - ctx,
> - (void __force *)va, vop_notify, callback, name);
> - if (!vq) {
> - err = -ENOMEM;
> - goto unmap;
> - }
> +
> info = va + _vr_size;
> magic = ioread32(&info->magic);
>
> @@ -341,7 +350,6 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
> goto unmap;
> }
>
> - /* Allocate and reassign used ring now */
> vdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
> sizeof(struct vring_used_elem) *
> le16_to_cpu(config.num));
> @@ -351,8 +359,17 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
> err = -ENOMEM;
> dev_err(_vop_dev(vdev), "%s %d err %d\n",
> __func__, __LINE__, err);
> - goto del_vq;
> + goto unmap;
> + }
> +
> + vq = vop_new_virtqueue(index, le16_to_cpu(config.num), dev, ctx,
> + (void __force *)va, vop_notify, callback,
> + name, used);
> + if (!vq) {
> + err = -ENOMEM;
> + goto free_used;
> }
> +
> vdev->used[index] = dma_map_single(&vpdev->dev, used,
> vdev->used_size[index],
> DMA_BIDIRECTIONAL);
> @@ -360,26 +377,17 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
> err = -ENOMEM;
> dev_err(_vop_dev(vdev), "%s %d err %d\n",
> __func__, __LINE__, err);
> - goto free_used;
> + goto del_vq;
> }
> writeq(vdev->used[index], &vqconfig->used_address);
> - /*
> - * To reassign the used ring here we are directly accessing
> - * struct vring_virtqueue which is a private data structure
> - * in virtio_ring.c. At the minimum, a BUILD_BUG_ON() in
> - * vring_new_virtqueue() would ensure that
> - * (&vq->vring == (struct vring *) (&vq->vq + 1));
> - */
> - vr = (struct vring *)(vq + 1);
> - vr->used = used;
>
> vq->priv = vdev;
> return vq;
> +del_vq:
> + vring_del_virtqueue(vq);
> free_used:
> free_pages((unsigned long)used,
> get_order(vdev->used_size[index]));
> -del_vq:
> - vring_del_virtqueue(vq);
> unmap:
> vpdev->hw_ops->unmap(vpdev, vdev->vr[index]);
> return ERR_PTR(err);
^ permalink raw reply
* [PATCH 0/5 v5] Fix virtio-blk issue with SWIOTLB
From: Joerg Roedel @ 2019-01-30 16:40 UTC (permalink / raw)
To: Michael S . Tsirkin, Jason Wang, Konrad Rzeszutek Wilk,
Christoph Hellwig
Cc: Jens Axboe, Thomas.Lendacky, jroedel, brijesh.singh, joro,
jon.grimm, jfehlig, linux-kernel, linux-block, iommu,
virtualization
Hi,
here is the next version of this patch-set. Previous
versions can be found here:
V1: https://lore.kernel.org/lkml/20190110134433.15672-1-joro@8bytes.org/
V2: https://lore.kernel.org/lkml/20190115132257.6426-1-joro@8bytes.org/
V3: https://lore.kernel.org/lkml/20190123163049.24863-1-joro@8bytes.org/
V4: https://lore.kernel.org/lkml/20190129084342.26030-1-joro@8bytes.org/
The problem solved here is a limitation of the SWIOTLB implementation,
which does not support allocations larger than 256kb. When the
virtio-blk driver tries to read/write a block larger than that, the
allocation of the dma-handle fails and an IO error is reported.
Changes to v4 are:
- Added Reviewed-by tags from Christoph
- Added missing EXPORT_SYMBOL(_GPL) lines
Please review.
Thanks,
Joerg
Joerg Roedel (5):
swiotlb: Introduce swiotlb_max_mapping_size()
swiotlb: Add is_swiotlb_active() function
dma: Introduce dma_max_mapping_size()
virtio: Introduce virtio_max_dma_size()
virtio-blk: Consider virtio_max_dma_size() for maximum segment size
Documentation/DMA-API.txt | 8 ++++++++
drivers/block/virtio_blk.c | 10 ++++++----
drivers/virtio/virtio_ring.c | 11 +++++++++++
include/linux/dma-mapping.h | 16 ++++++++++++++++
include/linux/swiotlb.h | 11 +++++++++++
include/linux/virtio.h | 2 ++
kernel/dma/direct.c | 12 ++++++++++++
kernel/dma/swiotlb.c | 14 ++++++++++++++
8 files changed, 80 insertions(+), 4 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 1/5] swiotlb: Introduce swiotlb_max_mapping_size()
From: Joerg Roedel @ 2019-01-30 16:40 UTC (permalink / raw)
To: Michael S . Tsirkin, Jason Wang, Konrad Rzeszutek Wilk,
Christoph Hellwig
Cc: Jens Axboe, Thomas.Lendacky, jroedel, brijesh.singh, joro,
jon.grimm, jfehlig, linux-kernel, linux-block, iommu,
virtualization
In-Reply-To: <20190130164007.26497-1-joro@8bytes.org>
From: Joerg Roedel <jroedel@suse.de>
The function returns the maximum size that can be remapped
by the SWIOTLB implementation. This function will be later
exposed to users through the DMA-API.
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
include/linux/swiotlb.h | 5 +++++
kernel/dma/swiotlb.c | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 7c007ed7505f..1c22d96e1742 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -62,6 +62,7 @@ extern void swiotlb_tbl_sync_single(struct device *hwdev,
extern int
swiotlb_dma_supported(struct device *hwdev, u64 mask);
+size_t swiotlb_max_mapping_size(struct device *dev);
#ifdef CONFIG_SWIOTLB
extern enum swiotlb_force swiotlb_force;
@@ -95,6 +96,10 @@ static inline unsigned int swiotlb_max_segment(void)
{
return 0;
}
+static inline size_t swiotlb_max_mapping_size(struct device *dev)
+{
+ return SIZE_MAX;
+}
#endif /* CONFIG_SWIOTLB */
extern void swiotlb_print_info(void);
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index 1fb6fd68b9c7..9cb21259cb0b 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -662,3 +662,8 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask)
{
return __phys_to_dma(hwdev, io_tlb_end - 1) <= mask;
}
+
+size_t swiotlb_max_mapping_size(struct device *dev)
+{
+ return ((size_t)1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE;
+}
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox