aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/gntdev.c34
-rw-r--r--include/xen/interface/features.h6
-rw-r--r--include/xen/interface/grant_table.h7
3 files changed, 47 insertions, 0 deletions
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index bccc54a80559..20c65771017d 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -244,6 +244,14 @@ static int find_grant_ptes(pte_t *pte, pgtable_t token,
244 BUG_ON(pgnr >= map->count); 244 BUG_ON(pgnr >= map->count);
245 pte_maddr = arbitrary_virt_to_machine(pte).maddr; 245 pte_maddr = arbitrary_virt_to_machine(pte).maddr;
246 246
247 /*
248 * Set the PTE as special to force get_user_pages_fast() fall
249 * back to the slow path. If this is not supported as part of
250 * the grant map, it will be done afterwards.
251 */
252 if (xen_feature(XENFEAT_gnttab_map_avail_bits))
253 flags |= (1 << _GNTMAP_guest_avail0);
254
247 gnttab_set_map_op(&map->map_ops[pgnr], pte_maddr, flags, 255 gnttab_set_map_op(&map->map_ops[pgnr], pte_maddr, flags,
248 map->grants[pgnr].ref, 256 map->grants[pgnr].ref,
249 map->grants[pgnr].domid); 257 map->grants[pgnr].domid);
@@ -252,6 +260,15 @@ static int find_grant_ptes(pte_t *pte, pgtable_t token,
252 return 0; 260 return 0;
253} 261}
254 262
263#ifdef CONFIG_X86
264static int set_grant_ptes_as_special(pte_t *pte, pgtable_t token,
265 unsigned long addr, void *data)
266{
267 set_pte_at(current->mm, addr, pte, pte_mkspecial(*pte));
268 return 0;
269}
270#endif
271
255static int map_grant_pages(struct grant_map *map) 272static int map_grant_pages(struct grant_map *map)
256{ 273{
257 int i, err = 0; 274 int i, err = 0;
@@ -840,6 +857,23 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
840 if (err) 857 if (err)
841 goto out_put_map; 858 goto out_put_map;
842 } 859 }
860 } else {
861#ifdef CONFIG_X86
862 /*
863 * If the PTEs were not made special by the grant map
864 * hypercall, do so here.
865 *
866 * This is racy since the mapping is already visible
867 * to userspace but userspace should be well-behaved
868 * enough to not touch it until the mmap() call
869 * returns.
870 */
871 if (!xen_feature(XENFEAT_gnttab_map_avail_bits)) {
872 apply_to_page_range(vma->vm_mm, vma->vm_start,
873 vma->vm_end - vma->vm_start,
874 set_grant_ptes_as_special, NULL);
875 }
876#endif
843 } 877 }
844 878
845 return 0; 879 return 0;
diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h
index 131a6ccdba25..6ad3d110bb81 100644
--- a/include/xen/interface/features.h
+++ b/include/xen/interface/features.h
@@ -41,6 +41,12 @@
41/* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */ 41/* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
42#define XENFEAT_mmu_pt_update_preserve_ad 5 42#define XENFEAT_mmu_pt_update_preserve_ad 5
43 43
44/*
45 * If set, GNTTABOP_map_grant_ref honors flags to be placed into guest kernel
46 * available pte bits.
47 */
48#define XENFEAT_gnttab_map_avail_bits 7
49
44/* x86: Does this Xen host support the HVM callback vector type? */ 50/* x86: Does this Xen host support the HVM callback vector type? */
45#define XENFEAT_hvm_callback_vector 8 51#define XENFEAT_hvm_callback_vector 8
46 52
diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h
index bcce56439d64..56806bc90c2f 100644
--- a/include/xen/interface/grant_table.h
+++ b/include/xen/interface/grant_table.h
@@ -526,6 +526,13 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_cache_flush);
526#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) 526#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte)
527 527
528/* 528/*
529 * Bits to be placed in guest kernel available PTE bits (architecture
530 * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).
531 */
532#define _GNTMAP_guest_avail0 (16)
533#define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0)
534
535/*
529 * Values for error status returns. All errors are -ve. 536 * Values for error status returns. All errors are -ve.
530 */ 537 */
531#define GNTST_okay (0) /* Normal return. */ 538#define GNTST_okay (0) /* Normal return. */