1*5741Smrj /* 2*5741Smrj * CDDL HEADER START 3*5741Smrj * 4*5741Smrj * The contents of this file are subject to the terms of the 5*5741Smrj * Common Development and Distribution License (the "License"). 6*5741Smrj * You may not use this file except in compliance with the License. 7*5741Smrj * 8*5741Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5741Smrj * or http://www.opensolaris.org/os/licensing. 10*5741Smrj * See the License for the specific language governing permissions 11*5741Smrj * and limitations under the License. 12*5741Smrj * 13*5741Smrj * When distributing Covered Code, include this CDDL HEADER in each 14*5741Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5741Smrj * If applicable, add the following below this CDDL HEADER, with the 16*5741Smrj * fields enclosed by brackets "[]" replaced with your own identifying 17*5741Smrj * information: Portions Copyright [yyyy] [name of copyright owner] 18*5741Smrj * 19*5741Smrj * CDDL HEADER END 20*5741Smrj */ 21*5741Smrj 22*5741Smrj /* 23*5741Smrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*5741Smrj * Use is subject to license terms. 25*5741Smrj */ 26*5741Smrj 27*5741Smrj #pragma ident "%Z%%M% %I% %E% SMI" 28*5741Smrj 29*5741Smrj /* 30*5741Smrj * gnttab.c 31*5741Smrj * 32*5741Smrj * Granting foreign access to our memory reservation. 33*5741Smrj * 34*5741Smrj * Copyright (c) 2005, Christopher Clark 35*5741Smrj * Copyright (c) 2004-2005, K A Fraser 36*5741Smrj * 37*5741Smrj * This file may be distributed separately from the Linux kernel, or 38*5741Smrj * incorporated into other software packages, subject to the following license: 39*5741Smrj * 40*5741Smrj * Permission is hereby granted, free of charge, to any person obtaining a copy 41*5741Smrj * of this source file (the "Software"), to deal in the Software without 42*5741Smrj * restriction, including without limitation the rights to use, copy, modify, 43*5741Smrj * merge, publish, distribute, sublicense, and/or sell copies of the Software, 44*5741Smrj * and to permit persons to whom the Software is furnished to do so, subject to 45*5741Smrj * the following conditions: 46*5741Smrj * 47*5741Smrj * The above copyright notice and this permission notice shall be included in 48*5741Smrj * all copies or substantial portions of the Software. 49*5741Smrj * 50*5741Smrj * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51*5741Smrj * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 52*5741Smrj * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 53*5741Smrj * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 54*5741Smrj * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 55*5741Smrj * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 56*5741Smrj * IN THE SOFTWARE. 57*5741Smrj */ 58*5741Smrj 59*5741Smrj #include <sys/types.h> 60*5741Smrj #include <sys/archsystm.h> 61*5741Smrj #ifdef XPV_HVM_DRIVER 62*5741Smrj #include <sys/xpv_support.h> 63*5741Smrj #include <sys/mman.h> 64*5741Smrj #include <vm/hat.h> 65*5741Smrj #endif 66*5741Smrj #include <sys/hypervisor.h> 67*5741Smrj #include <sys/gnttab.h> 68*5741Smrj #include <sys/sysmacros.h> 69*5741Smrj #include <sys/machsystm.h> 70*5741Smrj #include <sys/systm.h> 71*5741Smrj #include <sys/mutex.h> 72*5741Smrj #include <sys/atomic.h> 73*5741Smrj #include <sys/spl.h> 74*5741Smrj #include <sys/condvar.h> 75*5741Smrj #include <sys/cpuvar.h> 76*5741Smrj #include <sys/taskq.h> 77*5741Smrj #include <sys/panic.h> 78*5741Smrj #include <sys/cmn_err.h> 79*5741Smrj #include <sys/promif.h> 80*5741Smrj #include <sys/cpu.h> 81*5741Smrj #include <sys/vmem.h> 82*5741Smrj #include <vm/hat_i86.h> 83*5741Smrj #include <sys/bootconf.h> 84*5741Smrj #include <sys/bootsvcs.h> 85*5741Smrj #ifndef XPV_HVM_DRIVER 86*5741Smrj #include <sys/bootinfo.h> 87*5741Smrj #include <sys/multiboot.h> 88*5741Smrj #include <vm/kboot_mmu.h> 89*5741Smrj #endif 90*5741Smrj #include <sys/bootvfs.h> 91*5741Smrj #include <sys/bootprops.h> 92*5741Smrj #include <vm/seg_kmem.h> 93*5741Smrj 94*5741Smrj #define cmpxchg(t, c, n) atomic_cas_16((t), (c), (n)) 95*5741Smrj 96*5741Smrj /* External tools reserve first few grant table entries. */ 97*5741Smrj #define NR_RESERVED_ENTRIES 8 98*5741Smrj 99*5741Smrj #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * \ 100*5741Smrj MMU_PAGESIZE / sizeof (grant_entry_t)) 101*5741Smrj #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1) 102*5741Smrj #define VALID_GRANT_REF(r) ((r) < NR_GRANT_ENTRIES) 103*5741Smrj 104*5741Smrj static grant_ref_t gnttab_list[NR_GRANT_ENTRIES]; 105*5741Smrj static int gnttab_free_count; 106*5741Smrj static grant_ref_t gnttab_free_head; 107*5741Smrj static kmutex_t gnttab_list_lock; 108*5741Smrj 109*5741Smrj static grant_entry_t *shared; 110*5741Smrj #define GT_PGADDR(i) ((uintptr_t)shared + ((i) << PAGESHIFT)) 111*5741Smrj 112*5741Smrj static struct gnttab_free_callback *gnttab_free_callback_list = NULL; 113*5741Smrj 114*5741Smrj static int 115*5741Smrj get_free_entries(int count) 116*5741Smrj { 117*5741Smrj int ref; 118*5741Smrj grant_ref_t head; 119*5741Smrj 120*5741Smrj mutex_enter(&gnttab_list_lock); 121*5741Smrj if (gnttab_free_count < count) { 122*5741Smrj mutex_exit(&gnttab_list_lock); 123*5741Smrj return (-1); 124*5741Smrj } 125*5741Smrj ref = head = gnttab_free_head; 126*5741Smrj gnttab_free_count -= count; 127*5741Smrj while (count-- > 1) 128*5741Smrj head = gnttab_list[head]; 129*5741Smrj gnttab_free_head = gnttab_list[head]; 130*5741Smrj gnttab_list[head] = GNTTAB_LIST_END; 131*5741Smrj mutex_exit(&gnttab_list_lock); 132*5741Smrj return (ref); 133*5741Smrj } 134*5741Smrj 135*5741Smrj #define get_free_entry() get_free_entries(1) 136*5741Smrj 137*5741Smrj static void 138*5741Smrj do_free_callbacks(void) 139*5741Smrj { 140*5741Smrj struct gnttab_free_callback *callback, *next; 141*5741Smrj 142*5741Smrj callback = gnttab_free_callback_list; 143*5741Smrj gnttab_free_callback_list = NULL; 144*5741Smrj 145*5741Smrj while (callback != NULL) { 146*5741Smrj next = callback->next; 147*5741Smrj if (gnttab_free_count >= callback->count) { 148*5741Smrj callback->next = NULL; 149*5741Smrj callback->fn(callback->arg); 150*5741Smrj } else { 151*5741Smrj callback->next = gnttab_free_callback_list; 152*5741Smrj gnttab_free_callback_list = callback; 153*5741Smrj } 154*5741Smrj callback = next; 155*5741Smrj } 156*5741Smrj } 157*5741Smrj 158*5741Smrj static void 159*5741Smrj check_free_callbacks(void) 160*5741Smrj { 161*5741Smrj if (gnttab_free_callback_list) 162*5741Smrj do_free_callbacks(); 163*5741Smrj } 164*5741Smrj 165*5741Smrj static void 166*5741Smrj put_free_entry(grant_ref_t ref) 167*5741Smrj { 168*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 169*5741Smrj 170*5741Smrj mutex_enter(&gnttab_list_lock); 171*5741Smrj gnttab_list[ref] = gnttab_free_head; 172*5741Smrj gnttab_free_head = ref; 173*5741Smrj gnttab_free_count++; 174*5741Smrj check_free_callbacks(); 175*5741Smrj mutex_exit(&gnttab_list_lock); 176*5741Smrj } 177*5741Smrj 178*5741Smrj /* 179*5741Smrj * Public grant-issuing interface functions 180*5741Smrj */ 181*5741Smrj 182*5741Smrj int 183*5741Smrj gnttab_grant_foreign_access(domid_t domid, gnttab_frame_t frame, int readonly) 184*5741Smrj { 185*5741Smrj int ref; 186*5741Smrj 187*5741Smrj if ((ref = get_free_entry()) == -1) 188*5741Smrj return (-1); 189*5741Smrj 190*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 191*5741Smrj 192*5741Smrj shared[ref].frame = frame; 193*5741Smrj shared[ref].domid = domid; 194*5741Smrj membar_producer(); 195*5741Smrj shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); 196*5741Smrj 197*5741Smrj return (ref); 198*5741Smrj } 199*5741Smrj 200*5741Smrj void 201*5741Smrj gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, 202*5741Smrj gnttab_frame_t frame, int readonly) 203*5741Smrj { 204*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 205*5741Smrj 206*5741Smrj shared[ref].frame = frame; 207*5741Smrj shared[ref].domid = domid; 208*5741Smrj membar_producer(); 209*5741Smrj shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); 210*5741Smrj } 211*5741Smrj 212*5741Smrj 213*5741Smrj int 214*5741Smrj gnttab_query_foreign_access(grant_ref_t ref) 215*5741Smrj { 216*5741Smrj uint16_t nflags; 217*5741Smrj 218*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 219*5741Smrj 220*5741Smrj nflags = shared[ref].flags; 221*5741Smrj 222*5741Smrj return (nflags & (GTF_reading|GTF_writing)); 223*5741Smrj } 224*5741Smrj 225*5741Smrj /* ARGSUSED */ 226*5741Smrj int 227*5741Smrj gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) 228*5741Smrj { 229*5741Smrj uint16_t flags, nflags; 230*5741Smrj 231*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 232*5741Smrj 233*5741Smrj nflags = shared[ref].flags; 234*5741Smrj do { 235*5741Smrj if ((flags = nflags) & (GTF_reading|GTF_writing)) { 236*5741Smrj cmn_err(CE_WARN, "g.e. still in use!"); 237*5741Smrj return (0); 238*5741Smrj } 239*5741Smrj } while ((nflags = cmpxchg(&shared[ref].flags, flags, 0)) != flags); 240*5741Smrj 241*5741Smrj return (1); 242*5741Smrj } 243*5741Smrj 244*5741Smrj void 245*5741Smrj gnttab_end_foreign_access(grant_ref_t ref, int readonly, gnttab_frame_t page) 246*5741Smrj { 247*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 248*5741Smrj 249*5741Smrj if (gnttab_end_foreign_access_ref(ref, readonly)) { 250*5741Smrj put_free_entry(ref); 251*5741Smrj /* 252*5741Smrj * XXPV - we don't support freeing a page here 253*5741Smrj */ 254*5741Smrj if (page != 0) { 255*5741Smrj cmn_err(CE_WARN, 256*5741Smrj "gnttab_end_foreign_access_ref: using unsupported free_page interface"); 257*5741Smrj /* free_page(page); */ 258*5741Smrj } 259*5741Smrj } else { 260*5741Smrj /* 261*5741Smrj * XXX This needs to be fixed so that the ref and page are 262*5741Smrj * placed on a list to be freed up later. 263*5741Smrj */ 264*5741Smrj cmn_err(CE_WARN, "leaking g.e. and page still in use!"); 265*5741Smrj } 266*5741Smrj } 267*5741Smrj 268*5741Smrj int 269*5741Smrj gnttab_grant_foreign_transfer(domid_t domid) 270*5741Smrj { 271*5741Smrj int ref; 272*5741Smrj 273*5741Smrj if ((ref = get_free_entry()) == -1) 274*5741Smrj return (-1); 275*5741Smrj 276*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 277*5741Smrj 278*5741Smrj shared[ref].frame = 0; 279*5741Smrj shared[ref].domid = domid; 280*5741Smrj membar_producer(); 281*5741Smrj shared[ref].flags = GTF_accept_transfer; 282*5741Smrj 283*5741Smrj return (ref); 284*5741Smrj } 285*5741Smrj 286*5741Smrj void 287*5741Smrj gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid) 288*5741Smrj { 289*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 290*5741Smrj 291*5741Smrj shared[ref].frame = 0; 292*5741Smrj shared[ref].domid = domid; 293*5741Smrj membar_producer(); 294*5741Smrj shared[ref].flags = GTF_accept_transfer; 295*5741Smrj } 296*5741Smrj 297*5741Smrj gnttab_frame_t 298*5741Smrj gnttab_end_foreign_transfer_ref(grant_ref_t ref) 299*5741Smrj { 300*5741Smrj gnttab_frame_t frame; 301*5741Smrj uint16_t flags; 302*5741Smrj 303*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 304*5741Smrj 305*5741Smrj /* 306*5741Smrj * If a transfer is not even yet started, try to reclaim the grant 307*5741Smrj * reference and return failure (== 0). 308*5741Smrj */ 309*5741Smrj while (!((flags = shared[ref].flags) & GTF_transfer_committed)) { 310*5741Smrj if (cmpxchg(&shared[ref].flags, flags, 0) == flags) 311*5741Smrj return (0); 312*5741Smrj (void) HYPERVISOR_yield(); 313*5741Smrj } 314*5741Smrj 315*5741Smrj /* If a transfer is in progress then wait until it is completed. */ 316*5741Smrj while (!(flags & GTF_transfer_completed)) { 317*5741Smrj flags = shared[ref].flags; 318*5741Smrj (void) HYPERVISOR_yield(); 319*5741Smrj } 320*5741Smrj 321*5741Smrj /* Read the frame number /after/ reading completion status. */ 322*5741Smrj membar_consumer(); 323*5741Smrj frame = shared[ref].frame; 324*5741Smrj ASSERT(frame != 0); 325*5741Smrj 326*5741Smrj return (frame); 327*5741Smrj } 328*5741Smrj 329*5741Smrj gnttab_frame_t 330*5741Smrj gnttab_end_foreign_transfer(grant_ref_t ref) 331*5741Smrj { 332*5741Smrj gnttab_frame_t frame; 333*5741Smrj 334*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 335*5741Smrj 336*5741Smrj frame = gnttab_end_foreign_transfer_ref(ref); 337*5741Smrj put_free_entry(ref); 338*5741Smrj return (frame); 339*5741Smrj } 340*5741Smrj 341*5741Smrj void 342*5741Smrj gnttab_free_grant_reference(grant_ref_t ref) 343*5741Smrj { 344*5741Smrj ASSERT(VALID_GRANT_REF(ref)); 345*5741Smrj 346*5741Smrj put_free_entry(ref); 347*5741Smrj } 348*5741Smrj 349*5741Smrj void 350*5741Smrj gnttab_free_grant_references(grant_ref_t head) 351*5741Smrj { 352*5741Smrj grant_ref_t ref; 353*5741Smrj int count = 1; 354*5741Smrj 355*5741Smrj if (head == GNTTAB_LIST_END) 356*5741Smrj return; 357*5741Smrj mutex_enter(&gnttab_list_lock); 358*5741Smrj ref = head; 359*5741Smrj while (gnttab_list[ref] != GNTTAB_LIST_END) { 360*5741Smrj ref = gnttab_list[ref]; 361*5741Smrj count++; 362*5741Smrj } 363*5741Smrj gnttab_list[ref] = gnttab_free_head; 364*5741Smrj gnttab_free_head = head; 365*5741Smrj gnttab_free_count += count; 366*5741Smrj check_free_callbacks(); 367*5741Smrj mutex_exit(&gnttab_list_lock); 368*5741Smrj } 369*5741Smrj 370*5741Smrj int 371*5741Smrj gnttab_alloc_grant_references(uint16_t count, grant_ref_t *head) 372*5741Smrj { 373*5741Smrj int h = get_free_entries(count); 374*5741Smrj 375*5741Smrj if (h == -1) 376*5741Smrj return (-1); 377*5741Smrj 378*5741Smrj *head = h; 379*5741Smrj 380*5741Smrj return (0); 381*5741Smrj } 382*5741Smrj 383*5741Smrj int 384*5741Smrj gnttab_claim_grant_reference(grant_ref_t *private_head) 385*5741Smrj { 386*5741Smrj grant_ref_t g = *private_head; 387*5741Smrj 388*5741Smrj if (g == GNTTAB_LIST_END) 389*5741Smrj return (-1); 390*5741Smrj *private_head = gnttab_list[g]; 391*5741Smrj return (g); 392*5741Smrj } 393*5741Smrj 394*5741Smrj void 395*5741Smrj gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t release) 396*5741Smrj { 397*5741Smrj ASSERT(VALID_GRANT_REF(release)); 398*5741Smrj 399*5741Smrj gnttab_list[release] = *private_head; 400*5741Smrj *private_head = release; 401*5741Smrj } 402*5741Smrj 403*5741Smrj void 404*5741Smrj gnttab_request_free_callback(struct gnttab_free_callback *callback, 405*5741Smrj void (*fn)(void *), void *arg, uint16_t count) 406*5741Smrj { 407*5741Smrj mutex_enter(&gnttab_list_lock); 408*5741Smrj if (callback->next) 409*5741Smrj goto out; 410*5741Smrj callback->fn = fn; 411*5741Smrj callback->arg = arg; 412*5741Smrj callback->count = count; 413*5741Smrj callback->next = gnttab_free_callback_list; 414*5741Smrj gnttab_free_callback_list = callback; 415*5741Smrj check_free_callbacks(); 416*5741Smrj out: 417*5741Smrj mutex_exit(&gnttab_list_lock); 418*5741Smrj } 419*5741Smrj 420*5741Smrj #ifdef XPV_HVM_DRIVER 421*5741Smrj 422*5741Smrj static void 423*5741Smrj gnttab_map(void) 424*5741Smrj { 425*5741Smrj struct xen_add_to_physmap xatp; 426*5741Smrj caddr_t va; 427*5741Smrj pfn_t pfn; 428*5741Smrj int i; 429*5741Smrj 430*5741Smrj va = (caddr_t)shared; 431*5741Smrj for (i = 0; i < NR_GRANT_FRAMES; i++) { 432*5741Smrj pfn = hat_getpfnum(kas.a_hat, va); 433*5741Smrj 434*5741Smrj xatp.domid = DOMID_SELF; 435*5741Smrj xatp.idx = i; 436*5741Smrj xatp.space = XENMAPSPACE_grant_table; 437*5741Smrj xatp.gpfn = pfn; 438*5741Smrj hat_unload(kas.a_hat, va, MMU_PAGESIZE, HAT_UNLOAD); 439*5741Smrj if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0) 440*5741Smrj panic("Couldn't map grant table"); 441*5741Smrj 442*5741Smrj hat_devload(kas.a_hat, va, MMU_PAGESIZE, pfn, 443*5741Smrj PROT_READ | PROT_WRITE, 444*5741Smrj HAT_LOAD | HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST); 445*5741Smrj 446*5741Smrj va += MMU_PAGESIZE; 447*5741Smrj } 448*5741Smrj } 449*5741Smrj 450*5741Smrj void 451*5741Smrj gnttab_init(void) 452*5741Smrj { 453*5741Smrj int i; 454*5741Smrj 455*5741Smrj shared = (grant_entry_t *)xen_alloc_pages(NR_GRANT_FRAMES); 456*5741Smrj 457*5741Smrj gnttab_map(); 458*5741Smrj 459*5741Smrj for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++) 460*5741Smrj gnttab_list[i] = i + 1; 461*5741Smrj gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES; 462*5741Smrj gnttab_free_head = NR_RESERVED_ENTRIES; 463*5741Smrj 464*5741Smrj mutex_init(&gnttab_list_lock, NULL, MUTEX_DEFAULT, NULL); 465*5741Smrj } 466*5741Smrj 467*5741Smrj void 468*5741Smrj gnttab_resume(void) 469*5741Smrj { 470*5741Smrj gnttab_map(); 471*5741Smrj } 472*5741Smrj 473*5741Smrj #else /* XPV_HVM_DRIVER */ 474*5741Smrj 475*5741Smrj void 476*5741Smrj gnttab_init(void) 477*5741Smrj { 478*5741Smrj gnttab_setup_table_t set; 479*5741Smrj gnttab_frame_t frames[NR_GRANT_FRAMES]; 480*5741Smrj int i; 481*5741Smrj 482*5741Smrj set.dom = DOMID_SELF; 483*5741Smrj set.nr_frames = NR_GRANT_FRAMES; 484*5741Smrj /*LINTED: constant in conditional context*/ 485*5741Smrj set_xen_guest_handle(set.frame_list, frames); 486*5741Smrj 487*5741Smrj /* 488*5741Smrj * Take 4 pages of grant table space from the hypervisor and map it 489*5741Smrj */ 490*5741Smrj if ((HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &set, 1) != 0) || 491*5741Smrj (set.status != 0)) { 492*5741Smrj cmn_err(CE_PANIC, "Grant Table setup failed"); 493*5741Smrj } 494*5741Smrj 495*5741Smrj shared = vmem_xalloc(heap_arena, NR_GRANT_FRAMES * MMU_PAGESIZE, 496*5741Smrj MMU_PAGESIZE, 0, 0, 0, 0, VM_SLEEP); 497*5741Smrj 498*5741Smrj for (i = 0; i < NR_GRANT_FRAMES; i++) 499*5741Smrj kbm_map_ma(FRAME_TO_MA(frames[i]), GT_PGADDR(i), 0); 500*5741Smrj 501*5741Smrj for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++) 502*5741Smrj gnttab_list[i] = i + 1; 503*5741Smrj gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES; 504*5741Smrj gnttab_free_head = NR_RESERVED_ENTRIES; 505*5741Smrj 506*5741Smrj mutex_init(&gnttab_list_lock, NULL, MUTEX_DEFAULT, NULL); 507*5741Smrj } 508*5741Smrj 509*5741Smrj void 510*5741Smrj gnttab_resume(void) 511*5741Smrj { 512*5741Smrj gnttab_setup_table_t set; 513*5741Smrj gnttab_frame_t frames[NR_GRANT_FRAMES]; 514*5741Smrj int i; 515*5741Smrj 516*5741Smrj set.dom = DOMID_SELF; 517*5741Smrj set.nr_frames = NR_GRANT_FRAMES; 518*5741Smrj /*LINTED: constant in conditional context*/ 519*5741Smrj set_xen_guest_handle(set.frame_list, frames); 520*5741Smrj 521*5741Smrj /* 522*5741Smrj * Take NR_GRANT_FRAMES pages of grant table space from the 523*5741Smrj * hypervisor and map it 524*5741Smrj */ 525*5741Smrj if ((HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &set, 1) != 0) || 526*5741Smrj (set.status != 0)) { 527*5741Smrj cmn_err(CE_PANIC, "Grant Table setup failed"); 528*5741Smrj } 529*5741Smrj 530*5741Smrj for (i = 0; i < NR_GRANT_FRAMES; i++) { 531*5741Smrj (void) HYPERVISOR_update_va_mapping(GT_PGADDR(i), 532*5741Smrj FRAME_TO_MA(frames[i]) | PT_VALID | PT_WRITABLE, 533*5741Smrj UVMF_INVLPG | UVMF_ALL); 534*5741Smrj } 535*5741Smrj } 536*5741Smrj 537*5741Smrj #endif /* XPV_HVM_DRIVER */ 538*5741Smrj 539*5741Smrj void 540*5741Smrj gnttab_suspend(void) 541*5741Smrj { 542*5741Smrj int i; 543*5741Smrj 544*5741Smrj /* 545*5741Smrj * clear grant table mappings before suspending 546*5741Smrj */ 547*5741Smrj for (i = 0; i < NR_GRANT_FRAMES; i++) { 548*5741Smrj (void) HYPERVISOR_update_va_mapping(GT_PGADDR(i), 549*5741Smrj 0, UVMF_INVLPG); 550*5741Smrj } 551*5741Smrj } 552*5741Smrj 553*5741Smrj /* 554*5741Smrj * Local variables: 555*5741Smrj * c-file-style: "solaris" 556*5741Smrj * indent-tabs-mode: t 557*5741Smrj * c-indent-level: 8 558*5741Smrj * c-basic-offset: 8 559*5741Smrj * tab-width: 8 560*5741Smrj * End: 561*5741Smrj */ 562