diff options
-rw-r--r-- | drivers/xen/gntdev.c | 34 | ||||
-rw-r--r-- | include/xen/interface/features.h | 6 | ||||
-rw-r--r-- | include/xen/interface/grant_table.h | 7 |
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 | ||
264 | static 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 | |||
255 | static int map_grant_pages(struct grant_map *map) | 272 | static 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. */ |