mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-12 18:34:24 +00:00
dm: fix the bug that infinite calls to vq_getchain()
The current code would cause infinite calls to vq_getchain() because that: - error check of vq_getchain() return value is missing. - virtqueue misunderstand that there are avaliable descripters even though the idx of avail ring is invalid. This patch fixes it by checking validity of the return of vq_getchain() and jump out of the loop for invalid return value. This patch alse add validity check in judgment of avaliable descriptor, and check if the diff between idx of avail ring and the last idx is greater than size of this queue. Tracked-On: #7038 Signed-off-by: Wen Qian <qian.wen@intel.com> Signed-off-by: Li Fei <fei1.li@intel.com> Acked-by: Wang Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
c93c2224e0
commit
ace5ef44e8
@ -392,7 +392,10 @@ virtio_console_notify_tx(void *vdev, struct virtio_vq_info *vq)
|
||||
port = virtio_console_vq_to_port(console, vq);
|
||||
|
||||
while (vq_has_descs(vq)) {
|
||||
vq_getchain(vq, &idx, iov, 1, flags);
|
||||
if (vq_getchain(vq, &idx, iov, 1, flags) < 1) {
|
||||
pr_err("%s: fail to getchain!\n", __func__);
|
||||
break;
|
||||
}
|
||||
if ((port != NULL) && (port->cb != NULL))
|
||||
port->cb(port, port->arg, iov, 1);
|
||||
|
||||
@ -481,6 +484,10 @@ virtio_console_backend_read(int fd __attribute__((unused)),
|
||||
|
||||
do {
|
||||
n = vq_getchain(vq, &idx, &iov, 1, NULL);
|
||||
if (n < 1){
|
||||
pr_err("%s: fail to getchain!\n", __func__);
|
||||
break;
|
||||
}
|
||||
len = readv(be->fd, &iov, n);
|
||||
if (len <= 0) {
|
||||
vq_retchain(vq);
|
||||
|
@ -688,7 +688,7 @@ virtio_gpio_notify(void *vdev, struct virtio_vq_info *vq)
|
||||
gpio = (struct virtio_gpio *)vdev;
|
||||
if (vq_has_descs(vq)) {
|
||||
n = vq_getchain(vq, &idx, iov, 2, NULL);
|
||||
if (n >= 3) {
|
||||
if (n < 1 || n >= 3) {
|
||||
WPRINTF(("virtio gpio, invalid chain number %d\n", n));
|
||||
virtio_gpio_abort(vq, idx);
|
||||
return;
|
||||
|
@ -322,7 +322,10 @@ virtio_rnd_get_entropy(void *param)
|
||||
pthread_mutex_unlock(&rnd->rx_mtx);
|
||||
|
||||
do {
|
||||
vq_getchain(vq, &idx, &iov, 1, NULL);
|
||||
if (vq_getchain(vq, &idx, &iov, 1, NULL) < 1) {
|
||||
pr_err("%s: fail to getchain!\n", __func__);
|
||||
break;
|
||||
}
|
||||
len = read(rnd->fd, iov.iov_base, iov.iov_len);
|
||||
if (len <= 0) {
|
||||
vq_retchain(vq);
|
||||
|
@ -477,8 +477,15 @@ vq_ring_ready(struct virtio_vq_info *vq)
|
||||
static inline bool
|
||||
vq_has_descs(struct virtio_vq_info *vq)
|
||||
{
|
||||
return (vq_ring_ready(vq) && vq->last_avail !=
|
||||
vq->avail->idx);
|
||||
bool ret = false;
|
||||
if (vq_ring_ready(vq) && vq->last_avail != vq->avail->idx) {
|
||||
if ((uint16_t)((u_int)vq->avail->idx - vq->last_avail) > vq->qsize)
|
||||
pr_err ("%s: no valid descriptor\n", vq->base->vops->name);
|
||||
else
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user