Subject: Re: [v2] powerpc/vphn: fix endian issue in NUMA device node code

From: Greg Kurz <[email-masked]>
Date: Fri, 10 Oct 2014 10:20:33 +0200

On Tue,  7 Oct 2014 20:28:23 +1100 (EST)
Michael Ellerman <[email-masked]> wrote:

> On Fri, 2014-03-10 at 09:13:17 UTC, Greg Kurz wrote:
> > The associativity domain numbers are obtained from the hypervisor through
> > registers and written into memory by the guest: the packed array passed to
> > vphn_unpack_associativity() is then native-endian, unlike what was assumed
> > in the following commit:
> > 
> > This patch does two things:
> > - extract values from the packed array with shifts, in order to be endian
> >   neutral
> > - convert the resulting values to be32 as expected
> > 
> > Suggested-by: Anton Blanchard <[email-masked]>
> > Signed-off-by: Greg Kurz <[email-masked]>
> > Reviewed-by: Nishanth Aravamudan <[email-masked]>
> > Tested-by: Nishanth Aravamudan <[email-masked]>
> 
> 
> Hi Greg,
> 
> I'm a bit dense, it's after 8pm, but this seems like it's more complicated than
> it needs to be?
> 
> We get six 64-bit registers back from the hypervisor, they're cpu endian
> obviously, and each is defined to consist of four 2 byte fields.
> 
> So to unpack them, can't we just iterate over those six 64-bit values, which if
> we load them as 64-bit values will be back in cpu endian?
> 
> cheers
> 

First, I was sure I had Cc'd Benjamin... sorry for this omission :)

Hi Michael,

Do you mean something like the following ?

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b835bf0..fbe5a8b 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1421,8 +1421,11 @@ static long hcall_vphn(unsigned long cpu, __be32 *associativity)
        long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
        u64 flags = 1;
        int hwcpu = get_hard_smp_processor_id(cpu);
+       int i;
 
        rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
+       for (i = 0; i < 6; i++)
+               retbuf[i] = cpu_to_be64(retbuf[i]);
        vphn_unpack_associativity(retbuf, associativity);
 
        return rc;

Sure it also works and is a lot simplier... but it adds an extra loop. Also,
if the 3 first elements of the array contain 12 VPHN_FIELD_MSB fields, then
we don't even need to swap the remaining elements: only the parsing code
knows.

On the other hand, I understand this is not a hot path... so what should we
do ?

Cheers.

--
Greg