[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen staging] x86/hvm/ioreq: allow ioreq servers to use HVM_PARAM_[BUF]IOREQ_PFN



commit 3486f398a3ddea81ea8c67be981ce31d52036b3a
Author:     Paul Durrant <paul.durrant@xxxxxxxxxx>
AuthorDate: Tue Oct 9 09:25:48 2018 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Oct 19 13:41:55 2018 +0100

    x86/hvm/ioreq: allow ioreq servers to use HVM_PARAM_[BUF]IOREQ_PFN
    
    Since commit 2c257bd6 "x86/hvm: remove default ioreq server (again)" the
    GFNs allocated by the toolstack and set in HVM_PARAM_IOREQ_PFN and
    HVM_PARAM_BUFIOREQ_PFN have been unused. This patch allows them to be used
    by (non-default) ioreq servers.
    
    While in the area, also make sure HVM_PARAM_[BUF]IOREQ_PFN can only be set
    once. These parameters should have always been in the 'set once' category
    but this has, so far, not been enforced.
    
    NOTE: This fixes a compatibility issue. A guest created on a version of
          Xen that pre-dates the initial ioreq server implementation and then
          migrated in will currently fail to resume because its migration
          stream will lack values for HVM_PARAM_IOREQ_SERVER_PFN and
          HVM_PARAM_NR_IOREQ_SERVER_PAGES *unless* the system has an
          emulator domain that uses direct resource mapping (which depends
          on the version of privcmd it happens to have) in which case it
          will not require use of GFNs for the ioreq server shared
          pages.
    
    Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c           | 13 ++++++++++++
 xen/arch/x86/hvm/ioreq.c         | 46 ++++++++++++++++++++++++++++++++++++++--
 xen/include/asm-x86/hvm/domain.h |  3 ++-
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 4e03e067fa..af13de3745 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4079,6 +4079,8 @@ static int hvm_allow_set_param(struct domain *d,
     {
     /* The following parameters should only be changed once. */
     case HVM_PARAM_VIRIDIAN:
+    case HVM_PARAM_IOREQ_PFN:
+    case HVM_PARAM_BUFIOREQ_PFN:
     case HVM_PARAM_IOREQ_SERVER_PFN:
     case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
     case HVM_PARAM_ALTP2M:
@@ -4250,6 +4252,17 @@ static int hvmop_set_param(
 
         break;
     }
+
+    case HVM_PARAM_IOREQ_PFN:
+    case HVM_PARAM_BUFIOREQ_PFN:
+        BUILD_BUG_ON(HVM_PARAM_IOREQ_PFN >
+                     sizeof(d->arch.hvm.ioreq_gfn.legacy_mask) * 8);
+        BUILD_BUG_ON(HVM_PARAM_BUFIOREQ_PFN >
+                     sizeof(d->arch.hvm.ioreq_gfn.legacy_mask) * 8);
+        if ( a.value )
+            set_bit(a.index, &d->arch.hvm.ioreq_gfn.legacy_mask);
+        break;
+
     case HVM_PARAM_X87_FIP_WIDTH:
         if ( a.value != 0 && a.value != 4 && a.value != 8 )
         {
diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index 3569beaad5..e2e755a8a1 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -237,6 +237,22 @@ bool handle_hvm_io_completion(struct vcpu *v)
     return true;
 }
 
+static gfn_t hvm_alloc_legacy_ioreq_gfn(struct hvm_ioreq_server *s)
+{
+    struct domain *d = s->target;
+    unsigned int i;
+
+    BUILD_BUG_ON(HVM_PARAM_BUFIOREQ_PFN != HVM_PARAM_IOREQ_PFN + 1);
+
+    for ( i = HVM_PARAM_IOREQ_PFN; i <= HVM_PARAM_BUFIOREQ_PFN; i++ )
+    {
+        if ( !test_and_clear_bit(i, &d->arch.hvm.ioreq_gfn.legacy_mask) )
+            return _gfn(d->arch.hvm.params[i]);
+    }
+
+    return INVALID_GFN;
+}
+
 static gfn_t hvm_alloc_ioreq_gfn(struct hvm_ioreq_server *s)
 {
     struct domain *d = s->target;
@@ -248,7 +264,29 @@ static gfn_t hvm_alloc_ioreq_gfn(struct hvm_ioreq_server 
*s)
             return _gfn(d->arch.hvm.ioreq_gfn.base + i);
     }
 
-    return INVALID_GFN;
+    /*
+     * If we are out of 'normal' GFNs then we may still have a 'legacy'
+     * GFN available.
+     */
+    return hvm_alloc_legacy_ioreq_gfn(s);
+}
+
+static bool hvm_free_legacy_ioreq_gfn(struct hvm_ioreq_server *s,
+                                      gfn_t gfn)
+{
+    struct domain *d = s->target;
+    unsigned int i;
+
+    for ( i = HVM_PARAM_IOREQ_PFN; i <= HVM_PARAM_BUFIOREQ_PFN; i++ )
+    {
+        if ( gfn_eq(gfn, _gfn(d->arch.hvm.params[i])) )
+             break;
+    }
+    if ( i > HVM_PARAM_BUFIOREQ_PFN )
+        return false;
+
+    set_bit(i, &d->arch.hvm.ioreq_gfn.legacy_mask);
+    return true;
 }
 
 static void hvm_free_ioreq_gfn(struct hvm_ioreq_server *s, gfn_t gfn)
@@ -258,7 +296,11 @@ static void hvm_free_ioreq_gfn(struct hvm_ioreq_server *s, 
gfn_t gfn)
 
     ASSERT(!gfn_eq(gfn, INVALID_GFN));
 
-    set_bit(i, &d->arch.hvm.ioreq_gfn.mask);
+    if ( !hvm_free_legacy_ioreq_gfn(s, gfn) )
+    {
+        ASSERT(i < sizeof(d->arch.hvm.ioreq_gfn.mask) * 8);
+        set_bit(i, &d->arch.hvm.ioreq_gfn.mask);
+    }
 }
 
 static void hvm_unmap_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 80b2ab041e..3e7331817f 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -95,7 +95,8 @@ struct hvm_domain {
     /* Guest page range used for non-default ioreq servers */
     struct {
         unsigned long base;
-        unsigned long mask;
+        unsigned long mask; /* indexed by GFN minus base */
+        unsigned long legacy_mask; /* indexed by HVM param number */
     } ioreq_gfn;
 
     /* Lock protects all other values in the sub-struct and the default */
--
generated by git-patchbot for /home/xen/git/xen.git#staging

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.