WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] hvm, vt-d: Add memory cache-attribute pin

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvm, vt-d: Add memory cache-attribute pinning domctl for HVM
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 31 Oct 2007 15:03:43 -0700
Delivery-date: Wed, 31 Oct 2007 15:04:15 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1193146727 -3600
# Node ID b3fa9b58a102c17313da66e4c6150b117f3b3661
# Parent  9d1d27fddc50f65ba69966e33ef5026d0183d0dc
hvm, vt-d: Add memory cache-attribute pinning domctl for HVM
guests. Use this to pin virtual framebuffer VRAM as attribute WB, even
if guest tries to map with other attributes.
Signed-off-by: Disheng Su <disheng.su@xxxxxxxxx>
---
 tools/ioemu/hw/cirrus_vga.c         |    6 ++
 tools/libxc/xc_domain.c             |   15 ++++++
 tools/libxc/xenctrl.h               |    6 ++
 xen/arch/x86/domctl.c               |   19 ++++++++
 xen/arch/x86/hvm/hvm.c              |   20 +++++++-
 xen/arch/x86/hvm/mtrr.c             |   81 ++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm/shadow/multi.c      |   11 ++++
 xen/include/asm-x86/hvm/cacheattr.h |   33 ++++++++++++++
 xen/include/asm-x86/hvm/domain.h    |    7 ++-
 xen/include/public/domctl.h         |   18 ++++++++
 10 files changed, 209 insertions(+), 7 deletions(-)

diff -r 9d1d27fddc50 -r b3fa9b58a102 tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Tue Oct 23 13:47:01 2007 +0100
+++ b/tools/ioemu/hw/cirrus_vga.c       Tue Oct 23 14:38:47 2007 +0100
@@ -2565,6 +2565,12 @@ static void *set_vram_mapping(unsigned l
         return NULL;
     }
 
+    (void)xc_domain_pin_memory_cacheattr(
+        xc_handle, domid,
+        begin >> TARGET_PAGE_BITS,
+        end >> TARGET_PAGE_BITS,
+        XEN_DOMCTL_MEM_CACHEATTR_WB);
+
     vram_pointer = xc_map_foreign_pages(xc_handle, domid,
                                         PROT_READ|PROT_WRITE,
                                         extent_start, nr_extents);
diff -r 9d1d27fddc50 -r b3fa9b58a102 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Tue Oct 23 13:47:01 2007 +0100
+++ b/tools/libxc/xc_domain.c   Tue Oct 23 14:38:47 2007 +0100
@@ -373,6 +373,21 @@ int xc_domain_setmaxmem(int xc_handle,
     domctl.cmd = XEN_DOMCTL_max_mem;
     domctl.domain = (domid_t)domid;
     domctl.u.max_mem.max_memkb = max_memkb;
+    return do_domctl(xc_handle, &domctl);
+}
+
+int xc_domain_pin_memory_cacheattr(int xc_handle,
+                                   uint32_t domid,
+                                   unsigned long start,
+                                   unsigned long end,
+                                   unsigned int type)
+{
+    DECLARE_DOMCTL;
+    domctl.cmd = XEN_DOMCTL_pin_mem_cacheattr;
+    domctl.domain = (domid_t)domid;
+    domctl.u.pin_mem_cacheattr.start = start;
+    domctl.u.pin_mem_cacheattr.end = end;
+    domctl.u.pin_mem_cacheattr.type = type;
     return do_domctl(xc_handle, &domctl);
 }
 
diff -r 9d1d27fddc50 -r b3fa9b58a102 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Oct 23 13:47:01 2007 +0100
+++ b/tools/libxc/xenctrl.h     Tue Oct 23 14:38:47 2007 +0100
@@ -614,6 +614,12 @@ int xc_domain_iomem_permission(int xc_ha
                                unsigned long nr_mfns,
                                uint8_t allow_access);
 
