mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
KVM: arm64: Honor UX/PX attributes for EL2 S1 mappings
Now that we potentially have two bits to deal with when setting execution permissions, make sure we correctly handle them when both when building the page tables and when reading back from them. Reported-by: Alexandru Elisei <alexandru.elisei@arm.com> Reviewed-by: Fuad Tabba <tabba@google.com> Reviewed-by: Joey Gouly <joey.gouly@arm.com> Tested-by: Fuad Tabba <tabba@google.com> Link: https://patch.msgid.link/20251210173024.561160-7-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
@@ -342,6 +342,9 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
|
||||
if (!(prot & KVM_PGTABLE_PROT_R))
|
||||
return -EINVAL;
|
||||
|
||||
if (!cpus_have_final_cap(ARM64_KVM_HVHE))
|
||||
prot &= ~KVM_PGTABLE_PROT_UX;
|
||||
|
||||
if (prot & KVM_PGTABLE_PROT_X) {
|
||||
if (prot & KVM_PGTABLE_PROT_W)
|
||||
return -EINVAL;
|
||||
@@ -351,8 +354,16 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
|
||||
|
||||
if (system_supports_bti_kernel())
|
||||
attr |= KVM_PTE_LEAF_ATTR_HI_S1_GP;
|
||||
}
|
||||
|
||||
if (cpus_have_final_cap(ARM64_KVM_HVHE)) {
|
||||
if (!(prot & KVM_PGTABLE_PROT_PX))
|
||||
attr |= KVM_PTE_LEAF_ATTR_HI_S1_PXN;
|
||||
if (!(prot & KVM_PGTABLE_PROT_UX))
|
||||
attr |= KVM_PTE_LEAF_ATTR_HI_S1_UXN;
|
||||
} else {
|
||||
attr |= KVM_PTE_LEAF_ATTR_HI_S1_XN;
|
||||
if (!(prot & KVM_PGTABLE_PROT_PX))
|
||||
attr |= KVM_PTE_LEAF_ATTR_HI_S1_XN;
|
||||
}
|
||||
|
||||
attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_AP, ap);
|
||||
@@ -373,8 +384,15 @@ enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte)
|
||||
if (!kvm_pte_valid(pte))
|
||||
return prot;
|
||||
|
||||
if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN))
|
||||
prot |= KVM_PGTABLE_PROT_X;
|
||||
if (cpus_have_final_cap(ARM64_KVM_HVHE)) {
|
||||
if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_PXN))
|
||||
prot |= KVM_PGTABLE_PROT_PX;
|
||||
if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_UXN))
|
||||
prot |= KVM_PGTABLE_PROT_UX;
|
||||
} else {
|
||||
if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN))
|
||||
prot |= KVM_PGTABLE_PROT_PX;
|
||||
}
|
||||
|
||||
ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte);
|
||||
if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO)
|
||||
|
||||
Reference in New Issue
Block a user