diff options
author | Jason Wang <jasowang@redhat.com> | 2019-01-16 16:54:42 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-17 21:43:24 -0800 |
commit | cc5e710759470bc7f3c61d11fd54586f15fdbdf4 (patch) | |
tree | c636103033e16eb5d9218b7c7cdbd98a89c4077c /drivers/vhost/vhost.h | |
parent | f655f8b818684716b2ebe35760c9b96184587d56 (diff) | |
download | linux-cc5e710759470bc7f3c61d11fd54586f15fdbdf4.tar.gz linux-cc5e710759470bc7f3c61d11fd54586f15fdbdf4.tar.bz2 linux-cc5e710759470bc7f3c61d11fd54586f15fdbdf4.zip |
vhost: log dirty page correctly
Vhost dirty page logging API is designed to sync through GPA. But we
try to log GIOVA when device IOTLB is enabled. This is wrong and may
lead to missing data after migration.
To solve this issue, when logging with device IOTLB enabled, we will:
1) reuse the device IOTLB translation result of GIOVA->HVA mapping to
get HVA, for writable descriptor, get HVA through iovec. For used
ring update, translate its GIOVA to HVA
2) traverse the GPA->HVA mapping to get the possible GPA and log
through GPA. Pay attention this reverse mapping is not guaranteed
to be unique, so we should log each possible GPA in this case.
This fix the failure of scp to guest during migration. In -next, we
will probably support passing GIOVA->GPA instead of GIOVA->HVA.
Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")
Reported-by: Jintack Lim <jintack@cs.columbia.edu>
Cc: Jintack Lim <jintack@cs.columbia.edu>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/vhost/vhost.h')
-rw-r--r-- | drivers/vhost/vhost.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 466ef7542291..1b675dad5e05 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -205,7 +205,8 @@ bool vhost_vq_avail_empty(struct vhost_dev *, struct vhost_virtqueue *); bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, - unsigned int log_num, u64 len); + unsigned int log_num, u64 len, + struct iovec *iov, int count); int vq_iotlb_prefetch(struct vhost_virtqueue *vq); struct vhost_msg_node *vhost_new_msg(struct vhost_virtqueue *vq, int type); |