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

Reply via email to