From: Avi Kivity <avi@redhat.com>
To: Christoffer Dall <c.dall@virtualopensystems.com>
Cc: android-virt@lists.cs.columbia.edu, kvm@vger.kernel.org
Subject: Re: [PATCH v8 11/15] ARM: KVM: World-switch implementation
Date: Thu, 21 Jun 2012 11:13:45 +0300 [thread overview]
Message-ID: <4FE2D7B9.9060401@redhat.com> (raw)
In-Reply-To: <CANM98qKf8z0J3hp0yUhuQ1cmAH8VvJCo_+M9_QAS-XiAdwP_XQ@mail.gmail.com>
On 06/20/2012 07:40 AM, Christoffer Dall wrote:
>
>>>
>>> cpu0 cpu1
>>> (vmid=0, gen=1) (gen=0)
>>> -------------------------- ----------------------
>>> gen == global_gen, return
>>>
>>> gen != global_gen
>>> increment global_gen
>>> smp_call_function
>>> reset_vm_context
>>> vmid=0
>>>
>>> enter with vmid=0 enter with vmid=0
>>
>> I can't see how the scenario above can happen. First, no-one can run
>> with vmid 0 - it is reserved for the host. If we bump global_gen on
>> cpuN, then since we do smp_call_function(x, x, wait=1) we are now sure
>> that after this call, all cpus(N-1) potentially being inside a VM will
>> have exited, called reset_vm_context, but before they can re-enter
>> into the guest, they will call update_vttbr, and if their generation
>> counter differs from global_gen, they will try to grab that spinlock
>> and everything should happen in order.
>>
>
> the whole vmid=0 confused me a bit. The point is since we moved the
> generation check outside the spin_lock we have to re-check, I see:
In fact I think the problem occured with the original code as well. The
problem is that the check is not atomic wrt guest entry, so
spin_lock
check/update
spin_unlock
enter guest
has a hole between spin_unlock and guest entry.
>
> /**
> + * check_new_vmid_gen - check that the VMID is still valid
> + * @kvm: The VM's VMID to checkt
> + *
> + * return true if there is a new generation of VMIDs being used
> + *
> + * The hardware supports only 256 values with the value zero reserved for the
> + * host, so we check if an assigned value belongs to a previous generation,
> + * which which requires us to assign a new value. If we're the first to use a
> + * VMID for the new generation, we must flush necessary caches and TLBs on all
> + * CPUs.
> + */
> +static bool check_new_vmid_gen(struct kvm *kvm)
> +{
> + if (likely(kvm->arch.vmid_gen == atomic64_read(&kvm_vmid_gen)))
> + return;
> +}
> +
> +/**
> * update_vttbr - Update the VTTBR with a valid VMID before the guest runs
> * @kvm The guest that we are about to run
> *
> @@ -324,15 +342,7 @@ static void update_vttbr(struct kvm *kvm)
> {
> phys_addr_t pgd_phys;
>
> - /*
> - * Check that the VMID is still valid.
> - * (The hardware supports only 256 values with the value zero
> - * reserved for the host, so we check if an assigned value belongs to
> - * a previous generation, which which requires us to assign a new
> - * value. If we're the first to use a VMID for the new generation,
> - * we must flush necessary caches and TLBs on all CPUs.)
> - */
> - if (likely(kvm->arch.vmid_gen == atomic64_read(&kvm_vmid_gen)))
> + if (!check_new_vmid_gen(kvm))
> return;
>
> spin_lock(&kvm_vmid_lock);
> @@ -504,6 +514,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu
> *vcpu, struct kvm_run *run)
> */
> preempt_disable();
> local_irq_disable();
> +
> + if (check_new_vmid_gen(kvm)) {
> + local_irq_enable();
> + preempt_enable();
> + continue;
> + }
> +
I see the same race with signals. Your signal_pending() check needs to
be after the local_irq_disable(), otherwise we can enter a guest with a
pending signal.
Better place the signal check before the vmid_gen check, to avoid the
possibility of a a signal being held up by other guests.
--
error compiling committee.c: too many arguments to function
next prev parent reply other threads:[~2012-06-21 8:13 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-15 19:06 [PATCH v8 00/15] KVM/ARM Implementation Christoffer Dall
2012-06-15 19:06 ` [PATCH v8 01/15] ARM: add mem_type prot_pte accessor Christoffer Dall
2012-06-15 19:07 ` [PATCH v8 02/15] KVM: use KVM_CAP_IRQ_ROUTING to protect the routing related code Christoffer Dall
2012-06-18 13:06 ` Avi Kivity
2012-06-15 19:07 ` [PATCH v8 03/15] KVM: Introduce __KVM_HAVE_IRQ_LINE Christoffer Dall
2012-06-18 13:07 ` Avi Kivity
2012-06-15 19:07 ` [PATCH v8 04/15] KVM: Guard mmu_notifier specific code with CONFIG_MMU_NOTIFIER Christoffer Dall
2012-06-18 13:08 ` Avi Kivity
2012-06-18 17:47 ` Christoffer Dall
2012-06-19 8:37 ` Avi Kivity
2012-06-28 21:28 ` Marcelo Tosatti
2012-06-15 19:07 ` [PATCH v8 05/15] ARM: KVM: Initial skeleton to compile KVM support Christoffer Dall
2012-06-15 19:07 ` [PATCH v8 06/15] ARM: KVM: Hypervisor identity mapping Christoffer Dall
2012-06-18 13:12 ` Avi Kivity
2012-06-18 17:55 ` Christoffer Dall
2012-06-19 8:38 ` Avi Kivity
2012-06-15 19:07 ` [PATCH v8 07/15] ARM: KVM: Hypervisor inititalization Christoffer Dall
2012-06-28 22:35 ` Marcelo Tosatti
2012-06-28 22:53 ` Christoffer Dall
2012-06-29 1:07 ` Marcelo Tosatti
2012-06-15 19:08 ` [PATCH v8 08/15] ARM: KVM: Module unloading support Christoffer Dall
2012-06-15 19:08 ` [PATCH v8 09/15] ARM: KVM: Memory virtualization setup Christoffer Dall
2012-06-21 12:29 ` Gleb Natapov
2012-06-21 19:48 ` Christoffer Dall
2012-06-28 22:34 ` Marcelo Tosatti
2012-06-28 22:51 ` Christoffer Dall
2012-06-15 19:08 ` [PATCH v8 10/15] ARM: KVM: Inject IRQs and FIQs from userspace Christoffer Dall
2012-06-18 13:32 ` Avi Kivity
2012-06-18 20:56 ` Christoffer Dall
2012-06-19 8:49 ` Avi Kivity
2012-06-20 3:17 ` Christoffer Dall
2012-06-15 19:08 ` [PATCH v8 11/15] ARM: KVM: World-switch implementation Christoffer Dall
2012-06-18 13:41 ` Avi Kivity
2012-06-18 22:05 ` Christoffer Dall
2012-06-19 9:16 ` Avi Kivity
2012-06-20 3:27 ` Christoffer Dall
2012-06-20 4:40 ` Christoffer Dall
2012-06-21 8:13 ` Avi Kivity [this message]
2012-06-21 17:54 ` Christoffer Dall
2012-07-02 13:07 ` Avi Kivity
2012-06-15 19:08 ` [PATCH v8 12/15] ARM: KVM: Emulation framework and CP15 emulation Christoffer Dall
2012-06-15 19:09 ` [PATCH v8 13/15] ARM: KVM: Handle guest faults in KVM Christoffer Dall
2012-06-18 13:45 ` Avi Kivity
2012-06-18 22:20 ` Christoffer Dall
2012-06-19 9:32 ` Avi Kivity
2012-06-19 10:41 ` Andrea Arcangeli
2012-06-20 15:13 ` Christoffer Dall
2012-06-20 17:49 ` Andrea Arcangeli
2012-06-15 19:09 ` [PATCH v8 14/15] ARM: KVM: Handle I/O aborts Christoffer Dall
2012-06-18 13:48 ` Avi Kivity
2012-06-18 22:28 ` Christoffer Dall
2012-06-15 19:09 ` [PATCH v8 15/15] ARM: KVM: Guest wait-for-interrupts (WFI) support Christoffer Dall
2012-06-28 21:49 ` [PATCH v8 00/15] KVM/ARM Implementation Marcelo Tosatti
2012-06-28 22:44 ` Christoffer Dall
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=4FE2D7B9.9060401@redhat.com \
--to=avi@redhat.com \
--cc=android-virt@lists.cs.columbia.edu \
--cc=c.dall@virtualopensystems.com \
--cc=kvm@vger.kernel.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.