1400
*-----------------------------------------------------------------------------
1402
* VMCIHost_FinishAttach --
1404
* Finish the "attach" operation by update the queues to be
1405
* backed by the shared memory represented by the "attach"
1409
* VMCI_SUCCESS on success or negative error on failure.
1414
*-----------------------------------------------------------------------------
1418
VMCIHost_FinishAttach(PageStoreAttachInfo *attach, // IN
1419
VMCIQueue *produceQ, // OUT
1420
VMCIQueue *consumeQ) // OUT
1422
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1423
produceQ->queueHeaderPtr = kmap(attach->producePages[0]);
1424
produceQ->page = &attach->producePages[1];
1425
consumeQ->queueHeaderPtr = kmap(attach->consumePages[0]);
1426
consumeQ->page = &attach->consumePages[1];
1429
* Host queue pair support for earlier kernels temporarily
1430
* disabled. See bug 365496.
1433
ASSERT_NOT_IMPLEMENTED(FALSE);
1435
produceQ->queueHeaderPtr = kmap(attach->produceIoBuf->maplist[0]);
1436
produceQ->page = &attach->produceIoBuf->maplist[1];
1437
consumeQ->queueHeaderPtr = kmap(attach->consumeIoBuf->maplist[0]);
1438
consumeQ->page = &attach->consumeIoBuf->maplist[1];
1442
return VMCI_SUCCESS;
1447
*-----------------------------------------------------------------------------
1449
* VMCIHost_DetachMappings --
1450
* Remove any local mappings of memory referenced in 'attach' in
1451
* preparation for releasing the shared memory region entirely.
1459
*-----------------------------------------------------------------------------
1463
VMCIHost_DetachMappings(PageStoreAttachInfo *attach) // IN
1466
* Unmap the header pages
1468
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1469
kunmap(attach->producePages[0]);
1470
kunmap(attach->consumePages[0]);
1473
* Host queue pair support for earlier kernels temporarily
1474
* disabled. See bug 365496.
1477
ASSERT_NOT_IMPLEMENTED(FALSE);
1479
kunmap(attach->produceIoBuf->maplist[0]);
1480
kunmap(attach->consumeIoBuf->maplist[0]);
1487
*-----------------------------------------------------------------------------
1489
* VMCIHost_GetUserMemory --
1490
* Lock the user pages referenced by the {produce,consume}Buffer
1491
* struct into memory and populate the {produce,consume}Pages
1492
* arrays in the attach structure with them.
1495
* VMCI_SUCCESS on sucess, negative error code on failure.
1500
*-----------------------------------------------------------------------------
1504
VMCIHost_GetUserMemory(PageStoreAttachInfo *attach) // IN/OUT
1506
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1508
int err = VMCI_SUCCESS;
1511
attach->producePages =
1512
VMCI_AllocKernelMem(attach->numProducePages * sizeof attach->producePages[0],
1513
VMCI_MEMORY_NORMAL);
1514
if (attach->producePages == NULL) {
1515
return VMCI_ERROR_NO_MEM;
1517
attach->consumePages =
1518
VMCI_AllocKernelMem(attach->numConsumePages * sizeof attach->consumePages[0],
1519
VMCI_MEMORY_NORMAL);
1520
if (attach->consumePages == NULL) {
1521
err = VMCI_ERROR_NO_MEM;
1525
down_write(¤t->mm->mmap_sem);
1526
retval = get_user_pages(current,
1528
(VA)attach->produceBuffer,
1529
attach->numProducePages,
1531
attach->producePages,
1533
if (retval < attach->numProducePages) {
1534
Log("get_user_pages(produce) failed: %d\n", retval);
1537
for (i = 0; i < retval; i++) {
1538
page_cache_release(attach->producePages[i]);
1541
err = VMCI_ERROR_NO_MEM;
1545
retval = get_user_pages(current,
1547
(VA)attach->consumeBuffer,
1548
attach->numConsumePages,
1550
attach->consumePages,
1552
if (retval < attach->numConsumePages) {
1554
Log("get_user_pages(consume) failed: %d\n", retval);
1556
for (i = 0; i < retval; i++) {
1557
page_cache_release(attach->consumePages[i]);
1560
for (i = 0; i < attach->numProducePages; i++) {
1561
page_cache_release(attach->producePages[i]);
1563
err = VMCI_ERROR_NO_MEM;
1567
up_write(¤t->mm->mmap_sem);
1570
if (err < VMCI_SUCCESS) {
1571
if (attach->producePages != NULL) {
1572
VMCI_FreeKernelMem(attach->producePages,
1573
attach->numProducePages *
1574
sizeof attach->producePages[0]);
1576
if (attach->consumePages != NULL) {
1577
VMCI_FreeKernelMem(attach->consumePages,
1578
attach->numConsumePages *
1579
sizeof attach->consumePages[0]);
1587
* Host queue pair support for earlier kernels temporarily
1588
* disabled. See bug 365496.
1591
ASSERT_NOT_IMPLEMENTED(FALSE);
1593
attach->produceIoBuf = VMCI_AllocKernelMem(sizeof *attach->produceIoBuf,
1594
VMCI_MEMORY_NORMAL);
1595
if (attach->produceIoBuf == NULL) {
1596
return VMCI_ERROR_NO_MEM;
1599
attach->consumeIoBuf = VMCI_AllocKernelMem(sizeof *attach->consumeIoBuf,
1600
VMCI_MEMORY_NORMAL);
1601
if (attach->consumeIoBuf == NULL) {
1602
VMCI_FreeKernelMem(attach->produceIoBuf,
1603
sizeof *attach->produceIoBuf);
1604
return VMCI_ERROR_NO_MEM;
1607
retval = map_user_kiobuf(WRITE, attach->produceIoBuf,
1608
(VA)attach->produceBuffer,
1609
attach->numProducePages * PAGE_SIZE);
1611
err = VMCI_ERROR_NO_ACCESS;
1615
retval = map_user_kiobuf(WRITE, attach->consumeIoBuf,
1616
(VA)attach->consumeBuffer,
1617
attach->numConsumePages * PAGE_SIZE);
1619
unmap_kiobuf(attach->produceIoBuf);
1620
err = VMCI_ERROR_NO_ACCESS;
1625
if (err < VMCI_SUCCESS) {
1626
if (attach->produceIoBuf != NULL) {
1627
VMCI_FreeKernelMem(attach->produceIoBuf,
1628
sizeof *attach->produceIoBuf);
1630
if (attach->consumeIoBuf != NULL) {
1631
VMCI_FreeKernelMem(attach->consumeIoBuf,
1632
sizeof *attach->consumeIoBuf);
1644
*-----------------------------------------------------------------------------
1646
* VMCIHost_ReleaseUserMemory --
1647
* Release the reference to user pages stored in the attach
1654
* Pages are released from the page cache and may become
1657
*-----------------------------------------------------------------------------
1661
VMCIHost_ReleaseUserMemory(PageStoreAttachInfo *attach) // IN
1664
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1667
ASSERT(attach->producePages);
1668
ASSERT(attach->consumePages);
1669
for (i = 0; i < attach->numProducePages; i++) {
1670
ASSERT(attach->producePages[i]);
1672
set_page_dirty(attach->producePages[i]);
1673
page_cache_release(attach->producePages[i]);
1676
for (i = 0; i < attach->numConsumePages; i++) {
1677
ASSERT(attach->consumePages[i]);
1679
set_page_dirty(attach->consumePages[i]);
1680
page_cache_release(attach->consumePages[i]);
1683
VMCI_FreeKernelMem(attach->producePages,
1684
attach->numProducePages *
1685
sizeof attach->producePages[0]);
1686
VMCI_FreeKernelMem(attach->consumePages,
1687
attach->numConsumePages *
1688
sizeof attach->consumePages[0]);
1691
* Host queue pair support for earlier kernels temporarily
1692
* disabled. See bug 365496.
1695
ASSERT_NOT_IMPLEMENTED(FALSE);
1697
mark_dirty_kiobuf(attach->produceIoBuf,
1698
attach->numProducePages * PAGE_SIZE);
1699
unmap_kiobuf(attach->produceIoBuf);
1701
mark_dirty_kiobuf(attach->consumeIoBuf,
1702
attach->numConsumePages * PAGE_SIZE);
1703
unmap_kiobuf(attach->consumeIoBuf);
1705
VMCI_FreeKernelMem(attach->produceIoBuf,
1706
sizeof *attach->produceIoBuf);
1707
VMCI_FreeKernelMem(attach->consumeIoBuf,
1708
sizeof *attach->consumeIoBuf);