|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/3] xen/arm: p2m: Perform local TLB invalidation on vCPU migration
On Wed, 8 Mar 2017, Julien Grall wrote:
> Hi Stefano,
>
> On 08/03/17 18:58, Stefano Stabellini wrote:
> > On Wed, 8 Mar 2017, Julien Grall wrote:
> > > The ARM architecture allows an OS to have per-CPU page tables, as it
> > > guarantees that TLBs never migrate from one CPU to another.
> > >
> > > This works fine until this is done in a guest. Consider the following
> > > scenario:
> > > - vcpu-0 maps P to V
> > > - vpcu-1 maps P' to V
> > >
> > > If run on the same physical CPU, vcpu-1 can hit in TLBs generated by
> > > vcpu-0 accesses, and access the wrong physical page.
> > >
> > > The solution to this is to keep a per-p2m map of which vCPU ran the last
> > > on each given pCPU and invalidate local TLBs if two vPCUs from the same
> > > VM run on the same CPU.
> > >
> > > Unfortunately it is not possible to allocate per-cpu variable on the
> > > fly. So for now the size of the array is NR_CPUS, this is fine because
> > > we still have space in the structure domain. We may want to add an
> > > helper to allocate per-cpu variable in the future.
> >
> > I think I understand the problem, thanks for the description. I have a
> > question: when a vcpu of a different domain is scheduled on a pcpu,
> > there is no impact on tlb flushes in relation to this problem, is there?
> >
> > For example:
> >
> > 1) vcpu0/domain1 -> pcpu0
> > 2) vcpu0/domain2 -> pcpu0
> > 3) vcpu1/domain1 -> pcpu0
> >
> > In 3) we still need to do the flush_tlb_local(), no matter if 2)
> > happened or not, right?
>
> That's correct. The last vCPU running is stored per p2m domain and belongs to
> the associated domain.
>
> >
> > Also, I have one suggestion below.
>
> [...]
>
> > > diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
> > > index 0899523084..18c57f936e 100644
> > > --- a/xen/include/asm-arm/p2m.h
> > > +++ b/xen/include/asm-arm/p2m.h
> > > @@ -96,6 +96,9 @@ struct p2m_domain {
> > >
> > > /* back pointer to domain */
> > > struct domain *domain;
> > > +
> > > + /* Keeping track on which CPU this p2m was used and for which vCPU */
> > > + uint8_t last_vcpu_ran[NR_CPUS];
> > > };
> >
> > NR_CPUS is usually much larger than cpu_possible_map. I think it would
> > be best to allocate last_vcpu_ran dynamically (after cpu_possible_map is
> > set). It should reduce the memory impact significantly.
>
> Well, I thought about it when I wrote the patch. p2m_domain is currently
> embedded in the structure domain and Xen will always allocate a page even if
> structure is smaller. So for now, static allocation is the best.
Maybe I misunderstood your answer or my suggestion wasn't clear. What
is the problem with something like the following (untested)?
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index bb327da..457038a 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -635,6 +635,7 @@ int arch_domain_create(struct domain *d, unsigned int
domcr_flags,
if ( is_hardware_domain(d) && (rc = domain_vuart_init(d)) )
goto fail;
+ d->arch.p2m.last_vcpu_ran = xmalloc_array(uint8_t, num_possible_cpus());
return 0;
fail:
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 0899523..606a875 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -96,6 +96,8 @@ struct p2m_domain {
/* back pointer to domain */
struct domain *domain;
+
+ uint8_t *last_vcpu_ran;
};
/*
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |