From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paolo Bonzini Subject: Re: [PATCH 3/4] KVM: Add SMAP support when setting CR4 Date: Thu, 27 Mar 2014 12:46:45 +0100 Message-ID: <53340FA5.1050905@redhat.com> References: <1395923135-15329-1-git-send-email-feng.wu@intel.com> <1395923135-15329-4-git-send-email-feng.wu@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit To: Feng Wu , gleb@redhat.com, hpa@zytor.com, kvm@vger.kernel.org Return-path: Received: from mail-ee0-f47.google.com ([74.125.83.47]:61008 "EHLO mail-ee0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753876AbaC0Lqv (ORCPT ); Thu, 27 Mar 2014 07:46:51 -0400 Received: by mail-ee0-f47.google.com with SMTP id b15so2778460eek.34 for ; Thu, 27 Mar 2014 04:46:49 -0700 (PDT) In-Reply-To: <1395923135-15329-4-git-send-email-feng.wu@intel.com> Sender: kvm-owner@vger.kernel.org List-ID: 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. Please test nested virtualization too. I think PFERR_RSVD_MASK should be removed in translate_nested_gpa. Paolo