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) { >