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]
Date:   Wed, 23 May 2018 11:24:53 +0530
From:   Viresh Kumar <viresh.kumar@...aro.org>
To:     Taniya Das <tdas@...eaurora.org>
Cc:     skannan@...eaurora.org, "Rafael J. Wysocki" <rjw@...ysocki.net>,
        linux-kernel@...r.kernel.org, linux-pm@...r.kernel.org,
        Stephen Boyd <sboyd@...nel.org>, robh@...nel.org,
        Rajendra Nayak <rnayak@...eaurora.org>,
        Amit Nischal <anischal@...eaurora.org>,
        devicetree@...r.kernel.org, amit.kucheria@...aro.org
Subject: Re: [PATCH v2 2/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW
 driver

On 22-05-18, 16:13, Taniya Das wrote:
> On 5/22/2018 12:36 AM, skannan@...eaurora.org wrote:
> > On 2018-05-21 02:01, Viresh Kumar wrote:
> > > On 19-05-18, 23:04, Taniya Das wrote:

> > > > +    /* Make sure the write goes through before proceeding */
> > > > +    mb();
> > > 
> > > Btw what happens right after this is done ? Are we guaranteed that the
> > > frequency is updated in the hardware after this ? What about enabling
> > > fast-switch for your platform ? Look at drivers/cpufreq/scmi-cpufreq.c
> > > to see how that is done.
> > 
> > Yeah, I don't think this is needed really.
> > 
> 
> Just want to make sure it doesn't really sit in the write buffer before
> return.

As per Saravana you will be dropping it now, right ?

> > > > +    index = readl_relaxed(c->perf_base);
> > > > +    index = min(index, LUT_MAX_ENTRIES - 1);
> > > 
> > > Will the hardware ever read a value over 39 here ?
> > 
> > The register could be initialized to whatever before the kernel is
> > brought up. Don't want to depend on it being correct to avoid out of
> > bounds access that could leak data.

Fair enough.

> > > > +static int qcom_read_lut(struct platform_device *pdev,
> > > > +             struct cpufreq_qcom *c)
> > > > +{
> > > > +    struct device *dev = &pdev->dev;
> > > > +    u32 data, src, lval, i, core_count, prev_cc;
> > > > +
> > > > +    c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
> > > > +                sizeof(*c->table), GFP_KERNEL);
> > > > +    if (!c->table)
> > > > +        return -ENOMEM;
> > > > +
> > > > +    for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> > > > +        data = readl_relaxed(c->lut_base + i * LUT_ROW_SIZE);
> > > > +        src = ((data & GENMASK(31, 30)) >> 30);
> > > > +        lval = (data & GENMASK(7, 0));
> > > > +        core_count = CORE_COUNT_VAL(data);
> > > > +
> > > > +        if (!src)
> > > > +            c->table[i].frequency = INIT_RATE / 1000;
> > > > +        else
> > > > +            c->table[i].frequency = XO_RATE * lval / 1000;
> > > > +
> > > > +        c->table[i].driver_data = c->table[i].frequency;
> > > 
> > > Why do you need to use driver_data here? Why can't you simple use
> > > frequency field in the below conditional expressions ?
> > > 
> 
> The frequency field would be marked INVALID in case the core count does not
> match and the frequency data would be lost.
> 
> > > > +
> > > > +        dev_dbg(dev, "index=%d freq=%d, core_count %d\n",
> > > > +            i, c->table[i].frequency, core_count);
> > > > +
> > > > +        if (core_count != c->max_cores)
> > > > +            c->table[i].frequency = CPUFREQ_ENTRY_INVALID;
> > > > +
> > > > +        /*
> > > > +         * Two of the same frequencies with the same core counts means
> > > > +         * end of table.
> > > > +         */
> > > > +        if (i > 0 && c->table[i - 1].driver_data ==
> > > > +            c->table[i].driver_data && prev_cc == core_count) {
> > > > +            struct cpufreq_frequency_table *prev = &c->table[i - 1];
> > > > +
> > > > +            if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
> > > 
> > > There can only be a single boost frequency at max ?
> > 
> > As of now, yes. If that changes, we'll change this code later.
> > 
> > > > +                prev->flags = CPUFREQ_BOOST_FREQ;
> > > > +                prev->frequency = prev->driver_data;
> > > 
> > > Okay you are using driver_data as a local variable to keep this value
> > > safe which you might have overwritten. Maybe use a simple variable
> > > prev_freq for this. It would be much more readable in that case and
> > > you wouldn't end up abusing the driver_data field.
> > > 
> 
> Please correct me, currently the driver_data is not used by cpufreq core and
> that was the reason to use it. In case you still think it is not a good way
> to handle it, I would try to handle it differently.

Yeah, the driver data will not be used by cpufreq core, but I think
the code would be far more readable if you use a local variable like
prev_freq instead.

> > > > +            }
> > > > +
> > > > +            break;
> > > > +        }
> > > > +        prev_cc = core_count;
> > > > +    }
> > > > +    c->table[i].frequency = CPUFREQ_TABLE_END;
> > > 
> > > Wouldn't you end up writing on c->table[40].frequency here if there
> > > are 40 frequency value present ?
> > 
> > Yeah, the loop condition needs to be fixed.
> > 
> 
> The table allocation is done for 'LUT_MAX_ENTRIES + 1'.
> Yes in case we have all [0-39] (i.e 40 entries) read from the hardware,
> would store the same and mark the 40th index as table end. Please correct if
> I missed something in your comment.

Ahh, you are right. I misread it.

-- 
viresh

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