diff mbox

[07/31] KVM: arm/arm64: vgic-v3: Add accessors for the ICH_APxRn_EL2 registers

Message ID 20170503104606.19342-8-marc.zyngier@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Marc Zyngier May 3, 2017, 10:45 a.m. UTC
As we're about to access the Active Priority registers a lot more,
let's define accessors that take the register number as a parameter.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/hyp/vgic-v3-sr.c | 116 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 100 insertions(+), 16 deletions(-)

Comments

Mark Rutland May 3, 2017, 3:32 p.m. UTC | #1
On Wed, May 03, 2017 at 11:45:42AM +0100, Marc Zyngier wrote:
> As we're about to access the Active Priority registers a lot more,
> let's define accessors that take the register number as a parameter.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  virt/kvm/arm/hyp/vgic-v3-sr.c | 116 ++++++++++++++++++++++++++++++++++++------
>  1 file changed, 100 insertions(+), 16 deletions(-)
> 
> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
> index 32c3295929b0..990d9d1e85d0 100644
> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
> @@ -118,6 +118,90 @@ static void __hyp_text __gic_v3_set_lr(u64 val, int lr)
>  	}
>  }
>  
> +static void __hyp_text __vgic_v3_write_ap0rn(u32 val, int n)
> +{
> +	switch (n) {
> +	case 0:
> +		write_gicreg(val, ICH_AP0R0_EL2);
> +		break;
> +	case 1:
> +		write_gicreg(val, ICH_AP0R1_EL2);
> +		break;
> +	case 2:
> +		write_gicreg(val, ICH_AP0R2_EL2);
> +		break;
> +	case 3:
> +		write_gicreg(val, ICH_AP0R3_EL2);
> +		break;
> +	}

Is there any way we can get a build or runtime failure for an
out-of-bounds n value?

> +}

Given this is used with a constant n, you could make this:

