On 8/8/2024 5:51 AM, Thinh Nguyen wrote: > On Wed, Aug 07, 2024, Selvarasu Ganesan wrote: >> On 8/7/2024 5:44 AM, Thinh Nguyen wrote: >>> On Mon, Jul 22, 2024, Selvarasu Ganesan wrote: >>>> This commit addresses an issue where the USB core could access an >>>> invalid event buffer address during runtime suspend, potentially causing >>>> SMMU faults and other memory issues. The problem arises from the >>>> following sequence. >>>> 1. In dwc3_gadget_suspend, there is a chance of a timeout when >>>> moving the USB core to the halt state after clearing the >>>> run/stop bit by software. >>>> 2. In dwc3_core_exit, the event buffer is cleared regardless of >>>> the USB core's status, which may lead to an SMMU faults and >>>> other memory issues. if the USB core tries to access the event >>>> buffer address. >>>> >>>> To prevent this issue, this commit ensures that the event buffer address >>>> is not cleared by software when the USB core is active during runtime >>>> suspend by checking its status before clearing the buffer address. >>> What happen after adding this check? Can the device resume and function >>> properly afterward? If not, do you know if a soft-reset will recover the >>> issue? >>> >>> Thanks, >>> Thinh >> Yes, we can see the proper resume with this fix even if the USB IP core >> not entered into halted during suspend. >> >> And we not tried soft reset as this fix is working fine. >> >> Anyway soft reset is part of resume sequence and it will reset or >> recover the USB IP state machine. >> > Ok. > > Just wonder, what condition does the buffer access become invalid? Its very hard to conclude the condition here as this issue is happening in some random scenario when do connect/disconnect USB cable continuously to Host PC with some time interval by using test scripts. > While it makes sense that we should not cleanup the buffer while the > controller is in run state, I don't think SMMU fault will always occur > when (!(reg & DWC3_DSTS_DEVCTRLHLT)) right? Yes are correct. We are not always getting SMMU fault. > >> Thanks, >> >> Selva >> >>>> Signed-off-by: Selvarasu Ganesan <selvarasu.g@xxxxxxxxxxx> >>>> --- >>>> drivers/usb/dwc3/core.c | 4 +++- >>>> 1 file changed, 3 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c >>>> index cb82557678dd..c7c1a253862e 100644 >>>> --- a/drivers/usb/dwc3/core.c >>>> +++ b/drivers/usb/dwc3/core.c >>>> @@ -559,8 +559,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) >>>> void dwc3_event_buffers_cleanup(struct dwc3 *dwc) >>>> { >>>> struct dwc3_event_buffer *evt; >>>> + u32 reg; >>>> >>>> - if (!dwc->ev_buf) >>>> + reg = dwc3_readl(dwc->regs, DWC3_DSTS); >>>> + if (!dwc->ev_buf || !(reg & DWC3_DSTS_DEVCTRLHLT)) >>>> return; > Can you separate the checks so we don't have to read register for all > conditions? Sure, will update in next version. > > if (!dwc->ev_buf) > return; > > /* > * If dwc3_core_exit() fails, event buffer is not > * accessible for <XYZ> platforms. > */ > reg = dwc3_readl(dwc->regs, DWC3_DSTS); > if (!(reg & DWC3_DSTS_DEVCTRLHLT)) > return; > > Thanks, > Thinh > >>>> >>>> evt = dwc->ev_buf; >>>> -- >>>> 2.17.1