]> git.ipfire.org Git - thirdparty/kernel/stable.git/blobdiff - arch/arm64/kvm/hyp/pgtable.c
Merge tag 'kvmarm-6.9' of https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm...
[thirdparty/kernel/stable.git] / arch / arm64 / kvm / hyp / pgtable.c
index ab9d05fcf98b23b992343d6a11a1daf9de806b3a..3fae5830f8d2c72f4ed4032cfd99fd285cbcb885 100644 (file)
@@ -717,15 +717,29 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
 static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
                                kvm_pte_t *ptep)
 {
-       bool device = prot & KVM_PGTABLE_PROT_DEVICE;
-       kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
-                           KVM_S2_MEMATTR(pgt, NORMAL);
+       kvm_pte_t attr;
        u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
 
+       switch (prot & (KVM_PGTABLE_PROT_DEVICE |
+                       KVM_PGTABLE_PROT_NORMAL_NC)) {
+       case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
+               return -EINVAL;
+       case KVM_PGTABLE_PROT_DEVICE:
+               if (prot & KVM_PGTABLE_PROT_X)
+                       return -EINVAL;
+               attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
+               break;
+       case KVM_PGTABLE_PROT_NORMAL_NC:
+               if (prot & KVM_PGTABLE_PROT_X)
+                       return -EINVAL;
+               attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
+               break;
+       default:
+               attr = KVM_S2_MEMATTR(pgt, NORMAL);
+       }
+
        if (!(prot & KVM_PGTABLE_PROT_X))
                attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
-       else if (device)
-               return -EINVAL;
 
        if (prot & KVM_PGTABLE_PROT_R)
                attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;