+int xc_domain_pin_memory_cacheattr(int xc_handle,
+                                   uint32_t domid,
+                                   unsigned long start,
+                                   unsigned long end,
+                                   unsigned int type);
+
 unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid,
                                     unsigned long mfn);
 
diff -r 9d1d27fddc50 -r b3fa9b58a102 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Tue Oct 23 13:47:01 2007 +0100
+++ b/xen/arch/x86/domctl.c     Tue Oct 23 14:38:47 2007 +0100
@@ -23,6 +23,7 @@
 #include <asm/irq.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
+#include <asm/hvm/cacheattr.h>
 #include <asm/processor.h>
 #include <xsm/xsm.h>
 #include <xen/list.h>
@@ -678,6 +679,24 @@ long arch_do_domctl(
     }
     break;    
 
+    case XEN_DOMCTL_pin_mem_cacheattr:
+    {
+        struct domain *d;
+
+        ret = -ESRCH;
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d == NULL )
+            break;
+
+        ret = hvm_set_mem_pinned_cacheattr(
+            d, domctl->u.pin_mem_cacheattr.start,
+            domctl->u.pin_mem_cacheattr.end,
+            domctl->u.pin_mem_cacheattr.type);
+
+        rcu_unlock_domain(d);
+    }
+    break;
+
     default:
         ret = -ENOSYS;
         break;
diff -r 9d1d27fddc50 -r b3fa9b58a102 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Oct 23 13:47:01 2007 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Tue Oct 23 14:38:47 2007 +0100
@@ -44,6 +44,7 @@
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/vpt.h>
 #include <asm/hvm/support.h>
+#include <asm/hvm/cacheattr.h>
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
 #include <public/version.h>
@@ -228,20 +229,32 @@ int hvm_domain_initialise(struct domain 
     spin_lock_init(&d->arch.hvm_domain.irq_lock);
     spin_lock_init(&d->arch.hvm_domain.uc_lock);
 
+    hvm_init_cacheattr_region_list(d);
+
     rc = paging_enable(d, PG_refcounts|PG_translate|PG_external);
     if ( rc != 0 )
-        return rc;
+        goto fail1;
 
     vpic_init(d);
 
     rc = vioapic_init(d);
     if ( rc != 0 )
-        return rc;
+        goto fail1;
 
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
 
-    return hvm_funcs.domain_initialise(d);
+    rc = hvm_funcs.domain_initialise(d);
+    if ( rc != 0 )
+        goto fail2;
+
+    return 0;
+
+ fail2:
+    vioapic_deinit(d);
+ fail1:
+    hvm_destroy_cacheattr_region_list(d);
+    return rc;
 }
 
 void hvm_domain_relinquish_resources(struct domain *d)
