diff mbox series

[v3,02/41] KVM: PPC: Book3S HV: Prevent radix guests from setting LPCR[TC]

Message ID 20210305150638.2675513-3-npiggin@gmail.com
State Superseded
Headers show
Series KVM: PPC: Book3S: C-ify the P9 entry/exit code | expand

Commit Message

Nicholas Piggin March 5, 2021, 3:05 p.m. UTC
This bit only applies to hash partitions.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/kvm/book3s_hv.c        | 6 ++++--
 arch/powerpc/kvm/book3s_hv_nested.c | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

Comments

Fabiano Rosas March 8, 2021, 3:47 p.m. UTC | #1
Nicholas Piggin <npiggin@gmail.com> writes:

> This bit only applies to hash partitions.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
>  arch/powerpc/kvm/book3s_hv.c        | 6 ++++--
>  arch/powerpc/kvm/book3s_hv_nested.c | 2 +-
>  2 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index c40eeb20be39..2e29b96ef775 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -1666,10 +1666,12 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr,
>
>  	/*
>  	 * Userspace can only modify DPFD (default prefetch depth),
> -	 * ILE (interrupt little-endian) and TC (translation control).
> +	 * ILE (interrupt little-endian) and TC (translation control) if HPT.
>  	 * On POWER8 and POWER9 userspace can also modify AIL (alt. interrupt loc.).
>  	 */
> -	mask = LPCR_DPFD | LPCR_ILE | LPCR_TC;
> +	mask = LPCR_DPFD | LPCR_ILE;
> +	if (!kvm_is_radix(kvm))
> +		mask |= LPCR_TC;

I think in theory there is a possibility that userspace sets the LPCR
while we running Radix and then calls the KVM_PPC_CONFIGURE_V3_MMU ioctl
right after to switch to HPT. I'm not sure if that would make sense but
maybe it's something to consider...

>  	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
>  		mask |= LPCR_AIL;
>  		/* LPCR[AIL]=1/2 is disallowed */
> diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
> index b496079e02f7..0e6cf650cbfe 100644
> --- a/arch/powerpc/kvm/book3s_hv_nested.c
> +++ b/arch/powerpc/kvm/book3s_hv_nested.c
> @@ -141,7 +141,7 @@ static void sanitise_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
>  	 * Don't let L1 change LPCR bits for the L2 except these:
>  	 * Keep this in sync with kvmppc_set_lpcr.
>  	 */
> -	mask = LPCR_DPFD | LPCR_ILE | LPCR_TC | LPCR_LD | LPCR_LPES | LPCR_MER;
> +	mask = LPCR_DPFD | LPCR_ILE | LPCR_LD | LPCR_LPES | LPCR_MER;
>  	/* LPCR[AIL]=1/2 is disallowed */
>  	if ((hr->lpcr & LPCR_AIL) && (hr->lpcr & LPCR_AIL) != LPCR_AIL_3)
>  		hr->lpcr &= ~LPCR_AIL;
Nicholas Piggin March 9, 2021, 1:14 a.m. UTC | #2
Excerpts from Fabiano Rosas's message of March 9, 2021 1:47 am:
> Nicholas Piggin <npiggin@gmail.com> writes:
> 
>> This bit only applies to hash partitions.
>>
>> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
>> ---
>>  arch/powerpc/kvm/book3s_hv.c        | 6 ++++--
>>  arch/powerpc/kvm/book3s_hv_nested.c | 2 +-
>>  2 files changed, 5 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
>> index c40eeb20be39..2e29b96ef775 100644
>> --- a/arch/powerpc/kvm/book3s_hv.c
>> +++ b/arch/powerpc/kvm/book3s_hv.c
>> @@ -1666,10 +1666,12 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr,
>>
>>  	/*
>>  	 * Userspace can only modify DPFD (default prefetch depth),
>> -	 * ILE (interrupt little-endian) and TC (translation control).
>> +	 * ILE (interrupt little-endian) and TC (translation control) if HPT.
>>  	 * On POWER8 and POWER9 userspace can also modify AIL (alt. interrupt loc.).
>>  	 */
>> -	mask = LPCR_DPFD | LPCR_ILE | LPCR_TC;
>> +	mask = LPCR_DPFD | LPCR_ILE;
>> +	if (!kvm_is_radix(kvm))
>> +		mask |= LPCR_TC;
> 
> I think in theory there is a possibility that userspace sets the LPCR
> while we running Radix and then calls the KVM_PPC_CONFIGURE_V3_MMU ioctl
> right after to switch to HPT. I'm not sure if that would make sense but
> maybe it's something to consider...

Oh actually it is an issue for the later AIL patch I think.

So LPCR will have to be filtered again when switching MMU mode.

Good catch, I'll add something for that.

Thanks,
Nick

> 
>>  	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
>>  		mask |= LPCR_AIL;
>>  		/* LPCR[AIL]=1/2 is disallowed */
>> diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
>> index b496079e02f7..0e6cf650cbfe 100644
>> --- a/arch/powerpc/kvm/book3s_hv_nested.c
>> +++ b/arch/powerpc/kvm/book3s_hv_nested.c
>> @@ -141,7 +141,7 @@ static void sanitise_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
>>  	 * Don't let L1 change LPCR bits for the L2 except these:
>>  	 * Keep this in sync with kvmppc_set_lpcr.
>>  	 */
>> -	mask = LPCR_DPFD | LPCR_ILE | LPCR_TC | LPCR_LD | LPCR_LPES | LPCR_MER;
>> +	mask = LPCR_DPFD | LPCR_ILE | LPCR_LD | LPCR_LPES | LPCR_MER;
>>  	/* LPCR[AIL]=1/2 is disallowed */
>>  	if ((hr->lpcr & LPCR_AIL) && (hr->lpcr & LPCR_AIL) != LPCR_AIL_3)
>>  		hr->lpcr &= ~LPCR_AIL;
>
diff mbox series

Patch

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index c40eeb20be39..2e29b96ef775 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1666,10 +1666,12 @@  static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr,
 
 	/*
 	 * Userspace can only modify DPFD (default prefetch depth),
-	 * ILE (interrupt little-endian) and TC (translation control).
+	 * ILE (interrupt little-endian) and TC (translation control) if HPT.
 	 * On POWER8 and POWER9 userspace can also modify AIL (alt. interrupt loc.).
 	 */
-	mask = LPCR_DPFD | LPCR_ILE | LPCR_TC;
+	mask = LPCR_DPFD | LPCR_ILE;
+	if (!kvm_is_radix(kvm))
+		mask |= LPCR_TC;
 	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
 		mask |= LPCR_AIL;
 		/* LPCR[AIL]=1/2 is disallowed */
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index b496079e02f7..0e6cf650cbfe 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -141,7 +141,7 @@  static void sanitise_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
 	 * Don't let L1 change LPCR bits for the L2 except these:
 	 * Keep this in sync with kvmppc_set_lpcr.
 	 */
-	mask = LPCR_DPFD | LPCR_ILE | LPCR_TC | LPCR_LD | LPCR_LPES | LPCR_MER;
+	mask = LPCR_DPFD | LPCR_ILE | LPCR_LD | LPCR_LPES | LPCR_MER;
 	/* LPCR[AIL]=1/2 is disallowed */
 	if ((hr->lpcr & LPCR_AIL) && (hr->lpcr & LPCR_AIL) != LPCR_AIL_3)
 		hr->lpcr &= ~LPCR_AIL;