@@ -1383,15 +1383,19 @@ int create_existing_sysmem(struct dxgdevice *device,
13831383 void * kmem = NULL ;
13841384 int ret = 0 ;
13851385 struct dxgkvmb_command_setexistingsysmemstore * set_store_command ;
1386+ struct dxgkvmb_command_setexistingsysmempages * set_pages_command ;
13861387 u64 alloc_size = host_alloc -> allocation_size ;
13871388 u32 npages = alloc_size >> PAGE_SHIFT ;
13881389 struct dxgvmbusmsg msg = {.hdr = NULL };
1389-
1390- ret = init_message (& msg , device -> adapter , device -> process ,
1391- sizeof (* set_store_command ));
1392- if (ret )
1393- goto cleanup ;
1394- set_store_command = (void * )msg .msg ;
1390+ const u32 max_pfns_in_message =
1391+ (DXG_MAX_VM_BUS_PACKET_SIZE - sizeof (* set_pages_command ) -
1392+ PAGE_SIZE ) / sizeof (__u64 );
1393+ u32 alloc_offset_in_pages = 0 ;
1394+ struct page * * page_in ;
1395+ u64 * pfn ;
1396+ u32 pages_to_send ;
1397+ u32 i ;
1398+ struct dxgglobal * dxgglobal = dxggbl ();
13951399
13961400 /*
13971401 * Create a guest physical address list and set it as the allocation
@@ -1402,6 +1406,7 @@ int create_existing_sysmem(struct dxgdevice *device,
14021406 DXG_TRACE ("Alloc size: %lld" , alloc_size );
14031407
14041408 dxgalloc -> cpu_address = (void * )sysmem ;
1409+
14051410 dxgalloc -> pages = vzalloc (npages * sizeof (void * ));
14061411 if (dxgalloc -> pages == NULL ) {
14071412 DXG_ERR ("failed to allocate pages" );
@@ -1419,39 +1424,87 @@ int create_existing_sysmem(struct dxgdevice *device,
14191424 ret = - ENOMEM ;
14201425 goto cleanup ;
14211426 }
1422- kmem = vmap (dxgalloc -> pages , npages , VM_MAP , PAGE_KERNEL );
1423- if (kmem == NULL ) {
1424- DXG_ERR ("vmap failed" );
1425- ret = - ENOMEM ;
1426- goto cleanup ;
1427- }
1428- ret1 = vmbus_establish_gpadl (dxgglobal_get_vmbus (), kmem ,
1429- alloc_size , & dxgalloc -> gpadl );
1430- if (ret1 ) {
1431- DXG_ERR ("establish_gpadl failed: %d" , ret1 );
1432- ret = - ENOMEM ;
1433- goto cleanup ;
1434- }
1427+ if (!dxgglobal -> map_guest_pages_enabled ) {
1428+ ret = init_message (& msg , device -> adapter , device -> process ,
1429+ sizeof (* set_store_command ));
1430+ if (ret )
1431+ goto cleanup ;
1432+ set_store_command = (void * )msg .msg ;
1433+
1434+ kmem = vmap (dxgalloc -> pages , npages , VM_MAP , PAGE_KERNEL );
1435+ if (kmem == NULL ) {
1436+ DXG_ERR ("vmap failed" );
1437+ ret = - ENOMEM ;
1438+ goto cleanup ;
1439+ }
1440+ ret1 = vmbus_establish_gpadl (dxgglobal_get_vmbus (), kmem ,
1441+ alloc_size , & dxgalloc -> gpadl );
1442+ if (ret1 ) {
1443+ DXG_ERR ("establish_gpadl failed: %d" , ret1 );
1444+ ret = - ENOMEM ;
1445+ goto cleanup ;
1446+ }
14351447#ifdef _MAIN_KERNEL_
1436- DXG_TRACE ("New gpadl %d" , dxgalloc -> gpadl .gpadl_handle );
1448+ DXG_TRACE ("New gpadl %d" , dxgalloc -> gpadl .gpadl_handle );
14371449#else
1438- DXG_TRACE ("New gpadl %d" , dxgalloc -> gpadl );
1450+ DXG_TRACE ("New gpadl %d" , dxgalloc -> gpadl );
14391451#endif
14401452
1441- command_vgpu_to_host_init2 (& set_store_command -> hdr ,
1442- DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE ,
1443- device -> process -> host_handle );
1444- set_store_command -> device = device -> handle ;
1445- set_store_command -> device = device -> handle ;
1446- set_store_command -> allocation = host_alloc -> allocation ;
1453+ command_vgpu_to_host_init2 (& set_store_command -> hdr ,
1454+ DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE ,
1455+ device -> process -> host_handle );
1456+ set_store_command -> device = device -> handle ;
1457+ set_store_command -> allocation = host_alloc -> allocation ;
14471458#ifdef _MAIN_KERNEL_
1448- set_store_command -> gpadl = dxgalloc -> gpadl .gpadl_handle ;
1459+ set_store_command -> gpadl = dxgalloc -> gpadl .gpadl_handle ;
14491460#else
1450- set_store_command -> gpadl = dxgalloc -> gpadl ;
1461+ set_store_command -> gpadl = dxgalloc -> gpadl ;
14511462#endif
1452- ret = dxgvmb_send_sync_msg_ntstatus (msg .channel , msg .hdr , msg .size );
1453- if (ret < 0 )
1454- DXG_ERR ("failed to set existing store: %x" , ret );
1463+ ret = dxgvmb_send_sync_msg_ntstatus (msg .channel , msg .hdr ,
1464+ msg .size );
1465+ if (ret < 0 )
1466+ DXG_ERR ("failed set existing store: %x" , ret );
1467+ } else {
1468+ /*
1469+ * Send the list of the allocation PFNs to the host. The host
1470+ * will map the pages for GPU access.
1471+ */
1472+
1473+ ret = init_message (& msg , device -> adapter , device -> process ,
1474+ sizeof (* set_pages_command ) +
1475+ max_pfns_in_message * sizeof (u64 ));
1476+ if (ret )
1477+ goto cleanup ;
1478+ set_pages_command = (void * )msg .msg ;
1479+ command_vgpu_to_host_init2 (& set_pages_command -> hdr ,
1480+ DXGK_VMBCOMMAND_SETEXISTINGSYSMEMPAGES ,
1481+ device -> process -> host_handle );
1482+ set_pages_command -> device = device -> handle ;
1483+ set_pages_command -> allocation = host_alloc -> allocation ;
1484+
1485+ page_in = dxgalloc -> pages ;
1486+ while (alloc_offset_in_pages < npages ) {
1487+ pfn = (u64 * )((char * )msg .msg +
1488+ sizeof (* set_pages_command ));
1489+ pages_to_send = min (npages - alloc_offset_in_pages ,
1490+ max_pfns_in_message );
1491+ set_pages_command -> num_pages = pages_to_send ;
1492+ set_pages_command -> alloc_offset_in_pages =
1493+ alloc_offset_in_pages ;
1494+
1495+ for (i = 0 ; i < pages_to_send ; i ++ )
1496+ * pfn ++ = page_to_pfn (* page_in ++ );
1497+
1498+ ret = dxgvmb_send_sync_msg_ntstatus (msg .channel ,
1499+ msg .hdr ,
1500+ msg .size );
1501+ if (ret < 0 ) {
1502+ DXG_ERR ("failed set existing pages: %x" , ret );
1503+ break ;
1504+ }
1505+ alloc_offset_in_pages += pages_to_send ;
1506+ }
1507+ }
14551508
14561509cleanup :
14571510 if (kmem )
0 commit comments