diff mbox

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

Message ID 1484909410-11673-2-git-send-email-sudeep.holla@arm.com (mailing list archive)
State New, archived
Headers show

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

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
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.
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
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.
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
diff mbox

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