The S2 page table code doesn't use the SW bits yet, but we are about
to need them to encode some guest Stage-2 information (its mapping size
in the form of the TTL encoding).

Propagate the SW bits specified by the caller, and store them into
the corresponding entry.

Signed-off-by: Marc Zyngier <[email protected]>
---
 arch/arm64/include/asm/kvm_pgtable.h | 10 ++++++++++
 arch/arm64/kvm/hyp/pgtable.c         |  6 ++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h 
b/arch/arm64/include/asm/kvm_pgtable.h
index c3674c47d48c..4f432ea3094c 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -92,6 +92,10 @@ struct kvm_pgtable {
  * @KVM_PGTABLE_PROT_W:                Write permission.
  * @KVM_PGTABLE_PROT_R:                Read permission.
  * @KVM_PGTABLE_PROT_DEVICE:   Device attributes.
+ * @KVM_PGTABLE_PROT_S2_SW0:   SW bit 0.
+ * @KVM_PGTABLE_PROT_S2_SW1:   SW bit 1.
+ * @KVM_PGTABLE_PROT_S2_SW2:   SW bit 2.
+ * @KVM_PGTABLE_PROT_S2_SW3:   SW bit 3.
  */
 enum kvm_pgtable_prot {
        KVM_PGTABLE_PROT_X                      = BIT(0),
@@ -99,6 +103,12 @@ enum kvm_pgtable_prot {
        KVM_PGTABLE_PROT_R                      = BIT(2),
 
        KVM_PGTABLE_PROT_DEVICE                 = BIT(3),
+
+       /* Cunningly, this matches the PTE bits... */
+       KVM_PGTABLE_PROT_S2_SW0                 = BIT(55),
+       KVM_PGTABLE_PROT_S2_SW1                 = BIT(56),
+       KVM_PGTABLE_PROT_S2_SW2                 = BIT(57),
+       KVM_PGTABLE_PROT_S2_SW3                 = BIT(58),
 };
 
 #define PAGE_HYP               (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index c37c1dc4feaf..fa85da30c9b8 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -43,6 +43,7 @@
 #define KVM_PTE_LEAF_ATTR_HI_S1_XN     BIT(54)
 
 #define KVM_PTE_LEAF_ATTR_HI_S2_XN     BIT(54)
+#define KVM_PTE_LEAF_ATTR_HI_S2_SW     GENMASK(58, 55)
 
 #define KVM_PTE_LEAF_ATTR_S2_PERMS     (KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
                                         KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
@@ -539,6 +540,7 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, 
enum kvm_pgtable_prot p
 
        attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh);
        attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF;
+       attr |= prot & KVM_PTE_LEAF_ATTR_HI_S2_SW;
        *ptep = attr;
 
        return 0;
@@ -975,6 +977,10 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable 
*pgt, u64 addr,
        if (prot & KVM_PGTABLE_PROT_X)
                clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
 
+       /* Always propagate the SW bits */
+       clr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_SW, 0xf);
+       set |= prot & KVM_PTE_LEAF_ATTR_HI_S2_SW;
+
        ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level);
        if (!ret)
                kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, pgt->mmu, addr, level);
-- 
2.29.2

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to