Skip to content

Commit c0cc438

Browse files
author
Marc Zyngier
committed
KVM: arm64: Compute shareability for LPA2
LPA2 gets the memory access shareability from TCR_ELx instead of getting it form the descriptors. Store it in the walk info struct so that it is passed around and evaluated as required. Reviewed-by: Oliver Upton <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent e4bd479 commit c0cc438

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

arch/arm64/include/asm/kvm_nested.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ struct s1_walk_info {
295295
unsigned int pgshift;
296296
unsigned int txsz;
297297
int sl;
298+
u8 sh;
298299
bool as_el0;
299300
bool hpd;
300301
bool e0poe;

arch/arm64/kvm/at.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
188188
if (!tbi && (u64)sign_extend64(va, 55) != va)
189189
goto addrsz;
190190

191+
wi->sh = (wi->regime == TR_EL2 ?
192+
FIELD_GET(TCR_EL2_SH0_MASK, tcr) :
193+
(va55 ?
194+
FIELD_GET(TCR_SH1_MASK, tcr) :
195+
FIELD_GET(TCR_SH0_MASK, tcr)));
196+
191197
va = (u64)sign_extend64(va, 55);
192198

193199
/* Let's put the MMU disabled case aside immediately */
@@ -697,21 +703,36 @@ static u8 combine_s1_s2_attr(u8 s1, u8 s2)
697703
#define ATTR_OSH 0b10
698704
#define ATTR_ISH 0b11
699705

700-
static u8 compute_sh(u8 attr, u64 desc)
706+
static u8 compute_final_sh(u8 attr, u8 sh)
701707
{
702-
u8 sh;
703-
704708
/* Any form of device, as well as NC has SH[1:0]=0b10 */
705709
if (MEMATTR_IS_DEVICE(attr) || attr == MEMATTR(NC, NC))
706710
return ATTR_OSH;
707711

708-
sh = FIELD_GET(PTE_SHARED, desc);
709712
if (sh == ATTR_RSV) /* Reserved, mapped to NSH */
710713
sh = ATTR_NSH;
711714

712715
return sh;
713716
}
714717

718+
static u8 compute_s1_sh(struct s1_walk_info *wi, struct s1_walk_result *wr,
719+
u8 attr)
720+
{
721+
u8 sh;
722+
723+
/*
724+
* non-52bit and LPA have their basic shareability described in the
725+
* descriptor. LPA2 gets it from the corresponding field in TCR,
726+
* conveniently recorded in the walk info.
727+
*/
728+
if (!wi->pa52bit || BIT(wi->pgshift) == SZ_64K)
729+
sh = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_SH, wr->desc);
730+
else
731+
sh = wi->sh;
732+
733+
return compute_final_sh(attr, sh);
734+
}
735+
715736
static u8 combine_sh(u8 s1_sh, u8 s2_sh)
716737
{
717738
if (s1_sh == ATTR_OSH || s2_sh == ATTR_OSH)
@@ -725,7 +746,7 @@ static u8 combine_sh(u8 s1_sh, u8 s2_sh)
725746
static u64 compute_par_s12(struct kvm_vcpu *vcpu, u64 s1_par,
726747
struct kvm_s2_trans *tr)
727748
{
728-
u8 s1_parattr, s2_memattr, final_attr;
749+
u8 s1_parattr, s2_memattr, final_attr, s2_sh;
729750
u64 par;
730751

731752
/* If S2 has failed to translate, report the damage */
@@ -798,11 +819,13 @@ static u64 compute_par_s12(struct kvm_vcpu *vcpu, u64 s1_par,
798819
!MEMATTR_IS_DEVICE(final_attr))
799820
final_attr = MEMATTR(NC, NC);
800821

822+
s2_sh = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S2_SH, tr->desc);
823+
801824
par = FIELD_PREP(SYS_PAR_EL1_ATTR, final_attr);
802825
par |= tr->output & GENMASK(47, 12);
803826
par |= FIELD_PREP(SYS_PAR_EL1_SH,
804827
combine_sh(FIELD_GET(SYS_PAR_EL1_SH, s1_par),
805-
compute_sh(final_attr, tr->desc)));
828+
compute_final_sh(final_attr, s2_sh)));
806829

807830
return par;
808831
}
@@ -856,7 +879,7 @@ static u64 compute_par_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
856879
par |= FIELD_PREP(SYS_PAR_EL1_ATTR, mair);
857880
par |= wr->pa & GENMASK_ULL(47, 12);
858881

859-
sh = compute_sh(mair, wr->desc);
882+
sh = compute_s1_sh(wi, wr, mair);
860883
par |= FIELD_PREP(SYS_PAR_EL1_SH, sh);
861884
}
862885

0 commit comments

Comments
 (0)