mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 12:42:54 +00:00
DM USB: fix memory leak during reboot
1. free memory during pci_xhci_dev_destroy. 2. add libusb_free_device_list to free the list of devices previously discovered using libusb_get_device_list(). 3. fix possible memory corruption. Tracked-On: #2892 Signed-off-by: Conghui Chen <conghui.chen@intel.com> Reviewed-by: Xiaoguang Wu <xiaoguang.wu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
f22347346e
commit
e8dda1e914
@ -892,7 +892,7 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
edev = xdev->devices[vport];
|
edev = xdev->devices[vport];
|
||||||
for (slot = 1; slot < XHCI_MAX_SLOTS; ++slot)
|
for (slot = 1; slot <= XHCI_MAX_SLOTS; ++slot)
|
||||||
if (xdev->slots[slot] == edev)
|
if (xdev->slots[slot] == edev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1056,6 +1056,8 @@ pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de)
|
|||||||
{
|
{
|
||||||
struct usb_devemu *ue;
|
struct usb_devemu *ue;
|
||||||
struct usb_dev *ud;
|
struct usb_dev *ud;
|
||||||
|
struct pci_xhci_dev_ep *vdep;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (de) {
|
if (de) {
|
||||||
ue = de->dev_ue;
|
ue = de->dev_ue;
|
||||||
@ -1072,6 +1074,18 @@ pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de)
|
|||||||
if (ue->ue_devtype == USB_DEV_PORT_MAPPER)
|
if (ue->ue_devtype == USB_DEV_PORT_MAPPER)
|
||||||
free(ue);
|
free(ue);
|
||||||
|
|
||||||
|
for (i = 1; i < XHCI_MAX_ENDPOINTS; i++) {
|
||||||
|
vdep = &de->eps[i];
|
||||||
|
if (vdep->ep_xfer) {
|
||||||
|
if (vdep->ep_xfer->ureq) {
|
||||||
|
free(vdep->ep_xfer->ureq);
|
||||||
|
vdep->ep_xfer->ureq = NULL;
|
||||||
|
}
|
||||||
|
free(vdep->ep_xfer);
|
||||||
|
vdep->ep_xfer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(de);
|
free(de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3962,7 +3976,7 @@ pci_xhci_parse_opts(struct pci_xhci_vdev *xdev, char *opts)
|
|||||||
|
|
||||||
/* allocate neccessary resources during parsing*/
|
/* allocate neccessary resources during parsing*/
|
||||||
xdev->devices = calloc(XHCI_MAX_DEVS + 1, sizeof(*xdev->devices));
|
xdev->devices = calloc(XHCI_MAX_DEVS + 1, sizeof(*xdev->devices));
|
||||||
xdev->slots = calloc(XHCI_MAX_SLOTS, sizeof(*xdev->slots));
|
xdev->slots = calloc(XHCI_MAX_SLOTS + 1, sizeof(*xdev->slots));
|
||||||
xdev->portregs = calloc(XHCI_MAX_DEVS + 1, sizeof(*xdev->portregs));
|
xdev->portregs = calloc(XHCI_MAX_DEVS + 1, sizeof(*xdev->portregs));
|
||||||
if (!xdev->devices || !xdev->slots || !xdev->portregs) {
|
if (!xdev->devices || !xdev->slots || !xdev->portregs) {
|
||||||
rc = -2;
|
rc = -2;
|
||||||
|
@ -125,21 +125,22 @@ internal_scan(struct libusb_device ***list, int list_sz, int depth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
usb_dev_scan_dev()
|
usb_dev_scan_dev(struct libusb_device ***devlist)
|
||||||
{
|
{
|
||||||
int num_devs;
|
int num_devs;
|
||||||
struct libusb_device **devlist;
|
|
||||||
int8_t visit[USB_MAX_DEVICES];
|
int8_t visit[USB_MAX_DEVICES];
|
||||||
|
|
||||||
if (!g_ctx.libusb_ctx)
|
if (!g_ctx.libusb_ctx)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
num_devs = libusb_get_device_list(g_ctx.libusb_ctx, &devlist);
|
num_devs = libusb_get_device_list(g_ctx.libusb_ctx, devlist);
|
||||||
if (num_devs < 0)
|
if (num_devs < 0) {
|
||||||
|
*devlist = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
memset(visit, 0, sizeof(visit));
|
memset(visit, 0, sizeof(visit));
|
||||||
internal_scan(&devlist, num_devs, 1, visit, USB_MAX_DEVICES);
|
internal_scan(devlist, num_devs, 1, visit, USB_MAX_DEVICES);
|
||||||
return num_devs;
|
return num_devs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1215,7 +1216,7 @@ usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
|
|||||||
g_ctx.notify_cb = notify_cb;
|
g_ctx.notify_cb = notify_cb;
|
||||||
g_ctx.intr_cb = intr_cb;
|
g_ctx.intr_cb = intr_cb;
|
||||||
|
|
||||||
num_devs = usb_dev_scan_dev();
|
num_devs = usb_dev_scan_dev(&g_ctx.devlist);
|
||||||
UPRINTF(LINF, "found %d devices before Guest OS booted\r\n", num_devs);
|
UPRINTF(LINF, "found %d devices before Guest OS booted\r\n", num_devs);
|
||||||
|
|
||||||
native_conn_evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
|
native_conn_evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
|
||||||
@ -1260,10 +1261,15 @@ usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
if (g_ctx.libusb_ctx)
|
if (g_ctx.devlist) {
|
||||||
libusb_exit(g_ctx.libusb_ctx);
|
libusb_free_device_list(g_ctx.devlist, 1);
|
||||||
|
g_ctx.devlist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ctx.libusb_ctx) {
|
||||||
|
libusb_exit(g_ctx.libusb_ctx);
|
||||||
g_ctx.libusb_ctx = NULL;
|
g_ctx.libusb_ctx = NULL;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,6 +1287,11 @@ usb_dev_sys_deinit(void)
|
|||||||
g_ctx.thread_exit = 1;
|
g_ctx.thread_exit = 1;
|
||||||
pthread_join(g_ctx.thread, NULL);
|
pthread_join(g_ctx.thread, NULL);
|
||||||
|
|
||||||
|
if (g_ctx.devlist) {
|
||||||
|
libusb_free_device_list(g_ctx.devlist, 1);
|
||||||
|
g_ctx.devlist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
libusb_exit(g_ctx.libusb_ctx);
|
libusb_exit(g_ctx.libusb_ctx);
|
||||||
g_ctx.libusb_ctx = NULL;
|
g_ctx.libusb_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,8 @@ struct usb_dev_sys_ctx_info {
|
|||||||
usb_dev_sys_cb notify_cb;
|
usb_dev_sys_cb notify_cb;
|
||||||
usb_dev_sys_cb intr_cb;
|
usb_dev_sys_cb intr_cb;
|
||||||
|
|
||||||
|
libusb_device **devlist;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* private data from HCD layer
|
* private data from HCD layer
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user