[3.19.y-ckt stable] Patch "ARM/arm64: KVM: test properly for a PTE's uncachedness" has been added to staging queue
Kamal Mostafa
kamal at canonical.com
Tue Dec 15 21:44:51 UTC 2015
On Tue, 2015-12-15 at 22:36 +0100, Christoffer Dall wrote:
> On Tue, Dec 15, 2015 at 01:24:31PM -0800, Kamal Mostafa wrote:
> > This is a note to let you know that I have just added a patch titled
> >
> > ARM/arm64: KVM: test properly for a PTE's uncachedness
> >
> > to the linux-3.19.y-queue branch of the 3.19.y-ckt extended stable tree
> > which can be found at:
> >
> > http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.19.y-queue
> >
> > This patch is scheduled to be released in version 3.19.8-ckt12.
> >
> > If you, or anyone else, feels it should not be added to this tree, please
> > reply to this email.
>
> This fix was incorrect and was subsequently updated by the following
> commit in mainline:
>
> 0de58f8 (ARM/arm64: KVM: correct PTE uncachedness check, 2015-12-03)
>
> That update should be applied along with this one.
>
> Thanks,
> -Christoffer
Thanks very much Christoffer, I'll make sure the follow-up fix gets
applied in the same 3.19-stable release.
-Kamal
> > ------
> >
> > From 215d740cfc3c554856542c00581e9b7169eb18e7 Mon Sep 17 00:00:00 2001
> > From: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> > Date: Tue, 10 Nov 2015 15:11:20 +0100
> > Subject: ARM/arm64: KVM: test properly for a PTE's uncachedness
> >
> > commit e6fab54423450d699a09ec2b899473a541f61971 upstream.
> >
> > The open coded tests for checking whether a PTE maps a page as
> > uncached use a flawed '(pte_val(xxx) & CONST) != CONST' pattern,
> > which is not guaranteed to work since the type of a mapping is
> > not a set of mutually exclusive bits
> >
> > For HYP mappings, the type is an index into the MAIR table (i.e, the
> > index itself does not contain any information whatsoever about the
> > type of the mapping), and for stage-2 mappings it is a bit field where
> > normal memory and device types are defined as follows:
> >
> > #define MT_S2_NORMAL 0xf
> > #define MT_S2_DEVICE_nGnRE 0x1
> >
> > I.e., masking *and* comparing with the latter matches on the former,
> > and we have been getting lucky merely because the S2 device mappings
> > also have the PTE_UXN bit set, or we would misidentify memory mappings
> > as device mappings.
> >
> > Since the unmap_range() code path (which contains one instance of the
> > flawed test) is used both for HYP mappings and stage-2 mappings, and
> > considering the difference between the two, it is non-trivial to fix
> > this by rewriting the tests in place, as it would involve passing
> > down the type of mapping through all the functions.
> >
> > However, since HYP mappings and stage-2 mappings both deal with host
> > physical addresses, we can simply check whether the mapping is backed
> > by memory that is managed by the host kernel, and only perform the
> > D-cache maintenance if this is the case.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> > Tested-by: Pavel Fedin <p.fedin at samsung.com>
> > Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
> > Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
> > Signed-off-by: Kamal Mostafa <kamal at canonical.com>
> > ---
> > arch/arm/kvm/mmu.c | 15 +++++++--------
> > 1 file changed, 7 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> > index 0512ed4..a2c1ebf 100644
> > --- a/arch/arm/kvm/mmu.c
> > +++ b/arch/arm/kvm/mmu.c
> > @@ -78,6 +78,11 @@ static void kvm_flush_dcache_pud(pud_t pud)
> > __kvm_flush_dcache_pud(pud);
> > }
> >
> > +static bool kvm_is_device_pfn(unsigned long pfn)
> > +{
> > + return !pfn_valid(pfn);
> > +}
> > +
> > static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
> > int min, int max)
> > {
> > @@ -174,7 +179,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
> > kvm_tlb_flush_vmid_ipa(kvm, addr);
> >
> > /* No need to invalidate the cache for device mappings */
> > - if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
> > + if (!kvm_is_device_pfn(__phys_to_pfn(addr)))
> > kvm_flush_dcache_pte(old_pte);
> >
> > put_page(virt_to_page(pte));
> > @@ -266,8 +271,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
> >
> > pte = pte_offset_kernel(pmd, addr);
> > do {
> > - if (!pte_none(*pte) &&
> > - (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
> > + if (!pte_none(*pte) && !kvm_is_device_pfn(__phys_to_pfn(addr)))
> > kvm_flush_dcache_pte(*pte);
> > } while (pte++, addr += PAGE_SIZE, addr != end);
> > }
> > @@ -983,11 +987,6 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
> > return kvm_vcpu_dabt_iswrite(vcpu);
> > }
> >
> > -static bool kvm_is_device_pfn(unsigned long pfn)
> > -{
> > - return !pfn_valid(pfn);
> > -}
> > -
> > static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
> > unsigned long size, bool uncached)
> > {
> > --
> > 1.9.1
> >
>
More information about the kernel-team
mailing list