1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * sun4v LDC Link Layer Shared Memory Routines 28 */ 29 #include <sys/types.h> 30 #include <sys/kmem.h> 31 #include <sys/cmn_err.h> 32 #include <sys/ksynch.h> 33 #include <sys/debug.h> 34 #include <sys/cyclic.h> 35 #include <sys/machsystm.h> 36 #include <sys/vm.h> 37 #include <sys/machcpuvar.h> 38 #include <sys/mmu.h> 39 #include <sys/pte.h> 40 #include <vm/hat.h> 41 #include <vm/as.h> 42 #include <vm/hat_sfmmu.h> 43 #include <sys/vm_machparam.h> 44 #include <vm/seg_kmem.h> 45 #include <vm/seg_kpm.h> 46 #include <sys/hypervisor_api.h> 47 #include <sys/ldc.h> 48 #include <sys/ldc_impl.h> 49 50 /* LDC variables used by shared memory routines */ 51 extern ldc_soft_state_t *ldcssp; 52 extern int ldc_max_retries; 53 extern clock_t ldc_delay; 54 55 #ifdef DEBUG 56 extern int ldcdbg; 57 #endif 58 59 /* LDC internal functions used by shared memory routines */ 60 extern void i_ldc_reset(ldc_chan_t *ldcp, boolean_t force_reset); 61 extern int i_ldc_h2v_error(int h_error); 62 63 #ifdef DEBUG 64 extern void ldcdebug(int64_t id, const char *fmt, ...); 65 #endif 66 67 /* Memory synchronization internal functions */ 68 static int i_ldc_mem_acquire_release(ldc_mem_handle_t mhandle, 69 uint8_t direction, uint64_t offset, size_t size); 70 static int i_ldc_dring_acquire_release(ldc_dring_handle_t dhandle, 71 uint8_t direction, uint64_t start, uint64_t end); 72 static int i_ldc_mem_map(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie, 73 uint32_t ccount, uint8_t mtype, uint8_t perm, caddr_t *vaddr, 74 caddr_t *raddr); 75 static int i_ldc_mem_bind_handle(ldc_mem_handle_t mhandle, caddr_t vaddr, 76 size_t len, uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, 77 uint32_t *ccount); 78 79 /* 80 * LDC framework supports mapping remote domain's memory 81 * either directly or via shadow memory pages. Default 82 * support is currently implemented via shadow copy. 83 * Direct map can be enabled by setting 'ldc_shmem_enabled' 84 */ 85 int ldc_shmem_enabled = 1; 86 87 /* 88 * Use of directly mapped shared memory for LDC descriptor 89 * rings is permitted if this variable is non-zero. 90 */ 91 int ldc_dring_shmem_enabled = 1; 92 93 /* 94 * The major and minor versions required to use directly 95 * mapped shared memory for LDC descriptor rings. The 96 * ldc_dring_shmem_hv_force variable, if set to a non-zero 97 * value, overrides the hypervisor API version check. 98 */ 99 static int ldc_dring_shmem_hv_major = 1; 100 static int ldc_dring_shmem_hv_minor = 1; 101 static int ldc_dring_shmem_hv_force = 0; 102 103 /* 104 * The results of the hypervisor service group API check. 105 * A non-zero value indicates the HV includes support for 106 * descriptor ring shared memory. 107 */ 108 static int ldc_dring_shmem_hv_ok = 0; 109 110 /* 111 * Pages exported for remote access over each channel is 112 * maintained in a table registered with the Hypervisor. 113 * The default number of entries in the table is set to 114 * 'ldc_mtbl_entries'. 115 */ 116 uint64_t ldc_maptable_entries = LDC_MTBL_ENTRIES; 117 118 #define IDX2COOKIE(idx, pg_szc, pg_shift) \ 119 (((pg_szc) << LDC_COOKIE_PGSZC_SHIFT) | ((idx) << (pg_shift))) 120 121 /* 122 * Pages imported over each channel are maintained in a global (per-guest) 123 * mapin table. Starting with HV LDC API version 1.2, HV supports APIs to 124 * obtain information about the total size of the memory that can be direct 125 * mapped through this mapin table. The minimum size of the mapin area that we 126 * expect is defined below. 127 */ 128 #define GIGABYTE ((uint64_t)(1 << 30)) 129 uint64_t ldc_mapin_size_min = GIGABYTE; 130 131 /* HV LDC API version that supports mapin size info */ 132 #define LDC_MAPIN_VER_MAJOR 1 133 #define LDC_MAPIN_VER_MINOR 2 134 135 /* 136 * Sets ldc_dring_shmem_hv_ok to a non-zero value if the HV LDC 137 * API version supports directly mapped shared memory or if it has 138 * been explicitly enabled via ldc_dring_shmem_hv_force. 139 */ 140 void 141 i_ldc_mem_set_hsvc_vers(uint64_t major, uint64_t minor) 142 { 143 if ((major == ldc_dring_shmem_hv_major && 144 minor >= ldc_dring_shmem_hv_minor) || 145 (major > ldc_dring_shmem_hv_major) || 146 (ldc_dring_shmem_hv_force != 0)) { 147 ldc_dring_shmem_hv_ok = 1; 148 } 149 } 150 151 /* 152 * initialize mapin table. 153 */ 154 void 155 i_ldc_init_mapin(ldc_soft_state_t *ldcssp, uint64_t major, uint64_t minor) 156 { 157 int rv; 158 uint64_t sz; 159 uint64_t table_type = LDC_MAPIN_TYPE_REGULAR; 160 161 /* set mapin size to default. */ 162 ldcssp->mapin_size = LDC_DIRECT_MAP_SIZE_DEFAULT; 163 164 /* Check if the HV supports mapin size API. */ 165 if ((major == LDC_MAPIN_VER_MAJOR && 166 minor < LDC_MAPIN_VER_MINOR) || 167 (major < LDC_MAPIN_VER_MAJOR)) { 168 /* Older version of HV. */ 169 return; 170 } 171 172 /* Get info about the mapin size supported by HV */ 173 rv = hv_ldc_mapin_size_max(table_type, &sz); 174 if (rv != 0) { 175 cmn_err(CE_NOTE, "Failed to get mapin information\n"); 176 return; 177 } 178 179 /* Save the table size */ 180 ldcssp->mapin_size = sz; 181 182 D1(DBG_ALL_LDCS, "%s: mapin_size read from HV is (0x%llx)\n", 183 __func__, sz); 184 } 185 186 /* 187 * Allocate a memory handle for the channel and link it into the list 188 * Also choose which memory table to use if this is the first handle 189 * being assigned to this channel 190 */ 191 int 192 ldc_mem_alloc_handle(ldc_handle_t handle, ldc_mem_handle_t *mhandle) 193 { 194 ldc_chan_t *ldcp; 195 ldc_mhdl_t *mhdl; 196 197 if (handle == NULL) { 198 DWARN(DBG_ALL_LDCS, 199 "ldc_mem_alloc_handle: invalid channel handle\n"); 200 return (EINVAL); 201 } 202 ldcp = (ldc_chan_t *)handle; 203 204 mutex_enter(&ldcp->lock); 205 206 /* check to see if channel is initalized */ 207 if ((ldcp->tstate & ~TS_IN_RESET) < TS_INIT) { 208 DWARN(ldcp->id, 209 "ldc_mem_alloc_handle: (0x%llx) channel not initialized\n", 210 ldcp->id); 211 mutex_exit(&ldcp->lock); 212 return (EINVAL); 213 } 214 215 /* allocate handle for channel */ 216 mhdl = kmem_cache_alloc(ldcssp->memhdl_cache, KM_SLEEP); 217 218 /* initialize the lock */ 219 mutex_init(&mhdl->lock, NULL, MUTEX_DRIVER, NULL); 220 221 mhdl->myshadow = B_FALSE; 222 mhdl->memseg = NULL; 223 mhdl->ldcp = ldcp; 224 mhdl->status = LDC_UNBOUND; 225 226 /* insert memory handle (@ head) into list */ 227 if (ldcp->mhdl_list == NULL) { 228 ldcp->mhdl_list = mhdl; 229 mhdl->next = NULL; 230 } else { 231 /* insert @ head */ 232 mhdl->next = ldcp->mhdl_list; 233 ldcp->mhdl_list = mhdl; 234 } 235 236 /* return the handle */ 237 *mhandle = (ldc_mem_handle_t)mhdl; 238 239 mutex_exit(&ldcp->lock); 240 241 D1(ldcp->id, "ldc_mem_alloc_handle: (0x%llx) allocated handle 0x%llx\n", 242 ldcp->id, mhdl); 243 244 return (0); 245 } 246 247 /* 248 * Free memory handle for the channel and unlink it from the list 249 */ 250 int 251 ldc_mem_free_handle(ldc_mem_handle_t mhandle) 252 { 253 ldc_mhdl_t *mhdl, *phdl; 254 ldc_chan_t *ldcp; 255 256 if (mhandle == NULL) { 257 DWARN(DBG_ALL_LDCS, 258 "ldc_mem_free_handle: invalid memory handle\n"); 259 return (EINVAL); 260 } 261 mhdl = (ldc_mhdl_t *)mhandle; 262 263 mutex_enter(&mhdl->lock); 264 265 ldcp = mhdl->ldcp; 266 267 if (mhdl->status == LDC_BOUND || mhdl->status == LDC_MAPPED) { 268 DWARN(ldcp->id, 269 "ldc_mem_free_handle: cannot free, 0x%llx hdl bound\n", 270 mhdl); 271 mutex_exit(&mhdl->lock); 272 return (EINVAL); 273 } 274 mutex_exit(&mhdl->lock); 275 276 mutex_enter(&ldcp->mlist_lock); 277 278 phdl = ldcp->mhdl_list; 279 280 /* first handle */ 281 if (phdl == mhdl) { 282 ldcp->mhdl_list = mhdl->next; 283 mutex_destroy(&mhdl->lock); 284 kmem_cache_free(ldcssp->memhdl_cache, mhdl); 285 286 D1(ldcp->id, 287 "ldc_mem_free_handle: (0x%llx) freed handle 0x%llx\n", 288 ldcp->id, mhdl); 289 } else { 290 /* walk the list - unlink and free */ 291 while (phdl != NULL) { 292 if (phdl->next == mhdl) { 293 phdl->next = mhdl->next; 294 mutex_destroy(&mhdl->lock); 295 kmem_cache_free(ldcssp->memhdl_cache, mhdl); 296 D1(ldcp->id, 297 "ldc_mem_free_handle: (0x%llx) freed " 298 "handle 0x%llx\n", ldcp->id, mhdl); 299 break; 300 } 301 phdl = phdl->next; 302 } 303 } 304 305 if (phdl == NULL) { 306 DWARN(ldcp->id, 307 "ldc_mem_free_handle: invalid handle 0x%llx\n", mhdl); 308 mutex_exit(&ldcp->mlist_lock); 309 return (EINVAL); 310 } 311 312 mutex_exit(&ldcp->mlist_lock); 313 314 return (0); 315 } 316 317 /* 318 * Bind a memory handle to a virtual address. 319 * The virtual address is converted to the corresponding real addresses. 320 * Returns pointer to the first ldc_mem_cookie and the total number 321 * of cookies for this virtual address. Other cookies can be obtained 322 * using the ldc_mem_nextcookie() call. If the pages are stored in 323 * consecutive locations in the table, a single cookie corresponding to 324 * the first location is returned. The cookie size spans all the entries. 325 * 326 * If the VA corresponds to a page that is already being exported, reuse 327 * the page and do not export it again. Bump the page's use count. 328 */ 329 int 330 ldc_mem_bind_handle(ldc_mem_handle_t mhandle, caddr_t vaddr, size_t len, 331 uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, uint32_t *ccount) 332 { 333 /* 334 * Check if direct shared memory map is enabled, if not change 335 * the mapping type to SHADOW_MAP. 336 */ 337 if (ldc_shmem_enabled == 0) 338 mtype = LDC_SHADOW_MAP; 339 340 return (i_ldc_mem_bind_handle(mhandle, vaddr, len, mtype, perm, 341 cookie, ccount)); 342 } 343 344 static int 345 i_ldc_mem_bind_handle(ldc_mem_handle_t mhandle, caddr_t vaddr, size_t len, 346 uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, uint32_t *ccount) 347 { 348 ldc_mhdl_t *mhdl; 349 ldc_chan_t *ldcp; 350 ldc_mtbl_t *mtbl; 351 ldc_memseg_t *memseg; 352 ldc_mte_t tmp_mte; 353 uint64_t index, prev_index = 0; 354 int64_t cookie_idx; 355 uintptr_t raddr, ra_aligned; 356 uint64_t psize, poffset, v_offset; 357 uint64_t pg_shift, pg_size, pg_size_code, pg_mask; 358 pgcnt_t npages; 359 caddr_t v_align, addr; 360 int i, rv; 361 362 if (mhandle == NULL) { 363 DWARN(DBG_ALL_LDCS, 364 "ldc_mem_bind_handle: invalid memory handle\n"); 365 return (EINVAL); 366 } 367 mhdl = (ldc_mhdl_t *)mhandle; 368 ldcp = mhdl->ldcp; 369 370 /* clear count */ 371 *ccount = 0; 372 373 mutex_enter(&mhdl->lock); 374 375 if (mhdl->status == LDC_BOUND || mhdl->memseg != NULL) { 376 DWARN(ldcp->id, 377 "ldc_mem_bind_handle: (0x%x) handle already bound\n", 378 mhandle); 379 mutex_exit(&mhdl->lock); 380 return (EINVAL); 381 } 382 383 /* Force address and size to be 8-byte aligned */ 384 if ((((uintptr_t)vaddr | len) & 0x7) != 0) { 385 DWARN(ldcp->id, 386 "ldc_mem_bind_handle: addr/size is not 8-byte aligned\n"); 387 mutex_exit(&mhdl->lock); 388 return (EINVAL); 389 } 390 391 mutex_enter(&ldcp->lock); 392 393 /* 394 * If this channel is binding a memory handle for the 395 * first time allocate it a memory map table and initialize it 396 */ 397 if ((mtbl = ldcp->mtbl) == NULL) { 398 399 /* Allocate and initialize the map table structure */ 400 mtbl = kmem_zalloc(sizeof (ldc_mtbl_t), KM_SLEEP); 401 mtbl->num_entries = mtbl->num_avail = ldc_maptable_entries; 402 mtbl->size = ldc_maptable_entries * sizeof (ldc_mte_slot_t); 403 mtbl->next_entry = NULL; 404 mtbl->contigmem = B_TRUE; 405 406 /* Allocate the table itself */ 407 mtbl->table = (ldc_mte_slot_t *) 408 contig_mem_alloc_align(mtbl->size, MMU_PAGESIZE); 409 if (mtbl->table == NULL) { 410 411 /* allocate a page of memory using kmem_alloc */ 412 mtbl->table = kmem_alloc(MMU_PAGESIZE, KM_SLEEP); 413 mtbl->size = MMU_PAGESIZE; 414 mtbl->contigmem = B_FALSE; 415 mtbl->num_entries = mtbl->num_avail = 416 mtbl->size / sizeof (ldc_mte_slot_t); 417 DWARN(ldcp->id, 418 "ldc_mem_bind_handle: (0x%llx) reduced tbl size " 419 "to %lx entries\n", ldcp->id, mtbl->num_entries); 420 } 421 422 /* zero out the memory */ 423 bzero(mtbl->table, mtbl->size); 424 425 /* initialize the lock */ 426 mutex_init(&mtbl->lock, NULL, MUTEX_DRIVER, NULL); 427 428 /* register table for this channel */ 429 rv = hv_ldc_set_map_table(ldcp->id, 430 va_to_pa(mtbl->table), mtbl->num_entries); 431 if (rv != 0) { 432 DWARN(DBG_ALL_LDCS, 433 "ldc_mem_bind_handle: (0x%lx) err %d mapping tbl", 434 ldcp->id, rv); 435 if (mtbl->contigmem) 436 contig_mem_free(mtbl->table, mtbl->size); 437 else 438 kmem_free(mtbl->table, mtbl->size); 439 mutex_destroy(&mtbl->lock); 440 kmem_free(mtbl, sizeof (ldc_mtbl_t)); 441 mutex_exit(&ldcp->lock); 442 mutex_exit(&mhdl->lock); 443 return (EIO); 444 } 445 446 ldcp->mtbl = mtbl; 447 448 D1(ldcp->id, 449 "ldc_mem_bind_handle: (0x%llx) alloc'd map table 0x%llx\n", 450 ldcp->id, ldcp->mtbl->table); 451 } 452 453 mutex_exit(&ldcp->lock); 454 455 /* FUTURE: get the page size, pgsz code, and shift */ 456 pg_size = MMU_PAGESIZE; 457 pg_size_code = page_szc(pg_size); 458 pg_shift = page_get_shift(pg_size_code); 459 pg_mask = ~(pg_size - 1); 460 461 D1(ldcp->id, "ldc_mem_bind_handle: (0x%llx) binding " 462 "va 0x%llx pgsz=0x%llx, pgszc=0x%llx, pg_shift=0x%llx\n", 463 ldcp->id, vaddr, pg_size, pg_size_code, pg_shift); 464 465 /* aligned VA and its offset */ 466 v_align = (caddr_t)(((uintptr_t)vaddr) & ~(pg_size - 1)); 467 v_offset = ((uintptr_t)vaddr) & (pg_size - 1); 468 469 npages = (len+v_offset)/pg_size; 470 npages = ((len+v_offset)%pg_size == 0) ? npages : npages+1; 471 472 D1(ldcp->id, "ldc_mem_bind_handle: binding " 473 "(0x%llx) v=0x%llx,val=0x%llx,off=0x%x,pgs=0x%x\n", 474 ldcp->id, vaddr, v_align, v_offset, npages); 475 476 /* lock the memory table - exclusive access to channel */ 477 mutex_enter(&mtbl->lock); 478 479 if (npages > mtbl->num_avail) { 480 D1(ldcp->id, "ldc_mem_bind_handle: (0x%llx) no table entries\n", 481 ldcp->id); 482 mutex_exit(&mtbl->lock); 483 mutex_exit(&mhdl->lock); 484 return (ENOMEM); 485 } 486 487 /* Allocate a memseg structure */ 488 memseg = mhdl->memseg = 489 kmem_cache_alloc(ldcssp->memseg_cache, KM_SLEEP); 490 491 /* Allocate memory to store all pages and cookies */ 492 memseg->pages = kmem_zalloc((sizeof (ldc_page_t) * npages), KM_SLEEP); 493 memseg->cookies = 494 kmem_zalloc((sizeof (ldc_mem_cookie_t) * npages), KM_SLEEP); 495 496 D2(ldcp->id, "ldc_mem_bind_handle: (0x%llx) processing 0x%llx pages\n", 497 ldcp->id, npages); 498 499 addr = v_align; 500 501 /* 502 * Table slots are used in a round-robin manner. The algorithm permits 503 * inserting duplicate entries. Slots allocated earlier will typically 504 * get freed before we get back to reusing the slot.Inserting duplicate 505 * entries should be OK as we only lookup entries using the cookie addr 506 * i.e. tbl index, during export, unexport and copy operation. 507 * 508 * One implementation what was tried was to search for a duplicate 509 * page entry first and reuse it. The search overhead is very high and 510 * in the vnet case dropped the perf by almost half, 50 to 24 mbps. 511 * So it does make sense to avoid searching for duplicates. 512 * 513 * But during the process of searching for a free slot, if we find a 514 * duplicate entry we will go ahead and use it, and bump its use count. 515 */ 516 517 /* index to start searching from */ 518 index = mtbl->next_entry; 519 cookie_idx = -1; 520 521 tmp_mte.ll = 0; /* initialise fields to 0 */ 522 523 if (mtype & LDC_DIRECT_MAP) { 524 tmp_mte.mte_r = (perm & LDC_MEM_R) ? 1 : 0; 525 tmp_mte.mte_w = (perm & LDC_MEM_W) ? 1 : 0; 526 tmp_mte.mte_x = (perm & LDC_MEM_X) ? 1 : 0; 527 } 528 529 if (mtype & LDC_SHADOW_MAP) { 530 tmp_mte.mte_cr = (perm & LDC_MEM_R) ? 1 : 0; 531 tmp_mte.mte_cw = (perm & LDC_MEM_W) ? 1 : 0; 532 } 533 534 if (mtype & LDC_IO_MAP) { 535 tmp_mte.mte_ir = (perm & LDC_MEM_R) ? 1 : 0; 536 tmp_mte.mte_iw = (perm & LDC_MEM_W) ? 1 : 0; 537 } 538 539 D1(ldcp->id, "ldc_mem_bind_handle mte=0x%llx\n", tmp_mte.ll); 540 541 tmp_mte.mte_pgszc = pg_size_code; 542 543 /* initialize each mem table entry */ 544 for (i = 0; i < npages; i++) { 545 546 /* check if slot is available in the table */ 547 while (mtbl->table[index].entry.ll != 0) { 548 549 index = (index + 1) % mtbl->num_entries; 550 551 if (index == mtbl->next_entry) { 552 /* we have looped around */ 553 DWARN(DBG_ALL_LDCS, 554 "ldc_mem_bind_handle: (0x%llx) cannot find " 555 "entry\n", ldcp->id); 556 *ccount = 0; 557 558 /* NOTE: free memory, remove previous entries */ 559 /* this shouldnt happen as num_avail was ok */ 560 561 mutex_exit(&mtbl->lock); 562 mutex_exit(&mhdl->lock); 563 return (ENOMEM); 564 } 565 } 566 567 /* get the real address */ 568 raddr = va_to_pa((void *)addr); 569 ra_aligned = ((uintptr_t)raddr & pg_mask); 570 571 /* build the mte */ 572 tmp_mte.mte_rpfn = ra_aligned >> pg_shift; 573 574 D1(ldcp->id, "ldc_mem_bind_handle mte=0x%llx\n", tmp_mte.ll); 575 576 /* update entry in table */ 577 mtbl->table[index].entry = tmp_mte; 578 579 D2(ldcp->id, "ldc_mem_bind_handle: (0x%llx) stored MTE 0x%llx" 580 " into loc 0x%llx\n", ldcp->id, tmp_mte.ll, index); 581 582 /* calculate the size and offset for this export range */ 583 if (i == 0) { 584 /* first page */ 585 psize = min((pg_size - v_offset), len); 586 poffset = v_offset; 587 588 } else if (i == (npages - 1)) { 589 /* last page */ 590 psize = (((uintptr_t)(vaddr + len)) & 591 ((uint64_t)(pg_size-1))); 592 if (psize == 0) 593 psize = pg_size; 594 poffset = 0; 595 596 } else { 597 /* middle pages */ 598 psize = pg_size; 599 poffset = 0; 600 } 601 602 /* store entry for this page */ 603 memseg->pages[i].index = index; 604 memseg->pages[i].raddr = raddr; 605 memseg->pages[i].mte = &(mtbl->table[index]); 606 607 /* create the cookie */ 608 if (i == 0 || (index != prev_index + 1)) { 609 cookie_idx++; 610 memseg->cookies[cookie_idx].addr = 611 IDX2COOKIE(index, pg_size_code, pg_shift); 612 memseg->cookies[cookie_idx].addr |= poffset; 613 memseg->cookies[cookie_idx].size = psize; 614 615 } else { 616 memseg->cookies[cookie_idx].size += psize; 617 } 618 619 D1(ldcp->id, "ldc_mem_bind_handle: bound " 620 "(0x%llx) va=0x%llx, idx=0x%llx, " 621 "ra=0x%llx(sz=0x%x,off=0x%x)\n", 622 ldcp->id, addr, index, raddr, psize, poffset); 623 624 /* decrement number of available entries */ 625 mtbl->num_avail--; 626 627 /* increment va by page size */ 628 addr += pg_size; 629 630 /* increment index */ 631 prev_index = index; 632 index = (index + 1) % mtbl->num_entries; 633 634 /* save the next slot */ 635 mtbl->next_entry = index; 636 } 637 638 mutex_exit(&mtbl->lock); 639 640 /* memory handle = bound */ 641 mhdl->mtype = mtype; 642 mhdl->perm = perm; 643 mhdl->status = LDC_BOUND; 644 645 /* update memseg_t */ 646 memseg->vaddr = vaddr; 647 memseg->raddr = memseg->pages[0].raddr; 648 memseg->size = len; 649 memseg->npages = npages; 650 memseg->ncookies = cookie_idx + 1; 651 memseg->next_cookie = (memseg->ncookies > 1) ? 1 : 0; 652 653 /* return count and first cookie */ 654 *ccount = memseg->ncookies; 655 cookie->addr = memseg->cookies[0].addr; 656 cookie->size = memseg->cookies[0].size; 657 658 D1(ldcp->id, 659 "ldc_mem_bind_handle: (0x%llx) bound 0x%llx, va=0x%llx, " 660 "pgs=0x%llx cookies=0x%llx\n", 661 ldcp->id, mhdl, vaddr, npages, memseg->ncookies); 662 663 mutex_exit(&mhdl->lock); 664 return (0); 665 } 666 667 /* 668 * Return the next cookie associated with the specified memory handle 669 */ 670 int 671 ldc_mem_nextcookie(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie) 672 { 673 ldc_mhdl_t *mhdl; 674 ldc_chan_t *ldcp; 675 ldc_memseg_t *memseg; 676 677 if (mhandle == NULL) { 678 DWARN(DBG_ALL_LDCS, 679 "ldc_mem_nextcookie: invalid memory handle\n"); 680 return (EINVAL); 681 } 682 mhdl = (ldc_mhdl_t *)mhandle; 683 684 mutex_enter(&mhdl->lock); 685 686 ldcp = mhdl->ldcp; 687 memseg = mhdl->memseg; 688 689 if (cookie == 0) { 690 DWARN(ldcp->id, 691 "ldc_mem_nextcookie:(0x%llx) invalid cookie arg\n", 692 ldcp->id); 693 mutex_exit(&mhdl->lock); 694 return (EINVAL); 695 } 696 697 if (memseg->next_cookie != 0) { 698 cookie->addr = memseg->cookies[memseg->next_cookie].addr; 699 cookie->size = memseg->cookies[memseg->next_cookie].size; 700 memseg->next_cookie++; 701 if (memseg->next_cookie == memseg->ncookies) 702 memseg->next_cookie = 0; 703 704 } else { 705 DWARN(ldcp->id, 706 "ldc_mem_nextcookie:(0x%llx) no more cookies\n", ldcp->id); 707 cookie->addr = 0; 708 cookie->size = 0; 709 mutex_exit(&mhdl->lock); 710 return (EINVAL); 711 } 712 713 D1(ldcp->id, 714 "ldc_mem_nextcookie: (0x%llx) cookie addr=0x%llx,sz=0x%llx\n", 715 ldcp->id, cookie->addr, cookie->size); 716 717 mutex_exit(&mhdl->lock); 718 return (0); 719 } 720 721 /* 722 * Unbind the virtual memory region associated with the specified 723 * memory handle. Allassociated cookies are freed and the corresponding 724 * RA space is no longer exported. 725 */ 726 int 727 ldc_mem_unbind_handle(ldc_mem_handle_t mhandle) 728 { 729 ldc_mhdl_t *mhdl; 730 ldc_chan_t *ldcp; 731 ldc_mtbl_t *mtbl; 732 ldc_memseg_t *memseg; 733 uint64_t cookie_addr; 734 uint64_t pg_shift, pg_size_code; 735 int i, rv, retries; 736 737 if (mhandle == NULL) { 738 DWARN(DBG_ALL_LDCS, 739 "ldc_mem_unbind_handle: invalid memory handle\n"); 740 return (EINVAL); 741 } 742 mhdl = (ldc_mhdl_t *)mhandle; 743 744 mutex_enter(&mhdl->lock); 745 746 if (mhdl->status == LDC_UNBOUND) { 747 DWARN(DBG_ALL_LDCS, 748 "ldc_mem_unbind_handle: (0x%x) handle is not bound\n", 749 mhandle); 750 mutex_exit(&mhdl->lock); 751 return (EINVAL); 752 } 753 754 ldcp = mhdl->ldcp; 755 mtbl = ldcp->mtbl; 756 757 memseg = mhdl->memseg; 758 759 /* lock the memory table - exclusive access to channel */ 760 mutex_enter(&mtbl->lock); 761 762 /* undo the pages exported */ 763 for (i = 0; i < memseg->npages; i++) { 764 765 /* clear the entry from the table */ 766 memseg->pages[i].mte->entry.ll = 0; 767 768 /* check for mapped pages, revocation cookie != 0 */ 769 if (memseg->pages[i].mte->cookie) { 770 771 pg_size_code = page_szc(MMU_PAGESIZE); 772 pg_shift = page_get_shift(pg_size_code); 773 cookie_addr = IDX2COOKIE(memseg->pages[i].index, 774 pg_size_code, pg_shift); 775 776 D1(ldcp->id, "ldc_mem_unbind_handle: (0x%llx) revoke " 777 "cookie 0x%llx, rcookie 0x%llx\n", ldcp->id, 778 cookie_addr, memseg->pages[i].mte->cookie); 779 780 retries = 0; 781 do { 782 rv = hv_ldc_revoke(ldcp->id, cookie_addr, 783 memseg->pages[i].mte->cookie); 784 785 if (rv != H_EWOULDBLOCK) 786 break; 787 788 drv_usecwait(ldc_delay); 789 790 } while (retries++ < ldc_max_retries); 791 792 if (rv) { 793 DWARN(ldcp->id, 794 "ldc_mem_unbind_handle: (0x%llx) cannot " 795 "revoke mapping, cookie %llx\n", ldcp->id, 796 cookie_addr); 797 } 798 } 799 800 mtbl->num_avail++; 801 } 802 mutex_exit(&mtbl->lock); 803 804 /* free the allocated memseg and page structures */ 805 kmem_free(memseg->pages, (sizeof (ldc_page_t) * memseg->npages)); 806 kmem_free(memseg->cookies, 807 (sizeof (ldc_mem_cookie_t) * memseg->npages)); 808 kmem_cache_free(ldcssp->memseg_cache, memseg); 809 810 /* uninitialize the memory handle */ 811 mhdl->memseg = NULL; 812 mhdl->status = LDC_UNBOUND; 813 814 D1(ldcp->id, "ldc_mem_unbind_handle: (0x%llx) unbound handle 0x%llx\n", 815 ldcp->id, mhdl); 816 817 mutex_exit(&mhdl->lock); 818 return (0); 819 } 820 821 /* 822 * Get information about the dring. The base address of the descriptor 823 * ring along with the type and permission are returned back. 824 */ 825 int 826 ldc_mem_info(ldc_mem_handle_t mhandle, ldc_mem_info_t *minfo) 827 { 828 ldc_mhdl_t *mhdl; 829 830 if (mhandle == NULL) { 831 DWARN(DBG_ALL_LDCS, "ldc_mem_info: invalid memory handle\n"); 832 return (EINVAL); 833 } 834 mhdl = (ldc_mhdl_t *)mhandle; 835 836 if (minfo == NULL) { 837 DWARN(DBG_ALL_LDCS, "ldc_mem_info: invalid args\n"); 838 return (EINVAL); 839 } 840 841 mutex_enter(&mhdl->lock); 842 843 minfo->status = mhdl->status; 844 if (mhdl->status == LDC_BOUND || mhdl->status == LDC_MAPPED) { 845 minfo->vaddr = mhdl->memseg->vaddr; 846 minfo->raddr = mhdl->memseg->raddr; 847 minfo->mtype = mhdl->mtype; 848 minfo->perm = mhdl->perm; 849 } 850 mutex_exit(&mhdl->lock); 851 852 return (0); 853 } 854 855 /* 856 * Copy data either from or to the client specified virtual address 857 * space to or from the exported memory associated with the cookies. 858 * The direction argument determines whether the data is read from or 859 * written to exported memory. 860 */ 861 int 862 ldc_mem_copy(ldc_handle_t handle, caddr_t vaddr, uint64_t off, size_t *size, 863 ldc_mem_cookie_t *cookies, uint32_t ccount, uint8_t direction) 864 { 865 ldc_chan_t *ldcp; 866 uint64_t local_voff, local_valign; 867 uint64_t cookie_addr, cookie_size; 868 uint64_t pg_shift, pg_size, pg_size_code; 869 uint64_t export_caddr, export_poff, export_psize, export_size; 870 uint64_t local_ra, local_poff, local_psize; 871 uint64_t copy_size, copied_len = 0, total_bal = 0, idx = 0; 872 pgcnt_t npages; 873 size_t len = *size; 874 int i, rv = 0; 875 876 uint64_t chid; 877 878 if (handle == NULL) { 879 DWARN(DBG_ALL_LDCS, "ldc_mem_copy: invalid channel handle\n"); 880 return (EINVAL); 881 } 882 ldcp = (ldc_chan_t *)handle; 883 chid = ldcp->id; 884 885 /* check to see if channel is UP */ 886 if (ldcp->tstate != TS_UP) { 887 DWARN(chid, "ldc_mem_copy: (0x%llx) channel is not UP\n", 888 chid); 889 return (ECONNRESET); 890 } 891 892 /* Force address and size to be 8-byte aligned */ 893 if ((((uintptr_t)vaddr | len) & 0x7) != 0) { 894 DWARN(chid, 895 "ldc_mem_copy: addr/sz is not 8-byte aligned\n"); 896 return (EINVAL); 897 } 898 899 /* Find the size of the exported memory */ 900 export_size = 0; 901 for (i = 0; i < ccount; i++) 902 export_size += cookies[i].size; 903 904 /* check to see if offset is valid */ 905 if (off > export_size) { 906 DWARN(chid, 907 "ldc_mem_copy: (0x%llx) start offset > export mem size\n", 908 chid); 909 return (EINVAL); 910 } 911 912 /* 913 * Check to see if the export size is smaller than the size we 914 * are requesting to copy - if so flag an error 915 */ 916 if ((export_size - off) < *size) { 917 DWARN(chid, 918 "ldc_mem_copy: (0x%llx) copy size > export mem size\n", 919 chid); 920 return (EINVAL); 921 } 922 923 total_bal = min(export_size, *size); 924 925 /* FUTURE: get the page size, pgsz code, and shift */ 926 pg_size = MMU_PAGESIZE; 927 pg_size_code = page_szc(pg_size); 928 pg_shift = page_get_shift(pg_size_code); 929 930 D1(chid, "ldc_mem_copy: copying data " 931 "(0x%llx) va 0x%llx pgsz=0x%llx, pgszc=0x%llx, pg_shift=0x%llx\n", 932 chid, vaddr, pg_size, pg_size_code, pg_shift); 933 934 /* aligned VA and its offset */ 935 local_valign = (((uintptr_t)vaddr) & ~(pg_size - 1)); 936 local_voff = ((uintptr_t)vaddr) & (pg_size - 1); 937 938 npages = (len+local_voff)/pg_size; 939 npages = ((len+local_voff)%pg_size == 0) ? npages : npages+1; 940 941 D1(chid, 942 "ldc_mem_copy: (0x%llx) v=0x%llx,val=0x%llx,off=0x%x,pgs=0x%x\n", 943 chid, vaddr, local_valign, local_voff, npages); 944 945 local_ra = va_to_pa((void *)local_valign); 946 local_poff = local_voff; 947 local_psize = min(len, (pg_size - local_voff)); 948 949 len -= local_psize; 950 951 /* 952 * find the first cookie in the list of cookies 953 * if the offset passed in is not zero 954 */ 955 for (idx = 0; idx < ccount; idx++) { 956 cookie_size = cookies[idx].size; 957 if (off < cookie_size) 958 break; 959 off -= cookie_size; 960 } 961 962 cookie_addr = cookies[idx].addr + off; 963 cookie_size = cookies[idx].size - off; 964 965 export_caddr = cookie_addr & ~(pg_size - 1); 966 export_poff = cookie_addr & (pg_size - 1); 967 export_psize = min(cookie_size, (pg_size - export_poff)); 968 969 for (;;) { 970 971 copy_size = min(export_psize, local_psize); 972 973 D1(chid, 974 "ldc_mem_copy:(0x%llx) dir=0x%x, caddr=0x%llx," 975 " loc_ra=0x%llx, exp_poff=0x%llx, loc_poff=0x%llx," 976 " exp_psz=0x%llx, loc_psz=0x%llx, copy_sz=0x%llx," 977 " total_bal=0x%llx\n", 978 chid, direction, export_caddr, local_ra, export_poff, 979 local_poff, export_psize, local_psize, copy_size, 980 total_bal); 981 982 rv = hv_ldc_copy(chid, direction, 983 (export_caddr + export_poff), (local_ra + local_poff), 984 copy_size, &copied_len); 985 986 if (rv != 0) { 987 int error = EIO; 988 uint64_t rx_hd, rx_tl; 989 990 DWARN(chid, 991 "ldc_mem_copy: (0x%llx) err %d during copy\n", 992 (unsigned long long)chid, rv); 993 DWARN(chid, 994 "ldc_mem_copy: (0x%llx) dir=0x%x, caddr=0x%lx, " 995 "loc_ra=0x%lx, exp_poff=0x%lx, loc_poff=0x%lx," 996 " exp_psz=0x%lx, loc_psz=0x%lx, copy_sz=0x%lx," 997 " copied_len=0x%lx, total_bal=0x%lx\n", 998 chid, direction, export_caddr, local_ra, 999 export_poff, local_poff, export_psize, local_psize, 1000 copy_size, copied_len, total_bal); 1001 1002 *size = *size - total_bal; 1003 1004 /* 1005 * check if reason for copy error was due to 1006 * a channel reset. we need to grab the lock 1007 * just in case we have to do a reset. 1008 */ 1009 mutex_enter(&ldcp->lock); 1010 mutex_enter(&ldcp->tx_lock); 1011 1012 rv = hv_ldc_rx_get_state(ldcp->id, 1013 &rx_hd, &rx_tl, &(ldcp->link_state)); 1014 if (ldcp->link_state == LDC_CHANNEL_DOWN || 1015 ldcp->link_state == LDC_CHANNEL_RESET) { 1016 i_ldc_reset(ldcp, B_FALSE); 1017 error = ECONNRESET; 1018 } 1019 1020 mutex_exit(&ldcp->tx_lock); 1021 mutex_exit(&ldcp->lock); 1022 1023 return (error); 1024 } 1025 1026 ASSERT(copied_len <= copy_size); 1027 1028 D2(chid, "ldc_mem_copy: copied=0x%llx\n", copied_len); 1029 export_poff += copied_len; 1030 local_poff += copied_len; 1031 export_psize -= copied_len; 1032 local_psize -= copied_len; 1033 cookie_size -= copied_len; 1034 1035 total_bal -= copied_len; 1036 1037 if (copy_size != copied_len) 1038 continue; 1039 1040 if (export_psize == 0 && total_bal != 0) { 1041 1042 if (cookie_size == 0) { 1043 idx++; 1044 cookie_addr = cookies[idx].addr; 1045 cookie_size = cookies[idx].size; 1046 1047 export_caddr = cookie_addr & ~(pg_size - 1); 1048 export_poff = cookie_addr & (pg_size - 1); 1049 export_psize = 1050 min(cookie_size, (pg_size-export_poff)); 1051 } else { 1052 export_caddr += pg_size; 1053 export_poff = 0; 1054 export_psize = min(cookie_size, pg_size); 1055 } 1056 } 1057 1058 if (local_psize == 0 && total_bal != 0) { 1059 local_valign += pg_size; 1060 local_ra = va_to_pa((void *)local_valign); 1061 local_poff = 0; 1062 local_psize = min(pg_size, len); 1063 len -= local_psize; 1064 } 1065 1066 /* check if we are all done */ 1067 if (total_bal == 0) 1068 break; 1069 } 1070 1071 1072 D1(chid, 1073 "ldc_mem_copy: (0x%llx) done copying sz=0x%llx\n", 1074 chid, *size); 1075 1076 return (0); 1077 } 1078 1079 /* 1080 * Copy data either from or to the client specified virtual address 1081 * space to or from HV physical memory. 1082 * 1083 * The direction argument determines whether the data is read from or 1084 * written to HV memory. direction values are LDC_COPY_IN/OUT similar 1085 * to the ldc_mem_copy interface 1086 */ 1087 int 1088 ldc_mem_rdwr_cookie(ldc_handle_t handle, caddr_t vaddr, size_t *size, 1089 caddr_t paddr, uint8_t direction) 1090 { 1091 ldc_chan_t *ldcp; 1092 uint64_t local_voff, local_valign; 1093 uint64_t pg_shift, pg_size, pg_size_code; 1094 uint64_t target_pa, target_poff, target_psize, target_size; 1095 uint64_t local_ra, local_poff, local_psize; 1096 uint64_t copy_size, copied_len = 0; 1097 pgcnt_t npages; 1098 size_t len = *size; 1099 int rv = 0; 1100 1101 if (handle == NULL) { 1102 DWARN(DBG_ALL_LDCS, 1103 "ldc_mem_rdwr_cookie: invalid channel handle\n"); 1104 return (EINVAL); 1105 } 1106 ldcp = (ldc_chan_t *)handle; 1107 1108 mutex_enter(&ldcp->lock); 1109 1110 /* check to see if channel is UP */ 1111 if (ldcp->tstate != TS_UP) { 1112 DWARN(ldcp->id, 1113 "ldc_mem_rdwr_cookie: (0x%llx) channel is not UP\n", 1114 ldcp->id); 1115 mutex_exit(&ldcp->lock); 1116 return (ECONNRESET); 1117 } 1118 1119 /* Force address and size to be 8-byte aligned */ 1120 if ((((uintptr_t)vaddr | len) & 0x7) != 0) { 1121 DWARN(ldcp->id, 1122 "ldc_mem_rdwr_cookie: addr/size is not 8-byte aligned\n"); 1123 mutex_exit(&ldcp->lock); 1124 return (EINVAL); 1125 } 1126 1127 target_size = *size; 1128 1129 /* FUTURE: get the page size, pgsz code, and shift */ 1130 pg_size = MMU_PAGESIZE; 1131 pg_size_code = page_szc(pg_size); 1132 pg_shift = page_get_shift(pg_size_code); 1133 1134 D1(ldcp->id, "ldc_mem_rdwr_cookie: copying data " 1135 "(0x%llx) va 0x%llx pgsz=0x%llx, pgszc=0x%llx, pg_shift=0x%llx\n", 1136 ldcp->id, vaddr, pg_size, pg_size_code, pg_shift); 1137 1138 /* aligned VA and its offset */ 1139 local_valign = ((uintptr_t)vaddr) & ~(pg_size - 1); 1140 local_voff = ((uintptr_t)vaddr) & (pg_size - 1); 1141 1142 npages = (len + local_voff) / pg_size; 1143 npages = ((len + local_voff) % pg_size == 0) ? npages : npages+1; 1144 1145 D1(ldcp->id, "ldc_mem_rdwr_cookie: (0x%llx) v=0x%llx, " 1146 "val=0x%llx,off=0x%x,pgs=0x%x\n", 1147 ldcp->id, vaddr, local_valign, local_voff, npages); 1148 1149 local_ra = va_to_pa((void *)local_valign); 1150 local_poff = local_voff; 1151 local_psize = min(len, (pg_size - local_voff)); 1152 1153 len -= local_psize; 1154 1155 target_pa = ((uintptr_t)paddr) & ~(pg_size - 1); 1156 target_poff = ((uintptr_t)paddr) & (pg_size - 1); 1157 target_psize = pg_size - target_poff; 1158 1159 for (;;) { 1160 1161 copy_size = min(target_psize, local_psize); 1162 1163 D1(ldcp->id, 1164 "ldc_mem_rdwr_cookie: (0x%llx) dir=0x%x, tar_pa=0x%llx," 1165 " loc_ra=0x%llx, tar_poff=0x%llx, loc_poff=0x%llx," 1166 " tar_psz=0x%llx, loc_psz=0x%llx, copy_sz=0x%llx," 1167 " total_bal=0x%llx\n", 1168 ldcp->id, direction, target_pa, local_ra, target_poff, 1169 local_poff, target_psize, local_psize, copy_size, 1170 target_size); 1171 1172 rv = hv_ldc_copy(ldcp->id, direction, 1173 (target_pa + target_poff), (local_ra + local_poff), 1174 copy_size, &copied_len); 1175 1176 if (rv != 0) { 1177 DWARN(DBG_ALL_LDCS, 1178 "ldc_mem_rdwr_cookie: (0x%lx) err %d during copy\n", 1179 ldcp->id, rv); 1180 DWARN(DBG_ALL_LDCS, 1181 "ldc_mem_rdwr_cookie: (0x%llx) dir=%lld, " 1182 "tar_pa=0x%llx, loc_ra=0x%llx, tar_poff=0x%llx, " 1183 "loc_poff=0x%llx, tar_psz=0x%llx, loc_psz=0x%llx, " 1184 "copy_sz=0x%llx, total_bal=0x%llx\n", 1185 ldcp->id, direction, target_pa, local_ra, 1186 target_poff, local_poff, target_psize, local_psize, 1187 copy_size, target_size); 1188 1189 *size = *size - target_size; 1190 mutex_exit(&ldcp->lock); 1191 return (i_ldc_h2v_error(rv)); 1192 } 1193 1194 D2(ldcp->id, "ldc_mem_rdwr_cookie: copied=0x%llx\n", 1195 copied_len); 1196 target_poff += copied_len; 1197 local_poff += copied_len; 1198 target_psize -= copied_len; 1199 local_psize -= copied_len; 1200 1201 target_size -= copied_len; 1202 1203 if (copy_size != copied_len) 1204 continue; 1205 1206 if (target_psize == 0 && target_size != 0) { 1207 target_pa += pg_size; 1208 target_poff = 0; 1209 target_psize = min(pg_size, target_size); 1210 } 1211 1212 if (local_psize == 0 && target_size != 0) { 1213 local_valign += pg_size; 1214 local_ra = va_to_pa((void *)local_valign); 1215 local_poff = 0; 1216 local_psize = min(pg_size, len); 1217 len -= local_psize; 1218 } 1219 1220 /* check if we are all done */ 1221 if (target_size == 0) 1222 break; 1223 } 1224 1225 mutex_exit(&ldcp->lock); 1226 1227 D1(ldcp->id, "ldc_mem_rdwr_cookie: (0x%llx) done copying sz=0x%llx\n", 1228 ldcp->id, *size); 1229 1230 return (0); 1231 } 1232 1233 /* 1234 * Map an exported memory segment into the local address space. If the 1235 * memory range was exported for direct map access, a HV call is made 1236 * to allocate a RA range. If the map is done via a shadow copy, local 1237 * shadow memory is allocated and the base VA is returned in 'vaddr'. If 1238 * the mapping is a direct map then the RA is returned in 'raddr'. 1239 */ 1240 int 1241 ldc_mem_map(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie, uint32_t ccount, 1242 uint8_t mtype, uint8_t perm, caddr_t *vaddr, caddr_t *raddr) 1243 { 1244 /* 1245 * Check if direct map over shared memory is enabled, if not change 1246 * the mapping type to SHADOW_MAP. 1247 */ 1248 if (ldc_shmem_enabled == 0) 1249 mtype = LDC_SHADOW_MAP; 1250 1251 return (i_ldc_mem_map(mhandle, cookie, ccount, mtype, perm, 1252 vaddr, raddr)); 1253 } 1254 1255 static int 1256 i_ldc_mem_map(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie, 1257 uint32_t ccount, uint8_t mtype, uint8_t perm, caddr_t *vaddr, 1258 caddr_t *raddr) 1259 { 1260 1261 int i, j, idx, rv, retries; 1262 ldc_chan_t *ldcp; 1263 ldc_mhdl_t *mhdl; 1264 ldc_memseg_t *memseg; 1265 caddr_t tmpaddr; 1266 uint64_t map_perm = perm; 1267 uint64_t pg_size, pg_shift, pg_size_code, pg_mask; 1268 uint64_t exp_size = 0, base_off, map_size, npages; 1269 uint64_t cookie_addr, cookie_off, cookie_size; 1270 tte_t ldc_tte; 1271 1272 if (mhandle == NULL) { 1273 DWARN(DBG_ALL_LDCS, "ldc_mem_map: invalid memory handle\n"); 1274 return (EINVAL); 1275 } 1276 mhdl = (ldc_mhdl_t *)mhandle; 1277 1278 mutex_enter(&mhdl->lock); 1279 1280 if (mhdl->status == LDC_BOUND || mhdl->status == LDC_MAPPED || 1281 mhdl->memseg != NULL) { 1282 DWARN(DBG_ALL_LDCS, 1283 "ldc_mem_map: (0x%llx) handle bound/mapped\n", mhandle); 1284 mutex_exit(&mhdl->lock); 1285 return (EINVAL); 1286 } 1287 1288 ldcp = mhdl->ldcp; 1289 1290 mutex_enter(&ldcp->lock); 1291 1292 if (ldcp->tstate != TS_UP) { 1293 DWARN(ldcp->id, 1294 "ldc_mem_dring_map: (0x%llx) channel is not UP\n", 1295 ldcp->id); 1296 mutex_exit(&ldcp->lock); 1297 mutex_exit(&mhdl->lock); 1298 return (ECONNRESET); 1299 } 1300 1301 if ((mtype & (LDC_SHADOW_MAP|LDC_DIRECT_MAP|LDC_IO_MAP)) == 0) { 1302 DWARN(ldcp->id, "ldc_mem_map: invalid map type\n"); 1303 mutex_exit(&ldcp->lock); 1304 mutex_exit(&mhdl->lock); 1305 return (EINVAL); 1306 } 1307 1308 D1(ldcp->id, "ldc_mem_map: (0x%llx) cookie = 0x%llx,0x%llx\n", 1309 ldcp->id, cookie->addr, cookie->size); 1310 1311 /* FUTURE: get the page size, pgsz code, and shift */ 1312 pg_size = MMU_PAGESIZE; 1313 pg_size_code = page_szc(pg_size); 1314 pg_shift = page_get_shift(pg_size_code); 1315 pg_mask = ~(pg_size - 1); 1316 1317 /* calculate the number of pages in the exported cookie */ 1318 base_off = cookie[0].addr & (pg_size - 1); 1319 for (idx = 0; idx < ccount; idx++) 1320 exp_size += cookie[idx].size; 1321 map_size = P2ROUNDUP((exp_size + base_off), pg_size); 1322 npages = (map_size >> pg_shift); 1323 1324 /* Allocate memseg structure */ 1325 memseg = mhdl->memseg = 1326 kmem_cache_alloc(ldcssp->memseg_cache, KM_SLEEP); 1327 1328 /* Allocate memory to store all pages and cookies */ 1329 memseg->pages = kmem_zalloc((sizeof (ldc_page_t) * npages), KM_SLEEP); 1330 memseg->cookies = 1331 kmem_zalloc((sizeof (ldc_mem_cookie_t) * ccount), KM_SLEEP); 1332 1333 D2(ldcp->id, "ldc_mem_map: (0x%llx) exp_size=0x%llx, map_size=0x%llx," 1334 "pages=0x%llx\n", ldcp->id, exp_size, map_size, npages); 1335 1336 /* 1337 * Check to see if the client is requesting direct or shadow map 1338 * If direct map is requested, try to map remote memory first, 1339 * and if that fails, revert to shadow map 1340 */ 1341 if (mtype == LDC_DIRECT_MAP) { 1342 1343 /* Allocate kernel virtual space for mapping */ 1344 memseg->vaddr = vmem_xalloc(heap_arena, map_size, 1345 pg_size, 0, 0, NULL, NULL, VM_NOSLEEP); 1346 if (memseg->vaddr == NULL) { 1347 DWARN(DBG_ALL_LDCS, 1348 "ldc_mem_map: (0x%lx) memory map failed\n", 1349 ldcp->id); 1350 kmem_free(memseg->cookies, 1351 (sizeof (ldc_mem_cookie_t) * ccount)); 1352 kmem_free(memseg->pages, 1353 (sizeof (ldc_page_t) * npages)); 1354 kmem_cache_free(ldcssp->memseg_cache, memseg); 1355 1356 mutex_exit(&ldcp->lock); 1357 mutex_exit(&mhdl->lock); 1358 return (ENOMEM); 1359 } 1360 1361 /* Unload previous mapping */ 1362 hat_unload(kas.a_hat, memseg->vaddr, map_size, 1363 HAT_UNLOAD_NOSYNC | HAT_UNLOAD_UNLOCK); 1364 1365 /* for each cookie passed in - map into address space */ 1366 idx = 0; 1367 cookie_size = 0; 1368 tmpaddr = memseg->vaddr; 1369 1370 for (i = 0; i < npages; i++) { 1371 1372 if (cookie_size == 0) { 1373 ASSERT(idx < ccount); 1374 cookie_addr = cookie[idx].addr & pg_mask; 1375 cookie_off = cookie[idx].addr & (pg_size - 1); 1376 cookie_size = 1377 P2ROUNDUP((cookie_off + cookie[idx].size), 1378 pg_size); 1379 idx++; 1380 } 1381 1382 D1(ldcp->id, "ldc_mem_map: (0x%llx) mapping " 1383 "cookie 0x%llx, bal=0x%llx\n", ldcp->id, 1384 cookie_addr, cookie_size); 1385 1386 /* map the cookie into address space */ 1387 for (retries = 0; retries < ldc_max_retries; 1388 retries++) { 1389 1390 rv = hv_ldc_mapin(ldcp->id, cookie_addr, 1391 &memseg->pages[i].raddr, &map_perm); 1392 if (rv != H_EWOULDBLOCK && rv != H_ETOOMANY) 1393 break; 1394 1395 drv_usecwait(ldc_delay); 1396 } 1397 1398 if (rv || memseg->pages[i].raddr == 0) { 1399 DWARN(ldcp->id, 1400 "ldc_mem_map: (0x%llx) hv mapin err %d\n", 1401 ldcp->id, rv); 1402 1403 /* remove previous mapins */ 1404 hat_unload(kas.a_hat, memseg->vaddr, map_size, 1405 HAT_UNLOAD_NOSYNC | HAT_UNLOAD_UNLOCK); 1406 for (j = 0; j < i; j++) { 1407 rv = hv_ldc_unmap( 1408 memseg->pages[j].raddr); 1409 if (rv) { 1410 DWARN(ldcp->id, 1411 "ldc_mem_map: (0x%llx) " 1412 "cannot unmap ra=0x%llx\n", 1413 ldcp->id, 1414 memseg->pages[j].raddr); 1415 } 1416 } 1417 1418 /* free kernel virtual space */ 1419 vmem_free(heap_arena, (void *)memseg->vaddr, 1420 map_size); 1421 1422 /* direct map failed - revert to shadow map */ 1423 mtype = LDC_SHADOW_MAP; 1424 break; 1425 1426 } else { 1427 1428 D1(ldcp->id, 1429 "ldc_mem_map: (0x%llx) vtop map 0x%llx -> " 1430 "0x%llx, cookie=0x%llx, perm=0x%llx\n", 1431 ldcp->id, tmpaddr, memseg->pages[i].raddr, 1432 cookie_addr, perm); 1433 1434 /* 1435 * NOTE: Calling hat_devload directly, causes it 1436 * to look for page_t using the pfn. Since this 1437 * addr is greater than the memlist, it treates 1438 * it as non-memory 1439 */ 1440 sfmmu_memtte(&ldc_tte, 1441 (pfn_t)(memseg->pages[i].raddr >> pg_shift), 1442 PROT_READ | PROT_WRITE | HAT_NOSYNC, TTE8K); 1443 1444 D1(ldcp->id, 1445 "ldc_mem_map: (0x%llx) ra 0x%llx -> " 1446 "tte 0x%llx\n", ldcp->id, 1447 memseg->pages[i].raddr, ldc_tte); 1448 1449 sfmmu_tteload(kas.a_hat, &ldc_tte, tmpaddr, 1450 NULL, HAT_LOAD_LOCK); 1451 1452 cookie_size -= pg_size; 1453 cookie_addr += pg_size; 1454 tmpaddr += pg_size; 1455 } 1456 } 1457 } 1458 1459 if (mtype == LDC_SHADOW_MAP) { 1460 if (*vaddr == NULL) { 1461 memseg->vaddr = kmem_zalloc(exp_size, KM_SLEEP); 1462 mhdl->myshadow = B_TRUE; 1463 1464 D1(ldcp->id, "ldc_mem_map: (0x%llx) allocated " 1465 "shadow page va=0x%llx\n", ldcp->id, memseg->vaddr); 1466 } else { 1467 /* 1468 * Use client supplied memory for memseg->vaddr 1469 * WARNING: assuming that client mem is >= exp_size 1470 */ 1471 memseg->vaddr = *vaddr; 1472 } 1473 1474 /* Save all page and cookie information */ 1475 for (i = 0, tmpaddr = memseg->vaddr; i < npages; i++) { 1476 memseg->pages[i].raddr = va_to_pa(tmpaddr); 1477 tmpaddr += pg_size; 1478 } 1479 1480 } 1481 1482 /* save all cookies */ 1483 bcopy(cookie, memseg->cookies, ccount * sizeof (ldc_mem_cookie_t)); 1484 1485 /* update memseg_t */ 1486 memseg->raddr = memseg->pages[0].raddr; 1487 memseg->size = (mtype == LDC_SHADOW_MAP) ? exp_size : map_size; 1488 memseg->npages = npages; 1489 memseg->ncookies = ccount; 1490 memseg->next_cookie = 0; 1491 1492 /* memory handle = mapped */ 1493 mhdl->mtype = mtype; 1494 mhdl->perm = perm; 1495 mhdl->status = LDC_MAPPED; 1496 1497 D1(ldcp->id, "ldc_mem_map: (0x%llx) mapped 0x%llx, ra=0x%llx, " 1498 "va=0x%llx, pgs=0x%llx cookies=0x%llx\n", 1499 ldcp->id, mhdl, memseg->raddr, memseg->vaddr, 1500 memseg->npages, memseg->ncookies); 1501 1502 if (mtype == LDC_SHADOW_MAP) 1503 base_off = 0; 1504 if (raddr) 1505 *raddr = (caddr_t)(memseg->raddr | base_off); 1506 if (vaddr) 1507 *vaddr = (caddr_t)((uintptr_t)memseg->vaddr | base_off); 1508 1509 mutex_exit(&ldcp->lock); 1510 mutex_exit(&mhdl->lock); 1511 return (0); 1512 } 1513 1514 /* 1515 * Unmap a memory segment. Free shadow memory (if any). 1516 */ 1517 int 1518 ldc_mem_unmap(ldc_mem_handle_t mhandle) 1519 { 1520 int i, rv; 1521 ldc_mhdl_t *mhdl = (ldc_mhdl_t *)mhandle; 1522 ldc_chan_t *ldcp; 1523 ldc_memseg_t *memseg; 1524 1525 if (mhdl == 0 || mhdl->status != LDC_MAPPED) { 1526 DWARN(DBG_ALL_LDCS, 1527 "ldc_mem_unmap: (0x%llx) handle is not mapped\n", 1528 mhandle); 1529 return (EINVAL); 1530 } 1531 1532 mutex_enter(&mhdl->lock); 1533 1534 ldcp = mhdl->ldcp; 1535 memseg = mhdl->memseg; 1536 1537 D1(ldcp->id, "ldc_mem_unmap: (0x%llx) unmapping handle 0x%llx\n", 1538 ldcp->id, mhdl); 1539 1540 /* if we allocated shadow memory - free it */ 1541 if (mhdl->mtype == LDC_SHADOW_MAP && mhdl->myshadow) { 1542 kmem_free(memseg->vaddr, memseg->size); 1543 } else if (mhdl->mtype == LDC_DIRECT_MAP) { 1544 1545 /* unmap in the case of DIRECT_MAP */ 1546 hat_unload(kas.a_hat, memseg->vaddr, memseg->size, 1547 HAT_UNLOAD_UNLOCK); 1548 1549 for (i = 0; i < memseg->npages; i++) { 1550 rv = hv_ldc_unmap(memseg->pages[i].raddr); 1551 if (rv) { 1552 DWARN(DBG_ALL_LDCS, 1553 "ldc_mem_map: (0x%lx) hv unmap err %d\n", 1554 ldcp->id, rv); 1555 } 1556 } 1557 1558 vmem_free(heap_arena, (void *)memseg->vaddr, memseg->size); 1559 } 1560 1561 /* free the allocated memseg and page structures */ 1562 kmem_free(memseg->pages, (sizeof (ldc_page_t) * memseg->npages)); 1563 kmem_free(memseg->cookies, 1564 (sizeof (ldc_mem_cookie_t) * memseg->ncookies)); 1565 kmem_cache_free(ldcssp->memseg_cache, memseg); 1566 1567 /* uninitialize the memory handle */ 1568 mhdl->memseg = NULL; 1569 mhdl->status = LDC_UNBOUND; 1570 1571 D1(ldcp->id, "ldc_mem_unmap: (0x%llx) unmapped handle 0x%llx\n", 1572 ldcp->id, mhdl); 1573 1574 mutex_exit(&mhdl->lock); 1575 return (0); 1576 } 1577 1578 /* 1579 * Internal entry point for LDC mapped memory entry consistency 1580 * semantics. Acquire copies the contents of the remote memory 1581 * into the local shadow copy. The release operation copies the local 1582 * contents into the remote memory. The offset and size specify the 1583 * bounds for the memory range being synchronized. 1584 */ 1585 static int 1586 i_ldc_mem_acquire_release(ldc_mem_handle_t mhandle, uint8_t direction, 1587 uint64_t offset, size_t size) 1588 { 1589 int err; 1590 ldc_mhdl_t *mhdl; 1591 ldc_chan_t *ldcp; 1592 ldc_memseg_t *memseg; 1593 caddr_t local_vaddr; 1594 size_t copy_size; 1595 1596 if (mhandle == NULL) { 1597 DWARN(DBG_ALL_LDCS, 1598 "i_ldc_mem_acquire_release: invalid memory handle\n"); 1599 return (EINVAL); 1600 } 1601 mhdl = (ldc_mhdl_t *)mhandle; 1602 1603 mutex_enter(&mhdl->lock); 1604 1605 if (mhdl->status != LDC_MAPPED || mhdl->ldcp == NULL) { 1606 DWARN(DBG_ALL_LDCS, 1607 "i_ldc_mem_acquire_release: not mapped memory\n"); 1608 mutex_exit(&mhdl->lock); 1609 return (EINVAL); 1610 } 1611 1612 /* do nothing for direct map */ 1613 if (mhdl->mtype == LDC_DIRECT_MAP) { 1614 mutex_exit(&mhdl->lock); 1615 return (0); 1616 } 1617 1618 /* do nothing if COPY_IN+MEM_W and COPY_OUT+MEM_R */ 1619 if ((direction == LDC_COPY_IN && (mhdl->perm & LDC_MEM_R) == 0) || 1620 (direction == LDC_COPY_OUT && (mhdl->perm & LDC_MEM_W) == 0)) { 1621 mutex_exit(&mhdl->lock); 1622 return (0); 1623 } 1624 1625 if (offset >= mhdl->memseg->size || 1626 (offset + size) > mhdl->memseg->size) { 1627 DWARN(DBG_ALL_LDCS, 1628 "i_ldc_mem_acquire_release: memory out of range\n"); 1629 mutex_exit(&mhdl->lock); 1630 return (EINVAL); 1631 } 1632 1633 /* get the channel handle and memory segment */ 1634 ldcp = mhdl->ldcp; 1635 memseg = mhdl->memseg; 1636 1637 if (mhdl->mtype == LDC_SHADOW_MAP) { 1638 1639 local_vaddr = memseg->vaddr + offset; 1640 copy_size = size; 1641 1642 /* copy to/from remote from/to local memory */ 1643 err = ldc_mem_copy((ldc_handle_t)ldcp, local_vaddr, offset, 1644 ©_size, memseg->cookies, memseg->ncookies, 1645 direction); 1646 if (err || copy_size != size) { 1647 DWARN(ldcp->id, 1648 "i_ldc_mem_acquire_release: copy failed\n"); 1649 mutex_exit(&mhdl->lock); 1650 return (err); 1651 } 1652 } 1653 1654 mutex_exit(&mhdl->lock); 1655 1656 return (0); 1657 } 1658 1659 /* 1660 * Ensure that the contents in the remote memory seg are consistent 1661 * with the contents if of local segment 1662 */ 1663 int 1664 ldc_mem_acquire(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size) 1665 { 1666 return (i_ldc_mem_acquire_release(mhandle, LDC_COPY_IN, offset, size)); 1667 } 1668 1669 1670 /* 1671 * Ensure that the contents in the local memory seg are consistent 1672 * with the contents if of remote segment 1673 */ 1674 int 1675 ldc_mem_release(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size) 1676 { 1677 return (i_ldc_mem_acquire_release(mhandle, LDC_COPY_OUT, offset, size)); 1678 } 1679 1680 /* 1681 * Allocate a descriptor ring. The size of each each descriptor 1682 * must be 8-byte aligned and the entire ring should be a multiple 1683 * of MMU_PAGESIZE. 1684 */ 1685 int 1686 ldc_mem_dring_create(uint32_t len, uint32_t dsize, ldc_dring_handle_t *dhandle) 1687 { 1688 ldc_dring_t *dringp; 1689 size_t size = (dsize * len); 1690 1691 D1(DBG_ALL_LDCS, "ldc_mem_dring_create: len=0x%x, size=0x%x\n", 1692 len, dsize); 1693 1694 if (dhandle == NULL) { 1695 DWARN(DBG_ALL_LDCS, "ldc_mem_dring_create: invalid dhandle\n"); 1696 return (EINVAL); 1697 } 1698 1699 if (len == 0) { 1700 DWARN(DBG_ALL_LDCS, "ldc_mem_dring_create: invalid length\n"); 1701 return (EINVAL); 1702 } 1703 1704 /* descriptor size should be 8-byte aligned */ 1705 if (dsize == 0 || (dsize & 0x7)) { 1706 DWARN(DBG_ALL_LDCS, "ldc_mem_dring_create: invalid size\n"); 1707 return (EINVAL); 1708 } 1709 1710 *dhandle = 0; 1711 1712 /* Allocate a desc ring structure */ 1713 dringp = kmem_zalloc(sizeof (ldc_dring_t), KM_SLEEP); 1714 1715 /* Initialize dring */ 1716 dringp->length = len; 1717 dringp->dsize = dsize; 1718 1719 /* round off to multiple of pagesize */ 1720 dringp->size = (size & MMU_PAGEMASK); 1721 if (size & MMU_PAGEOFFSET) 1722 dringp->size += MMU_PAGESIZE; 1723 1724 dringp->status = LDC_UNBOUND; 1725 1726 /* allocate descriptor ring memory */ 1727 dringp->base = kmem_zalloc(dringp->size, KM_SLEEP); 1728 1729 /* initialize the desc ring lock */ 1730 mutex_init(&dringp->lock, NULL, MUTEX_DRIVER, NULL); 1731 1732 /* Add descriptor ring to the head of global list */ 1733 mutex_enter(&ldcssp->lock); 1734 dringp->next = ldcssp->dring_list; 1735 ldcssp->dring_list = dringp; 1736 mutex_exit(&ldcssp->lock); 1737 1738 *dhandle = (ldc_dring_handle_t)dringp; 1739 1740 D1(DBG_ALL_LDCS, "ldc_mem_dring_create: dring allocated\n"); 1741 1742 return (0); 1743 } 1744 1745 1746 /* 1747 * Destroy a descriptor ring. 1748 */ 1749 int 1750 ldc_mem_dring_destroy(ldc_dring_handle_t dhandle) 1751 { 1752 ldc_dring_t *dringp; 1753 ldc_dring_t *tmp_dringp; 1754 1755 D1(DBG_ALL_LDCS, "ldc_mem_dring_destroy: entered\n"); 1756 1757 if (dhandle == NULL) { 1758 DWARN(DBG_ALL_LDCS, 1759 "ldc_mem_dring_destroy: invalid desc ring handle\n"); 1760 return (EINVAL); 1761 } 1762 dringp = (ldc_dring_t *)dhandle; 1763 1764 if (dringp->status == LDC_BOUND) { 1765 DWARN(DBG_ALL_LDCS, 1766 "ldc_mem_dring_destroy: desc ring is bound\n"); 1767 return (EACCES); 1768 } 1769 1770 mutex_enter(&dringp->lock); 1771 mutex_enter(&ldcssp->lock); 1772 1773 /* remove from linked list - if not bound */ 1774 tmp_dringp = ldcssp->dring_list; 1775 if (tmp_dringp == dringp) { 1776 ldcssp->dring_list = dringp->next; 1777 dringp->next = NULL; 1778 1779 } else { 1780 while (tmp_dringp != NULL) { 1781 if (tmp_dringp->next == dringp) { 1782 tmp_dringp->next = dringp->next; 1783 dringp->next = NULL; 1784 break; 1785 } 1786 tmp_dringp = tmp_dringp->next; 1787 } 1788 if (tmp_dringp == NULL) { 1789 DWARN(DBG_ALL_LDCS, 1790 "ldc_mem_dring_destroy: invalid descriptor\n"); 1791 mutex_exit(&ldcssp->lock); 1792 mutex_exit(&dringp->lock); 1793 return (EINVAL); 1794 } 1795 } 1796 1797 mutex_exit(&ldcssp->lock); 1798 1799 /* free the descriptor ring */ 1800 kmem_free(dringp->base, dringp->size); 1801 1802 mutex_exit(&dringp->lock); 1803 1804 /* destroy dring lock */ 1805 mutex_destroy(&dringp->lock); 1806 1807 /* free desc ring object */ 1808 kmem_free(dringp, sizeof (ldc_dring_t)); 1809 1810 return (0); 1811 } 1812 1813 /* 1814 * Bind a previously allocated dring to a channel. The channel should 1815 * be OPEN in order to bind the ring to the channel. Returns back a 1816 * descriptor ring cookie. The descriptor ring is exported for remote 1817 * access by the client at the other end of the channel. An entry for 1818 * dring pages is stored in map table (via call to ldc_mem_bind_handle). 1819 */ 1820 int 1821 ldc_mem_dring_bind(ldc_handle_t handle, ldc_dring_handle_t dhandle, 1822 uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, uint32_t *ccount) 1823 { 1824 int err; 1825 ldc_chan_t *ldcp; 1826 ldc_dring_t *dringp; 1827 ldc_mem_handle_t mhandle; 1828 1829 /* check to see if channel is initalized */ 1830 if (handle == NULL) { 1831 DWARN(DBG_ALL_LDCS, 1832 "ldc_mem_dring_bind: invalid channel handle\n"); 1833 return (EINVAL); 1834 } 1835 ldcp = (ldc_chan_t *)handle; 1836 1837 if (dhandle == NULL) { 1838 DWARN(DBG_ALL_LDCS, 1839 "ldc_mem_dring_bind: invalid desc ring handle\n"); 1840 return (EINVAL); 1841 } 1842 dringp = (ldc_dring_t *)dhandle; 1843 1844 if (cookie == NULL) { 1845 DWARN(ldcp->id, 1846 "ldc_mem_dring_bind: invalid cookie arg\n"); 1847 return (EINVAL); 1848 } 1849 1850 /* ensure the mtype is valid */ 1851 if ((mtype & (LDC_SHADOW_MAP|LDC_DIRECT_MAP)) == 0) { 1852 DWARN(ldcp->id, "ldc_mem_dring_bind: invalid map type\n"); 1853 return (EINVAL); 1854 } 1855 1856 /* no need to bind as direct map if it's not HV supported or enabled */ 1857 if (!ldc_dring_shmem_hv_ok || !ldc_dring_shmem_enabled) { 1858 mtype = LDC_SHADOW_MAP; 1859 } 1860 1861 mutex_enter(&dringp->lock); 1862 1863 if (dringp->status == LDC_BOUND) { 1864 DWARN(DBG_ALL_LDCS, 1865 "ldc_mem_dring_bind: (0x%llx) descriptor ring is bound\n", 1866 ldcp->id); 1867 mutex_exit(&dringp->lock); 1868 return (EINVAL); 1869 } 1870 1871 if ((perm & LDC_MEM_RW) == 0) { 1872 DWARN(DBG_ALL_LDCS, 1873 "ldc_mem_dring_bind: invalid permissions\n"); 1874 mutex_exit(&dringp->lock); 1875 return (EINVAL); 1876 } 1877 1878 if ((mtype & (LDC_SHADOW_MAP|LDC_DIRECT_MAP|LDC_IO_MAP)) == 0) { 1879 DWARN(DBG_ALL_LDCS, "ldc_mem_dring_bind: invalid type\n"); 1880 mutex_exit(&dringp->lock); 1881 return (EINVAL); 1882 } 1883 1884 dringp->ldcp = ldcp; 1885 1886 /* create an memory handle */ 1887 err = ldc_mem_alloc_handle(handle, &mhandle); 1888 if (err || mhandle == NULL) { 1889 DWARN(DBG_ALL_LDCS, 1890 "ldc_mem_dring_bind: (0x%llx) error allocating mhandle\n", 1891 ldcp->id); 1892 mutex_exit(&dringp->lock); 1893 return (err); 1894 } 1895 dringp->mhdl = mhandle; 1896 1897 /* bind the descriptor ring to channel */ 1898 err = i_ldc_mem_bind_handle(mhandle, dringp->base, dringp->size, 1899 mtype, perm, cookie, ccount); 1900 if (err) { 1901 DWARN(ldcp->id, 1902 "ldc_mem_dring_bind: (0x%llx) error binding mhandle\n", 1903 ldcp->id); 1904 mutex_exit(&dringp->lock); 1905 return (err); 1906 } 1907 1908 /* 1909 * For now return error if we get more than one cookie 1910 * FUTURE: Return multiple cookies .. 1911 */ 1912 if (*ccount > 1) { 1913 (void) ldc_mem_unbind_handle(mhandle); 1914 (void) ldc_mem_free_handle(mhandle); 1915 1916 dringp->ldcp = NULL; 1917 dringp->mhdl = NULL; 1918 *ccount = 0; 1919 1920 mutex_exit(&dringp->lock); 1921 return (EAGAIN); 1922 } 1923 1924 /* Add descriptor ring to channel's exported dring list */ 1925 mutex_enter(&ldcp->exp_dlist_lock); 1926 dringp->ch_next = ldcp->exp_dring_list; 1927 ldcp->exp_dring_list = dringp; 1928 mutex_exit(&ldcp->exp_dlist_lock); 1929 1930 dringp->status = LDC_BOUND; 1931 1932 mutex_exit(&dringp->lock); 1933 1934 return (0); 1935 } 1936 1937 /* 1938 * Return the next cookie associated with the specified dring handle 1939 */ 1940 int 1941 ldc_mem_dring_nextcookie(ldc_dring_handle_t dhandle, ldc_mem_cookie_t *cookie) 1942 { 1943 int rv = 0; 1944 ldc_dring_t *dringp; 1945 ldc_chan_t *ldcp; 1946 1947 if (dhandle == NULL) { 1948 DWARN(DBG_ALL_LDCS, 1949 "ldc_mem_dring_nextcookie: invalid desc ring handle\n"); 1950 return (EINVAL); 1951 } 1952 dringp = (ldc_dring_t *)dhandle; 1953 mutex_enter(&dringp->lock); 1954 1955 if (dringp->status != LDC_BOUND) { 1956 DWARN(DBG_ALL_LDCS, 1957 "ldc_mem_dring_nextcookie: descriptor ring 0x%llx " 1958 "is not bound\n", dringp); 1959 mutex_exit(&dringp->lock); 1960 return (EINVAL); 1961 } 1962 1963 ldcp = dringp->ldcp; 1964 1965 if (cookie == NULL) { 1966 DWARN(ldcp->id, 1967 "ldc_mem_dring_nextcookie:(0x%llx) invalid cookie arg\n", 1968 ldcp->id); 1969 mutex_exit(&dringp->lock); 1970 return (EINVAL); 1971 } 1972 1973 rv = ldc_mem_nextcookie((ldc_mem_handle_t)dringp->mhdl, cookie); 1974 mutex_exit(&dringp->lock); 1975 1976 return (rv); 1977 } 1978 1979 /* 1980 * Unbind a previously bound dring from a channel. 1981 */ 1982 int 1983 ldc_mem_dring_unbind(ldc_dring_handle_t dhandle) 1984 { 1985 ldc_dring_t *dringp; 1986 ldc_dring_t *tmp_dringp; 1987 ldc_chan_t *ldcp; 1988 1989 if (dhandle == NULL) { 1990 DWARN(DBG_ALL_LDCS, 1991 "ldc_mem_dring_unbind: invalid desc ring handle\n"); 1992 return (EINVAL); 1993 } 1994 dringp = (ldc_dring_t *)dhandle; 1995 1996 mutex_enter(&dringp->lock); 1997 1998 if (dringp->status == LDC_UNBOUND) { 1999 DWARN(DBG_ALL_LDCS, 2000 "ldc_mem_dring_bind: descriptor ring 0x%llx is unbound\n", 2001 dringp); 2002 mutex_exit(&dringp->lock); 2003 return (EINVAL); 2004 } 2005 ldcp = dringp->ldcp; 2006 2007 mutex_enter(&ldcp->exp_dlist_lock); 2008 2009 tmp_dringp = ldcp->exp_dring_list; 2010 if (tmp_dringp == dringp) { 2011 ldcp->exp_dring_list = dringp->ch_next; 2012 dringp->ch_next = NULL; 2013 2014 } else { 2015 while (tmp_dringp != NULL) { 2016 if (tmp_dringp->ch_next == dringp) { 2017 tmp_dringp->ch_next = dringp->ch_next; 2018 dringp->ch_next = NULL; 2019 break; 2020 } 2021 tmp_dringp = tmp_dringp->ch_next; 2022 } 2023 if (tmp_dringp == NULL) { 2024 DWARN(DBG_ALL_LDCS, 2025 "ldc_mem_dring_unbind: invalid descriptor\n"); 2026 mutex_exit(&ldcp->exp_dlist_lock); 2027 mutex_exit(&dringp->lock); 2028 return (EINVAL); 2029 } 2030 } 2031 2032 mutex_exit(&ldcp->exp_dlist_lock); 2033 2034 (void) ldc_mem_unbind_handle((ldc_mem_handle_t)dringp->mhdl); 2035 (void) ldc_mem_free_handle((ldc_mem_handle_t)dringp->mhdl); 2036 2037 dringp->ldcp = NULL; 2038 dringp->mhdl = NULL; 2039 dringp->status = LDC_UNBOUND; 2040 2041 mutex_exit(&dringp->lock); 2042 2043 return (0); 2044 } 2045 2046 #ifdef DEBUG 2047 void 2048 i_ldc_mem_inject_dring_clear(ldc_chan_t *ldcp) 2049 { 2050 ldc_dring_t *dp; 2051 ldc_mhdl_t *mhdl; 2052 ldc_mtbl_t *mtbl; 2053 ldc_memseg_t *memseg; 2054 uint64_t cookie_addr; 2055 uint64_t pg_shift, pg_size_code; 2056 int i, rv, retries; 2057 2058 /* has a map table been allocated? */ 2059 if ((mtbl = ldcp->mtbl) == NULL) 2060 return; 2061 2062 /* lock the memory table - exclusive access to channel */ 2063 mutex_enter(&mtbl->lock); 2064 2065 /* lock the exported dring list */ 2066 mutex_enter(&ldcp->exp_dlist_lock); 2067 2068 for (dp = ldcp->exp_dring_list; dp != NULL; dp = dp->ch_next) { 2069 if ((mhdl = (ldc_mhdl_t *)dp->mhdl) == NULL) 2070 continue; 2071 2072 if ((memseg = mhdl->memseg) == NULL) 2073 continue; 2074 2075 /* undo the pages exported */ 2076 for (i = 0; i < memseg->npages; i++) { 2077 2078 /* clear the entry from the table */ 2079 memseg->pages[i].mte->entry.ll = 0; 2080 2081 pg_size_code = page_szc(MMU_PAGESIZE); 2082 pg_shift = page_get_shift(pg_size_code); 2083 cookie_addr = IDX2COOKIE(memseg->pages[i].index, 2084 pg_size_code, pg_shift); 2085 2086 retries = 0; 2087 do { 2088 rv = hv_ldc_revoke(ldcp->id, cookie_addr, 2089 memseg->pages[i].mte->cookie); 2090 2091 if (rv != H_EWOULDBLOCK) 2092 break; 2093 2094 drv_usecwait(ldc_delay); 2095 2096 } while (retries++ < ldc_max_retries); 2097 2098 if (rv != 0) { 2099 DWARN(ldcp->id, 2100 "i_ldc_mem_inject_dring_clear(): " 2101 "hv_ldc_revoke failed: " 2102 "channel: 0x%lx, cookie addr: 0x%p," 2103 "cookie: 0x%lx, rv: %d", 2104 ldcp->id, cookie_addr, 2105 memseg->pages[i].mte->cookie, rv); 2106 } 2107 2108 mtbl->num_avail++; 2109 } 2110 } 2111 2112 mutex_exit(&ldcp->exp_dlist_lock); 2113 mutex_exit(&mtbl->lock); 2114 } 2115 #endif 2116 2117 /* 2118 * Get information about the dring. The base address of the descriptor 2119 * ring along with the type and permission are returned back. 2120 */ 2121 int 2122 ldc_mem_dring_info(ldc_dring_handle_t dhandle, ldc_mem_info_t *minfo) 2123 { 2124 ldc_dring_t *dringp; 2125 int rv; 2126 2127 if (dhandle == NULL) { 2128 DWARN(DBG_ALL_LDCS, 2129 "ldc_mem_dring_info: invalid desc ring handle\n"); 2130 return (EINVAL); 2131 } 2132 dringp = (ldc_dring_t *)dhandle; 2133 2134 mutex_enter(&dringp->lock); 2135 2136 if (dringp->mhdl) { 2137 rv = ldc_mem_info(dringp->mhdl, minfo); 2138 if (rv) { 2139 DWARN(DBG_ALL_LDCS, 2140 "ldc_mem_dring_info: error reading mem info\n"); 2141 mutex_exit(&dringp->lock); 2142 return (rv); 2143 } 2144 } else { 2145 minfo->vaddr = dringp->base; 2146 minfo->raddr = NULL; 2147 minfo->status = dringp->status; 2148 } 2149 2150 mutex_exit(&dringp->lock); 2151 2152 return (0); 2153 } 2154 2155 /* 2156 * Map an exported descriptor ring into the local address space. If the 2157 * descriptor ring was exported for direct map access, a HV call is made 2158 * to allocate a RA range. If the map is done via a shadow copy, local 2159 * shadow memory is allocated. 2160 */ 2161 int 2162 ldc_mem_dring_map(ldc_handle_t handle, ldc_mem_cookie_t *cookie, 2163 uint32_t ccount, uint32_t len, uint32_t dsize, uint8_t mtype, 2164 ldc_dring_handle_t *dhandle) 2165 { 2166 int err; 2167 ldc_chan_t *ldcp = (ldc_chan_t *)handle; 2168 ldc_mem_handle_t mhandle; 2169 ldc_dring_t *dringp; 2170 size_t dring_size; 2171 2172 if (dhandle == NULL) { 2173 DWARN(DBG_ALL_LDCS, 2174 "ldc_mem_dring_map: invalid dhandle\n"); 2175 return (EINVAL); 2176 } 2177 2178 /* check to see if channel is initalized */ 2179 if (handle == NULL) { 2180 DWARN(DBG_ALL_LDCS, 2181 "ldc_mem_dring_map: invalid channel handle\n"); 2182 return (EINVAL); 2183 } 2184 ldcp = (ldc_chan_t *)handle; 2185 2186 if (cookie == NULL) { 2187 DWARN(ldcp->id, 2188 "ldc_mem_dring_map: (0x%llx) invalid cookie\n", 2189 ldcp->id); 2190 return (EINVAL); 2191 } 2192 2193 /* FUTURE: For now we support only one cookie per dring */ 2194 ASSERT(ccount == 1); 2195 2196 if (cookie->size < (dsize * len)) { 2197 DWARN(ldcp->id, 2198 "ldc_mem_dring_map: (0x%llx) invalid dsize/len\n", 2199 ldcp->id); 2200 return (EINVAL); 2201 } 2202 2203 /* ensure the mtype is valid */ 2204 if ((mtype & (LDC_SHADOW_MAP|LDC_DIRECT_MAP)) == 0) { 2205 DWARN(ldcp->id, "ldc_mem_dring_map: invalid map type\n"); 2206 return (EINVAL); 2207 } 2208 2209 /* do not attempt direct map if it's not HV supported or enabled */ 2210 if (!ldc_dring_shmem_hv_ok || !ldc_dring_shmem_enabled) { 2211 mtype = LDC_SHADOW_MAP; 2212 } 2213 2214 *dhandle = 0; 2215 2216 /* Allocate an dring structure */ 2217 dringp = kmem_zalloc(sizeof (ldc_dring_t), KM_SLEEP); 2218 2219 D1(ldcp->id, 2220 "ldc_mem_dring_map: 0x%x,0x%x,0x%x,0x%llx,0x%llx\n", 2221 mtype, len, dsize, cookie->addr, cookie->size); 2222 2223 /* Initialize dring */ 2224 dringp->length = len; 2225 dringp->dsize = dsize; 2226 2227 /* round of to multiple of page size */ 2228 dring_size = len * dsize; 2229 dringp->size = (dring_size & MMU_PAGEMASK); 2230 if (dring_size & MMU_PAGEOFFSET) 2231 dringp->size += MMU_PAGESIZE; 2232 2233 dringp->ldcp = ldcp; 2234 2235 /* create an memory handle */ 2236 err = ldc_mem_alloc_handle(handle, &mhandle); 2237 if (err || mhandle == NULL) { 2238 DWARN(DBG_ALL_LDCS, 2239 "ldc_mem_dring_map: cannot alloc hdl err=%d\n", 2240 err); 2241 kmem_free(dringp, sizeof (ldc_dring_t)); 2242 return (ENOMEM); 2243 } 2244 2245 dringp->mhdl = mhandle; 2246 dringp->base = NULL; 2247 2248 /* map the dring into local memory */ 2249 err = i_ldc_mem_map(mhandle, cookie, ccount, mtype, LDC_MEM_RW, 2250 &(dringp->base), NULL); 2251 if (err || dringp->base == NULL) { 2252 DWARN(DBG_ALL_LDCS, 2253 "ldc_mem_dring_map: cannot map desc ring err=%d\n", err); 2254 (void) ldc_mem_free_handle(mhandle); 2255 kmem_free(dringp, sizeof (ldc_dring_t)); 2256 return (ENOMEM); 2257 } 2258 2259 /* initialize the desc ring lock */ 2260 mutex_init(&dringp->lock, NULL, MUTEX_DRIVER, NULL); 2261 2262 /* Add descriptor ring to channel's imported dring list */ 2263 mutex_enter(&ldcp->imp_dlist_lock); 2264 dringp->ch_next = ldcp->imp_dring_list; 2265 ldcp->imp_dring_list = dringp; 2266 mutex_exit(&ldcp->imp_dlist_lock); 2267 2268 dringp->status = LDC_MAPPED; 2269 2270 *dhandle = (ldc_dring_handle_t)dringp; 2271 2272 return (0); 2273 } 2274 2275 /* 2276 * Unmap a descriptor ring. Free shadow memory (if any). 2277 */ 2278 int 2279 ldc_mem_dring_unmap(ldc_dring_handle_t dhandle) 2280 { 2281 ldc_dring_t *dringp; 2282 ldc_dring_t *tmp_dringp; 2283 ldc_chan_t *ldcp; 2284 2285 if (dhandle == NULL) { 2286 DWARN(DBG_ALL_LDCS, 2287 "ldc_mem_dring_unmap: invalid desc ring handle\n"); 2288 return (EINVAL); 2289 } 2290 dringp = (ldc_dring_t *)dhandle; 2291 2292 if (dringp->status != LDC_MAPPED) { 2293 DWARN(DBG_ALL_LDCS, 2294 "ldc_mem_dring_unmap: not a mapped desc ring\n"); 2295 return (EINVAL); 2296 } 2297 2298 mutex_enter(&dringp->lock); 2299 2300 ldcp = dringp->ldcp; 2301 2302 mutex_enter(&ldcp->imp_dlist_lock); 2303 2304 /* find and unlink the desc ring from channel import list */ 2305 tmp_dringp = ldcp->imp_dring_list; 2306 if (tmp_dringp == dringp) { 2307 ldcp->imp_dring_list = dringp->ch_next; 2308 dringp->ch_next = NULL; 2309 2310 } else { 2311 while (tmp_dringp != NULL) { 2312 if (tmp_dringp->ch_next == dringp) { 2313 tmp_dringp->ch_next = dringp->ch_next; 2314 dringp->ch_next = NULL; 2315 break; 2316 } 2317 tmp_dringp = tmp_dringp->ch_next; 2318 } 2319 if (tmp_dringp == NULL) { 2320 DWARN(DBG_ALL_LDCS, 2321 "ldc_mem_dring_unmap: invalid descriptor\n"); 2322 mutex_exit(&ldcp->imp_dlist_lock); 2323 mutex_exit(&dringp->lock); 2324 return (EINVAL); 2325 } 2326 } 2327 2328 mutex_exit(&ldcp->imp_dlist_lock); 2329 2330 /* do a LDC memory handle unmap and free */ 2331 (void) ldc_mem_unmap(dringp->mhdl); 2332 (void) ldc_mem_free_handle((ldc_mem_handle_t)dringp->mhdl); 2333 2334 dringp->status = 0; 2335 dringp->ldcp = NULL; 2336 2337 mutex_exit(&dringp->lock); 2338 2339 /* destroy dring lock */ 2340 mutex_destroy(&dringp->lock); 2341 2342 /* free desc ring object */ 2343 kmem_free(dringp, sizeof (ldc_dring_t)); 2344 2345 return (0); 2346 } 2347 2348 /* 2349 * Internal entry point for descriptor ring access entry consistency 2350 * semantics. Acquire copies the contents of the remote descriptor ring 2351 * into the local shadow copy. The release operation copies the local 2352 * contents into the remote dring. The start and end locations specify 2353 * bounds for the entries being synchronized. 2354 */ 2355 static int 2356 i_ldc_dring_acquire_release(ldc_dring_handle_t dhandle, 2357 uint8_t direction, uint64_t start, uint64_t end) 2358 { 2359 int err; 2360 ldc_dring_t *dringp; 2361 ldc_chan_t *ldcp; 2362 ldc_mhdl_t *mhdl; 2363 uint64_t soff; 2364 size_t copy_size; 2365 2366 if (dhandle == NULL) { 2367 DWARN(DBG_ALL_LDCS, 2368 "i_ldc_dring_acquire_release: invalid desc ring handle\n"); 2369 return (EINVAL); 2370 } 2371 dringp = (ldc_dring_t *)dhandle; 2372 mutex_enter(&dringp->lock); 2373 2374 if (dringp->status != LDC_MAPPED || dringp->ldcp == NULL) { 2375 DWARN(DBG_ALL_LDCS, 2376 "i_ldc_dring_acquire_release: not a mapped desc ring\n"); 2377 mutex_exit(&dringp->lock); 2378 return (EINVAL); 2379 } 2380 2381 if (start >= dringp->length || end >= dringp->length) { 2382 DWARN(DBG_ALL_LDCS, 2383 "i_ldc_dring_acquire_release: index out of range\n"); 2384 mutex_exit(&dringp->lock); 2385 return (EINVAL); 2386 } 2387 2388 mhdl = (ldc_mhdl_t *)dringp->mhdl; 2389 if (mhdl == NULL) { 2390 DWARN(DBG_ALL_LDCS, 2391 "i_ldc_dring_acquire_release: invalid memory handle\n"); 2392 mutex_exit(&dringp->lock); 2393 return (EINVAL); 2394 } 2395 2396 if (mhdl->mtype != LDC_SHADOW_MAP) { 2397 DWARN(DBG_ALL_LDCS, 2398 "i_ldc_dring_acquire_release: invalid mtype: %d\n", 2399 mhdl->mtype); 2400 mutex_exit(&dringp->lock); 2401 return (EINVAL); 2402 } 2403 2404 /* get the channel handle */ 2405 ldcp = dringp->ldcp; 2406 2407 copy_size = (start <= end) ? (((end - start) + 1) * dringp->dsize) : 2408 ((dringp->length - start) * dringp->dsize); 2409 2410 /* Calculate the relative offset for the first desc */ 2411 soff = (start * dringp->dsize); 2412 2413 /* copy to/from remote from/to local memory */ 2414 D1(ldcp->id, "i_ldc_dring_acquire_release: c1 off=0x%llx sz=0x%llx\n", 2415 soff, copy_size); 2416 err = i_ldc_mem_acquire_release((ldc_mem_handle_t)dringp->mhdl, 2417 direction, soff, copy_size); 2418 if (err) { 2419 DWARN(ldcp->id, 2420 "i_ldc_dring_acquire_release: copy failed\n"); 2421 mutex_exit(&dringp->lock); 2422 return (err); 2423 } 2424 2425 /* do the balance */ 2426 if (start > end) { 2427 copy_size = ((end + 1) * dringp->dsize); 2428 soff = 0; 2429 2430 /* copy to/from remote from/to local memory */ 2431 D1(ldcp->id, "i_ldc_dring_acquire_release: c2 " 2432 "off=0x%llx sz=0x%llx\n", soff, copy_size); 2433 err = i_ldc_mem_acquire_release((ldc_mem_handle_t)dringp->mhdl, 2434 direction, soff, copy_size); 2435 if (err) { 2436 DWARN(ldcp->id, 2437 "i_ldc_dring_acquire_release: copy failed\n"); 2438 mutex_exit(&dringp->lock); 2439 return (err); 2440 } 2441 } 2442 2443 mutex_exit(&dringp->lock); 2444 2445 return (0); 2446 } 2447 2448 /* 2449 * Ensure that the contents in the local dring are consistent 2450 * with the contents if of remote dring 2451 */ 2452 int 2453 ldc_mem_dring_acquire(ldc_dring_handle_t dhandle, uint64_t start, uint64_t end) 2454 { 2455 return (i_ldc_dring_acquire_release(dhandle, LDC_COPY_IN, start, end)); 2456 } 2457 2458 /* 2459 * Ensure that the contents in the remote dring are consistent 2460 * with the contents if of local dring 2461 */ 2462 int 2463 ldc_mem_dring_release(ldc_dring_handle_t dhandle, uint64_t start, uint64_t end) 2464 { 2465 return (i_ldc_dring_acquire_release(dhandle, LDC_COPY_OUT, start, end)); 2466 } 2467