@@ -259,6 +272,7 @@ void hvm_domain_destroy(struct domain *d
 {
     hvm_funcs.domain_destroy(d);
     vioapic_deinit(d);
+    hvm_destroy_cacheattr_region_list(d);
 }
 
 static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
diff -r 9d1d27fddc50 -r b3fa9b58a102 xen/arch/x86/hvm/mtrr.c
--- a/xen/arch/x86/hvm/mtrr.c   Tue Oct 23 13:47:01 2007 +0100
+++ b/xen/arch/x86/hvm/mtrr.c   Tue Oct 23 14:38:47 2007 +0100
@@ -26,6 +26,7 @@
 #include <stdbool.h>
 #include <asm/mtrr.h>
 #include <asm/hvm/support.h>
+#include <asm/hvm/cacheattr.h>
 
 /* Xen holds the native MTRR MSRs */
 extern struct mtrr_state mtrr_state;
@@ -685,3 +686,83 @@ bool_t mtrr_pat_not_equal(struct vcpu *v
 
     return 0;
 }
+
+void hvm_init_cacheattr_region_list(
+    struct domain *d)
+{
+    INIT_LIST_HEAD(&d->arch.hvm_domain.pinned_cacheattr_ranges);
+}
+
+void hvm_destroy_cacheattr_region_list(
+    struct domain *d)
+{
+    struct list_head *head = &d->arch.hvm_domain.pinned_cacheattr_ranges;
+    struct hvm_mem_pinned_cacheattr_range *range;
+
+    while ( !list_empty(head) )
+    {
+        range = list_entry(head->next,
+                           struct hvm_mem_pinned_cacheattr_range,
+                           list);
+        list_del(&range->list);
+        xfree(range);
+    }
+}
+
+int hvm_get_mem_pinned_cacheattr(
+    struct domain *d,
+    unsigned long guest_fn,
+    unsigned int *type)
+{
+    struct hvm_mem_pinned_cacheattr_range *range;
+
+    *type = 0;
+
+    if ( !is_hvm_domain(d) )
+        return 0;
+
+    list_for_each_entry_rcu ( range,
+                              &d->arch.hvm_domain.pinned_cacheattr_ranges,
+                              list )
+    {
+        if ( (guest_fn >= range->start) && (guest_fn <= range->end) )
+        {
+            *type = range->type;
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+int hvm_set_mem_pinned_cacheattr(
+    struct domain *d,
+    unsigned long gfn_start,
+    unsigned long gfn_end,
+    unsigned int  type)
+{
+    struct hvm_mem_pinned_cacheattr_range *range;
+
+    if ( !((type == PAT_TYPE_UNCACHABLE) ||
+           (type == PAT_TYPE_WRCOMB) ||
+           (type == PAT_TYPE_WRTHROUGH) ||
+           (type == PAT_TYPE_WRPROT) ||
+           (type == PAT_TYPE_WRBACK) ||
+           (type == PAT_TYPE_UC_MINUS)) ||
+         !is_hvm_domain(d) )
+        return -EINVAL;
+
+    range = xmalloc(struct hvm_mem_pinned_cacheattr_range);
+    if ( range == NULL )
+        return -ENOMEM;
+
+    memset(range, 0, sizeof(*range));
+
+    range->start = gfn_start;
+    range->end = gfn_end;
+    range->type = type;
+
+    list_add_rcu(&range->list, &d->arch.hvm_domain.pinned_cacheattr_ranges);
+
+    return 0;
+}
diff -r 9d1d27fddc50 -r b3fa9b58a102 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Tue Oct 23 13:47:01 2007 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c    Tue Oct 23 14:38:47 2007 +0100
@@ -33,6 +33,7 @@
 #include <asm/shadow.h>
 #include <asm/flushtlb.h>
 #include <asm/hvm/hvm.h>
+#include <asm/hvm/cacheattr.h>
 #include <asm/mtrr.h>
 #include "private.h"
 #include "types.h"
@@ -715,8 +716,14 @@ _sh_propagate(struct vcpu *v,
     sflags = gflags & pass_thru_flags;
 
     /* Only change memory caching type for pass-through domain */
-    if ( (level == 1) && !list_empty(&(domain_hvm_iommu(d)->pdev_list)) ) {
-        if ( v->domain->arch.hvm_domain.is_in_uc_mode )
+    if ( (level == 1) && is_hvm_domain(d) &&
+         !list_empty(&(domain_hvm_iommu(d)->pdev_list)) )
+    {
+        unsigned int type;
+        if ( hvm_get_mem_pinned_cacheattr(d, gfn_x(guest_l1e_get_gfn(*gp)),
+                                          &type) )
+            sflags |= pat_type_2_pte_flags(type);
+        else if ( v->domain->arch.hvm_domain.is_in_uc_mode )
             sflags |= pat_type_2_pte_flags(PAT_TYPE_UNCACHABLE);
         else
             sflags |= get_pat_flags(v,
diff -r 9d1d27fddc50 -r b3fa9b58a102 xen/include/asm-x86/hvm/cacheattr.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/hvm/cacheattr.h       Tue Oct 23 14:38:47 2007 +0100
@@ -0,0 +1,33 @@
+#ifndef __HVM_CACHEATTR_H__
+#define __HVM_CACHEATTR_H__
+
+struct hvm_mem_pinned_cacheattr_range {
+    struct list_head list;
+    uint64_t start, end;
+    unsigned int type;
+};
+
+void hvm_init_cacheattr_region_list(
+    struct domain *d);
+void hvm_destroy_cacheattr_region_list(
+    struct domain *d);
+
+/*
+ * To see guest_fn is in the pinned range or not,
+ * if yes, return 1, and set type to value in this range
+ * if no,  return 0, and set type to 0
+ */
+int hvm_get_mem_pinned_cacheattr(
+    struct domain *d,
+    unsigned long guest_fn,
+    unsigned int *type);
+
+
+/* Set pinned caching type for a domain. */
+int hvm_set_mem_pinned_cacheattr(
+    struct domain *d,
+    unsigned long gfn_start,
+    unsigned long gfn_end,
+    unsigned int  type);
+
+#endif /* __HVM_CACHEATTR_H__ */
diff -r 9d1d27fddc50 -r b3fa9b58a102 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h  Tue Oct 23 13:47:01 2007 +0100
+++ b/xen/include/asm-x86/hvm/domain.h  Tue Oct 23 14:38:47 2007 +0100
@@ -61,11 +61,14 @@ struct hvm_domain {
 
     unsigned long          vmx_apic_access_mfn;
 
+    /* Memory ranges with pinned cache attributes. */
+    struct list_head       pinned_cacheattr_ranges;
+
     /* If one of vcpus of this domain is in no_fill_mode or
      * mtrr/pat between vcpus is not the same, set is_in_uc_mode
      */
-    spinlock_t       uc_lock;
-    bool_t           is_in_uc_mode;
+    spinlock_t             uc_lock;
+    bool_t                 is_in_uc_mode;
 
     /* Pass-through */
     struct hvm_iommu       hvm_iommu;
diff -r 9d1d27fddc50 -r b3fa9b58a102 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Tue Oct 23 13:47:01 2007 +0100
+++ b/xen/include/public/domctl.h       Tue Oct 23 14:38:47 2007 +0100
@@ -495,6 +495,23 @@ typedef struct xen_domctl_ioport_mapping
 typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t);
 
+/*
+ * Pin caching type of RAM space for x86 HVM domU.
+ */
+#define XEN_DOMCTL_pin_mem_cacheattr 41
+/* Caching types: these happen to be the same as x86 MTRR/PAT type codes. */
+#define XEN_DOMCTL_MEM_CACHEATTR_UC  0
+#define XEN_DOMCTL_MEM_CACHEATTR_WC  1
+#define XEN_DOMCTL_MEM_CACHEATTR_WT  4
+#define XEN_DOMCTL_MEM_CACHEATTR_WP  5
+#define XEN_DOMCTL_MEM_CACHEATTR_WB  6
+#define XEN_DOMCTL_MEM_CACHEATTR_UCM 7
+struct xen_domctl_pin_mem_cacheattr {
+    uint64_t start, end;
+    unsigned int type; /* XEN_DOMCTL_MEM_CACHEATTR_* */
+};
+typedef struct xen_domctl_pin_mem_cacheattr xen_domctl_pin_mem_cacheattr_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_pin_mem_cacheattr_t);
 
 struct xen_domctl {
     uint32_t cmd;
@@ -529,6 +546,7 @@ struct xen_domctl {
         struct xen_domctl_bind_pt_irq       bind_pt_irq;
         struct xen_domctl_memory_mapping    memory_mapping;
         struct xen_domctl_ioport_mapping    ioport_mapping;
+        struct xen_domctl_pin_mem_cacheattr pin_mem_cacheattr;
         uint8_t                             pad[128];
     } u;
 };

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] hvm, vt-d: Add memory cache-attribute pinning domctl for HVM, Xen patchbot-unstable <=