diff mbox

[RFC,02/12] x86/np2m: add np2m_flush_eptp()

Message ID 20170718103429.25020-3-sergey.dyasli@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sergey Dyasli July 18, 2017, 10:34 a.m. UTC
The new function finds all np2m objects with the specified eptp and
flushes them. p2m_flush_table_locked() is added in order not to release
the p2m lock after np2m_base check.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
---
 xen/arch/x86/mm/p2m.c     | 34 +++++++++++++++++++++++++++++++---
 xen/include/asm-x86/p2m.h |  2 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

Comments

Egger, Christoph Aug. 1, 2017, 7:55 a.m. UTC | #1
On 18.07.17 12:34, Sergey Dyasli wrote:
> The new function finds all np2m objects with the specified eptp and
> flushes them. p2m_flush_table_locked() is added in order not to release
> the p2m lock after np2m_base check.
> 
> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
> ---
>  xen/arch/x86/mm/p2m.c     | 34 +++++++++++++++++++++++++++++++---
>  xen/include/asm-x86/p2m.h |  2 ++
>  2 files changed, 33 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
> index b8c8bba421..bc330d8f52 100644
> --- a/xen/arch/x86/mm/p2m.c
> +++ b/xen/arch/x86/mm/p2m.c
> @@ -1708,15 +1708,14 @@ p2m_getlru_nestedp2m(struct domain *d, struct p2m_domain *p2m)
>      return p2m;
>  }
>  
> -/* Reset this p2m table to be empty */
>  static void
> -p2m_flush_table(struct p2m_domain *p2m)
> +p2m_flush_table_locked(struct p2m_domain *p2m)
>  {
>      struct page_info *top, *pg;
>      struct domain *d = p2m->domain;
>      mfn_t mfn;
>  
> -    p2m_lock(p2m);
> +    ASSERT(p2m_locked_by_me(p2m));
>  
>      /*
>       * "Host" p2m tables can have shared entries &c that need a bit more care
> @@ -1756,6 +1755,14 @@ p2m_flush_table(struct p2m_domain *p2m)
>      p2m_unlock(p2m);
>  }
>  
> +/* Reset this p2m table to be empty */
> +static void
> +p2m_flush_table(struct p2m_domain *p2m)
> +{
> +    p2m_lock(p2m);
> +    p2m_flush_table_locked(p2m);
> +}
> +
>  void
>  p2m_flush(struct vcpu *v, struct p2m_domain *p2m)
>  {
> @@ -1773,6 +1780,27 @@ p2m_flush_nestedp2m(struct domain *d)
>          p2m_flush_table(d->arch.nested_p2m[i]);
>  }
>  
> +void np2m_flush_eptp(struct vcpu *v, unsigned long eptp)
> +{
> +    struct domain *d = v->domain;
> +    struct p2m_domain *p2m;
> +    unsigned int i;
> +
> +    eptp &= ~(0xfffull);
> +
> +    nestedp2m_lock(d);
> +    for ( i = 0; i < MAX_NESTEDP2M; i++ )
> +    {
> +        p2m = d->arch.nested_p2m[i];
> +        p2m_lock(p2m);
> +        if ( p2m->np2m_base == eptp )
> +            p2m_flush_table_locked(p2m);
> +        else
> +            p2m_unlock(p2m);
> +    }
> +    nestedp2m_unlock(d);
> +}
> +

What exactly is eptp specific in this function ?

Christoph


>  static void assign_np2m(struct vcpu *v, struct p2m_domain *p2m)
>  {
>      struct nestedvcpu *nv = &vcpu_nestedhvm(v);
> diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
> index 9086bb35dc..0e39999387 100644
> --- a/xen/include/asm-x86/p2m.h
> +++ b/xen/include/asm-x86/p2m.h
> @@ -779,6 +779,8 @@ int p2m_pt_handle_deferred_changes(uint64_t gpa);
>  void p2m_flush(struct vcpu *v, struct p2m_domain *p2m);
>  /* Flushes all nested p2m tables */
>  void p2m_flush_nestedp2m(struct domain *d);
> +/* Flushes all np2m objects with the specified eptp */
> +void np2m_flush_eptp(struct vcpu *v, unsigned long eptp);
>  
>  void nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
>      l1_pgentry_t *p, l1_pgentry_t new, unsigned int level);
> 

Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B
Sergey Dyasli Aug. 3, 2017, 2:18 p.m. UTC | #2
On Tue, 2017-08-01 at 09:55 +0200, Egger, Christoph wrote:
> On 18.07.17 12:34, Sergey Dyasli wrote:

> > The new function finds all np2m objects with the specified eptp and

> > flushes them. p2m_flush_table_locked() is added in order not to release

> > the p2m lock after np2m_base check.

> > 

> > Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>

> > ---

> >  xen/arch/x86/mm/p2m.c     | 34 +++++++++++++++++++++++++++++++---

> >  xen/include/asm-x86/p2m.h |  2 ++

> >  2 files changed, 33 insertions(+), 3 deletions(-)

> > 

> > diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c

> > index b8c8bba421..bc330d8f52 100644

> > --- a/xen/arch/x86/mm/p2m.c

> > +++ b/xen/arch/x86/mm/p2m.c

> > @@ -1708,15 +1708,14 @@ p2m_getlru_nestedp2m(struct domain *d, struct p2m_domain *p2m)

> >      return p2m;

> >  }

> >  

> > -/* Reset this p2m table to be empty */

> >  static void

> > -p2m_flush_table(struct p2m_domain *p2m)

> > +p2m_flush_table_locked(struct p2m_domain *p2m)

> >  {

> >      struct page_info *top, *pg;

> >      struct domain *d = p2m->domain;

> >      mfn_t mfn;

> >  

> > -    p2m_lock(p2m);

> > +    ASSERT(p2m_locked_by_me(p2m));

> >  

> >      /*

> >       * "Host" p2m tables can have shared entries &c that need a bit more care

> > @@ -1756,6 +1755,14 @@ p2m_flush_table(struct p2m_domain *p2m)

> >      p2m_unlock(p2m);

> >  }

> >  

> > +/* Reset this p2m table to be empty */

> > +static void

> > +p2m_flush_table(struct p2m_domain *p2m)

> > +{

> > +    p2m_lock(p2m);

> > +    p2m_flush_table_locked(p2m);

> > +}

> > +

> >  void

> >  p2m_flush(struct vcpu *v, struct p2m_domain *p2m)

> >  {

> > @@ -1773,6 +1780,27 @@ p2m_flush_nestedp2m(struct domain *d)

> >          p2m_flush_table(d->arch.nested_p2m[i]);

> >  }

> >  

> > +void np2m_flush_eptp(struct vcpu *v, unsigned long eptp)

> > +{

> > +    struct domain *d = v->domain;

> > +    struct p2m_domain *p2m;

> > +    unsigned int i;

> > +

> > +    eptp &= ~(0xfffull);

> > +

> > +    nestedp2m_lock(d);

> > +    for ( i = 0; i < MAX_NESTEDP2M; i++ )

> > +    {

> > +        p2m = d->arch.nested_p2m[i];

> > +        p2m_lock(p2m);

> > +        if ( p2m->np2m_base == eptp )

> > +            p2m_flush_table_locked(p2m);

> > +        else

> > +            p2m_unlock(p2m);

> > +    }

> > +    nestedp2m_unlock(d);

> > +}

> > +

> 

> What exactly is eptp specific in this function ?


Yes, good point. I seem to be too focused on Intel. The correct parameter
name should be np2m_base, of course.

> >  static void assign_np2m(struct vcpu *v, struct p2m_domain *p2m)

> >  {

> >      struct nestedvcpu *nv = &vcpu_nestedhvm(v);

> > diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h

> > index 9086bb35dc..0e39999387 100644

> > --- a/xen/include/asm-x86/p2m.h

> > +++ b/xen/include/asm-x86/p2m.h

> > @@ -779,6 +779,8 @@ int p2m_pt_handle_deferred_changes(uint64_t gpa);

> >  void p2m_flush(struct vcpu *v, struct p2m_domain *p2m);

> >  /* Flushes all nested p2m tables */

> >  void p2m_flush_nestedp2m(struct domain *d);

> > +/* Flushes all np2m objects with the specified eptp */

> > +void np2m_flush_eptp(struct vcpu *v, unsigned long eptp);

> >  

> >  void nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,

> >      l1_pgentry_t *p, l1_pgentry_t new, unsigned int level);

> > 

> 

> Amazon Development Center Germany GmbH

> Berlin - Dresden - Aachen

> main office: Krausenstr. 38, 10117 Berlin

> Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger

> Ust-ID: DE289237879

> Eingetragen am Amtsgericht Charlottenburg HRB 149173 B

-- 
Thanks,
Sergey
Jan Beulich Aug. 3, 2017, 2:40 p.m. UTC | #3
>>> Sergey Dyasli <sergey.dyasli@citrix.com> 08/03/17 4:20 PM >>>
>On Tue, 2017-08-01 at 09:55 +0200, Egger, Christoph wrote:
>> On 18.07.17 12:34, Sergey Dyasli wrote:
>> > @@ -1773,6 +1780,27 @@ p2m_flush_nestedp2m(struct domain *d)
>> >          p2m_flush_table(d->arch.nested_p2m[i]);
>> >  }
>> >  
>> > +void np2m_flush_eptp(struct vcpu *v, unsigned long eptp)
>> > +{
>> > +    struct domain *d = v->domain;
>> > +    struct p2m_domain *p2m;
>> > +    unsigned int i;
>> > +
>> > +    eptp &= ~(0xfffull);
>> > +
>> > +    nestedp2m_lock(d);
>> > +    for ( i = 0; i < MAX_NESTEDP2M; i++ )
>> > +    {
>> > +        p2m = d->arch.nested_p2m[i];
>> > +        p2m_lock(p2m);
>> > +        if ( p2m->np2m_base == eptp )
>> > +            p2m_flush_table_locked(p2m);
>> > +        else
>> > +            p2m_unlock(p2m);
>> > +    }
>> > +    nestedp2m_unlock(d);
>> > +}
>> > +
>> 
>> What exactly is eptp specific in this function ?
>
>Yes, good point. I seem to be too focused on Intel. The correct parameter
>name should be np2m_base, of course.

