mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-31 23:38:24 +00:00
DM: Add the return value check in case cause Null pointer exception
paddr_guest2host may return NULL, this patch checks the return value to avoid null pointer dereference. Tracked-On: #5514 Signed-off-by: Liu Long <long.liu@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
9ab1110f80
commit
b37442564b
@ -23,6 +23,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "vmmapi.h"
|
||||
#include "monitor.h"
|
||||
@ -188,6 +189,10 @@ int parse_pm_by_vuart(const char *opts)
|
||||
char *str, *cpy, *type;
|
||||
|
||||
str = cpy = strdup(opts);
|
||||
if (!str) {
|
||||
pr_err("Function strdup return %d in %s line %d!\n", errno, __func__, __LINE__);
|
||||
return error;
|
||||
}
|
||||
type = strsep(&str, ",");
|
||||
|
||||
if (type != NULL) {
|
||||
|
@ -786,6 +786,10 @@ read_prdt(struct ahci_port *p, int slot, uint8_t *cfis,
|
||||
|
||||
dbcsz = (prdt->dbc & DBCMASK) + 1;
|
||||
ptr = paddr_guest2host(ahci_ctx(p->ahci_dev), prdt->dba, dbcsz);
|
||||
if (!ptr) {
|
||||
WPRINTF("%s:%d invalid gpa 0x%x!\n", __func__, __LINE__, prdt->dba);
|
||||
continue;
|
||||
}
|
||||
sublen = MIN(len, dbcsz);
|
||||
memcpy(to, ptr, sublen);
|
||||
len -= sublen;
|
||||
@ -905,6 +909,10 @@ write_prdt(struct ahci_port *p, int slot, uint8_t *cfis,
|
||||
|
||||
dbcsz = (prdt->dbc & DBCMASK) + 1;
|
||||
ptr = paddr_guest2host(ahci_ctx(p->ahci_dev), prdt->dba, dbcsz);
|
||||
if (!ptr) {
|
||||
WPRINTF("%s:%d invalid gpa 0x%x!\n", __func__, __LINE__, prdt->dba);
|
||||
continue;
|
||||
}
|
||||
sublen = MIN(len, dbcsz);
|
||||
memcpy(ptr, from, sublen);
|
||||
len -= sublen;
|
||||
@ -1812,6 +1820,10 @@ ahci_handle_slot(struct ahci_port *p, int slot)
|
||||
#endif
|
||||
cfis = paddr_guest2host(ahci_ctx(ahci_dev), hdr->ctba,
|
||||
0x80 + hdr->prdtl * sizeof(struct ahci_prdt_entry));
|
||||
if (!cfis) {
|
||||
WPRINTF("%s:%d invalid gpa 0x%x!\n", __func__, __LINE__, hdr->ctba);
|
||||
return;
|
||||
}
|
||||
#ifdef AHCI_DEBUG
|
||||
prdt = (struct ahci_prdt_entry *)(cfis + 0x80);
|
||||
|
||||
|
@ -84,6 +84,7 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <semaphore.h>
|
||||
#include "usb.h"
|
||||
#include "usbdi.h"
|
||||
@ -1121,7 +1122,7 @@ static int
|
||||
pci_xhci_change_port(struct pci_xhci_vdev *xdev, int port, int usb_speed,
|
||||
int conn, int need_intr)
|
||||
{
|
||||
int speed, error;
|
||||
int speed;
|
||||
struct xhci_trb evtrb;
|
||||
struct pci_xhci_portregs *reg;
|
||||
|
||||
@ -1152,12 +1153,12 @@ pci_xhci_change_port(struct pci_xhci_vdev *xdev, int port, int usb_speed,
|
||||
XHCI_TRB_EVENT_PORT_STS_CHANGE);
|
||||
|
||||
/* put it in the event ring */
|
||||
error = pci_xhci_insert_event(xdev, &evtrb, 1);
|
||||
if (error != XHCI_TRB_ERROR_SUCCESS)
|
||||
UPRINTF(LWRN, "fail to report port change\r\n");
|
||||
|
||||
if (pci_xhci_insert_event(xdev, &evtrb, 1) != 0) {
|
||||
UPRINTF(LFTL, "Failed to inject the change port event!\r\n");
|
||||
return -1;
|
||||
}
|
||||
UPRINTF(LDBG, "%s: port %d:%08X\r\n", __func__, port, reg->portsc);
|
||||
return (error == XHCI_TRB_ERROR_SUCCESS) ? 0 : -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1371,7 +1372,8 @@ pci_xhci_portregs_write(struct pci_xhci_vdev *xdev,
|
||||
pci_xhci_set_evtrb(&evtrb, port,
|
||||
XHCI_TRB_ERROR_SUCCESS,
|
||||
XHCI_TRB_EVENT_PORT_STS_CHANGE);
|
||||
pci_xhci_insert_event(xdev, &evtrb, 1);
|
||||
if (pci_xhci_insert_event(xdev, &evtrb, 1) != 0)
|
||||
UPRINTF(LFTL, "Failed to inject port status change event!\r\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1807,9 +1809,7 @@ pci_xhci_insert_event(struct pci_xhci_vdev *xdev,
|
||||
struct xhci_erst *erst;
|
||||
struct xhci_trb *evts;
|
||||
uint64_t erdp;
|
||||
int erdp_idx, err;
|
||||
|
||||
err = XHCI_TRB_ERROR_SUCCESS;
|
||||
int erdp_idx;
|
||||
|
||||
rts = &xdev->rtsregs;
|
||||
erdp = rts->intrreg.erdp & ~0xF;
|
||||
@ -1829,8 +1829,12 @@ pci_xhci_insert_event(struct pci_xhci_vdev *xdev,
|
||||
evtrb->dwTrb3 &= ~XHCI_TRB_3_CYCLE_BIT;
|
||||
evtrb->dwTrb3 |= rts->event_pcs;
|
||||
|
||||
erst = &rts->erstba_p[rts->er_enq_seg];
|
||||
evts = XHCI_GADDR(xdev, erst->qwRingSegBase);
|
||||
if (!evts) {
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x in insert event!\r\n",
|
||||
erst->qwRingSegBase);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(&evts[rts->er_enq_idx], evtrb, sizeof(struct xhci_trb));
|
||||
|
||||
if (rts->er_enq_idx == erst->dwRingSegSize - 1) {
|
||||
@ -1846,7 +1850,7 @@ pci_xhci_insert_event(struct pci_xhci_vdev *xdev,
|
||||
if (do_intr)
|
||||
pci_xhci_assert_interrupt(xdev);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
@ -2027,6 +2031,12 @@ pci_xhci_cmd_address_device(struct pci_xhci_vdev *xdev,
|
||||
uint8_t rh_port;
|
||||
|
||||
input_ctx = XHCI_GADDR(xdev, trb->qwTrb0 & ~0xFUL);
|
||||
if (!input_ctx) {
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x in address device!\r\n",
|
||||
trb->qwTrb0 & ~0xFUL);
|
||||
cmderr = XHCI_TRB_ERROR_TRB;
|
||||
goto done;
|
||||
}
|
||||
islot_ctx = &input_ctx->ctx_slot;
|
||||
ep0_ctx = &input_ctx->ctx_ep[1];
|
||||
|
||||
@ -2215,6 +2225,12 @@ pci_xhci_cmd_config_ep(struct pci_xhci_vdev *xdev,
|
||||
*/
|
||||
|
||||
input_ctx = XHCI_GADDR(xdev, trb->qwTrb0 & ~0xFUL);
|
||||
if (!input_ctx) {
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x in configure endpoint!\r\n",
|
||||
trb->qwTrb0 & ~0xFUL);
|
||||
cmderr = XHCI_TRB_ERROR_TRB;
|
||||
goto done;
|
||||
}
|
||||
dev_ctx = dev->dev_ctx;
|
||||
UPRINTF(LDBG, "config_ep inputctx: D:x%08x A:x%08x 7:x%08x\r\n",
|
||||
input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1,
|
||||
@ -2400,6 +2416,11 @@ pci_xhci_find_stream(struct pci_xhci_vdev *xdev,
|
||||
return XHCI_TRB_ERROR_STREAM_TYPE;
|
||||
|
||||
sctx = XHCI_GADDR(xdev, ep->qwEpCtx2 & ~0xFUL) + streamid;
|
||||
if (!sctx) {
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x in find stream!\r\n",
|
||||
ep->qwEpCtx2 & ~0xFUL);
|
||||
return XHCI_TRB_ERROR_TRB;
|
||||
}
|
||||
if (!XHCI_SCTX_0_SCT_GET(sctx->qwSctx0))
|
||||
return XHCI_TRB_ERROR_STREAM_TYPE;
|
||||
|
||||
@ -2502,6 +2523,12 @@ pci_xhci_cmd_eval_ctx(struct pci_xhci_vdev *xdev,
|
||||
uint32_t cmderr;
|
||||
|
||||
input_ctx = XHCI_GADDR(xdev, trb->qwTrb0 & ~0xFUL);
|
||||
if (!input_ctx) {
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x in eval context!\r\n",
|
||||
trb->qwTrb0 & ~0xFUL);
|
||||
cmderr = XHCI_TRB_ERROR_TRB;
|
||||
goto done;
|
||||
}
|
||||
islot_ctx = &input_ctx->ctx_slot;
|
||||
ep0_ctx = &input_ctx->ctx_ep[1];
|
||||
|
||||
@ -2588,9 +2615,7 @@ pci_xhci_complete_commands(struct pci_xhci_vdev *xdev)
|
||||
uint32_t type;
|
||||
uint32_t slot;
|
||||
uint32_t cmderr;
|
||||
int error;
|
||||
|
||||
error = 0;
|
||||
xdev->opregs.crcr |= XHCI_CRCR_LO_CRR;
|
||||
|
||||
trb = xdev->opregs.cr_p;
|
||||
@ -2715,15 +2740,22 @@ pci_xhci_complete_commands(struct pci_xhci_vdev *xdev)
|
||||
evtrb.dwTrb3 |= XHCI_TRB_3_SLOT_SET(slot);
|
||||
UPRINTF(LDBG, "command 0x%x result: 0x%x\r\n",
|
||||
type, cmderr);
|
||||
pci_xhci_insert_event(xdev, &evtrb, 1);
|
||||
if (pci_xhci_insert_event(xdev, &evtrb, 1) != 0) {
|
||||
UPRINTF(LFTL, "Failed to inject command completion event!\r\n");
|
||||
return -ENAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
trb = pci_xhci_trb_next(xdev, trb, &crcr);
|
||||
if (!trb) {
|
||||
UPRINTF(LDBG, "Get the invalid trb in %s!\r\n", __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xdev->opregs.crcr = crcr | (xdev->opregs.crcr & XHCI_CRCR_LO_CA) | ccs;
|
||||
xdev->opregs.crcr &= ~XHCI_CRCR_LO_CRR;
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2814,6 +2846,11 @@ pci_xhci_xfer_complete(struct pci_xhci_vdev *xdev, struct usb_xfer *xfer,
|
||||
hcb = xfer->data[i].hcb;
|
||||
evtrb.qwTrb0 = hcb->trb_addr;
|
||||
trb = XHCI_GADDR(xdev, evtrb.qwTrb0);
|
||||
if (!trb) {
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x when get the trb!\r\n",
|
||||
evtrb.qwTrb0);
|
||||
continue;
|
||||
}
|
||||
trbflags = trb->dwTrb3;
|
||||
|
||||
UPRINTF(LDBG, "xfer[%d] done?%u:%d trb %x %016lx %x "
|
||||
@ -2878,8 +2915,10 @@ pci_xhci_xfer_complete(struct pci_xhci_vdev *xdev, struct usb_xfer *xfer,
|
||||
}
|
||||
|
||||
*do_intr = 1;
|
||||
|
||||
pci_xhci_insert_event(xdev, &evtrb, *do_intr);
|
||||
if (pci_xhci_insert_event(xdev, &evtrb, 1) != 0) {
|
||||
UPRINTF(LFTL, "Failed to inject xfer complete event!\r\n");
|
||||
return err;
|
||||
}
|
||||
/* The xHC stop on the TRB in error.*/
|
||||
if (err != XHCI_TRB_ERROR_SUCCESS &&
|
||||
err != XHCI_TRB_ERROR_SHORT_PKT)
|
||||
@ -3170,6 +3209,11 @@ retry:
|
||||
}
|
||||
|
||||
trb = pci_xhci_trb_next(xdev, trb, &addr);
|
||||
if (!trb) {
|
||||
UPRINTF(LDBG, "Get invalid trb in %s!\n", __func__);
|
||||
err = XHCI_TRB_ERROR_TRB;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
UPRINTF(LDBG, "next trb: 0x%lx\r\n", (uint64_t)trb);
|
||||
|
||||
@ -3299,6 +3343,11 @@ pci_xhci_device_doorbell(struct pci_xhci_vdev *xdev,
|
||||
ringaddr = sctx_tr->ringaddr;
|
||||
ccs = sctx_tr->ccs;
|
||||
trb = XHCI_GADDR(xdev, sctx_tr->ringaddr & ~0xFUL);
|
||||
if (!trb) {
|
||||
UPRINTF(LDBG, "Invalid gpa 0x%x in write device doorbell!\r\n",
|
||||
sctx_tr->ringaddr & ~0xFUL);
|
||||
return;
|
||||
}
|
||||
UPRINTF(LDBG, "doorbell, stream %u, ccs %lx, trb ccs %x\r\n",
|
||||
streamid, ep_ctx->qwEpCtx2 & XHCI_TRB_3_CYCLE_BIT,
|
||||
trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT);
|
||||
@ -3399,10 +3448,14 @@ pci_xhci_rtsregs_write(struct pci_xhci_vdev *xdev,
|
||||
|
||||
rts->erstba_p = XHCI_GADDR(xdev, xdev->rtsregs.intrreg.erstba
|
||||
& ~0x3FUL);
|
||||
UPRINTF(LDBG, "wr erstba erst (%p) ptr 0x%lx, sz %u\r\n",
|
||||
if (rts->erstba_p)
|
||||
UPRINTF(LDBG, "wr erstba erst (%p) ptr 0x%lx, sz %u\r\n",
|
||||
rts->erstba_p,
|
||||
rts->erstba_p->qwRingSegBase,
|
||||
rts->erstba_p->dwRingSegSize);
|
||||
else
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x in write runtime register!\r\n",
|
||||
xdev->rtsregs.intrreg.erstba & ~0x3FUL);
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
@ -3533,8 +3586,12 @@ pci_xhci_hostop_write(struct pci_xhci_vdev *xdev,
|
||||
xdev->opregs.dcbaa_p = XHCI_GADDR(xdev, xdev->opregs.dcbaap
|
||||
& ~0x3FUL);
|
||||
|
||||
UPRINTF(LDBG, "opregs dcbaap = 0x%lx (vaddr 0x%lx)\r\n",
|
||||
xdev->opregs.dcbaap, (uint64_t)xdev->opregs.dcbaa_p);
|
||||
if (xdev->opregs.dcbaa_p)
|
||||
UPRINTF(LDBG, "opregs dcbaap = 0x%lx (vaddr 0x%lx)\r\n",
|
||||
xdev->opregs.dcbaap, (uint64_t)xdev->opregs.dcbaa_p);
|
||||
else
|
||||
UPRINTF(LFTL, "Invalid gpa 0x%x when get XHCI_DCBAAP_HI\n",
|
||||
xdev->opregs.dcbaap & ~0x3FUL);
|
||||
break;
|
||||
|
||||
case XHCI_CONFIG:
|
||||
@ -3845,7 +3902,7 @@ pci_xhci_reset_port(struct pci_xhci_vdev *xdev, int portn, int warm)
|
||||
struct pci_xhci_portregs *port;
|
||||
struct xhci_trb evtrb;
|
||||
struct usb_native_devinfo *di;
|
||||
int speed, error;
|
||||
int speed;
|
||||
int index;
|
||||
|
||||
UPRINTF(LINF, "reset port %d\r\n", portn);
|
||||
@ -3871,10 +3928,8 @@ pci_xhci_reset_port(struct pci_xhci_vdev *xdev, int portn, int warm)
|
||||
pci_xhci_set_evtrb(&evtrb, portn,
|
||||
XHCI_TRB_ERROR_SUCCESS,
|
||||
XHCI_TRB_EVENT_PORT_STS_CHANGE);
|
||||
error = pci_xhci_insert_event(xdev, &evtrb, 1);
|
||||
if (error != XHCI_TRB_ERROR_SUCCESS)
|
||||
UPRINTF(LWRN, "reset port insert event "
|
||||
"failed\n");
|
||||
if (pci_xhci_insert_event(xdev, &evtrb, 1) != 0)
|
||||
UPRINTF(LFTL, "Failed to inject reset port event!\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3894,7 +3949,6 @@ pci_xhci_dev_intr(struct usb_hci *hci, int epctx)
|
||||
struct pci_xhci_vdev *xdev;
|
||||
struct pci_xhci_portregs *p;
|
||||
struct xhci_endp_ctx *ep_ctx;
|
||||
int error = 0;
|
||||
int dir_in;
|
||||
int epid;
|
||||
|
||||
@ -3929,9 +3983,10 @@ pci_xhci_dev_intr(struct usb_hci *hci, int epctx)
|
||||
pci_xhci_set_evtrb(&evtrb, hci->hci_port,
|
||||
XHCI_TRB_ERROR_SUCCESS,
|
||||
XHCI_TRB_EVENT_PORT_STS_CHANGE);
|
||||
error = pci_xhci_insert_event(xdev, &evtrb, 0);
|
||||
if (error != XHCI_TRB_ERROR_SUCCESS)
|
||||
goto done;
|
||||
if (pci_xhci_insert_event(xdev, &evtrb, 0) != 0) {
|
||||
UPRINTF(LFTL, "Failed to inject port status change event!\r\n");
|
||||
return -ENAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
dev_ctx = dev->dev_ctx;
|
||||
@ -3946,8 +4001,7 @@ pci_xhci_dev_intr(struct usb_hci *hci, int epctx)
|
||||
|
||||
pci_xhci_device_doorbell(xdev, hci->hci_port, epid, 0);
|
||||
|
||||
done:
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4297,9 +4351,11 @@ pci_xhci_isoc_handler(void *arg, uint64_t param)
|
||||
return;
|
||||
}
|
||||
|
||||
pci_xhci_insert_event(pdata->dev->xdev, &trb, 1);
|
||||
UPRINTF(LINF, "send %srun to slot %d ep %d\r\n", pdata->dir == TOKEN_IN
|
||||
? "under" : "over", pdata->slot, pdata->epnum);
|
||||
if (pci_xhci_insert_event(pdata->dev->xdev, &trb, 1) != 0)
|
||||
UPRINTF(LFTL, "Failed to inject isoc transfer complete event!\r\n");
|
||||
else
|
||||
UPRINTF(LINF, "send %srun to slot %d ep %d\r\n", pdata->dir == TOKEN_IN
|
||||
? "under" : "over", pdata->slot, pdata->epnum);
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user