lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Y+tPWAUBwBxcOPFm@hovoldconsulting.com>
Date:   Tue, 14 Feb 2023 10:07:36 +0100
From:   Johan Hovold <johan@...nel.org>
To:     Manivannan Sadhasivam <manivannan.sadhasivam@...aro.org>
Cc:     will@...nel.org, joro@...tes.org, robin.murphy@....com,
        andersson@...nel.org, johan+linaro@...nel.org, steev@...i.org,
        linux-arm-kernel@...ts.infradead.org, iommu@...ts.linux.dev,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH] iommu/arm-smmu-qcom: Rework the logic finding the bypass
 quirk

On Tue, Feb 14, 2023 at 01:23:12PM +0530, Manivannan Sadhasivam wrote:
> On Mon, Feb 13, 2023 at 05:43:56PM +0100, Johan Hovold wrote:
> > On Wed, Feb 01, 2023 at 01:55:00PM +0530, Manivannan Sadhasivam wrote:
> > > The logic used to find the quirky firmware that intercepts the writes to
> > > S2CR register to replace bypass type streams with a fault, and ignore the
> > > fault type, is not working with the firmware on newer SoCs like SC8280XP.
> > > 
> > > The current logic uses the last stream mapping group (num_mapping_groups
> > > - 1) as an index for finding quirky firmware. But on SC8280XP, this
> > > logic is not working as the number of stream mapping groups reported by
> > > the SMMU (163 as on the SC8280XP-CRD device) is not valid for some reason.
> > 
> > NUMSMRG read back as 162 here, both on my CRD and X13s. Was '163' a typo
> > or a real difference?
> > 
> 
> Ah yes, it is 162 indeed. Sorry, typo!
> 
> > > So the current logic that checks the (163-1) S2CR entry fails to detect
> > > the quirky firmware on these devices and triggers invalid context fault
> > > for bypass streams.
> > > 
> > > To fix this issue, rework the logic to find the first non-valid (free)
> > > stream mapping register group (SMR) and use that index to access S2CR
> > > for detecting the bypass quirk.
> > 
> > So while this works for the quirk detection, shouldn't we also do
> > something about that bogus NUMSMRG value? At least cap it at 128, which
> > appears to be the maximum according to the specification, for example,
> > by clearing bit 7 when any of the lower bits are set?
> > 
> > That would give us 35 (or 36) groups and working quirk detection with
> > just the following smaller patch:
> > 
> 
> I'm not certain if the value is bogus or not. It is clear that the spec
> specifies 128 as the max but internal qcom document shows that they indeed
> set 162 on purpose in the hypervisor.
>
> So until we get a clear view on that, I'd not cap it.

But if we fault as soon as we try to do something with those register
groups above 128 that also violate the spec, it doesn't seem right to
trust the fw value here.

Clarification from Qualcomm would be good either way, but if they are
indication that it's not just a bug that has left bit 7 set then
limiting to 128 also seems reasonable (i.e. not by clearing the high
bit, but by using the minimum of 128 and size below).

> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > index 2ff7a72cf377..0f564a86c352 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > @@ -1744,6 +1744,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
> >                         return -ENODEV;
> >                 }
> >  
> > +               if (size > 0x80) {
> > +                       dev_warn(smmu->dev,
> > +                                "invalid number of SMR groups, clearing bit 7\n");
> > +                       size -= 0x80;
> > +               }
> > +
> >                 /* Zero-initialised to mark as invalid */
> >                 smmu->smrs = devm_kcalloc(smmu->dev, size, sizeof(*smmu->smrs),
> >                                           GFP_KERNEL);
> > 
> > I also verified that using index 127 (group 128) for the quirk detection
> > works on my CRD, while the invalid index 128 fails (as do index 161
> > which would currently be used).
> > 
> > > This also warrants a change in variable name from last_s2cr to free_s2cr.
> > > 
> > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@...aro.org>
> > > ---
> > >  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 24 +++++++++++++++++-----
> > >  1 file changed, 19 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > > index 78fc0e1bf215..4104f81b8d8f 100644
> > > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > > @@ -267,23 +267,37 @@ static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> > >  
> > >  static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
> > >  {
> > > -	unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
> > >  	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> > > +	u32 free_s2cr;
> > >  	u32 reg;
> > >  	u32 smr;
> > >  	int i;
> > >  
> > > +	/*
> > > +	 * Find the first non-valid (free) stream mapping register group and
> > > +	 * use that index to access S2CR for detecting the bypass quirk.
> > > +	 */
> > > +	for (i = 0; i < smmu->num_mapping_groups; i++) {
> > > +		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> > > +
> > > +		if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
> > > +			break;
> > > +	}
> > > +
> > > +	free_s2cr = ARM_SMMU_GR0_S2CR(i);
> > 
> > In the unlikely event that there is no free group this would access an
> > invalid index.
> > 
> 
> Hmm, theoretically yes. But what would be the plan of action if that happens?
> Should we just bail out with error or skip the quirk detection?

Yes, skipping quirk detection seems preferable to crashing systems that
don't need the quirk.

Johan

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