diff mbox series

[2/2] arm64: kvm: upgrade csselr and ccsidr to 64-bit values

Message ID 1484909410-11673-2-git-send-email-sudeep.holla@arm.com
State New
Headers show
Series [1/2] arm64: kvm: reuse existing cache type/info related macros | expand

Commit Message

Sudeep Holla Jan. 20, 2017, 10:50 a.m. UTC
csselr and ccsidr are treated as 64-bit values already elsewhere in the
kernel. It also aligns well with the architecture extensions that allow
64-bit format for ccsidr.

This patch upgrades the existing accesses to csselr and ccsidr from
32-bit to 64-bit in preparation to add support to those extensions.

Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

---
 arch/arm64/kvm/sys_regs.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Comments

Christoffer Dall Jan. 23, 2017, 9:08 p.m. UTC | #1
On Fri, Jan 20, 2017 at 10:50:10AM +0000, Sudeep Holla wrote:
> csselr and ccsidr are treated as 64-bit values already elsewhere in the

> kernel. It also aligns well with the architecture extensions that allow

> 64-bit format for ccsidr.

> 

> This patch upgrades the existing accesses to csselr and ccsidr from

> 32-bit to 64-bit in preparation to add support to those extensions.

> 

> Cc: Christoffer Dall <christoffer.dall@linaro.org>

> Cc: Marc Zyngier <marc.zyngier@arm.com>

> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

> ---

>  arch/arm64/kvm/sys_regs.c | 18 +++++++++---------

>  1 file changed, 9 insertions(+), 9 deletions(-)

> 

> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c

> index 5dca1f10340f..a3559a8a2b0c 100644

> --- a/arch/arm64/kvm/sys_regs.c

> +++ b/arch/arm64/kvm/sys_regs.c

> @@ -58,15 +58,15 @@

>   */

>  

>  /* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */

> -static u32 cache_levels;

> +static u64 cache_levels;

>  

>  /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */

>  #define CSSELR_MAX 	((MAX_CACHE_LEVEL - 1) >> 1)

>  

>  /* Which cache CCSIDR represents depends on CSSELR value. */

> -static u32 get_ccsidr(u32 csselr)

> +static u64 get_ccsidr(u64 csselr)

>  {

> -	u32 ccsidr;

> +	u64 ccsidr;

>  

>  	/* Make sure noone else changes CSSELR during this! */

>  	local_irq_disable();

> @@ -1952,9 +1952,9 @@ static int set_invariant_sys_reg(u64 id, void __user *uaddr)

>  	return 0;

>  }

>  

> -static bool is_valid_cache(u32 val)

> +static bool is_valid_cache(u64 val)

