Re: [RFC 4/7] KVM: MMU: Refactor pkr_mask to cache condition

From: Chenyi Qiang
Date: Wed Jan 27 2021 - 00:58:28 EST




On 1/27/2021 2:16 AM, Paolo Bonzini wrote:
On 07/08/20 10:48, Chenyi Qiang wrote:

         * index of the protection domain, so pte_pkey * 2 is
         * is the index of the first bit for the domain.
         */
-        pkr_bits = (vcpu->arch.pkru >> (pte_pkey * 2)) & 3;
+        if (pte_access & PT_USER_MASK)
+            pkr_bits = (vcpu->arch.pkru >> (pte_pkey * 2)) & 3;
+        else
+            pkr_bits = 0;

-        /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */
-        offset = (pfec & ~1) +
-            ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT));
+        /* clear present bit */
+        offset = (pfec & ~1);

         pkr_bits &= mmu->pkr_mask >> offset;
         errcode |= -pkr_bits & PFERR_PK_MASK;

I think this is incorrect.  mmu->pkr_mask must cover both clear and set ACC_USER_MASK, in to cover all combinations of CR4.PKE and CR4.PKS. Right now, check_pkey is !ff && pte_user, but you need to make it something like

    check_pkey = !ff && (pte_user ? cr4_pke : cr4_pks);

Paolo

Oh, I didn't distinguish the cr4_pke/cr4_pks check. Will fix this issue.