Paolo Bonzini wrote on 2014-03-27:
> Il 27/03/2014 13:25, Feng Wu ha scritto:
>> +void update_permission_bitmask(struct kvm_vcpu *vcpu,
>>              struct kvm_mmu *mmu, bool ept)
>>  {
>>      unsigned bit, byte, pfec;
>>      u8 map;
>> -    bool fault, x, w, u, wf, uf, ff, smep;
>> +    bool fault, x, w, u, wf, uf, ff, smep, smap;
>> 
>>      smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); + smap =
>>  kvm_read_cr4_bits(vcpu, X86_CR4_SMAP);      for (byte = 0; byte <
>>  ARRAY_SIZE(mmu->permissions); ++byte) {             pfec = byte << 1;       
>>         map = 0;
>> @@ -3617,11 +3618,26 @@ static void update_permission_bitmask(struct
> kvm_vcpu *vcpu,
>>                              w |= !is_write_protection(vcpu) && !uf;
>>                              /* Disallow supervisor fetches of user code if 
>> cr4.smep */
>>                              x &= !(smep && u && !uf);
>> +
>> +                            /*
>> +                             * SMAP:kernel-mode data accesses from user-mode
>> +                             * mappings should fault. A fault is considered
>> +                             * as a SMAP violation if all of the following
>> +                             * conditions are ture:
>> +                             *   - X86_CR4_SMAP is set in CR4
>> +                             *   - An user page is accessed
>> +                             *   - !(CPL<3 && X86_EFLAGS_AC is set)
>> +                             *   - Page fault in kernel mode
>> +                             */
>> +                            smap = smap && u && !uf &&
>> +                                    !((kvm_x86_ops->get_cpl(vcpu) < 3) &&
>> +                                    ((kvm_x86_ops->get_rflags(vcpu) &
>> +                                    X86_EFLAGS_AC) == 1));
> 
> Unfortunately this doesn't work.
> 
> The reason is that changing X86_EFLAGS_AC doesn't trigger
> update_permission_bitmask.  So the value of CPL < 3 && AC = 1 must not
> be checked in update_permission_bitmask; instead, it must be included
> in the index into the permissions array.  You can reuse the
> PFERR_RSVD_MASK bit, like
> 
>       smapf = pfec & PFERR_RSVD_MASK;
>       ...
>               smap = smap && smapf u && !uf;
> 
> The VCPU can then be passed to permission_fault in order to get the
> value of the CPL and the AC bit.

Is CPL check needed? Shouldn't it already have been covered by U bit?

> 
> Please test nested virtualization too.  I think PFERR_RSVD_MASK should
> be removed in translate_nested_gpa.
> 
> Paolo


Best regards,
Yang


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to