And (at the risk of stating the obvious) the function name shouldn't include
"ept" then either.

Jan
George Dunlap Aug. 28, 2017, 4:08 p.m. UTC | #4
On 07/18/2017 11:34 AM, Sergey Dyasli wrote:
> The new function finds all np2m objects with the specified eptp and
> flushes them. p2m_flush_table_locked() is added in order not to release
> the p2m lock after np2m_base check.
> 
> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>

This patch looks plausible except for...

> ---
>  xen/arch/x86/mm/p2m.c     | 34 +++++++++++++++++++++++++++++++---
>  xen/include/asm-x86/p2m.h |  2 ++
>  2 files changed, 33 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
> index b8c8bba421..bc330d8f52 100644
> --- a/xen/arch/x86/mm/p2m.c
> +++ b/xen/arch/x86/mm/p2m.c
> @@ -1708,15 +1708,14 @@ p2m_getlru_nestedp2m(struct domain *d, struct p2m_domain *p2m)
>      return p2m;
>  }
>  
> -/* Reset this p2m table to be empty */
>  static void
> -p2m_flush_table(struct p2m_domain *p2m)
> +p2m_flush_table_locked(struct p2m_domain *p2m)
>  {
>      struct page_info *top, *pg;
>      struct domain *d = p2m->domain;
>      mfn_t mfn;
>  
> -    p2m_lock(p2m);
> +    ASSERT(p2m_locked_by_me(p2m));
>  
>      /*
>       * "Host" p2m tables can have shared entries &c that need a bit more care
> @@ -1756,6 +1755,14 @@ p2m_flush_table(struct p2m_domain *p2m)
>      p2m_unlock(p2m);

...this.  Why on earth would we unlock this at the end of the function,
instead of letting the caller do it?

If we were to do that, at very least it should be called
"p2m_flush_and_unlock_table()".  But I think we just want to leave the
unlock out, because...

>  }
>  
> +/* Reset this p2m table to be empty */
> +static void
> +p2m_flush_table(struct p2m_domain *p2m)
> +{
> +    p2m_lock(p2m);
> +    p2m_flush_table_locked(p2m);

..this looks wrong -- a balanced lock/unlock is easier to verify, and...

> +}
> +
>  void
>  p2m_flush(struct vcpu *v, struct p2m_domain *p2m)
>  {
> @@ -1773,6 +1780,27 @@ p2m_flush_nestedp2m(struct domain *d)
>          p2m_flush_table(d->arch.nested_p2m[i]);
>  }
>  
> +void np2m_flush_eptp(struct vcpu *v, unsigned long eptp)
> +{
> +    struct domain *d = v->domain;
> +    struct p2m_domain *p2m;
> +    unsigned int i;
> +
> +    eptp &= ~(0xfffull);
> +
> +    nestedp2m_lock(d);
> +    for ( i = 0; i < MAX_NESTEDP2M; i++ )
> +    {
> +        p2m = d->arch.nested_p2m[i];
> +        p2m_lock(p2m);
> +        if ( p2m->np2m_base == eptp )
> +            p2m_flush_table_locked(p2m);
> +        else
> +            p2m_unlock(p2m);

...here we have essentially a pointless 'else'.  Lock/unlock around the
whole conditional would make much more sense.

 -George
diff mbox

Patch

diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index b8c8bba421..bc330d8f52 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1708,15 +1708,14 @@  p2m_getlru_nestedp2m(struct domain *d, struct p2m_domain *p2m)
     return p2m;
 }
 
-/* Reset this p2m table to be empty */
 static void
-p2m_flush_table(struct p2m_domain *p2m)
+p2m_flush_table_locked(struct p2m_domain *p2m)
 {
     struct page_info *top, *pg;
     struct domain *d = p2m->domain;
     mfn_t mfn;
 
-    p2m_lock(p2m);
+    ASSERT(p2m_locked_by_me(p2m));
 
     /*
      * "Host" p2m tables can have shared entries &c that need a bit more care
@@ -1756,6 +1755,14 @@  p2m_flush_table(struct p2m_domain *p2m)
     p2m_unlock(p2m);
 }
 
+/* Reset this p2m table to be empty */
+static void
+p2m_flush_table(struct p2m_domain *p2m)
+{
+    p2m_lock(p2m);
+    p2m_flush_table_locked(p2m);
+}
+
 void
 p2m_flush(struct vcpu *v, struct p2m_domain *p2m)
 {
@@ -1773,6 +1780,27 @@  p2m_flush_nestedp2m(struct domain *d)
         p2m_flush_table(d->arch.nested_p2m[i]);
 }
 
+void np2m_flush_eptp(struct vcpu *v, unsigned long eptp)
+{
+    struct domain *d = v->domain;
+    struct p2m_domain *p2m;
+    unsigned int i;
+
+    eptp &= ~(0xfffull);
+
+    nestedp2m_lock(d);
+    for ( i = 0; i < MAX_NESTEDP2M; i++ )
+    {
+        p2m = d->arch.nested_p2m[i];
+        p2m_lock(p2m);
+        if ( p2m->np2m_base == eptp )
+            p2m_flush_table_locked(p2m);
+        else
+            p2m_unlock(p2m);
+    }
+    nestedp2m_unlock(d);
+}
+
 static void assign_np2m(struct vcpu *v, struct p2m_domain *p2m)
 {
     struct nestedvcpu *nv = &vcpu_nestedhvm(v);
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 9086bb35dc..0e39999387 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -779,6 +779,8 @@  int p2m_pt_handle_deferred_changes(uint64_t gpa);
 void p2m_flush(struct vcpu *v, struct p2m_domain *p2m);
 /* Flushes all nested p2m tables */
 void p2m_flush_nestedp2m(struct domain *d);
+/* Flushes all np2m objects with the specified eptp */
+void np2m_flush_eptp(struct vcpu *v, unsigned long eptp);
 
 void nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
     l1_pgentry_t *p, l1_pgentry_t new, unsigned int level);