~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201207201942

« back to all changes in this revision

Viewing changes to modules/linux/vmci/vmciKernelIf.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-03-20 10:19:00 UTC
  • mfrom: (1.1.4 upstream) (2.4.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090320101900-1o604camiubq2de8
Tags: 2009.03.18-154848-2
Correcting patch system depends (Closes: #520493).

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
#include "pgtbl.h"
49
49
#include <linux/vmalloc.h>
50
50
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
51
 
#  include <linux/mm.h>         /* For vmalloc_to_page() */
 
51
#  include <linux/mm.h>         /* For vmalloc_to_page() and get_user_pages()*/
 
52
#else
 
53
#  include <linux/iobuf.h>      /* For map_user_kiobuf() and unmap_kiobuf() */
52
54
#endif
53
55
#include <linux/socket.h>       /* For memcpy_{to,from}iovec(). */
 
56
#include <linux/pagemap.h>      /* For page_cache_release() */
54
57
#include "vm_assert.h"
55
58
#include "vmci_kernel_if.h"
 
59
#ifndef VMX86_TOOLS
 
60
#  include "vmciQueuePair.h"
 
61
#endif
 
62
 
56
63
#include "vmci_queue_pair.h"
 
64
#include "vmci_iocontrols.h"
57
65
 
58
66
/*
59
67
 * In Linux 2.6.25 kernels and onwards, the symbol init_mm is no
694
702
                 VMCIEventReleaseCB releaseCB,  // IN:
695
703
                 void *clientData)              // IN:
696
704
{
 
705
   /*
 
706
    * XXX Should this be a TASK_UNINTERRUPTIBLE wait? I'm leaving it
 
707
    * as it was for now.
 
708
    */
 
709
   VMCI_WaitOnEventInterruptible(event, releaseCB, clientData);
 
710
}
 
711
 
 
712
 
 
713
/*
 
714
 *-----------------------------------------------------------------------------
 
715
 *
 
716
 * VMCI_WaitOnEventInterruptible --
 
717
 *
 
718
 * Results:
 
719
 *      True if the wait was interrupted by a signal, false otherwise.
 
720
 *
 
721
 * Side effects:
 
722
 *      None.
 
723
 *
 
724
 *-----------------------------------------------------------------------------
 
725
 */
 
726
 
 
727
Bool
 
728
VMCI_WaitOnEventInterruptible(VMCIEvent *event,              // IN:
 
729
                              VMCIEventReleaseCB releaseCB,  // IN:
 
730
                              void *clientData)              // IN:
 
731
{
697
732
   DECLARE_WAITQUEUE(wait, current);
698
733
 
699
734
   if (event == NULL || releaseCB == NULL) {
700
 
      return;
 
735
      return FALSE;
701
736
   }
702
737
 
703
738
   add_wait_queue(event, &wait);
715
750
   schedule();
716
751
   current->state = TASK_RUNNING;
717
752
   remove_wait_queue(event, &wait);
 
753
 
 
754
   return signal_pending(current);
718
755
}
719
756
 
720
757
 
810
847
}
811
848
 
812
849
 
 
850
#ifdef VMX86_TOOLS
813
851
/*
814
852
 *-----------------------------------------------------------------------------
815
853
 *
1059
1097
 
1060
1098
   return VMCI_SUCCESS;
1061
1099
}
 
1100
#endif
1062
1101
 
1063
1102
 
1064
1103
#ifdef __KERNEL__
1352
1391
   }
1353
1392
   return TRUE;
1354
1393
}
 
1394
 
 
1395
 
 
1396
 
 
1397
#ifndef VMX86_TOOLS
 
1398
 
 
1399
/*
 
1400
 *-----------------------------------------------------------------------------
 
1401
 *
 
1402
 * VMCIHost_FinishAttach --
 
1403
 
 
1404
 *       Finish the "attach" operation by update the queues to be
 
1405
 *       backed by the shared memory represented by the "attach"
 
1406
 *       structure.
 
1407
 *
 
1408
 * Results:
 
1409
 *       VMCI_SUCCESS on success or negative error on failure.
 
1410
 *
 
1411
 * Side Effects:
 
1412
 *       None
 
1413
 *
 
1414
 *-----------------------------------------------------------------------------
 
1415
 */
 
1416
 
 
1417
int
 
1418
VMCIHost_FinishAttach(PageStoreAttachInfo *attach,      // IN
 
1419
                      VMCIQueue *produceQ,              // OUT
 
1420
                      VMCIQueue *consumeQ)              // OUT
 
1421
{
 
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];
 
1427
#else
 
1428
   /*
 
1429
    * Host queue pair support for earlier kernels temporarily
 
1430
    * disabled. See bug 365496.
 
1431
    */
 
1432
 
 
1433
   ASSERT_NOT_IMPLEMENTED(FALSE);
 
1434
#if 0 
 
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];
 
1439
#endif
 
1440
#endif
 
