hcd-xhci: check & correct param before using it
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>
This commit is contained in:
		
							parent
							
								
									9348243687
								
							
						
					
					
						commit
						20729dbd01
					
				@ -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;
 | 
			
		||||
    }
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user