Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.8-rc3 1160 lines 31 kB view raw
1/****************************************************************************** 2 * grant_table.c 3 * 4 * Granting foreign access to our memory reservation. 5 * 6 * Copyright (c) 2005-2006, Christopher Clark 7 * Copyright (c) 2004-2005, K A Fraser 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License version 2 11 * as published by the Free Software Foundation; or, when distributed 12 * separately from the Linux kernel or incorporated into other 13 * software packages, subject to the following license: 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining a copy 16 * of this source file (the "Software"), to deal in the Software without 17 * restriction, including without limitation the rights to use, copy, modify, 18 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 19 * and to permit persons to whom the Software is furnished to do so, subject to 20 * the following conditions: 21 * 22 * The above copyright notice and this permission notice shall be included in 23 * all copies or substantial portions of the Software. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 31 * IN THE SOFTWARE. 32 */ 33 34#define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt 35 36#include <linux/sched.h> 37#include <linux/mm.h> 38#include <linux/slab.h> 39#include <linux/vmalloc.h> 40#include <linux/uaccess.h> 41#include <linux/io.h> 42#include <linux/delay.h> 43#include <linux/hardirq.h> 44#include <linux/workqueue.h> 45 46#include <xen/xen.h> 47#include <xen/interface/xen.h> 48#include <xen/page.h> 49#include <xen/grant_table.h> 50#include <xen/interface/memory.h> 51#include <xen/hvc-console.h> 52#include <xen/swiotlb-xen.h> 53#include <xen/balloon.h> 54#include <asm/xen/hypercall.h> 55#include <asm/xen/interface.h> 56 57#include <asm/pgtable.h> 58#include <asm/sync_bitops.h> 59 60/* External tools reserve first few grant table entries. */ 61#define NR_RESERVED_ENTRIES 8 62#define GNTTAB_LIST_END 0xffffffff 63 64static grant_ref_t **gnttab_list; 65static unsigned int nr_grant_frames; 66static int gnttab_free_count; 67static grant_ref_t gnttab_free_head; 68static DEFINE_SPINLOCK(gnttab_list_lock); 69struct grant_frames xen_auto_xlat_grant_frames; 70 71static union { 72 struct grant_entry_v1 *v1; 73 void *addr; 74} gnttab_shared; 75 76/*This is a structure of function pointers for grant table*/ 77struct gnttab_ops { 78 /* 79 * Mapping a list of frames for storing grant entries. Frames parameter 80 * is used to store grant table address when grant table being setup, 81 * nr_gframes is the number of frames to map grant table. Returning 82 * GNTST_okay means success and negative value means failure. 83 */ 84 int (*map_frames)(xen_pfn_t *frames, unsigned int nr_gframes); 85 /* 86 * Release a list of frames which are mapped in map_frames for grant 87 * entry status. 88 */ 89 void (*unmap_frames)(void); 90 /* 91 * Introducing a valid entry into the grant table, granting the frame of 92 * this grant entry to domain for accessing or transfering. Ref 93 * parameter is reference of this introduced grant entry, domid is id of 94 * granted domain, frame is the page frame to be granted, and flags is 95 * status of the grant entry to be updated. 96 */ 97 void (*update_entry)(grant_ref_t ref, domid_t domid, 98 unsigned long frame, unsigned flags); 99 /* 100 * Stop granting a grant entry to domain for accessing. Ref parameter is 101 * reference of a grant entry whose grant access will be stopped, 102 * readonly is not in use in this function. If the grant entry is 103 * currently mapped for reading or writing, just return failure(==0) 104 * directly and don't tear down the grant access. Otherwise, stop grant 105 * access for this entry and return success(==1). 106 */ 107 int (*end_foreign_access_ref)(grant_ref_t ref, int readonly); 108 /* 109 * Stop granting a grant entry to domain for transfer. Ref parameter is 110 * reference of a grant entry whose grant transfer will be stopped. If 111 * tranfer has not started, just reclaim the grant entry and return 112 * failure(==0). Otherwise, wait for the transfer to complete and then 113 * return the frame. 114 */ 115 unsigned long (*end_foreign_transfer_ref)(grant_ref_t ref); 116 /* 117 * Query the status of a grant entry. Ref parameter is reference of 118 * queried grant entry, return value is the status of queried entry. 119 * Detailed status(writing/reading) can be gotten from the return value 120 * by bit operations. 121 */ 122 int (*query_foreign_access)(grant_ref_t ref); 123}; 124 125struct unmap_refs_callback_data { 126 struct completion completion; 127 int result; 128}; 129 130static const struct gnttab_ops *gnttab_interface; 131 132static int grant_table_version; 133static int grefs_per_grant_frame; 134 135static struct gnttab_free_callback *gnttab_free_callback_list; 136 137static int gnttab_expand(unsigned int req_entries); 138 139#define RPP (PAGE_SIZE / sizeof(grant_ref_t)) 140 141static inline grant_ref_t *__gnttab_entry(grant_ref_t entry) 142{ 143 return &gnttab_list[(entry) / RPP][(entry) % RPP]; 144} 145/* This can be used as an l-value */ 146#define gnttab_entry(entry) (*__gnttab_entry(entry)) 147 148static int get_free_entries(unsigned count) 149{ 150 unsigned long flags; 151 int ref, rc = 0; 152 grant_ref_t head; 153 154 spin_lock_irqsave(&gnttab_list_lock, flags); 155 156 if ((gnttab_free_count < count) && 157 ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) { 158 spin_unlock_irqrestore(&gnttab_list_lock, flags); 159 return rc; 160 } 161 162 ref = head = gnttab_free_head; 163 gnttab_free_count -= count; 164 while (count-- > 1) 165 head = gnttab_entry(head); 166 gnttab_free_head = gnttab_entry(head); 167 gnttab_entry(head) = GNTTAB_LIST_END; 168 169 spin_unlock_irqrestore(&gnttab_list_lock, flags); 170 171 return ref; 172} 173 174static void do_free_callbacks(void) 175{ 176 struct gnttab_free_callback *callback, *next; 177 178 callback = gnttab_free_callback_list; 179 gnttab_free_callback_list = NULL; 180 181 while (callback != NULL) { 182 next = callback->next; 183 if (gnttab_free_count >= callback->count) { 184 callback->next = NULL; 185 callback->fn(callback->arg); 186 } else { 187 callback->next = gnttab_free_callback_list; 188 gnttab_free_callback_list = callback; 189 } 190 callback = next; 191 } 192} 193 194static inline void check_free_callbacks(void) 195{ 196 if (unlikely(gnttab_free_callback_list)) 197 do_free_callbacks(); 198} 199 200static void put_free_entry(grant_ref_t ref) 201{ 202 unsigned long flags; 203 spin_lock_irqsave(&gnttab_list_lock, flags); 204 gnttab_entry(ref) = gnttab_free_head; 205 gnttab_free_head = ref; 206 gnttab_free_count++; 207 check_free_callbacks(); 208 spin_unlock_irqrestore(&gnttab_list_lock, flags); 209} 210 211/* 212 * Following applies to gnttab_update_entry_v1. 213 * Introducing a valid entry into the grant table: 214 * 1. Write ent->domid. 215 * 2. Write ent->frame: 216 * GTF_permit_access: Frame to which access is permitted. 217 * GTF_accept_transfer: Pseudo-phys frame slot being filled by new 218 * frame, or zero if none. 219 * 3. Write memory barrier (WMB). 220 * 4. Write ent->flags, inc. valid type. 221 */ 222static void gnttab_update_entry_v1(grant_ref_t ref, domid_t domid, 223 unsigned long frame, unsigned flags) 224{ 225 gnttab_shared.v1[ref].domid = domid; 226 gnttab_shared.v1[ref].frame = frame; 227 wmb(); 228 gnttab_shared.v1[ref].flags = flags; 229} 230 231/* 232 * Public grant-issuing interface functions 233 */ 234void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, 235 unsigned long frame, int readonly) 236{ 237 gnttab_interface->update_entry(ref, domid, frame, 238 GTF_permit_access | (readonly ? GTF_readonly : 0)); 239} 240EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref); 241 242int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, 243 int readonly) 244{ 245 int ref; 246 247 ref = get_free_entries(1); 248 if (unlikely(ref < 0)) 249 return -ENOSPC; 250 251 gnttab_grant_foreign_access_ref(ref, domid, frame, readonly); 252 253 return ref; 254} 255EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); 256 257static int gnttab_query_foreign_access_v1(grant_ref_t ref) 258{ 259 return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing); 260} 261 262int gnttab_query_foreign_access(grant_ref_t ref) 263{ 264 return gnttab_interface->query_foreign_access(ref); 265} 266EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); 267 268static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly) 269{ 270 u16 flags, nflags; 271 u16 *pflags; 272 273 pflags = &gnttab_shared.v1[ref].flags; 274 nflags = *pflags; 275 do { 276 flags = nflags; 277 if (flags & (GTF_reading|GTF_writing)) 278 return 0; 279 } while ((nflags = sync_cmpxchg(pflags, flags, 0)) != flags); 280 281 return 1; 282} 283 284static inline int _gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) 285{ 286 return gnttab_interface->end_foreign_access_ref(ref, readonly); 287} 288 289int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) 290{ 291 if (_gnttab_end_foreign_access_ref(ref, readonly)) 292 return 1; 293 pr_warn("WARNING: g.e. %#x still in use!\n", ref); 294 return 0; 295} 296EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); 297 298struct deferred_entry { 299 struct list_head list; 300 grant_ref_t ref; 301 bool ro; 302 uint16_t warn_delay; 303 struct page *page; 304}; 305static LIST_HEAD(deferred_list); 306static void gnttab_handle_deferred(unsigned long); 307static DEFINE_TIMER(deferred_timer, gnttab_handle_deferred, 0, 0); 308 309static void gnttab_handle_deferred(unsigned long unused) 310{ 311 unsigned int nr = 10; 312 struct deferred_entry *first = NULL; 313 unsigned long flags; 314 315 spin_lock_irqsave(&gnttab_list_lock, flags); 316 while (nr--) { 317 struct deferred_entry *entry 318 = list_first_entry(&deferred_list, 319 struct deferred_entry, list); 320 321 if (entry == first) 322 break; 323 list_del(&entry->list); 324 spin_unlock_irqrestore(&gnttab_list_lock, flags); 325 if (_gnttab_end_foreign_access_ref(entry->ref, entry->ro)) { 326 put_free_entry(entry->ref); 327 if (entry->page) { 328 pr_debug("freeing g.e. %#x (pfn %#lx)\n", 329 entry->ref, page_to_pfn(entry->page)); 330 __free_page(entry->page); 331 } else 332 pr_info("freeing g.e. %#x\n", entry->ref); 333 kfree(entry); 334 entry = NULL; 335 } else { 336 if (!--entry->warn_delay) 337 pr_info("g.e. %#x still pending\n", entry->ref); 338 if (!first) 339 first = entry; 340 } 341 spin_lock_irqsave(&gnttab_list_lock, flags); 342 if (entry) 343 list_add_tail(&entry->list, &deferred_list); 344 else if (list_empty(&deferred_list)) 345 break; 346 } 347 if (!list_empty(&deferred_list) && !timer_pending(&deferred_timer)) { 348 deferred_timer.expires = jiffies + HZ; 349 add_timer(&deferred_timer); 350 } 351 spin_unlock_irqrestore(&gnttab_list_lock, flags); 352} 353 354static void gnttab_add_deferred(grant_ref_t ref, bool readonly, 355 struct page *page) 356{ 357 struct deferred_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 358 const char *what = KERN_WARNING "leaking"; 359 360 if (entry) { 361 unsigned long flags; 362 363 entry->ref = ref; 364 entry->ro = readonly; 365 entry->page = page; 366 entry->warn_delay = 60; 367 spin_lock_irqsave(&gnttab_list_lock, flags); 368 list_add_tail(&entry->list, &deferred_list); 369 if (!timer_pending(&deferred_timer)) { 370 deferred_timer.expires = jiffies + HZ; 371 add_timer(&deferred_timer); 372 } 373 spin_unlock_irqrestore(&gnttab_list_lock, flags); 374 what = KERN_DEBUG "deferring"; 375 } 376 printk("%s g.e. %#x (pfn %#lx)\n", 377 what, ref, page ? page_to_pfn(page) : -1); 378} 379 380void gnttab_end_foreign_access(grant_ref_t ref, int readonly, 381 unsigned long page) 382{ 383 if (gnttab_end_foreign_access_ref(ref, readonly)) { 384 put_free_entry(ref); 385 if (page != 0) 386 free_page(page); 387 } else 388 gnttab_add_deferred(ref, readonly, 389 page ? virt_to_page(page) : NULL); 390} 391EXPORT_SYMBOL_GPL(gnttab_end_foreign_access); 392 393int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn) 394{ 395 int ref; 396 397 ref = get_free_entries(1); 398 if (unlikely(ref < 0)) 399 return -ENOSPC; 400 gnttab_grant_foreign_transfer_ref(ref, domid, pfn); 401 402 return ref; 403} 404EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer); 405 406void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, 407 unsigned long pfn) 408{ 409 gnttab_interface->update_entry(ref, domid, pfn, GTF_accept_transfer); 410} 411EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref); 412 413static unsigned long gnttab_end_foreign_transfer_ref_v1(grant_ref_t ref) 414{ 415 unsigned long frame; 416 u16 flags; 417 u16 *pflags; 418 419 pflags = &gnttab_shared.v1[ref].flags; 420 421 /* 422 * If a transfer is not even yet started, try to reclaim the grant 423 * reference and return failure (== 0). 424 */ 425 while (!((flags = *pflags) & GTF_transfer_committed)) { 426 if (sync_cmpxchg(pflags, flags, 0) == flags) 427 return 0; 428 cpu_relax(); 429 } 430 431 /* If a transfer is in progress then wait until it is completed. */ 432 while (!(flags & GTF_transfer_completed)) { 433 flags = *pflags; 434 cpu_relax(); 435 } 436 437 rmb(); /* Read the frame number /after/ reading completion status. */ 438 frame = gnttab_shared.v1[ref].frame; 439 BUG_ON(frame == 0); 440 441 return frame; 442} 443 444unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) 445{ 446 return gnttab_interface->end_foreign_transfer_ref(ref); 447} 448EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref); 449 450unsigned long gnttab_end_foreign_transfer(grant_ref_t ref) 451{ 452 unsigned long frame = gnttab_end_foreign_transfer_ref(ref); 453 put_free_entry(ref); 454 return frame; 455} 456EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer); 457 458void gnttab_free_grant_reference(grant_ref_t ref) 459{ 460 put_free_entry(ref); 461} 462EXPORT_SYMBOL_GPL(gnttab_free_grant_reference); 463 464void gnttab_free_grant_references(grant_ref_t head) 465{ 466 grant_ref_t ref; 467 unsigned long flags; 468 int count = 1; 469 if (head == GNTTAB_LIST_END) 470 return; 471 spin_lock_irqsave(&gnttab_list_lock, flags); 472 ref = head; 473 while (gnttab_entry(ref) != GNTTAB_LIST_END) { 474 ref = gnttab_entry(ref); 475 count++; 476 } 477 gnttab_entry(ref) = gnttab_free_head; 478 gnttab_free_head = head; 479 gnttab_free_count += count; 480 check_free_callbacks(); 481 spin_unlock_irqrestore(&gnttab_list_lock, flags); 482} 483EXPORT_SYMBOL_GPL(gnttab_free_grant_references); 484 485int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) 486{ 487 int h = get_free_entries(count); 488 489 if (h < 0) 490 return -ENOSPC; 491 492 *head = h; 493 494 return 0; 495} 496EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references); 497 498int gnttab_empty_grant_references(const grant_ref_t *private_head) 499{ 500 return (*private_head == GNTTAB_LIST_END); 501} 502EXPORT_SYMBOL_GPL(gnttab_empty_grant_references); 503 504int gnttab_claim_grant_reference(grant_ref_t *private_head) 505{ 506 grant_ref_t g = *private_head; 507 if (unlikely(g == GNTTAB_LIST_END)) 508 return -ENOSPC; 509 *private_head = gnttab_entry(g); 510 return g; 511} 512EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference); 513 514void gnttab_release_grant_reference(grant_ref_t *private_head, 515 grant_ref_t release) 516{ 517 gnttab_entry(release) = *private_head; 518 *private_head = release; 519} 520EXPORT_SYMBOL_GPL(gnttab_release_grant_reference); 521 522void gnttab_request_free_callback(struct gnttab_free_callback *callback, 523 void (*fn)(void *), void *arg, u16 count) 524{ 525 unsigned long flags; 526 struct gnttab_free_callback *cb; 527 528 spin_lock_irqsave(&gnttab_list_lock, flags); 529 530 /* Check if the callback is already on the list */ 531 cb = gnttab_free_callback_list; 532 while (cb) { 533 if (cb == callback) 534 goto out; 535 cb = cb->next; 536 } 537 538 callback->fn = fn; 539 callback->arg = arg; 540 callback->count = count; 541 callback->next = gnttab_free_callback_list; 542 gnttab_free_callback_list = callback; 543 check_free_callbacks(); 544out: 545 spin_unlock_irqrestore(&gnttab_list_lock, flags); 546} 547EXPORT_SYMBOL_GPL(gnttab_request_free_callback); 548 549void gnttab_cancel_free_callback(struct gnttab_free_callback *callback) 550{ 551 struct gnttab_free_callback **pcb; 552 unsigned long flags; 553 554 spin_lock_irqsave(&gnttab_list_lock, flags); 555 for (pcb = &gnttab_free_callback_list; *pcb; pcb = &(*pcb)->next) { 556 if (*pcb == callback) { 557 *pcb = callback->next; 558 break; 559 } 560 } 561 spin_unlock_irqrestore(&gnttab_list_lock, flags); 562} 563EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback); 564 565static int grow_gnttab_list(unsigned int more_frames) 566{ 567 unsigned int new_nr_grant_frames, extra_entries, i; 568 unsigned int nr_glist_frames, new_nr_glist_frames; 569 570 BUG_ON(grefs_per_grant_frame == 0); 571 572 new_nr_grant_frames = nr_grant_frames + more_frames; 573 extra_entries = more_frames * grefs_per_grant_frame; 574 575 nr_glist_frames = (nr_grant_frames * grefs_per_grant_frame + RPP - 1) / RPP; 576 new_nr_glist_frames = 577 (new_nr_grant_frames * grefs_per_grant_frame + RPP - 1) / RPP; 578 for (i = nr_glist_frames; i < new_nr_glist_frames; i++) { 579 gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC); 580 if (!gnttab_list[i]) 581 goto grow_nomem; 582 } 583 584 585 for (i = grefs_per_grant_frame * nr_grant_frames; 586 i < grefs_per_grant_frame * new_nr_grant_frames - 1; i++) 587 gnttab_entry(i) = i + 1; 588 589 gnttab_entry(i) = gnttab_free_head; 590 gnttab_free_head = grefs_per_grant_frame * nr_grant_frames; 591 gnttab_free_count += extra_entries; 592 593 nr_grant_frames = new_nr_grant_frames; 594 595 check_free_callbacks(); 596 597 return 0; 598 599grow_nomem: 600 while (i-- > nr_glist_frames) 601 free_page((unsigned long) gnttab_list[i]); 602 return -ENOMEM; 603} 604 605static unsigned int __max_nr_grant_frames(void) 606{ 607 struct gnttab_query_size query; 608 int rc; 609 610 query.dom = DOMID_SELF; 611 612 rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &query, 1); 613 if ((rc < 0) || (query.status != GNTST_okay)) 614 return 4; /* Legacy max supported number of frames */ 615 616 return query.max_nr_frames; 617} 618 619unsigned int gnttab_max_grant_frames(void) 620{ 621 unsigned int xen_max = __max_nr_grant_frames(); 622 static unsigned int boot_max_nr_grant_frames; 623 624 /* First time, initialize it properly. */ 625 if (!boot_max_nr_grant_frames) 626 boot_max_nr_grant_frames = __max_nr_grant_frames(); 627 628 if (xen_max > boot_max_nr_grant_frames) 629 return boot_max_nr_grant_frames; 630 return xen_max; 631} 632EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); 633 634int gnttab_setup_auto_xlat_frames(phys_addr_t addr) 635{ 636 xen_pfn_t *pfn; 637 unsigned int max_nr_gframes = __max_nr_grant_frames(); 638 unsigned int i; 639 void *vaddr; 640 641 if (xen_auto_xlat_grant_frames.count) 642 return -EINVAL; 643 644 vaddr = xen_remap(addr, XEN_PAGE_SIZE * max_nr_gframes); 645 if (vaddr == NULL) { 646 pr_warn("Failed to ioremap gnttab share frames (addr=%pa)!\n", 647 &addr); 648 return -ENOMEM; 649 } 650 pfn = kcalloc(max_nr_gframes, sizeof(pfn[0]), GFP_KERNEL); 651 if (!pfn) { 652 xen_unmap(vaddr); 653 return -ENOMEM; 654 } 655 for (i = 0; i < max_nr_gframes; i++) 656 pfn[i] = XEN_PFN_DOWN(addr) + i; 657 658 xen_auto_xlat_grant_frames.vaddr = vaddr; 659 xen_auto_xlat_grant_frames.pfn = pfn; 660 xen_auto_xlat_grant_frames.count = max_nr_gframes; 661 662 return 0; 663} 664EXPORT_SYMBOL_GPL(gnttab_setup_auto_xlat_frames); 665 666void gnttab_free_auto_xlat_frames(void) 667{ 668 if (!xen_auto_xlat_grant_frames.count) 669 return; 670 kfree(xen_auto_xlat_grant_frames.pfn); 671 xen_unmap(xen_auto_xlat_grant_frames.vaddr); 672 673 xen_auto_xlat_grant_frames.pfn = NULL; 674 xen_auto_xlat_grant_frames.count = 0; 675 xen_auto_xlat_grant_frames.vaddr = NULL; 676} 677EXPORT_SYMBOL_GPL(gnttab_free_auto_xlat_frames); 678 679/** 680 * gnttab_alloc_pages - alloc pages suitable for grant mapping into 681 * @nr_pages: number of pages to alloc 682 * @pages: returns the pages 683 */ 684int gnttab_alloc_pages(int nr_pages, struct page **pages) 685{ 686 int i; 687 int ret; 688 689 ret = alloc_xenballooned_pages(nr_pages, pages); 690 if (ret < 0) 691 return ret; 692 693 for (i = 0; i < nr_pages; i++) { 694#if BITS_PER_LONG < 64 695 struct xen_page_foreign *foreign; 696 697 foreign = kzalloc(sizeof(*foreign), GFP_KERNEL); 698 if (!foreign) { 699 gnttab_free_pages(nr_pages, pages); 700 return -ENOMEM; 701 } 702 set_page_private(pages[i], (unsigned long)foreign); 703#endif 704 SetPagePrivate(pages[i]); 705 } 706 707 return 0; 708} 709EXPORT_SYMBOL(gnttab_alloc_pages); 710 711/** 712 * gnttab_free_pages - free pages allocated by gnttab_alloc_pages() 713 * @nr_pages; number of pages to free 714 * @pages: the pages 715 */ 716void gnttab_free_pages(int nr_pages, struct page **pages) 717{ 718 int i; 719 720 for (i = 0; i < nr_pages; i++) { 721 if (PagePrivate(pages[i])) { 722#if BITS_PER_LONG < 64 723 kfree((void *)page_private(pages[i])); 724#endif 725 ClearPagePrivate(pages[i]); 726 } 727 } 728 free_xenballooned_pages(nr_pages, pages); 729} 730EXPORT_SYMBOL(gnttab_free_pages); 731 732/* Handling of paged out grant targets (GNTST_eagain) */ 733#define MAX_DELAY 256 734static inline void 735gnttab_retry_eagain_gop(unsigned int cmd, void *gop, int16_t *status, 736 const char *func) 737{ 738 unsigned delay = 1; 739 740 do { 741 BUG_ON(HYPERVISOR_grant_table_op(cmd, gop, 1)); 742 if (*status == GNTST_eagain) 743 msleep(delay++); 744 } while ((*status == GNTST_eagain) && (delay < MAX_DELAY)); 745 746 if (delay >= MAX_DELAY) { 747 pr_err("%s: %s eagain grant\n", func, current->comm); 748 *status = GNTST_bad_page; 749 } 750} 751 752void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count) 753{ 754 struct gnttab_map_grant_ref *op; 755 756 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, batch, count)) 757 BUG(); 758 for (op = batch; op < batch + count; op++) 759 if (op->status == GNTST_eagain) 760 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, op, 761 &op->status, __func__); 762} 763EXPORT_SYMBOL_GPL(gnttab_batch_map); 764 765void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count) 766{ 767 struct gnttab_copy *op; 768 769 if (HYPERVISOR_grant_table_op(GNTTABOP_copy, batch, count)) 770 BUG(); 771 for (op = batch; op < batch + count; op++) 772 if (op->status == GNTST_eagain) 773 gnttab_retry_eagain_gop(GNTTABOP_copy, op, 774 &op->status, __func__); 775} 776EXPORT_SYMBOL_GPL(gnttab_batch_copy); 777 778void gnttab_foreach_grant_in_range(struct page *page, 779 unsigned int offset, 780 unsigned int len, 781 xen_grant_fn_t fn, 782 void *data) 783{ 784 unsigned int goffset; 785 unsigned int glen; 786 unsigned long xen_pfn; 787 788 len = min_t(unsigned int, PAGE_SIZE - offset, len); 789 goffset = xen_offset_in_page(offset); 790 791 xen_pfn = page_to_xen_pfn(page) + XEN_PFN_DOWN(offset); 792 793 while (len) { 794 glen = min_t(unsigned int, XEN_PAGE_SIZE - goffset, len); 795 fn(pfn_to_gfn(xen_pfn), goffset, glen, data); 796 797 goffset = 0; 798 xen_pfn++; 799 len -= glen; 800 } 801} 802EXPORT_SYMBOL_GPL(gnttab_foreach_grant_in_range); 803 804void gnttab_foreach_grant(struct page **pages, 805 unsigned int nr_grefs, 806 xen_grant_fn_t fn, 807 void *data) 808{ 809 unsigned int goffset = 0; 810 unsigned long xen_pfn = 0; 811 unsigned int i; 812 813 for (i = 0; i < nr_grefs; i++) { 814 if ((i % XEN_PFN_PER_PAGE) == 0) { 815 xen_pfn = page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]); 816 goffset = 0; 817 } 818 819 fn(pfn_to_gfn(xen_pfn), goffset, XEN_PAGE_SIZE, data); 820 821 goffset += XEN_PAGE_SIZE; 822 xen_pfn++; 823 } 824} 825 826int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, 827 struct gnttab_map_grant_ref *kmap_ops, 828 struct page **pages, unsigned int count) 829{ 830 int i, ret; 831 832 ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); 833 if (ret) 834 return ret; 835 836 for (i = 0; i < count; i++) { 837 /* Retry eagain maps */ 838 if (map_ops[i].status == GNTST_eagain) 839 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i, 840 &map_ops[i].status, __func__); 841 842 if (map_ops[i].status == GNTST_okay) { 843 struct xen_page_foreign *foreign; 844 845 SetPageForeign(pages[i]); 846 foreign = xen_page_foreign(pages[i]); 847 foreign->domid = map_ops[i].dom; 848 foreign->gref = map_ops[i].ref; 849 } 850 } 851 852 return set_foreign_p2m_mapping(map_ops, kmap_ops, pages, count); 853} 854EXPORT_SYMBOL_GPL(gnttab_map_refs); 855 856int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, 857 struct gnttab_unmap_grant_ref *kunmap_ops, 858 struct page **pages, unsigned int count) 859{ 860 unsigned int i; 861 int ret; 862 863 ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); 864 if (ret) 865 return ret; 866 867 for (i = 0; i < count; i++) 868 ClearPageForeign(pages[i]); 869 870 return clear_foreign_p2m_mapping(unmap_ops, kunmap_ops, pages, count); 871} 872EXPORT_SYMBOL_GPL(gnttab_unmap_refs); 873 874#define GNTTAB_UNMAP_REFS_DELAY 5 875 876static void __gnttab_unmap_refs_async(struct gntab_unmap_queue_data* item); 877 878static void gnttab_unmap_work(struct work_struct *work) 879{ 880 struct gntab_unmap_queue_data 881 *unmap_data = container_of(work, 882 struct gntab_unmap_queue_data, 883 gnttab_work.work); 884 if (unmap_data->age != UINT_MAX) 885 unmap_data->age++; 886 __gnttab_unmap_refs_async(unmap_data); 887} 888 889static void __gnttab_unmap_refs_async(struct gntab_unmap_queue_data* item) 890{ 891 int ret; 892 int pc; 893 894 for (pc = 0; pc < item->count; pc++) { 895 if (page_count(item->pages[pc]) > 1) { 896 unsigned long delay = GNTTAB_UNMAP_REFS_DELAY * (item->age + 1); 897 schedule_delayed_work(&item->gnttab_work, 898 msecs_to_jiffies(delay)); 899 return; 900 } 901 } 902 903 ret = gnttab_unmap_refs(item->unmap_ops, item->kunmap_ops, 904 item->pages, item->count); 905 item->done(ret, item); 906} 907 908void gnttab_unmap_refs_async(struct gntab_unmap_queue_data* item) 909{ 910 INIT_DELAYED_WORK(&item->gnttab_work, gnttab_unmap_work); 911 item->age = 0; 912 913 __gnttab_unmap_refs_async(item); 914} 915EXPORT_SYMBOL_GPL(gnttab_unmap_refs_async); 916 917static void unmap_refs_callback(int result, 918 struct gntab_unmap_queue_data *data) 919{ 920 struct unmap_refs_callback_data *d = data->data; 921 922 d->result = result; 923 complete(&d->completion); 924} 925 926int gnttab_unmap_refs_sync(struct gntab_unmap_queue_data *item) 927{ 928 struct unmap_refs_callback_data data; 929 930 init_completion(&data.completion); 931 item->data = &data; 932 item->done = &unmap_refs_callback; 933 gnttab_unmap_refs_async(item); 934 wait_for_completion(&data.completion); 935 936 return data.result; 937} 938EXPORT_SYMBOL_GPL(gnttab_unmap_refs_sync); 939 940static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) 941{ 942 int rc; 943 944 rc = arch_gnttab_map_shared(frames, nr_gframes, 945 gnttab_max_grant_frames(), 946 &gnttab_shared.addr); 947 BUG_ON(rc); 948 949 return 0; 950} 951 952static void gnttab_unmap_frames_v1(void) 953{ 954 arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); 955} 956 957static int gnttab_map(unsigned int start_idx, unsigned int end_idx) 958{ 959 struct gnttab_setup_table setup; 960 xen_pfn_t *frames; 961 unsigned int nr_gframes = end_idx + 1; 962 int rc; 963 964 if (xen_feature(XENFEAT_auto_translated_physmap)) { 965 struct xen_add_to_physmap xatp; 966 unsigned int i = end_idx; 967 rc = 0; 968 BUG_ON(xen_auto_xlat_grant_frames.count < nr_gframes); 969 /* 970 * Loop backwards, so that the first hypercall has the largest 971 * index, ensuring that the table will grow only once. 972 */ 973 do { 974 xatp.domid = DOMID_SELF; 975 xatp.idx = i; 976 xatp.space = XENMAPSPACE_grant_table; 977 xatp.gpfn = xen_auto_xlat_grant_frames.pfn[i]; 978 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); 979 if (rc != 0) { 980 pr_warn("grant table add_to_physmap failed, err=%d\n", 981 rc); 982 break; 983 } 984 } while (i-- > start_idx); 985 986 return rc; 987 } 988 989 /* No need for kzalloc as it is initialized in following hypercall 990 * GNTTABOP_setup_table. 991 */ 992 frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC); 993 if (!frames) 994 return -ENOMEM; 995 996 setup.dom = DOMID_SELF; 997 setup.nr_frames = nr_gframes; 998 set_xen_guest_handle(setup.frame_list, frames); 999 1000 rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); 1001 if (rc == -ENOSYS) { 1002 kfree(frames); 1003 return -ENOSYS; 1004 } 1005 1006 BUG_ON(rc || setup.status); 1007 1008 rc = gnttab_interface->map_frames(frames, nr_gframes); 1009 1010 kfree(frames); 1011 1012 return rc; 1013} 1014 1015static const struct gnttab_ops gnttab_v1_ops = { 1016 .map_frames = gnttab_map_frames_v1, 1017 .unmap_frames = gnttab_unmap_frames_v1, 1018 .update_entry = gnttab_update_entry_v1, 1019 .end_foreign_access_ref = gnttab_end_foreign_access_ref_v1, 1020 .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v1, 1021 .query_foreign_access = gnttab_query_foreign_access_v1, 1022}; 1023 1024static void gnttab_request_version(void) 1025{ 1026 /* Only version 1 is used, which will always be available. */ 1027 grant_table_version = 1; 1028 grefs_per_grant_frame = XEN_PAGE_SIZE / sizeof(struct grant_entry_v1); 1029 gnttab_interface = &gnttab_v1_ops; 1030 1031 pr_info("Grant tables using version %d layout\n", grant_table_version); 1032} 1033 1034static int gnttab_setup(void) 1035{ 1036 unsigned int max_nr_gframes; 1037 1038 max_nr_gframes = gnttab_max_grant_frames(); 1039 if (max_nr_gframes < nr_grant_frames) 1040 return -ENOSYS; 1041 1042 if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) { 1043 gnttab_shared.addr = xen_auto_xlat_grant_frames.vaddr; 1044 if (gnttab_shared.addr == NULL) { 1045 pr_warn("gnttab share frames (addr=0x%08lx) is not mapped!\n", 1046 (unsigned long)xen_auto_xlat_grant_frames.vaddr); 1047 return -ENOMEM; 1048 } 1049 } 1050 return gnttab_map(0, nr_grant_frames - 1); 1051} 1052 1053int gnttab_resume(void) 1054{ 1055 gnttab_request_version(); 1056 return gnttab_setup(); 1057} 1058 1059int gnttab_suspend(void) 1060{ 1061 if (!xen_feature(XENFEAT_auto_translated_physmap)) 1062 gnttab_interface->unmap_frames(); 1063 return 0; 1064} 1065 1066static int gnttab_expand(unsigned int req_entries) 1067{ 1068 int rc; 1069 unsigned int cur, extra; 1070 1071 BUG_ON(grefs_per_grant_frame == 0); 1072 cur = nr_grant_frames; 1073 extra = ((req_entries + (grefs_per_grant_frame-1)) / 1074 grefs_per_grant_frame); 1075 if (cur + extra > gnttab_max_grant_frames()) 1076 return -ENOSPC; 1077 1078 rc = gnttab_map(cur, cur + extra - 1); 1079 if (rc == 0) 1080 rc = grow_gnttab_list(extra); 1081 1082 return rc; 1083} 1084 1085int gnttab_init(void) 1086{ 1087 int i; 1088 unsigned long max_nr_grant_frames; 1089 unsigned int max_nr_glist_frames, nr_glist_frames; 1090 unsigned int nr_init_grefs; 1091 int ret; 1092 1093 gnttab_request_version(); 1094 max_nr_grant_frames = gnttab_max_grant_frames(); 1095 nr_grant_frames = 1; 1096 1097 /* Determine the maximum number of frames required for the 1098 * grant reference free list on the current hypervisor. 1099 */ 1100 BUG_ON(grefs_per_grant_frame == 0); 1101 max_nr_glist_frames = (max_nr_grant_frames * 1102 grefs_per_grant_frame / RPP); 1103 1104 gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *), 1105 GFP_KERNEL); 1106 if (gnttab_list == NULL) 1107 return -ENOMEM; 1108 1109 nr_glist_frames = (nr_grant_frames * grefs_per_grant_frame + RPP - 1) / RPP; 1110 for (i = 0; i < nr_glist_frames; i++) { 1111 gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); 1112 if (gnttab_list[i] == NULL) { 1113 ret = -ENOMEM; 1114 goto ini_nomem; 1115 } 1116 } 1117 1118 ret = arch_gnttab_init(max_nr_grant_frames); 1119 if (ret < 0) 1120 goto ini_nomem; 1121 1122 if (gnttab_setup() < 0) { 1123 ret = -ENODEV; 1124 goto ini_nomem; 1125 } 1126 1127 nr_init_grefs = nr_grant_frames * grefs_per_grant_frame; 1128 1129 for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) 1130 gnttab_entry(i) = i + 1; 1131 1132 gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END; 1133 gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES; 1134 gnttab_free_head = NR_RESERVED_ENTRIES; 1135 1136 printk("Grant table initialized\n"); 1137 return 0; 1138 1139 ini_nomem: 1140 for (i--; i >= 0; i--) 1141 free_page((unsigned long)gnttab_list[i]); 1142 kfree(gnttab_list); 1143 return ret; 1144} 1145EXPORT_SYMBOL_GPL(gnttab_init); 1146 1147static int __gnttab_init(void) 1148{ 1149 /* Delay grant-table initialization in the PV on HVM case */ 1150 if (xen_hvm_domain()) 1151 return 0; 1152 1153 if (!xen_pv_domain()) 1154 return -ENODEV; 1155 1156 return gnttab_init(); 1157} 1158/* Starts after core_initcall so that xen_pvh_gnttab_setup can be called 1159 * beforehand to initialize xen_auto_xlat_grant_frames. */ 1160core_initcall_sync(__gnttab_init);