[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm, vt-d: Add memory cache-attribute pinning domctl for HVM
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |