On 08/09/2017 06:02 AM, David Gibson wrote:
> On Tue, Aug 08, 2017 at 10:56:18AM +0200, Cédric Le Goater wrote:
>> '/ibm,plat-res-int-priorities' contains a list of priorities that the
>> hypervisor has reserved for its own use. Scan these ranges to choose
>> the lowest unused priority for the xive spapr backend.
>>
>> Signed-off-by: Cédric Le Goater <c...@kaod.org>
>> ---
>>  arch/powerpc/sysdev/xive/spapr.c | 62 
>> +++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 61 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/powerpc/sysdev/xive/spapr.c 
>> b/arch/powerpc/sysdev/xive/spapr.c
>> index 7fc40047c23d..220331986bd8 100644
>> --- a/arch/powerpc/sysdev/xive/spapr.c
>> +++ b/arch/powerpc/sysdev/xive/spapr.c
>> @@ -532,13 +532,70 @@ static const struct xive_ops xive_spapr_ops = {
>>      .name                   = "spapr",
>>  };
>>  
>> +/*
>> + * get max priority from "/ibm,plat-res-int-priorities"
>> + */
>> +static bool xive_get_max_prio(u8 *max_prio)
>> +{
>> +    struct device_node *rootdn;
>> +    const __be32 *reg;
>> +    u32 len;
>> +    int prio, found;
>> +
>> +    rootdn = of_find_node_by_path("/");
>> +    if (!rootdn) {
>> +            pr_err("not root node found !\n");
>> +            return false;
>> +    }
>> +
>> +    reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len);
>> +    if (!reg) {
>> +            pr_err("Failed to read 'ibm,plat-res-int-priorities' 
>> property\n");
>> +            return false;
>> +    }
>> +
>> +    if (len % (2 * sizeof(u32)) != 0) {
>> +            pr_err("invalid 'ibm,plat-res-int-priorities' property\n");
>> +            return false;
>> +    }
>> +
>> +    /* HW supports priorities in the range [0-7] and 0xFF is a
>> +     * wildcard priority used to mask. We scan the ranges reserved
>> +     * by the hypervisor to find the lowest priority we can use.
>> +     */
>> +    found = 0xFF;
>> +    for (prio = 0; prio < 8; prio++) {
>> +            int reserved = 0;
>> +            int i;
>> +
>> +            for (i = 0; i < len / (2 * sizeof(u32)); i++) {
>> +                    int base  = be32_to_cpu(reg[2 * i]);
>> +                    int range = be32_to_cpu(reg[2 * i + 1]);
>> +
>> +                    if (prio >= base && prio < base + range)
>> +                            reserved++;
>> +            }
>> +
>> +            if (!reserved)
>> +                    found = prio;
> 
> So you continue the loop here, rather than using break.  Which means
> found will be the highest valued priority that's not reserved.  Is
> that what you intended?  The commit message says you find the lowest
> unused, but do lower numbers mean higher priorities or the other way around?

yes. I should probably add a statement on how the priorities are 
ordered : the most privileged is the lowest value.

Thanks,

C. 

>> +    }
>> +
>> +    if (found == 0xFF) {
>> +            pr_err("no valid priority found in 
>> 'ibm,plat-res-int-priorities'\n");
>> +            return false;
>> +    }
>> +
>> +    *max_prio = found;
>> +    return true;
>> +}
>> +
>>  bool xive_spapr_init(void)
>>  {
>>      struct device_node *np;
>>      struct resource r;
>>      void __iomem *tima;
>>      struct property *prop;
>> -    u8 max_prio = 7;
>> +    u8 max_prio;
>>      u32 val;
>>      u32 len;
>>      const __be32 *reg;
>> @@ -566,6 +623,9 @@ bool xive_spapr_init(void)
>>              return false;
>>      }
>>  
>> +    if (!xive_get_max_prio(&max_prio))
>> +            return false;
>> +
>>      /* Feed the IRQ number allocator with the ranges given in the DT */
>>      reg = of_get_property(np, "ibm,xive-lisn-ranges", &len);
>>      if (!reg) {
> 

Reply via email to