From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 13/14] KVM: ARM: Handle guest faults in KVM
Date: Mon, 3 Dec 2012 13:06:27 +0000 [thread overview]
Message-ID: <20121203130627.GA20074@mudshark.cambridge.arm.com> (raw)
In-Reply-To: <CANM98qLNMTw5DGBJLPhXrMs_p5mvphxiEisrz4pLnMFpmm_eCQ@mail.gmail.com>
On Fri, Nov 30, 2012 at 09:40:37PM +0000, Christoffer Dall wrote:
> On Mon, Nov 19, 2012 at 10:07 AM, Will Deacon <will.deacon@arm.com> wrote:
> >
> > Why are PIPT caches affected by this? The virtual address is irrelevant.
> >
>
> The comment is slightly misleading, and I'll update it. Just so we're
> clear, this is the culprit:
>
> 1. guest uses page X, containing instruction A
> 2. page X gets swapped out
> 3. host uses page X, containing instruction B
> 4. instruction B enters i-cache at page X's cache line
> 5. page X gets swapped out
> 6. guest swaps page X back in
> 7. guest executes instruction B from cache, should execute instruction A
Ok, that's clearer. Thanks for the explanation.
> The point is that with PIPT we can flush only that page from the
> icache using the host virtual address, as the MMU will do the
> translation on the fly. In the VIPT we have to nuke the whole thing
> (unless we .
Unless we what? Could we flush using the host VA + all virtual aliases
instead?
> >> + * (or another VM) may have used this page at the same virtual address
> >> + * as this guest, and we read incorrect data from the icache. If
> >> + * we're using a PIPT cache, we can invalidate just that page, but if
> >> + * we are using a VIPT cache we need to invalidate the entire icache -
> >> + * damn shame - as written in the ARM ARM (DDI 0406C - Page B3-1384)
> >> + */
> >> + if (icache_is_pipt()) {
> >> + unsigned long hva = gfn_to_hva(kvm, gfn);
> >> + __cpuc_coherent_user_range(hva, hva + PAGE_SIZE);
> >> + } else if (!icache_is_vivt_asid_tagged()) {
> >> + /* any kind of VIPT cache */
> >> + __flush_icache_all();
> >> + }
> >
> > so what if it *is* vivt_asid_tagged? Surely that necessitates nuking the
> > thing, unless it's VMID tagged as well (does that even exist?).
> >
>
> see page B3-1392 in the ARM ARM, if it's vivt_asid_tagged it is also
> vmid tagged.
Great.
> >> + write_fault = false;
> >> + else
> >> + write_fault = true;
> >> +
> >> + if (fault_status == FSC_PERM && !write_fault) {
> >> + kvm_err("Unexpected L2 read permission error\n");
> >> + return -EFAULT;
> >> + }
> >> +
> >> + /* We need minimum second+third level pages */
> >> + ret = mmu_topup_memory_cache(memcache, 2, KVM_NR_MEM_OBJS);
> >> + if (ret)
> >> + return ret;
> >> +
> >> + mmu_seq = vcpu->kvm->mmu_notifier_seq;
> >> + smp_rmb();
> >
> > What's this barrier for and why isn't there a write barrier paired with
> > it?
> >
>
> The read barrier is to ensure that mmu_notifier_seq is read before we
> call gfn_to_pfn_prot (which is essentially get_user_pages), so that we
> don't get a page which is unmapped by an MMU notifier before we grab
> the spinlock that we would never see. I also added a comment
> explaining it in the patch below.
>
> There is a write barrier paired with it, see virt/kvm/kvm_main.c,
> specifically kvm_mmu_notifier_invalidate_page (the spin_unlock), and
> kvm_mmu_notifier_invalidate_range_end.
Ok, so it sounds like a homebrew seqlock implementatiom. Any reason KVM
isn't just using those directly?
Will
WARNING: multiple messages have this Message-ID (diff)
From: Will Deacon <will.deacon@arm.com>
To: Christoffer Dall <c.dall@virtualopensystems.com>
Cc: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"kvmarm@lists.cs.columbia.edu" <kvmarm@lists.cs.columbia.edu>,
Marc Zyngier <Marc.Zyngier@arm.com>,
Marcelo Tosatti <mtosatti@redhat.com>
Subject: Re: [PATCH v4 13/14] KVM: ARM: Handle guest faults in KVM
Date: Mon, 3 Dec 2012 13:06:27 +0000 [thread overview]
Message-ID: <20121203130627.GA20074@mudshark.cambridge.arm.com> (raw)
In-Reply-To: <CANM98qLNMTw5DGBJLPhXrMs_p5mvphxiEisrz4pLnMFpmm_eCQ@mail.gmail.com>
On Fri, Nov 30, 2012 at 09:40:37PM +0000, Christoffer Dall wrote:
> On Mon, Nov 19, 2012 at 10:07 AM, Will Deacon <will.deacon@arm.com> wrote:
> >
> > Why are PIPT caches affected by this? The virtual address is irrelevant.
> >
>
> The comment is slightly misleading, and I'll update it. Just so we're
> clear, this is the culprit:
>
> 1. guest uses page X, containing instruction A
> 2. page X gets swapped out
> 3. host uses page X, containing instruction B
> 4. instruction B enters i-cache at page X's cache line
> 5. page X gets swapped out
> 6. guest swaps page X back in
> 7. guest executes instruction B from cache, should execute instruction A
Ok, that's clearer. Thanks for the explanation.
> The point is that with PIPT we can flush only that page from the
> icache using the host virtual address, as the MMU will do the
> translation on the fly. In the VIPT we have to nuke the whole thing
> (unless we .
Unless we what? Could we flush using the host VA + all virtual aliases
instead?
> >> + * (or another VM) may have used this page at the same virtual address
> >> + * as this guest, and we read incorrect data from the icache. If
> >> + * we're using a PIPT cache, we can invalidate just that page, but if
> >> + * we are using a VIPT cache we need to invalidate the entire icache -
> >> + * damn shame - as written in the ARM ARM (DDI 0406C - Page B3-1384)
> >> + */
> >> + if (icache_is_pipt()) {
> >> + unsigned long hva = gfn_to_hva(kvm, gfn);
> >> + __cpuc_coherent_user_range(hva, hva + PAGE_SIZE);
> >> + } else if (!icache_is_vivt_asid_tagged()) {
> >> + /* any kind of VIPT cache */
> >> + __flush_icache_all();
> >> + }
> >
> > so what if it *is* vivt_asid_tagged? Surely that necessitates nuking the
> > thing, unless it's VMID tagged as well (does that even exist?).
> >
>
> see page B3-1392 in the ARM ARM, if it's vivt_asid_tagged it is also
> vmid tagged.
Great.
> >> + write_fault = false;
> >> + else
> >> + write_fault = true;
> >> +
> >> + if (fault_status == FSC_PERM && !write_fault) {
> >> + kvm_err("Unexpected L2 read permission error\n");
> >> + return -EFAULT;
> >> + }
> >> +
> >> + /* We need minimum second+third level pages */
> >> + ret = mmu_topup_memory_cache(memcache, 2, KVM_NR_MEM_OBJS);
> >> + if (ret)
> >> + return ret;
> >> +
> >> + mmu_seq = vcpu->kvm->mmu_notifier_seq;
> >> + smp_rmb();
> >
> > What's this barrier for and why isn't there a write barrier paired with
> > it?
> >
>
> The read barrier is to ensure that mmu_notifier_seq is read before we
> call gfn_to_pfn_prot (which is essentially get_user_pages), so that we
> don't get a page which is unmapped by an MMU notifier before we grab
> the spinlock that we would never see. I also added a comment
> explaining it in the patch below.
>
> There is a write barrier paired with it, see virt/kvm/kvm_main.c,
> specifically kvm_mmu_notifier_invalidate_page (the spin_unlock), and
> kvm_mmu_notifier_invalidate_range_end.
Ok, so it sounds like a homebrew seqlock implementatiom. Any reason KVM
isn't just using those directly?
Will
next prev parent reply other threads:[~2012-12-03 13:06 UTC|newest]
Thread overview: 130+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-10 15:42 [PATCH v4 00/14] KVM/ARM Implementation Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-10 15:42 ` [PATCH v4 01/14] ARM: Add page table and page defines needed by KVM Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-19 14:14 ` Will Deacon
2012-11-19 14:14 ` Will Deacon
2012-11-29 15:57 ` Christoffer Dall
2012-11-29 15:57 ` Christoffer Dall
2012-11-30 11:46 ` Will Deacon
2012-11-30 11:46 ` Will Deacon
2012-11-30 15:54 ` Christoffer Dall
2012-11-30 15:54 ` Christoffer Dall
2012-11-10 15:42 ` [PATCH v4 02/14] ARM: Section based HYP idmap Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-19 14:16 ` Will Deacon
2012-11-19 14:16 ` Will Deacon
2012-11-29 18:59 ` Christoffer Dall
2012-11-29 18:59 ` Christoffer Dall
2012-11-30 10:58 ` Will Deacon
2012-11-30 10:58 ` Will Deacon
2012-11-30 16:29 ` Christoffer Dall
2012-11-30 16:29 ` Christoffer Dall
2012-11-19 14:25 ` Rob Herring
2012-11-19 14:25 ` Rob Herring
2012-11-10 15:42 ` [PATCH v4 03/14] ARM: Factor out cpuid implementor and part number Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-19 14:21 ` Will Deacon
2012-11-19 14:21 ` Will Deacon
2012-11-29 21:38 ` Christoffer Dall
2012-11-29 21:38 ` Christoffer Dall
2012-11-30 10:21 ` Will Deacon
2012-11-30 10:21 ` Will Deacon
2012-11-30 15:42 ` Christoffer Dall
2012-11-30 15:42 ` Christoffer Dall
2012-11-10 15:42 ` [PATCH v4 04/14] KVM: ARM: Initial skeleton to compile KVM support Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-19 14:41 ` Will Deacon
2012-11-19 14:41 ` Will Deacon
2012-11-29 22:36 ` Christoffer Dall
2012-11-29 22:36 ` Christoffer Dall
2012-11-10 15:42 ` [PATCH v4 05/14] KVM: ARM: Hypervisor inititalization Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-19 14:51 ` Will Deacon
2012-11-19 14:51 ` Will Deacon
2012-11-19 15:27 ` Cyril Chemparathy
2012-11-19 15:27 ` Cyril Chemparathy
2012-11-30 5:41 ` Christoffer Dall
2012-11-30 5:41 ` Christoffer Dall
2012-11-10 15:42 ` [PATCH v4 06/14] KVM: ARM: Memory virtualization setup Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-19 14:53 ` Will Deacon
2012-11-19 14:53 ` Will Deacon
2012-11-19 15:05 ` Christoffer Dall
2012-11-19 15:05 ` Christoffer Dall
2012-11-10 15:42 ` [PATCH v4 07/14] KVM: ARM: Inject IRQs and FIQs from userspace Christoffer Dall
2012-11-10 15:42 ` Christoffer Dall
2012-11-19 14:55 ` Will Deacon
2012-11-19 14:55 ` Will Deacon
2012-11-19 15:04 ` Christoffer Dall
2012-11-19 15:04 ` Christoffer Dall
2012-11-19 15:26 ` Will Deacon
2012-11-19 15:26 ` Will Deacon
2012-11-19 16:09 ` Christoffer Dall
2012-11-19 16:09 ` Christoffer Dall
2012-11-19 16:21 ` Will Deacon
2012-11-19 16:21 ` Will Deacon
2012-11-30 6:13 ` Christoffer Dall
2012-11-30 6:13 ` Christoffer Dall
2012-11-10 15:43 ` [PATCH v4 08/14] KVM: ARM: World-switch implementation Christoffer Dall
2012-11-10 15:43 ` Christoffer Dall
2012-11-19 14:57 ` Will Deacon
2012-11-19 14:57 ` Will Deacon
2012-11-30 6:37 ` Christoffer Dall
2012-11-30 6:37 ` Christoffer Dall
2012-11-30 15:15 ` Will Deacon
2012-11-30 15:15 ` Will Deacon
2012-11-30 16:47 ` Christoffer Dall
2012-11-30 16:47 ` Christoffer Dall
2012-11-30 17:14 ` Will Deacon
2012-11-30 17:14 ` Will Deacon
2012-11-30 18:49 ` Christoffer Dall
2012-11-30 18:49 ` Christoffer Dall
2012-12-03 10:33 ` Marc Zyngier
2012-12-03 10:33 ` Marc Zyngier
2012-12-03 15:05 ` Christoffer Dall
2012-12-03 15:05 ` Christoffer Dall
2012-11-10 15:43 ` [PATCH v4 09/14] KVM: ARM: Emulation framework and CP15 emulation Christoffer Dall
2012-11-10 15:43 ` Christoffer Dall
2012-11-19 15:01 ` Will Deacon
2012-11-19 15:01 ` Will Deacon
2012-11-19 15:27 ` [kvmarm] " Peter Maydell
2012-11-19 15:27 ` Peter Maydell
2012-11-20 2:18 ` Rusty Russell
2012-11-20 2:18 ` Rusty Russell
2012-11-30 20:22 ` Christoffer Dall
2012-11-30 20:22 ` Christoffer Dall
2012-12-03 11:05 ` Will Deacon
2012-12-03 11:05 ` Will Deacon
2012-12-03 19:09 ` Christoffer Dall
2012-12-03 19:09 ` Christoffer Dall
2012-11-10 15:43 ` [PATCH v4 10/14] KVM: ARM: User space API for getting/setting co-proc registers Christoffer Dall
2012-11-10 15:43 ` Christoffer Dall
2012-11-19 15:02 ` Will Deacon
2012-11-19 15:02 ` Will Deacon
2012-11-30 6:42 ` Christoffer Dall
2012-11-30 6:42 ` Christoffer Dall
2012-11-10 15:43 ` [PATCH v4 11/14] KVM: ARM: Demux CCSIDR in the userspace API Christoffer Dall
2012-11-10 15:43 ` Christoffer Dall
2012-11-19 15:03 ` Will Deacon
2012-11-19 15:03 ` Will Deacon
2012-11-30 6:45 ` Christoffer Dall
2012-11-30 6:45 ` Christoffer Dall
2012-11-10 15:43 ` [PATCH v4 12/14] KVM: ARM: VFP userspace interface Christoffer Dall
2012-11-10 15:43 ` Christoffer Dall
2012-11-10 15:43 ` [PATCH v4 13/14] KVM: ARM: Handle guest faults in KVM Christoffer Dall
2012-11-10 15:43 ` Christoffer Dall
2012-11-19 15:07 ` Will Deacon
2012-11-19 15:07 ` Will Deacon
2012-11-30 21:40 ` Christoffer Dall
2012-11-30 21:40 ` Christoffer Dall
2012-12-03 13:06 ` Will Deacon [this message]
2012-12-03 13:06 ` Will Deacon
2012-12-03 15:02 ` Christoffer Dall
2012-12-03 15:02 ` Christoffer Dall
2012-11-10 15:43 ` [PATCH v4 14/14] KVM: ARM: Handle I/O aborts Christoffer Dall
2012-11-10 15:43 ` Christoffer Dall
2012-11-19 15:09 ` Will Deacon
2012-11-19 15:09 ` Will Deacon
2012-11-30 14:46 ` Dave Martin
2012-11-30 14:46 ` Dave Martin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121203130627.GA20074@mudshark.cambridge.arm.com \
--to=will.deacon@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.