#define __vgic_v3_write_ap0rn(v, n) \
	write_gicreg(v, ICH_AP0R##n##_EL2)

... which should also give you a warning for an out-of-bounds n.

Similar could apply for the other helpers here.

That would require some function -> macro conversion in later patches
though, so I can understand if you're not keen on that.

Thanks,
Mark.
Marc Zyngier May 3, 2017, 3:58 p.m. UTC | #2
On 03/05/17 16:32, Mark Rutland wrote:
> On Wed, May 03, 2017 at 11:45:42AM +0100, Marc Zyngier wrote:
>> As we're about to access the Active Priority registers a lot more,
>> let's define accessors that take the register number as a parameter.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  virt/kvm/arm/hyp/vgic-v3-sr.c | 116 ++++++++++++++++++++++++++++++++++++------
>>  1 file changed, 100 insertions(+), 16 deletions(-)
>>
>> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
>> index 32c3295929b0..990d9d1e85d0 100644
>> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
>> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
>> @@ -118,6 +118,90 @@ static void __hyp_text __gic_v3_set_lr(u64 val, int lr)
>>  	}
>>  }
>>  
>> +static void __hyp_text __vgic_v3_write_ap0rn(u32 val, int n)
>> +{
>> +	switch (n) {
>> +	case 0:
>> +		write_gicreg(val, ICH_AP0R0_EL2);
>> +		break;
>> +	case 1:
>> +		write_gicreg(val, ICH_AP0R1_EL2);
>> +		break;
>> +	case 2:
>> +		write_gicreg(val, ICH_AP0R2_EL2);
>> +		break;
>> +	case 3:
>> +		write_gicreg(val, ICH_AP0R3_EL2);
>> +		break;
>> +	}
> 
> Is there any way we can get a build or runtime failure for an
> out-of-bounds n value?

I'd rather avoid runtime failure on this path, because that's pretty
terminal. Build-time is a possibility, to some extent.

> 
>> +}
> 
> Given this is used with a constant n, you could make this:
> 
> #define __vgic_v3_write_ap0rn(v, n) \
> 	write_gicreg(v, ICH_AP0R##n##_EL2)
> 
> ... which should also give you a warning for an out-of-bounds n.
> 
> Similar could apply for the other helpers here.
> 
> That would require some function -> macro conversion in later patches
> though, so I can understand if you're not keen on that.

I don't mind reworking this if that makes it safer. But the real problem
is that the register number and the group are not necessarily constants
(see how this is used in __vgic_v3_get_highest_active_priority).

I'll have a look at how I can make that look a bit better.

Thanks,

	M.
Eric Auger May 17, 2017, 9:54 a.m. UTC | #3
Hi,

On 03/05/2017 12:45, Marc Zyngier wrote:
> As we're about to access the Active Priority registers a lot more,
> let's define accessors that take the register number as a parameter.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  virt/kvm/arm/hyp/vgic-v3-sr.c | 116 ++++++++++++++++++++++++++++++++++++------
>  1 file changed, 100 insertions(+), 16 deletions(-)
> 
> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
> index 32c3295929b0..990d9d1e85d0 100644
> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
> @@ -118,6 +118,90 @@ static void __hyp_text __gic_v3_set_lr(u64 val, int lr)
>  	}
>  }
>  
> +static void __hyp_text __vgic_v3_write_ap0rn(u32 val, int n)
> +{
> +	switch (n) {
> +	case 0:
> +		write_gicreg(val, ICH_AP0R0_EL2);
> +		break;
> +	case 1:
> +		write_gicreg(val, ICH_AP0R1_EL2);
> +		break;
> +	case 2:
> +		write_gicreg(val, ICH_AP0R2_EL2);
> +		break;
> +	case 3:
> +		write_gicreg(val, ICH_AP0R3_EL2);
> +		break;
> +	}
> +}
> +
> +static void __hyp_text __vgic_v3_write_ap1rn(u32 val, int n)
> +{
> +	switch (n) {
> +	case 0:
> +		write_gicreg(val, ICH_AP1R0_EL2);
> +		break;
> +	case 1:
> +		write_gicreg(val, ICH_AP1R1_EL2);
> +		break;
> +	case 2:
> +		write_gicreg(val, ICH_AP1R2_EL2);
> +		break;
> +	case 3:
> +		write_gicreg(val, ICH_AP1R3_EL2);
> +		break;
> +	}
> +}
> +
> +static u32 __hyp_text __vgic_v3_read_ap0rn(int n)
> +{
> +	u32 val;
> +
> +	switch (n) {
> +	case 0:
> +		val = read_gicreg(ICH_AP0R0_EL2);
> +		break;
> +	case 1:
> +		val = read_gicreg(ICH_AP0R1_EL2);
> +		break;
> +	case 2:
> +		val = read_gicreg(ICH_AP0R2_EL2);
> +		break;
> +	case 3:
> +		val = read_gicreg(ICH_AP0R3_EL2);
> +		break;
> +	default:
> +		unreachable();
I am not familiar with that macro. For my curiosity why is it used here
and not in write functions.

Besides Mark's comment,

Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
> +	}
> +
> +	return val;
> +}
> +
> +static u32 __hyp_text __vgic_v3_read_ap1rn(int n)
> +{
> +	u32 val;
> +
> +	switch (n) {
> +	case 0:
> +		val = read_gicreg(ICH_AP1R0_EL2);
> +		break;
> +	case 1:
> +		val = read_gicreg(ICH_AP1R1_EL2);
> +		break;
> +	case 2:
> +		val = read_gicreg(ICH_AP1R2_EL2);
> +		break;
> +	case 3:
> +		val = read_gicreg(ICH_AP1R3_EL2);
> +		break;
> +	default:
> +		unreachable();
> +	}
> +
> +	return val;
> +}
> +
>  void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
> @@ -154,22 +238,22 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
>  
>  		switch (nr_pre_bits) {
>  		case 7:
> -			cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2);
> -			cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2);
> +			cpu_if->vgic_ap0r[3] = __vgic_v3_read_ap0rn(3);
> +			cpu_if->vgic_ap0r[2] = __vgic_v3_read_ap0rn(2);
>  		case 6:
> -			cpu_if->vgic_ap0r[1] = read_gicreg(ICH_AP0R1_EL2);
> +			cpu_if->vgic_ap0r[1] = __vgic_v3_read_ap0rn(1);
>  		default:
> -			cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2);
> +			cpu_if->vgic_ap0r[0] = __vgic_v3_read_ap0rn(0);
>  		}
>  
>  		switch (nr_pre_bits) {
>  		case 7:
> -			cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2);
> -			cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2);
> +			cpu_if->vgic_ap1r[3] = __vgic_v3_read_ap1rn(3);
> +			cpu_if->vgic_ap1r[2] = __vgic_v3_read_ap1rn(2);
>  		case 6:
> -			cpu_if->vgic_ap1r[1] = read_gicreg(ICH_AP1R1_EL2);
> +			cpu_if->vgic_ap1r[1] = __vgic_v3_read_ap1rn(1);
>  		default:
> -			cpu_if->vgic_ap1r[0] = read_gicreg(ICH_AP1R0_EL2);
> +			cpu_if->vgic_ap1r[0] = __vgic_v3_read_ap1rn(0);
>  		}
>  	} else {
>  		cpu_if->vgic_elrsr = 0xffff;
> @@ -224,22 +308,22 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
>  
>  		switch (nr_pre_bits) {
>  		case 7:
> -			write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2);
> -			write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2);
> +			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[3], 3);
> +			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[2], 2);
>  		case 6:
> -			write_gicreg(cpu_if->vgic_ap0r[1], ICH_AP0R1_EL2);
> +			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[1], 1);
>  		default:
> -			write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2);
> +			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[0], 0);
>  		}
>  
>  		switch (nr_pre_bits) {
>  		case 7:
> -			write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2);
> -			write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2);
> +			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[3], 3);
> +			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[2], 2);
>  		case 6:
> -			write_gicreg(cpu_if->vgic_ap1r[1], ICH_AP1R1_EL2);
> +			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[1], 1);
>  		default:
> -			write_gicreg(cpu_if->vgic_ap1r[0], ICH_AP1R0_EL2);
> +			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[0], 0);
>  		}
>  
>  		for (i = 0; i < used_lrs; i++)
>
Marc Zyngier May 22, 2017, 6:52 p.m. UTC | #4
On Wed, May 17 2017 at 11:54:23 am BST, Auger Eric <eric.auger@redhat.com> wrote:
> Hi,
>
> On 03/05/2017 12:45, Marc Zyngier wrote:
>> As we're about to access the Active Priority registers a lot more,
>> let's define accessors that take the register number as a parameter.
>> 
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  virt/kvm/arm/hyp/vgic-v3-sr.c | 116 ++++++++++++++++++++++++++++++++++++------
>>  1 file changed, 100 insertions(+), 16 deletions(-)
>> 
>> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
>> index 32c3295929b0..990d9d1e85d0 100644
>> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
>> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
>> @@ -118,6 +118,90 @@ static void __hyp_text __gic_v3_set_lr(u64 val, int lr)
>>  	}
>>  }
>>  
>> +static void __hyp_text __vgic_v3_write_ap0rn(u32 val, int n)
>> +{
>> +	switch (n) {
>> +	case 0:
>> +		write_gicreg(val, ICH_AP0R0_EL2);
>> +		break;
>> +	case 1:
>> +		write_gicreg(val, ICH_AP0R1_EL2);
>> +		break;
>> +	case 2:
>> +		write_gicreg(val, ICH_AP0R2_EL2);
>> +		break;
>> +	case 3:
>> +		write_gicreg(val, ICH_AP0R3_EL2);
>> +		break;
>> +	}
>> +}
>> +
>> +static void __hyp_text __vgic_v3_write_ap1rn(u32 val, int n)
>> +{
>> +	switch (n) {
>> +	case 0:
>> +		write_gicreg(val, ICH_AP1R0_EL2);
>> +		break;
>> +	case 1:
>> +		write_gicreg(val, ICH_AP1R1_EL2);
>> +		break;
>> +	case 2:
>> +		write_gicreg(val, ICH_AP1R2_EL2);
>> +		break;
>> +	case 3:
>> +		write_gicreg(val, ICH_AP1R3_EL2);
>> +		break;
>> +	}
>> +}
>> +
>> +static u32 __hyp_text __vgic_v3_read_ap0rn(int n)
>> +{
>> +	u32 val;
>> +
>> +	switch (n) {
>> +	case 0:
>> +		val = read_gicreg(ICH_AP0R0_EL2);
>> +		break;
>> +	case 1:
>> +		val = read_gicreg(ICH_AP0R1_EL2);
>> +		break;
>> +	case 2:
>> +		val = read_gicreg(ICH_AP0R2_EL2);
>> +		break;
>> +	case 3:
>> +		val = read_gicreg(ICH_AP0R3_EL2);
>> +		break;
>> +	default:
>> +		unreachable();
> I am not familiar with that macro. For my curiosity why is it used here
> and not in write functions.

I probably have looked at the assembly code and realised that using this
macro was helping the compiler not to generate horrible code because it
doesn't know that it will always return a value.

The "write" part doesn't need this not to be awful, so I didn't feel the
need to add it. Can do though.

>
> Besides Mark's comment,
>
> Reviewed-by: Eric Auger <eric.auger@redhat.com>

Thanks,

	M.
Marc Zyngier May 30, 2017, 4:17 p.m. UTC | #5
On 03/05/17 16:58, Marc Zyngier wrote:
> On 03/05/17 16:32, Mark Rutland wrote:
>> On Wed, May 03, 2017 at 11:45:42AM +0100, Marc Zyngier wrote:
>>> As we're about to access the Active Priority registers a lot more,
>>> let's define accessors that take the register number as a parameter.
>>>
>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>> ---
>>>  virt/kvm/arm/hyp/vgic-v3-sr.c | 116 ++++++++++++++++++++++++++++++++++++------
>>>  1 file changed, 100 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
>>> index 32c3295929b0..990d9d1e85d0 100644
>>> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
>>> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
>>> @@ -118,6 +118,90 @@ static void __hyp_text __gic_v3_set_lr(u64 val, int lr)
>>>  	}
>>>  }
>>>  
>>> +static void __hyp_text __vgic_v3_write_ap0rn(u32 val, int n)
>>> +{
>>> +	switch (n) {
>>> +	case 0:
>>> +		write_gicreg(val, ICH_AP0R0_EL2);
>>> +		break;
>>> +	case 1:
>>> +		write_gicreg(val, ICH_AP0R1_EL2);
>>> +		break;
>>> +	case 2:
>>> +		write_gicreg(val, ICH_AP0R2_EL2);
>>> +		break;
>>> +	case 3:
>>> +		write_gicreg(val, ICH_AP0R3_EL2);
>>> +		break;
>>> +	}
>>
>> Is there any way we can get a build or runtime failure for an
>> out-of-bounds n value?
> 
> I'd rather avoid runtime failure on this path, because that's pretty
> terminal. Build-time is a possibility, to some extent.
> 
>>
>>> +}
>>
>> Given this is used with a constant n, you could make this:
>>
>> #define __vgic_v3_write_ap0rn(v, n) \
>> 	write_gicreg(v, ICH_AP0R##n##_EL2)
>>
>> ... which should also give you a warning for an out-of-bounds n.
>>
>> Similar could apply for the other helpers here.
>>
>> That would require some function -> macro conversion in later patches
>> though, so I can understand if you're not keen on that.
> 
> I don't mind reworking this if that makes it safer. But the real problem
> is that the register number and the group are not necessarily constants
> (see how this is used in __vgic_v3_get_highest_active_priority).
> 
> I'll have a look at how I can make that look a bit better.

So I had another look at that, and I'm not sure there is any way to make
it really nicer, other than expanding all of the apxrn accessors to deal
with non constant x and n (which makes the code look really awful).

I'm pretty confident that it is nigh impossible to get x or n out of
bounds so unless someone shouts, I plan on keeping this code mostly
unchanged for the next repost.

Thanks,

	M.
Mark Rutland May 30, 2017, 4:42 p.m. UTC | #6
On Tue, May 30, 2017 at 05:17:01PM +0100, Marc Zyngier wrote:
> On 03/05/17 16:58, Marc Zyngier wrote:
> > On 03/05/17 16:32, Mark Rutland wrote:
> >> On Wed, May 03, 2017 at 11:45:42AM +0100, Marc Zyngier wrote:
> >>> +static void __hyp_text __vgic_v3_write_ap0rn(u32 val, int n)
> >>> +{
> >>> +	switch (n) {
> >>> +	case 0:
> >>> +		write_gicreg(val, ICH_AP0R0_EL2);
> >>> +		break;
> >>> +	case 1:
> >>> +		write_gicreg(val, ICH_AP0R1_EL2);
> >>> +		break;
> >>> +	case 2:
> >>> +		write_gicreg(val, ICH_AP0R2_EL2);
> >>> +		break;
> >>> +	case 3:
> >>> +		write_gicreg(val, ICH_AP0R3_EL2);
> >>> +		break;
> >>> +	}
> >>
> >> Is there any way we can get a build or runtime failure for an
> >> out-of-bounds n value?
> > 
> > I'd rather avoid runtime failure on this path, because that's pretty
> > terminal. Build-time is a possibility, to some extent.

> >> Given this is used with a constant n, you could make this:
> >>
> >> #define __vgic_v3_write_ap0rn(v, n) \
> >> 	write_gicreg(v, ICH_AP0R##n##_EL2)
> >>
> >> ... which should also give you a warning for an out-of-bounds n.
> >>
> >> Similar could apply for the other helpers here.
> >>
> >> That would require some function -> macro conversion in later patches
> >> though, so I can understand if you're not keen on that.
> > 
> > I don't mind reworking this if that makes it safer. But the real problem
> > is that the register number and the group are not necessarily constants
> > (see how this is used in __vgic_v3_get_highest_active_priority).
> > 
> > I'll have a look at how I can make that look a bit better.
> 
> So I had another look at that, and I'm not sure there is any way to make
> it really nicer, other than expanding all of the apxrn accessors to deal
> with non constant x and n (which makes the code look really awful).
> 
> I'm pretty confident that it is nigh impossible to get x or n out of
> bounds so unless someone shouts, I plan on keeping this code mostly
> unchanged for the next repost.

Fair enough, thanks for taking a look anyhow.

Thanks,
Mark.
diff mbox

Patch

diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
index 32c3295929b0..990d9d1e85d0 100644
--- a/virt/kvm/arm/hyp/vgic-v3-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
@@ -118,6 +118,90 @@  static void __hyp_text __gic_v3_set_lr(u64 val, int lr)
 	}
 }
 
+static void __hyp_text __vgic_v3_write_ap0rn(u32 val, int n)
+{
+	switch (n) {
+	case 0:
+		write_gicreg(val, ICH_AP0R0_EL2);
+		break;
+	case 1:
+		write_gicreg(val, ICH_AP0R1_EL2);
+		break;
+	case 2:
+		write_gicreg(val, ICH_AP0R2_EL2);
+		break;
+	case 3:
+		write_gicreg(val, ICH_AP0R3_EL2);
+		break;
+	}
+}
+
+static void __hyp_text __vgic_v3_write_ap1rn(u32 val, int n)
+{
+	switch (n) {
+	case 0:
+		write_gicreg(val, ICH_AP1R0_EL2);
+		break;
+	case 1:
+		write_gicreg(val, ICH_AP1R1_EL2);
+		break;
+	case 2:
+		write_gicreg(val, ICH_AP1R2_EL2);
+		break;
+	case 3:
+		write_gicreg(val, ICH_AP1R3_EL2);
+		break;
+	}
+}
+
+static u32 __hyp_text __vgic_v3_read_ap0rn(int n)
+{
+	u32 val;
+
+	switch (n) {
+	case 0:
+		val = read_gicreg(ICH_AP0R0_EL2);
+		break;
+	case 1:
+		val = read_gicreg(ICH_AP0R1_EL2);
+		break;
+	case 2:
+		val = read_gicreg(ICH_AP0R2_EL2);
+		break;
+	case 3:
+		val = read_gicreg(ICH_AP0R3_EL2);
+		break;
+	default:
+		unreachable();
+	}
+
+	return val;
+}
+
+static u32 __hyp_text __vgic_v3_read_ap1rn(int n)
+{
+	u32 val;
+
+	switch (n) {
+	case 0:
+		val = read_gicreg(ICH_AP1R0_EL2);
+		break;
+	case 1:
+		val = read_gicreg(ICH_AP1R1_EL2);
+		break;
+	case 2:
+		val = read_gicreg(ICH_AP1R2_EL2);
+		break;
+	case 3:
+		val = read_gicreg(ICH_AP1R3_EL2);
+		break;
+	default:
+		unreachable();
+	}
+
+	return val;
+}
+
 void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
@@ -154,22 +238,22 @@  void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 
 		switch (nr_pre_bits) {
 		case 7:
-			cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2);
-			cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2);
+			cpu_if->vgic_ap0r[3] = __vgic_v3_read_ap0rn(3);
+			cpu_if->vgic_ap0r[2] = __vgic_v3_read_ap0rn(2);
 		case 6:
