Skip to content

Commit

Permalink
hcd-xhci: check & correct param before using it
Browse files Browse the repository at this point in the history
usb_xhci_realize() corrects invalid values of property "intrs"
automatically, but the uncorrected value is passed to msi_init(),
which chokes on invalid values.  Delay that until after the
correction.

Resources allocated by usb_xhci_init() are leaked when msi_init()
fails.  Fix by calling it after msi_init().

CC: Gerd Hoffmann <kraxel@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
CC: Marcel Apfelbaum <marcel@redhat.com>
CC: Michael S. Tsirkin <mst@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
Cao jin authored and mstsirkin committed Feb 1, 2017
1 parent 9348243 commit 20729db
Showing 1 changed file with 18 additions and 19 deletions.
37 changes: 18 additions & 19 deletions hw/usb/hcd-xhci.c
Expand Up @@ -3627,25 +3627,6 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
dev->config[PCI_CACHE_LINE_SIZE] = 0x10;
dev->config[0x60] = 0x30; /* release number */

usb_xhci_init(xhci);

if (xhci->msi != ON_OFF_AUTO_OFF) {
ret = msi_init(dev, 0x70, xhci->numintrs, true, false, &err);
/* Any error other than -ENOTSUP(board's MSI support is broken)
* is a programming error */
assert(!ret || ret == -ENOTSUP);
if (ret && xhci->msi == ON_OFF_AUTO_ON) {
/* Can't satisfy user's explicit msi=on request, fail */
error_append_hint(&err, "You have to use msi=auto (default) or "
"msi=off with this machine type.\n");
error_propagate(errp, err);
return;
}
assert(!err || xhci->msi == ON_OFF_AUTO_AUTO);
/* With msi=auto, we fall back to MSI off silently */
error_free(err);
}

if (xhci->numintrs > MAXINTRS) {
xhci->numintrs = MAXINTRS;
}
Expand All @@ -3667,6 +3648,24 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
xhci->max_pstreams_mask = 0;
}

if (xhci->msi != ON_OFF_AUTO_OFF) {
ret = msi_init(dev, 0x70, xhci->numintrs, true, false, &err);
/* Any error other than -ENOTSUP(board's MSI support is broken)
* is a programming error */
assert(!ret || ret == -ENOTSUP);
if (ret && xhci->msi == ON_OFF_AUTO_ON) {
/* Can't satisfy user's explicit msi=on request, fail */
error_append_hint(&err, "You have to use msi=auto (default) or "
"msi=off with this machine type.\n");
error_propagate(errp, err);
return;
}
assert(!err || xhci->msi == ON_OFF_AUTO_AUTO);
/* With msi=auto, we fall back to MSI off silently */
error_free(err);
}

usb_xhci_init(xhci);
xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci);

memory_region_init(&xhci->mem, OBJECT(xhci), "xhci", LEN_REGS);
Expand Down

0 comments on commit 20729db

Please sign in to comment.