From 7fce2462a0df5e3ab767103026cc0139e606facf Mon Sep 17 00:00:00 2001 From: Yin Fengwei Date: Mon, 26 Nov 2018 16:12:13 +0800 Subject: [PATCH] dm: apply new mevent API to avoid race issue in mei Pass teardown callback when add mevent in mei mediator code. Which could avoid run_callback calling after the related data structure is freed. Tracked-On: #1877 Signed-off-by: Yin Fengwei Acked-by: Yu Wang --- devicemodel/core/mevent.c | 5 ++-- devicemodel/hw/pci/virtio/virtio_mei.c | 34 +++++++++++++++++--------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/devicemodel/core/mevent.c b/devicemodel/core/mevent.c index 4ce88b3b3..b3dea660b 100644 --- a/devicemodel/core/mevent.c +++ b/devicemodel/core/mevent.c @@ -254,8 +254,6 @@ mevent_add(int tfd, enum ev_type type, return mevp; } else { - if (mevp->teardown) - mevp->teardown(mevp->teardown_param); free(mevp); return NULL; } @@ -347,6 +345,9 @@ mevent_delete_event(struct mevent *evp, int closefd) if (evp->closefd) { close(evp->me_fd); } + + if (evp->teardown) + evp->teardown(evp->teardown_param); free(evp); } return 0; diff --git a/devicemodel/hw/pci/virtio/virtio_mei.c b/devicemodel/hw/pci/virtio/virtio_mei.c index 8e81a05fd..1d0c66794 100644 --- a/devicemodel/hw/pci/virtio/virtio_mei.c +++ b/devicemodel/hw/pci/virtio/virtio_mei.c @@ -378,7 +378,6 @@ vmei_host_client_destroy(const struct refcnt *ref) { struct vmei_host_client *hclient; struct vmei_me_client *mclient; - unsigned int i; hclient = container_of(ref, struct vmei_host_client, ref); @@ -390,6 +389,14 @@ vmei_host_client_destroy(const struct refcnt *ref) if (hclient->rx_mevp) mevent_delete(hclient->rx_mevp); +} + +static void +vmei_rx_teardown(void *param) +{ + unsigned int i; + struct vmei_host_client *hclient = param; + if (hclient->client_fd > -1) close(hclient->client_fd); for (i = 0; i < VMEI_IOBUFS_MAX; i++) @@ -955,12 +962,21 @@ vmei_reset(void *vth) virtio_reset_dev(&vmei->base); } +static void +vmei_reset_teardown(void *param) +{ + struct virtio_mei *vmei = param; + vmei->reset_mevp = NULL; + + pthread_mutex_destroy(&vmei->mutex); + free(vmei->config); + free(vmei); +} + static void vmei_del_reset_event(struct virtio_mei *vmei) { if (vmei->reset_mevp) mevent_delete_close(vmei->reset_mevp); - - vmei->reset_mevp = NULL; } static void vmei_rx_callback(int fd, enum ev_type type, void *param); @@ -1017,7 +1033,7 @@ vmei_host_client_native_connect(struct vmei_host_client *hclient) /* add READ event into mevent */ hclient->rx_mevp = mevent_add(hclient->client_fd, EVF_READ, - vmei_rx_callback, hclient, NULL, NULL); + vmei_rx_callback, hclient, vmei_rx_teardown, hclient); if (!hclient->rx_mevp) return MEI_HBM_REJECTED; @@ -1951,7 +1967,7 @@ vmei_start(struct virtio_mei *vmei, bool do_rescan) hclient->client_fd = pipefd[0]; hclient->rx_mevp = mevent_add(hclient->client_fd, EVF_READ, - vmei_rx_callback, hclient, NULL, NULL); + vmei_rx_callback, hclient, vmei_rx_teardown, hclient); vmei->hbm_fd = pipefd[1]; if (do_rescan) { @@ -2051,7 +2067,7 @@ static int vmei_add_reset_event(struct virtio_mei *vmei) vmei->dev_state_first = true; vmei->reset_mevp = mevent_add(dev_state_fd, EVF_READ_ET, - vmei_reset_callback, vmei, NULL, NULL); + vmei_reset_callback, vmei, vmei_reset_teardown, vmei); if (!vmei->reset_mevp) { close(dev_state_fd); return -ENOMEM; @@ -2336,12 +2352,8 @@ vmei_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts) if (!vmei) return; - vmei_del_reset_event(vmei); vmei_stop(vmei); - - pthread_mutex_destroy(&vmei->mutex); - free(vmei->config); - free(vmei); + vmei_del_reset_event(vmei); } const struct pci_vdev_ops pci_ops_vmei = {