>  {

> -	u32 level, ctype;

> +	u64 level, ctype;

>  

>  	if (val >= CSSELR_MAX)

>  		return false;

> @@ -1979,8 +1979,8 @@ static bool is_valid_cache(u32 val)

>  

>  static int demux_c15_get(u64 id, void __user *uaddr)

>  {

> -	u32 val;

> -	u32 __user *uval = uaddr;

> +	u64 val;

> +	u64 __user *uval = uaddr;

>  

>  	/* Fail if we have unknown bits set. */

>  	if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK

> @@ -2004,8 +2004,8 @@ static int demux_c15_get(u64 id, void __user *uaddr)

>  

>  static int demux_c15_set(u64 id, void __user *uaddr)

>  {

> -	u32 val, newval;

> -	u32 __user *uval = uaddr;

> +	u64 val, newval;

> +	u64 __user *uval = uaddr;


Doesn't converting these uval pointers to u64 cause us to break the ABI
as we'll now be reading/writing 64-bit values to userspace with the
get_user and put_user following the declarations?

>  

>  	/* Fail if we have unknown bits set. */

>  	if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK

> -- 

> 2.7.4

> 


Thanks,
-Christoffer

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Sudeep Holla Jan. 24, 2017, 10:15 a.m. UTC | #2
On 23/01/17 21:08, Christoffer Dall wrote:
> On Fri, Jan 20, 2017 at 10:50:10AM +0000, Sudeep Holla wrote:

>> csselr and ccsidr are treated as 64-bit values already elsewhere in the

>> kernel. It also aligns well with the architecture extensions that allow

>> 64-bit format for ccsidr.

>>

>> This patch upgrades the existing accesses to csselr and ccsidr from

>> 32-bit to 64-bit in preparation to add support to those extensions.

>>

>> Cc: Christoffer Dall <christoffer.dall@linaro.org>

>> Cc: Marc Zyngier <marc.zyngier@arm.com>

>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

>> ---

>>  arch/arm64/kvm/sys_regs.c | 18 +++++++++---------

>>  1 file changed, 9 insertions(+), 9 deletions(-)

>>

>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c

>> index 5dca1f10340f..a3559a8a2b0c 100644

>> --- a/arch/arm64/kvm/sys_regs.c

>> +++ b/arch/arm64/kvm/sys_regs.c


[..]

>> @@ -2004,8 +2004,8 @@ static int demux_c15_get(u64 id, void __user *uaddr)

>>  

>>  static int demux_c15_set(u64 id, void __user *uaddr)

>>  {

>> -	u32 val, newval;

>> -	u32 __user *uval = uaddr;

>> +	u64 val, newval;

>> +	u64 __user *uval = uaddr;

> 

> Doesn't converting these uval pointers to u64 cause us to break the ABI

> as we'll now be reading/writing 64-bit values to userspace with the

> get_user and put_user following the declarations?

> 


Yes, I too have similar concern. IIUC it is always read via kvm_one_reg
structure. I could not find any specific user for this register to cross
check.

-- 
Regards,
Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Christoffer Dall Jan. 24, 2017, 10:30 a.m. UTC | #3
On Tue, Jan 24, 2017 at 10:15:38AM +0000, Sudeep Holla wrote:
> 

> 

> On 23/01/17 21:08, Christoffer Dall wrote:

> > On Fri, Jan 20, 2017 at 10:50:10AM +0000, Sudeep Holla wrote:

> >> csselr and ccsidr are treated as 64-bit values already elsewhere in the

> >> kernel. It also aligns well with the architecture extensions that allow

> >> 64-bit format for ccsidr.

> >>

> >> This patch upgrades the existing accesses to csselr and ccsidr from

> >> 32-bit to 64-bit in preparation to add support to those extensions.

> >>

> >> Cc: Christoffer Dall <christoffer.dall@linaro.org>

> >> Cc: Marc Zyngier <marc.zyngier@arm.com>

> >> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

> >> ---

> >>  arch/arm64/kvm/sys_regs.c | 18 +++++++++---------

> >>  1 file changed, 9 insertions(+), 9 deletions(-)

> >>

> >> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c

> >> index 5dca1f10340f..a3559a8a2b0c 100644

> >> --- a/arch/arm64/kvm/sys_regs.c

> >> +++ b/arch/arm64/kvm/sys_regs.c

> 

> [..]

> 

> >> @@ -2004,8 +2004,8 @@ static int demux_c15_get(u64 id, void __user *uaddr)

> >>  

> >>  static int demux_c15_set(u64 id, void __user *uaddr)

> >>  {

> >> -	u32 val, newval;

> >> -	u32 __user *uval = uaddr;

> >> +	u64 val, newval;

> >> +	u64 __user *uval = uaddr;

> > 

> > Doesn't converting these uval pointers to u64 cause us to break the ABI

> > as we'll now be reading/writing 64-bit values to userspace with the

> > get_user and put_user following the declarations?

> > 

> 

> Yes, I too have similar concern. IIUC it is always read via kvm_one_reg

> structure. I could not find any specific user for this register to cross

> check.

> 


Not sure it matters which interface we get the userspace pointer from?

This patch is definitely changing the write from a 32-bit write to a
64-bit write and there's a specific check prior to the put_user() call
which checks that userspace intended a 32-bit value and presumably
provided a 32-bit pointer.

So I think the only way to return 64-bit AArch32 system register values
to userspace (if that is the intention) is to define a new ID for 64-bit
CCSIDR registers and handle them separately.

Thanks,
-Christoffer

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Sudeep Holla Jan. 24, 2017, 10:55 a.m. UTC | #4
On 24/01/17 10:30, Christoffer Dall wrote:
> On Tue, Jan 24, 2017 at 10:15:38AM +0000, Sudeep Holla wrote:

>>

>>

>> On 23/01/17 21:08, Christoffer Dall wrote:

>>> On Fri, Jan 20, 2017 at 10:50:10AM +0000, Sudeep Holla wrote:

>>>> csselr and ccsidr are treated as 64-bit values already elsewhere in the

>>>> kernel. It also aligns well with the architecture extensions that allow

>>>> 64-bit format for ccsidr.

>>>>

>>>> This patch upgrades the existing accesses to csselr and ccsidr from

>>>> 32-bit to 64-bit in preparation to add support to those extensions.

>>>>

>>>> Cc: Christoffer Dall <christoffer.dall@linaro.org>

>>>> Cc: Marc Zyngier <marc.zyngier@arm.com>

>>>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

>>>> ---

>>>>  arch/arm64/kvm/sys_regs.c | 18 +++++++++---------

>>>>  1 file changed, 9 insertions(+), 9 deletions(-)

>>>>

>>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c

>>>> index 5dca1f10340f..a3559a8a2b0c 100644

>>>> --- a/arch/arm64/kvm/sys_regs.c

>>>> +++ b/arch/arm64/kvm/sys_regs.c

>>

>> [..]

>>

>>>> @@ -2004,8 +2004,8 @@ static int demux_c15_get(u64 id, void __user *uaddr)

>>>>  

>>>>  static int demux_c15_set(u64 id, void __user *uaddr)

>>>>  {

>>>> -	u32 val, newval;

>>>> -	u32 __user *uval = uaddr;

>>>> +	u64 val, newval;

>>>> +	u64 __user *uval = uaddr;

>>>

>>> Doesn't converting these uval pointers to u64 cause us to break the ABI

>>> as we'll now be reading/writing 64-bit values to userspace with the

>>> get_user and put_user following the declarations?

>>>

>>

>> Yes, I too have similar concern. IIUC it is always read via kvm_one_reg

>> structure. I could not find any specific user for this register to cross

>> check.

>>

> 

> Not sure it matters which interface we get the userspace pointer from?

> 


Agreed.

> This patch is definitely changing the write from a 32-bit write to a

> 64-bit write and there's a specific check prior to the put_user() call

> which checks that userspace intended a 32-bit value and presumably

> provided a 32-bit pointer.

> 


I see you point, I missed to see that check(just to be sure KVM_REG_SIZE
check right ?).

> So I think the only way to return 64-bit AArch32 system register values

> to userspace (if that is the intention) is to define a new ID for 64-bit

> CCSIDR registers and handle them separately.

> 


I will add KVM_REG_ARM_DEMUX_ID_CCSIDR_64B or something similar.
Thanks for the review.

-- 
Regards,
Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Christoffer Dall Jan. 24, 2017, 11:02 a.m. UTC | #5
On Tue, Jan 24, 2017 at 10:55:24AM +0000, Sudeep Holla wrote:
> 

> 

> On 24/01/17 10:30, Christoffer Dall wrote:

> > On Tue, Jan 24, 2017 at 10:15:38AM +0000, Sudeep Holla wrote:

> >>

> >>

> >> On 23/01/17 21:08, Christoffer Dall wrote:

> >>> On Fri, Jan 20, 2017 at 10:50:10AM +0000, Sudeep Holla wrote:

> >>>> csselr and ccsidr are treated as 64-bit values already elsewhere in the

> >>>> kernel. It also aligns well with the architecture extensions that allow

> >>>> 64-bit format for ccsidr.

> >>>>

> >>>> This patch upgrades the existing accesses to csselr and ccsidr from

> >>>> 32-bit to 64-bit in preparation to add support to those extensions.

> >>>>

> >>>> Cc: Christoffer Dall <christoffer.dall@linaro.org>

> >>>> Cc: Marc Zyngier <marc.zyngier@arm.com>

> >>>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

> >>>> ---

> >>>>  arch/arm64/kvm/sys_regs.c | 18 +++++++++---------

> >>>>  1 file changed, 9 insertions(+), 9 deletions(-)

> >>>>

> >>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c

> >>>> index 5dca1f10340f..a3559a8a2b0c 100644

> >>>> --- a/arch/arm64/kvm/sys_regs.c

> >>>> +++ b/arch/arm64/kvm/sys_regs.c

> >>

> >> [..]

> >>

> >>>> @@ -2004,8 +2004,8 @@ static int demux_c15_get(u64 id, void __user *uaddr)

> >>>>  

> >>>>  static int demux_c15_set(u64 id, void __user *uaddr)

> >>>>  {

> >>>> -	u32 val, newval;

> >>>> -	u32 __user *uval = uaddr;

> >>>> +	u64 val, newval;

> >>>> +	u64 __user *uval = uaddr;

> >>>

> >>> Doesn't converting these uval pointers to u64 cause us to break the ABI

> >>> as we'll now be reading/writing 64-bit values to userspace with the

> >>> get_user and put_user following the declarations?

> >>>

> >>

> >> Yes, I too have similar concern. IIUC it is always read via kvm_one_reg

> >> structure. I could not find any specific user for this register to cross

> >> check.

> >>

> > 

> > Not sure it matters which interface we get the userspace pointer from?

> > 

> 

> Agreed.

> 

> > This patch is definitely changing the write from a 32-bit write to a

> > 64-bit write and there's a specific check prior to the put_user() call

> > which checks that userspace intended a 32-bit value and presumably

> > provided a 32-bit pointer.

> > 

> 

> I see you point, I missed to see that check(just to be sure KVM_REG_SIZE

> check right ?).


yes.


> 

> > So I think the only way to return 64-bit AArch32 system register values

> > to userspace (if that is the intention) is to define a new ID for 64-bit

> > CCSIDR registers and handle them separately.

> > 

> 

> I will add KVM_REG_ARM_DEMUX_ID_CCSIDR_64B or something similar.

> Thanks for the review.

> 


Cool, thanks.
-Christoffer

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff mbox series

Patch

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 5dca1f10340f..a3559a8a2b0c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -58,15 +58,15 @@ 
  */
 
 /* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */
-static u32 cache_levels;
+static u64 cache_levels;
 
 /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */
 #define CSSELR_MAX 	((MAX_CACHE_LEVEL - 1) >> 1)
 
 /* Which cache CCSIDR represents depends on CSSELR value. */
-static u32 get_ccsidr(u32 csselr)
+static u64 get_ccsidr(u64 csselr)
 {
-	u32 ccsidr;
+	u64 ccsidr;
 
 	/* Make sure noone else changes CSSELR during this! */
 	local_irq_disable();
@@ -1952,9 +1952,9 @@  static int set_invariant_sys_reg(u64 id, void __user *uaddr)
 	return 0;
 }
 
-static bool is_valid_cache(u32 val)
+static bool is_valid_cache(u64 val)
 {
-	u32 level, ctype;
+	u64 level, ctype;
 
 	if (val >= CSSELR_MAX)
 		return false;
@@ -1979,8 +1979,8 @@  static bool is_valid_cache(u32 val)
 
 static int demux_c15_get(u64 id, void __user *uaddr)
 {
-	u32 val;
-	u32 __user *uval = uaddr;
+	u64 val;
+	u64 __user *uval = uaddr;
 
 	/* Fail if we have unknown bits set. */
 	if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK
@@ -2004,8 +2004,8 @@  static int demux_c15_get(u64 id, void __user *uaddr)
 
 static int demux_c15_set(u64 id, void __user *uaddr)
 {
-	u32 val, newval;
-	u32 __user *uval = uaddr;
+	u64 val, newval;
+	u64 __user *uval = uaddr;
 
 	/* Fail if we have unknown bits set. */
 	if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK