diff mbox

[PATCHv2] ARM64: Add AT_ARM64_MIDR to the aux vector

Message ID 1440873982-44062-1-git-send-email-apinski@cavium.com
State New
Headers show

Commit Message

Andrew Pinski Aug. 29, 2015, 6:46 p.m. UTC
It is useful to pass down MIDR register down to userland if all of
the online cores are all the same type.  This adds AT_ARM64_MIDR
aux vector type and passes down the midr system register.

This is alternative to MIDR_EL1 part of
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
It allows for faster access to midr_el1 than going through a trap and
does not exist if the set of cores are not the same.

Changes from v1:
Forgot to include the auxvec.h part.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/cpu.h         |    1 +
 arch/arm64/include/asm/elf.h         |    6 ++++++
 arch/arm64/include/uapi/asm/auxvec.h |    3 +++
 arch/arm64/kernel/cpuinfo.c          |   22 ++++++++++++++++++++++
 4 files changed, 32 insertions(+)

Comments

Mark Rutland Sept. 1, 2015, 4:33 p.m. UTC | #1
Hi,

On Sat, Aug 29, 2015 at 07:46:22PM +0100, Andrew Pinski wrote:
> It is useful to pass down MIDR register down to userland if all of
> the online cores are all the same type.  This adds AT_ARM64_MIDR
> aux vector type and passes down the midr system register.
> 
> This is alternative to MIDR_EL1 part of
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
> It allows for faster access to midr_el1 than going through a trap and
> does not exist if the set of cores are not the same.

I'm not sure I follow the rationale. If speed is important the
application can cache the value the first time it reads it with a trap.

This also means that the behaviour is different across homogeneous and
heterogeneous systems.

> Changes from v1:
> Forgot to include the auxvec.h part.
> 
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  arch/arm64/include/asm/cpu.h         |    1 +
>  arch/arm64/include/asm/elf.h         |    6 ++++++
>  arch/arm64/include/uapi/asm/auxvec.h |    3 +++
>  arch/arm64/kernel/cpuinfo.c          |   22 ++++++++++++++++++++++
>  4 files changed, 32 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
> index 8e797b2..fab0aa1 100644
> --- a/arch/arm64/include/asm/cpu.h
> +++ b/arch/arm64/include/asm/cpu.h
> @@ -62,5 +62,6 @@ DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
>  
>  void cpuinfo_store_cpu(void);
>  void __init cpuinfo_store_boot_cpu(void);
> +u32 get_arm64_midr(void);
>  
>  #endif /* __ASM_CPU_H */
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index faad6df..d3549de 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -17,6 +17,7 @@
>  #define __ASM_ELF_H
>  
>  #include <asm/hwcap.h>
> +#include <asm/cpu.h>
>  
>  /*
>   * ELF register definitions..
> @@ -138,8 +139,13 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>  
>  #define ARCH_DLINFO							\
>  do {									\
> +	u32 midr;							\
> +									\
>  	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
>  		    (elf_addr_t)current->mm->context.vdso);		\
> +	midr = get_arm64_midr();					\
> +	if (midr != 0)							\
> +		NEW_AUX_ENT(AT_ARM64_MIDR, (elf_addr_t)midr);		\
>  } while (0)
>  
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
> diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h
> index 22d6d88..dc55c56 100644
> --- a/arch/arm64/include/uapi/asm/auxvec.h
> +++ b/arch/arm64/include/uapi/asm/auxvec.h
> @@ -19,4 +19,7 @@
>  /* vDSO location */
>  #define AT_SYSINFO_EHDR	33
>  
> +/* Machine IDenfier Register (MDIR). */
> +#define AT_ARM64_MIDR 38
> +
>  #endif
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index 75d5a86..b14c87d 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -254,3 +254,25 @@ void __init cpuinfo_store_boot_cpu(void)
>  
>  	boot_cpu_data = *info;
>  }
> +
> +u32 get_arm64_midr(void)
> +{
> +	int i;
> +	u32 midr = 0;
> +
> +	for_each_online_cpu(i) {
> +		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
> +		u32 oldmidr = midr;
> +
> +		midr = cpuinfo->reg_midr;
> +		/*
> +		 * If there are cpus which have a different
> +		 * midr just return 0.
> +		 */
> +		if (oldmidr && oldmidr != midr)
> +			return 0;
> +	}
> +
> +	return midr;
> +}

If I have a big.LITTLE system where all the big CPUs are currently
offline, this will leave the MIDR the little CPUs in the auxvec.
However, at any point after this has run, I could hotplug the big CPUs
on and the little CPUs off, leaving this reporting a MIDR that
represents none of the online CPUs.

Given big.LITTLE and the potential for physical/dynamic hotplug (where
we won't know all the MIDRs in advance), I don't think that we can
generally expose a common MIDR in this fashion, and I don't think that
we should give the impression that we can.

I think that the only things we can do are expose the MIDR for CPU the
code is currently executing on (as Suzuki's patches do), and/or expose
all the MIDRs for currently online CPUs (as Steve's [1] patch does).
Anything else leaves us trying to provide semantics that we cannot
guarantee.

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359127.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Andrew Pinski Sept. 1, 2015, 4:51 p.m. UTC | #2
> On Sep 2, 2015, at 12:33 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> 
> Hi,
> 
>> On Sat, Aug 29, 2015 at 07:46:22PM +0100, Andrew Pinski wrote:
>> It is useful to pass down MIDR register down to userland if all of
>> the online cores are all the same type.  This adds AT_ARM64_MIDR
>> aux vector type and passes down the midr system register.
>> 
>> This is alternative to MIDR_EL1 part of
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
>> It allows for faster access to midr_el1 than going through a trap and
>> does not exist if the set of cores are not the same.
> 
> I'm not sure I follow the rationale. If speed is important the
> application can cache the value the first time it reads it with a trap.

It is also about compatibility also. Exposing the register is not backwards compatible but using the aux vector is. 

> 
> This also means that the behaviour is different across homogeneous and
> heterogeneous systems.
> 
>> Changes from v1:
>> Forgot to include the auxvec.h part.
>> 
>> Signed-off-by: Andrew Pinski <apinski@cavium.com>
>> ---
>> arch/arm64/include/asm/cpu.h         |    1 +
>> arch/arm64/include/asm/elf.h         |    6 ++++++
>> arch/arm64/include/uapi/asm/auxvec.h |    3 +++
>> arch/arm64/kernel/cpuinfo.c          |   22 ++++++++++++++++++++++
>> 4 files changed, 32 insertions(+)
>> 
>> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
>> index 8e797b2..fab0aa1 100644
>> --- a/arch/arm64/include/asm/cpu.h
>> +++ b/arch/arm64/include/asm/cpu.h
>> @@ -62,5 +62,6 @@ DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
>> 
>> void cpuinfo_store_cpu(void);
>> void __init cpuinfo_store_boot_cpu(void);
>> +u32 get_arm64_midr(void);
>> 
>> #endif /* __ASM_CPU_H */
>> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
>> index faad6df..d3549de 100644
>> --- a/arch/arm64/include/asm/elf.h
>> +++ b/arch/arm64/include/asm/elf.h
>> @@ -17,6 +17,7 @@
>> #define __ASM_ELF_H
>> 
>> #include <asm/hwcap.h>
>> +#include <asm/cpu.h>
>> 
>> /*
>>  * ELF register definitions..
>> @@ -138,8 +139,13 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>> 
>> #define ARCH_DLINFO                            \
>> do {                                    \
>> +    u32 midr;                            \
>> +                                    \
>>    NEW_AUX_ENT(AT_SYSINFO_EHDR,                    \
>>            (elf_addr_t)current->mm->context.vdso);        \
>> +    midr = get_arm64_midr();                    \
>> +    if (midr != 0)                            \
>> +        NEW_AUX_ENT(AT_ARM64_MIDR, (elf_addr_t)midr);        \
>> } while (0)
>> 
>> #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
>> diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h
>> index 22d6d88..dc55c56 100644
>> --- a/arch/arm64/include/uapi/asm/auxvec.h
>> +++ b/arch/arm64/include/uapi/asm/auxvec.h
>> @@ -19,4 +19,7 @@
>> /* vDSO location */
>> #define AT_SYSINFO_EHDR    33
>> 
>> +/* Machine IDenfier Register (MDIR). */
>> +#define AT_ARM64_MIDR 38
>> +
>> #endif
>> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
>> index 75d5a86..b14c87d 100644
>> --- a/arch/arm64/kernel/cpuinfo.c
>> +++ b/arch/arm64/kernel/cpuinfo.c
>> @@ -254,3 +254,25 @@ void __init cpuinfo_store_boot_cpu(void)
>> 
>>    boot_cpu_data = *info;
>> }
>> +
>> +u32 get_arm64_midr(void)
>> +{
>> +    int i;
>> +    u32 midr = 0;
>> +
>> +    for_each_online_cpu(i) {
>> +        struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
>> +        u32 oldmidr = midr;
>> +
>> +        midr = cpuinfo->reg_midr;
>> +        /*
>> +         * If there are cpus which have a different
>> +         * midr just return 0.
>> +         */
>> +        if (oldmidr && oldmidr != midr)
>> +            return 0;
>> +    }
>> +
>> +    return midr;
>> +}
> 
> If I have a big.LITTLE system where all the big CPUs are currently
> offline, this will leave the MIDR the little CPUs in the auxvec.
> However, at any point after this has run, I could hotplug the big CPUs
> on and the little CPUs off, leaving this reporting a MIDR that
> represents none of the online CPUs.
> 
> Given big.LITTLE and the potential for physical/dynamic hotplug (where
> we won't know all the MIDRs in advance), I don't think that we can
> generally expose a common MIDR in this fashion, and I don't think that
> we should give the impression that we can.

This is standard issue with hot plug and big.little. Really big.little is a design flaw but I am not going into that here. 


> 
> I think that the only things we can do are expose the MIDR for CPU the
> code is currently executing on (as Suzuki's patches do), and/or expose
> all the MIDRs for currently online CPUs (as Steve's [1] patch does).
> Anything else leaves us trying to provide semantics that we cannot
> guarantee.

Except they are not backwards compatible which means nobody in their right mind would use the register to get the midr that way. I am sorry but having a newer version of glibc working on a year old kernel is not going to fly. 

Thanks,
Andrew


> 
> Thanks,
> Mark.
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359127.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Mark Rutland Sept. 1, 2015, 5:19 p.m. UTC | #3
On Tue, Sep 01, 2015 at 05:51:44PM +0100, pinskia@gmail.com wrote:
> 
> 
> 
> 
> > On Sep 2, 2015, at 12:33 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > 
> > Hi,
> > 
> >> On Sat, Aug 29, 2015 at 07:46:22PM +0100, Andrew Pinski wrote:
> >> It is useful to pass down MIDR register down to userland if all of
> >> the online cores are all the same type.  This adds AT_ARM64_MIDR
> >> aux vector type and passes down the midr system register.
> >> 
> >> This is alternative to MIDR_EL1 part of
> >> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
> >> It allows for faster access to midr_el1 than going through a trap and
> >> does not exist if the set of cores are not the same.
> > 
> > I'm not sure I follow the rationale. If speed is important the
> > application can cache the value the first time it reads it with a trap.
> 
> It is also about compatibility also. Exposing the register is not
> backwards compatible but using the aux vector is. 

So long as we have HWCAP_CPUID describing the availability of register
access [2], then userspace can test for that before attempting to access
the MIDR.

Other than that, I don't see a backwards or forwards compatibility
issue.

> >> +u32 get_arm64_midr(void)
> >> +{
> >> +    int i;
> >> +    u32 midr = 0;
> >> +
> >> +    for_each_online_cpu(i) {
> >> +        struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
> >> +        u32 oldmidr = midr;
> >> +
> >> +        midr = cpuinfo->reg_midr;
> >> +        /*
> >> +         * If there are cpus which have a different
> >> +         * midr just return 0.
> >> +         */
> >> +        if (oldmidr && oldmidr != midr)
> >> +            return 0;
> >> +    }
> >> +
> >> +    return midr;
> >> +}
> > 
> > If I have a big.LITTLE system where all the big CPUs are currently
> > offline, this will leave the MIDR the little CPUs in the auxvec.
> > However, at any point after this has run, I could hotplug the big CPUs
> > on and the little CPUs off, leaving this reporting a MIDR that
> > represents none of the online CPUs.
> > 
> > Given big.LITTLE and the potential for physical/dynamic hotplug (where
> > we won't know all the MIDRs in advance), I don't think that we can
> > generally expose a common MIDR in this fashion, and I don't think that
> > we should give the impression that we can.
> 
> This is standard issue with hot plug and big.little. Really big.little
> is a design flaw but I am not going into that here. 

Regardless of our personal feelings on big.LITTLE, it's something we
have to deal with.

Hopefully it's a non-issue anyway; a MIDR provided by this interface can
really only be used to derive optimisation criteria rather than
non-architected properties required for correctness.

> > I think that the only things we can do are expose the MIDR for CPU the
> > code is currently executing on (as Suzuki's patches do), and/or expose
> > all the MIDRs for currently online CPUs (as Steve's [1] patch does).
> > Anything else leaves us trying to provide semantics that we cannot
> > guarantee.
> 
> Except they are not backwards compatible which means nobody in their
> right mind would use the register to get the midr that way.

I assume you missed the discussion of HWCAP_CPUID, which prevents the
compatibility issue I believe you're considering here.

> I am sorry but having a newer version of glibc working on a year old
> kernel is not going to fly. 

I'm not sure I follow this, unless you meant _not_ working.

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359127.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-August/363559.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Mark Rutland Sept. 1, 2015, 5:30 p.m. UTC | #4
[...]

> >>> On Sat, Aug 29, 2015 at 07:46:22PM +0100, Andrew Pinski wrote:
> >>> It is useful to pass down MIDR register down to userland if all of
> >>> the online cores are all the same type.  This adds AT_ARM64_MIDR
> >>> aux vector type and passes down the midr system register.
> >>> 
> >>> This is alternative to MIDR_EL1 part of
> >>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
> >>> It allows for faster access to midr_el1 than going through a trap and
> >>> does not exist if the set of cores are not the same.
> >> 
> >> I'm not sure I follow the rationale. If speed is important the
> >> application can cache the value the first time it reads it with a trap.
> > 
> > It is also about compatibility also. Exposing the register is not backwards compatible but using the aux vector is. 
> 
> That would also break big.little too. So either break it with hot plug or break it in userland, your choice. 

The value wouldn't be representative of the system as a whole; that is
true. However, we never guaranteed that it was, while the aux vector
code implied that we did.

For optimisation that may be good enough; code optimized for a different
uArch should still function on another, even if it is slower.

> >> This also means that the behaviour is different across homogeneous and
> >> heterogeneous systems.
> 
> That should be ok because it is still backwards compatible with what
> was done before.  My goal here is just to allow quick easy access to
> midr in the case of a homogeneous system which I care about, thunderx
> and to allow glibc to select a memcpy/memset that is better for
> thunderx. 

As I mentioned in the other thread, I think that HWCAP_CPUID is
sufficient to enable forwards and backwards compatibility. If it is
present then you can use the current CPU's MIDR to select a better
memcpy/memset if required.

Thanks,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Andrew Pinski Sept. 1, 2015, 5:58 p.m. UTC | #5
> On Sep 2, 2015, at 1:30 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> 
> [...]
> 
>>>>> On Sat, Aug 29, 2015 at 07:46:22PM +0100, Andrew Pinski wrote:
>>>>> It is useful to pass down MIDR register down to userland if all of
>>>>> the online cores are all the same type.  This adds AT_ARM64_MIDR
>>>>> aux vector type and passes down the midr system register.
>>>>> 
>>>>> This is alternative to MIDR_EL1 part of
>>>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
>>>>> It allows for faster access to midr_el1 than going through a trap and
>>>>> does not exist if the set of cores are not the same.
>>>> 
>>>> I'm not sure I follow the rationale. If speed is important the
>>>> application can cache the value the first time it reads it with a trap.
>>> 
>>> It is also about compatibility also. Exposing the register is not backwards compatible but using the aux vector is.
>> 
>> That would also break big.little too. So either break it with hot plug or break it in userland, your choice.
> 
> The value wouldn't be representative of the system as a whole; that is
> true. However, we never guaranteed that it was, while the aux vector
> code implied that we did.

Yes but I guess you talk about caching the value in userspace but doing it via the aux vector is the same as your suggestion. Just one difference is you don't get the aux vector entry if there is a CPU that is online which is different. No difference from your suggestion of caching it. Without considering hot pug for a second (that is a huge different issue all together), if userland wants to know if all up CPUs have the same midr, they would either read /sys entries (lots of syscalls) or bind to each CPU and do the trap. That means at least three or two syscalls/traps for each CPU. My way is none and gets a value of midr if they are all the Same for free. 

Again what is the difference between the aux vector and caching the value in userspace? Because it seems like you suggesting I do that but then avoiding big.little also. 

Thanks,
Andrew

> 
> For optimisation that may be good enough; code optimized for a different
> uArch should still function on another, even if it is slower.
> 
>>>> This also means that the behaviour is different across homogeneous and
>>>> heterogeneous systems.
>> 
>> That should be ok because it is still backwards compatible with what
>> was done before.  My goal here is just to allow quick easy access to
>> midr in the case of a homogeneous system which I care about, thunderx
>> and to allow glibc to select a memcpy/memset that is better for
>> thunderx.
> 
> As I mentioned in the other thread, I think that HWCAP_CPUID is
> sufficient to enable forwards and backwards compatibility. If it is
> present then you can use the current CPU's MIDR to select a better
> memcpy/memset if required.
> 
> Thanks,
> Mark.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
diff mbox

Patch

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index 8e797b2..fab0aa1 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -62,5 +62,6 @@  DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
 
 void cpuinfo_store_cpu(void);
 void __init cpuinfo_store_boot_cpu(void);
+u32 get_arm64_midr(void);
 
 #endif /* __ASM_CPU_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..d3549de 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -17,6 +17,7 @@ 
 #define __ASM_ELF_H
 
 #include <asm/hwcap.h>
+#include <asm/cpu.h>
 
 /*
  * ELF register definitions..
@@ -138,8 +139,13 @@  typedef struct user_fpsimd_state elf_fpregset_t;
 
 #define ARCH_DLINFO							\
 do {									\
+	u32 midr;							\
+									\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
 		    (elf_addr_t)current->mm->context.vdso);		\
+	midr = get_arm64_midr();					\
+	if (midr != 0)							\
+		NEW_AUX_ENT(AT_ARM64_MIDR, (elf_addr_t)midr);		\
 } while (0)
 
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h
index 22d6d88..dc55c56 100644
--- a/arch/arm64/include/uapi/asm/auxvec.h
+++ b/arch/arm64/include/uapi/asm/auxvec.h
@@ -19,4 +19,7 @@ 
 /* vDSO location */
 #define AT_SYSINFO_EHDR	33
 
+/* Machine IDenfier Register (MDIR). */
+#define AT_ARM64_MIDR 38
+
 #endif
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 75d5a86..b14c87d 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -254,3 +254,25 @@  void __init cpuinfo_store_boot_cpu(void)
 
 	boot_cpu_data = *info;
 }
+
+u32 get_arm64_midr(void)
+{
+	int i;
+	u32 midr = 0;
+
+	for_each_online_cpu(i) {
+		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+		u32 oldmidr = midr;
+
+		midr = cpuinfo->reg_midr;
+		/*
+		 * If there are cpus which have a different
+		 * midr just return 0.
+		 */
+		if (oldmidr && oldmidr != midr)
+			return 0;
+	}
+
+	return midr;
+}
+