1441
 
 
1442
   return VMCI_SUCCESS;
 
1443
}
 
1444
 
 
1445
 
 
1446
/*
 
1447
 *-----------------------------------------------------------------------------
 
1448
 *
 
1449
 * VMCIHost_DetachMappings --
 
1450
 *       Remove any local mappings of memory referenced in 'attach' in
 
1451
 *       preparation for releasing the shared memory region entirely.
 
1452
 *
 
1453
 * Results:
 
1454
 *       None.
 
1455
 *
 
1456
 * Side Effects:
 
1457
 *       None.
 
1458
 *
 
1459
 *-----------------------------------------------------------------------------
 
1460
 */
 
1461
 
 
1462
void
 
1463
VMCIHost_DetachMappings(PageStoreAttachInfo *attach)    // IN
 
1464
{
 
1465
   /*
 
1466
    * Unmap the header pages
 
1467
    */
 
1468
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
 
1469
   kunmap(attach->producePages[0]);
 
1470
   kunmap(attach->consumePages[0]);
 
1471
#else
 
1472
   /*
 
1473
    * Host queue pair support for earlier kernels temporarily
 
1474
    * disabled. See bug 365496.
 
1475
    */
 
1476
 
 
1477
   ASSERT_NOT_IMPLEMENTED(FALSE);
 
1478
#if 0
 
1479
   kunmap(attach->produceIoBuf->maplist[0]);
 
1480
   kunmap(attach->consumeIoBuf->maplist[0]);
 
1481
#endif
 
1482
#endif
 
1483
}
 
1484
 
 
1485
 
 
1486
/*
 
1487
 *-----------------------------------------------------------------------------
 
1488
 *
 
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.
 
1493
 *
 
1494
 * Results:
 
1495
 *       VMCI_SUCCESS on sucess, negative error code on failure.
 
1496
 *
 
1497
 * Side Effects:
 
1498
 *       None.
 
1499
 *
 
1500
 *-----------------------------------------------------------------------------
 
1501
 */
 
1502
 
 
1503
int
 
1504
VMCIHost_GetUserMemory(PageStoreAttachInfo *attach)         // IN/OUT
 
1505
{
 
1506
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
 
1507
   int retval;
 
1508
   int err = VMCI_SUCCESS;
 
1509
 
 
1510
 
 
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;
 
1516
   }
 
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;
 
1522
      goto errorDealloc;
 
1523
   }
 
1524
 
 
1525
   down_write(&current->mm->mmap_sem);
 
1526
   retval = get_user_pages(current,
 
1527
                           current->mm,
 
1528
                           (VA)attach->produceBuffer,
 
1529
                           attach->numProducePages,
 
1530
                           1, 0,
 
1531
                           attach->producePages,
 
1532
                           NULL);
 
1533
   if (retval < attach->numProducePages) {
 
1534
      Log("get_user_pages(produce) failed: %d\n", retval);
 
1535
      if (retval > 0) {
 
1536
         int i;
 
1537
         for (i = 0; i < retval; i++) {
 
1538
            page_cache_release(attach->producePages[i]);
 
1539
         }
 
1540
      }
 
1541
      err = VMCI_ERROR_NO_MEM;
 
1542
      goto out;
 
1543
   }
 
1544
 
 
1545
   retval = get_user_pages(current,
 
1546
                           current->mm,
 
1547
                           (VA)attach->consumeBuffer,
 
1548
                           attach->numConsumePages,
 
1549
                           1, 0,
 
1550
                           attach->consumePages,
 
1551
                           NULL);
 
1552
   if (retval < attach->numConsumePages) {
 
1553
      int i;
 
1554
      Log("get_user_pages(consume) failed: %d\n", retval);
 
1555
      if (retval > 0) {
 
1556
         for (i = 0; i < retval; i++) {
 
1557
            page_cache_release(attach->consumePages[i]);
 
1558
         }
 
1559
      }
 
1560
      for (i = 0; i < attach->numProducePages; i++) {
 
1561
         page_cache_release(attach->producePages[i]);
 
1562
      }
 
1563
      err = VMCI_ERROR_NO_MEM;
 
1564
   }
 
1565
 
 
1566
out:
 
1567
   up_write(&current->mm->mmap_sem);
 
1568
 
 
1569
errorDealloc:
 
1570
   if (err < VMCI_SUCCESS) {
 
1571
      if (attach->producePages != NULL) {
 
1572
         VMCI_FreeKernelMem(attach->producePages,
 
1573
                            attach->numProducePages *
 
1574
                            sizeof attach->producePages[0]);
 
1575
      }
 
1576
      if (attach->consumePages != NULL) {
 
1577
         VMCI_FreeKernelMem(attach->consumePages,
 
1578
                            attach->numConsumePages *
 
1579
                            sizeof attach->consumePages[0]);
 
1580
      }
 
1581
   }
 
1582
 
 
1583
   return err;
 
1584
 
 
1585
#else
 
