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. */ |