-			cpu_if->vgic_ap0r[1] = read_gicreg(ICH_AP0R1_EL2);
+			cpu_if->vgic_ap0r[1] = __vgic_v3_read_ap0rn(1);
 		default:
-			cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2);
+			cpu_if->vgic_ap0r[0] = __vgic_v3_read_ap0rn(0);
 		}
 
 		switch (nr_pre_bits) {
 		case 7:
-			cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2);
-			cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2);
+			cpu_if->vgic_ap1r[3] = __vgic_v3_read_ap1rn(3);
+			cpu_if->vgic_ap1r[2] = __vgic_v3_read_ap1rn(2);
 		case 6:
-			cpu_if->vgic_ap1r[1] = read_gicreg(ICH_AP1R1_EL2);
+			cpu_if->vgic_ap1r[1] = __vgic_v3_read_ap1rn(1);
 		default:
-			cpu_if->vgic_ap1r[0] = read_gicreg(ICH_AP1R0_EL2);
+			cpu_if->vgic_ap1r[0] = __vgic_v3_read_ap1rn(0);
 		}
 	} else {
 		cpu_if->vgic_elrsr = 0xffff;
@@ -224,22 +308,22 @@  void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
 
 		switch (nr_pre_bits) {
 		case 7:
-			write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2);
-			write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2);
+			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[3], 3);
+			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[2], 2);
 		case 6:
-			write_gicreg(cpu_if->vgic_ap0r[1], ICH_AP0R1_EL2);
+			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[1], 1);
 		default:
-			write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2);
+			__vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[0], 0);
 		}
 
 		switch (nr_pre_bits) {
 		case 7:
-			write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2);
-			write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2);
+			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[3], 3);
+			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[2], 2);
 		case 6:
-			write_gicreg(cpu_if->vgic_ap1r[1], ICH_AP1R1_EL2);
+			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[1], 1);
 		default:
-			write_gicreg(cpu_if->vgic_ap1r[0], ICH_AP1R0_EL2);
+			__vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[0], 0);
 		}
 
 		for (i = 0; i < used_lrs; i++)