1586
   /*
 
1587
    * Host queue pair support for earlier kernels temporarily
 
1588
    * disabled. See bug 365496.
 
1589
    */
 
1590
 
 
1591
   ASSERT_NOT_IMPLEMENTED(FALSE);
 
1592
#if 0
 
1593
   attach->produceIoBuf = VMCI_AllocKernelMem(sizeof *attach->produceIoBuf,
 
1594
                                              VMCI_MEMORY_NORMAL);
 
1595
   if (attach->produceIoBuf == NULL) {
 
1596
      return VMCI_ERROR_NO_MEM;
 
1597
   }
 
1598
 
 
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;
 
1605
   }
 
1606
 
 
1607
   retval = map_user_kiobuf(WRITE, attach->produceIoBuf,
 
1608
                            (VA)attach->produceBuffer,
 
1609
                            attach->numProducePages * PAGE_SIZE);
 
1610
   if (retval < 0) {
 
1611
      err = VMCI_ERROR_NO_ACCESS;
 
1612
      goto out;
 
1613
   }
 
1614
 
 
1615
   retval = map_user_kiobuf(WRITE, attach->consumeIoBuf,
 
1616
                            (VA)attach->consumeBuffer,
 
1617
                            attach->numConsumePages * PAGE_SIZE);
 
1618
   if (retval < 0) {
 
1619
      unmap_kiobuf(attach->produceIoBuf);
 
1620
      err = VMCI_ERROR_NO_ACCESS;
 
1621
   }
 
1622
 
 
1623
out:
 
1624
 
 
1625
   if (err < VMCI_SUCCESS) {
 
1626
      if (attach->produceIoBuf != NULL) {
 
1627
         VMCI_FreeKernelMem(attach->produceIoBuf,
 
1628
                            sizeof *attach->produceIoBuf);
 
1629
      }
 
1630
      if (attach->consumeIoBuf != NULL) {
 
1631
         VMCI_FreeKernelMem(attach->consumeIoBuf,
 
1632
                            sizeof *attach->consumeIoBuf);
 
1633
      }
 
1634
   }
 
1635
   return err;
 
1636
#else
 
1637
   return FALSE;
 
1638
#endif
 
1639
#endif
 
1640
}
 
1641
 
 
1642
 
 
1643
/*
 
1644
 *-----------------------------------------------------------------------------
 
1645
 *
 
1646
 * VMCIHost_ReleaseUserMemory --
 
1647
 *       Release the reference to user pages stored in the attach
 
1648
 *       struct
 
1649
 *
 
1650
 * Results:
 
1651
 *       None
 
1652
 *
 
1653
 * Side Effects:
 
1654
 *       Pages are released from the page cache and may become
 
1655
 *       swappable again.
 
1656
 *
 
1657
 *-----------------------------------------------------------------------------
 
1658
 */
 
1659
 
 
1660
void
 
1661
VMCIHost_ReleaseUserMemory(PageStoreAttachInfo *attach)         // IN
 
1662
{
 
1663
 
 
1664
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
 
1665
   int i;
 
1666
 
 
1667
   ASSERT(attach->producePages);
 
1668
   ASSERT(attach->consumePages);
 
1669
   for (i = 0; i < attach->numProducePages; i++) {
 
1670
      ASSERT(attach->producePages[i]);
 
1671
 
 
1672
      set_page_dirty(attach->producePages[i]);
 
1673
      page_cache_release(attach->producePages[i]);
 
1674
   }
 
1675
 
 
1676
   for (i = 0; i < attach->numConsumePages; i++) {
 
1677
      ASSERT(attach->consumePages[i]);
 
1678
 
 
1679
      set_page_dirty(attach->consumePages[i]);
 
1680
      page_cache_release(attach->consumePages[i]);
 
1681
   }
 
1682
 
 
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]);
 
1689
#else
 
1690
   /*
 
1691
    * Host queue pair support for earlier kernels temporarily
 
1692
    * disabled. See bug 365496.
 
1693
    */
 
1694
 
 
1695
   ASSERT_NOT_IMPLEMENTED(FALSE);
 
1696
#if 0
 
1697
   mark_dirty_kiobuf(attach->produceIoBuf,
 
1698
                     attach->numProducePages * PAGE_SIZE);
 
1699
   unmap_kiobuf(attach->produceIoBuf);
 
1700
 
 
1701
   mark_dirty_kiobuf(attach->consumeIoBuf,
 
1702
                     attach->numConsumePages * PAGE_SIZE);
 
1703
   unmap_kiobuf(attach->consumeIoBuf);
 
1704
 
 
1705
   VMCI_FreeKernelMem(attach->produceIoBuf,
 
1706
                      sizeof *attach->produceIoBuf);
 
1707
   VMCI_FreeKernelMem(attach->consumeIoBuf,
 
1708
                      sizeof *attach->consumeIoBuf);
 
1709
#endif
 
1710
#endif
 
1711
}
 
1712
 
 
1713
#endif