@@ -1331,15 +1331,18 @@ int create_existing_sysmem(struct dxgdevice *device,
13311331 void * kmem = NULL ;
13321332 int ret = 0 ;
13331333 struct dxgkvmb_command_setexistingsysmemstore * set_store_command ;
1334+ struct dxgkvmb_command_setexistingsysmempages * set_pages_command ;
13341335 u64 alloc_size = host_alloc -> allocation_size ;
13351336 u32 npages = alloc_size >> PAGE_SHIFT ;
13361337 struct dxgvmbusmsg msg = {.hdr = NULL };
1337-
1338- ret = init_message (& msg , device -> adapter , device -> process ,
1339- sizeof (* set_store_command ));
1340- if (ret )
1341- goto cleanup ;
1342- set_store_command = (void * )msg .msg ;
1338+ const u32 max_pfns_in_message =
1339+ (DXG_MAX_VM_BUS_PACKET_SIZE - sizeof (* set_pages_command ) -
1340+ PAGE_SIZE ) / sizeof (__u64 );
1341+ u32 alloc_offset_in_pages = 0 ;
1342+ struct page * * page_in ;
1343+ u64 * pfn ;
1344+ u32 pages_to_send ;
1345+ u32 i ;
13431346
13441347 /*
13451348 * Create a guest physical address list and set it as the allocation
@@ -1350,6 +1353,7 @@ int create_existing_sysmem(struct dxgdevice *device,
13501353 dev_dbg (dxgglobaldev , " Alloc size: %lld" , alloc_size );
13511354
13521355 dxgalloc -> cpu_address = (void * )sysmem ;
1356+
13531357 dxgalloc -> pages = vzalloc (npages * sizeof (void * ));
13541358 if (dxgalloc -> pages == NULL ) {
13551359 pr_err ("failed to allocate pages" );
@@ -1367,31 +1371,79 @@ int create_existing_sysmem(struct dxgdevice *device,
13671371 ret = - ENOMEM ;
13681372 goto cleanup ;
13691373 }
1370- kmem = vmap (dxgalloc -> pages , npages , VM_MAP , PAGE_KERNEL );
1371- if (kmem == NULL ) {
1372- pr_err ("vmap failed" );
1373- ret = - ENOMEM ;
1374- goto cleanup ;
1375- }
1376- ret1 = vmbus_establish_gpadl (dxgglobal_get_vmbus (), kmem ,
1377- alloc_size , & dxgalloc -> gpadl );
1378- if (ret1 ) {
1379- pr_err ("establish_gpadl failed: %d" , ret1 );
1380- ret = - ENOMEM ;
1381- goto cleanup ;
1382- }
1383- dev_dbg (dxgglobaldev , "New gpadl %d" , dxgalloc -> gpadl );
1374+ if (!dxgglobal -> map_guest_pages_enabled ) {
1375+ ret = init_message (& msg , device -> adapter , device -> process ,
1376+ sizeof (* set_store_command ));
1377+ if (ret )
1378+ goto cleanup ;
1379+ set_store_command = (void * )msg .msg ;
13841380
1385- command_vgpu_to_host_init2 (& set_store_command -> hdr ,
1386- DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE ,
1387- device -> process -> host_handle );
1388- set_store_command -> device = device -> handle ;
1389- set_store_command -> device = device -> handle ;
1390- set_store_command -> allocation = host_alloc -> allocation ;
1391- set_store_command -> gpadl = dxgalloc -> gpadl ;
1392- ret = dxgvmb_send_sync_msg_ntstatus (msg .channel , msg .hdr , msg .size );
1393- if (ret < 0 )
1394- pr_err ("failed to set existing store: %x" , ret );
1381+ kmem = vmap (dxgalloc -> pages , npages , VM_MAP , PAGE_KERNEL );
1382+ if (kmem == NULL ) {
1383+ pr_err ("vmap failed" );
1384+ ret = - ENOMEM ;
1385+ goto cleanup ;
1386+ }
1387+ ret1 = vmbus_establish_gpadl (dxgglobal_get_vmbus (), kmem ,
1388+ alloc_size , & dxgalloc -> gpadl );
1389+ if (ret1 ) {
1390+ pr_err ("establish_gpadl failed: %d" , ret1 );
1391+ ret = - ENOMEM ;
1392+ goto cleanup ;
1393+ }
1394+ dev_dbg (dxgglobaldev , "New gpadl %d" , dxgalloc -> gpadl );
1395+
1396+ command_vgpu_to_host_init2 (& set_store_command -> hdr ,
1397+ DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE ,
1398+ device -> process -> host_handle );
1399+ set_store_command -> device = device -> handle ;
1400+ set_store_command -> allocation = host_alloc -> allocation ;
1401+ set_store_command -> gpadl = dxgalloc -> gpadl ;
1402+ ret = dxgvmb_send_sync_msg_ntstatus (msg .channel , msg .hdr ,
1403+ msg .size );
1404+ if (ret < 0 )
1405+ pr_err ("failed to set existing store: %x" , ret );
1406+ } else {
1407+ /*
1408+ * Send the list of the allocation PFNs to the host. The host
1409+ * will map the pages for GPU access.
1410+ */
1411+
1412+ ret = init_message (& msg , device -> adapter , device -> process ,
1413+ sizeof (* set_pages_command ) +
1414+ max_pfns_in_message * sizeof (u64 ));
1415+ if (ret )
1416+ goto cleanup ;
1417+ set_pages_command = (void * )msg .msg ;
1418+ command_vgpu_to_host_init2 (& set_pages_command -> hdr ,
1419+ DXGK_VMBCOMMAND_SETEXISTINGSYSMEMPAGES ,
1420+ device -> process -> host_handle );
1421+ set_pages_command -> device = device -> handle ;
1422+ set_pages_command -> allocation = host_alloc -> allocation ;
1423+
1424+ page_in = dxgalloc -> pages ;
1425+ while (alloc_offset_in_pages < npages ) {
1426+ pfn = (u64 * )((char * )msg .msg +
1427+ sizeof (* set_pages_command ));
1428+ pages_to_send = min (npages - alloc_offset_in_pages ,
1429+ max_pfns_in_message );
1430+ set_pages_command -> num_pages = pages_to_send ;
1431+ set_pages_command -> alloc_offset_in_pages =
1432+ alloc_offset_in_pages ;
1433+
1434+ for (i = 0 ; i < pages_to_send ; i ++ )
1435+ * pfn ++ = page_to_pfn (* page_in ++ );
1436+
1437+ ret = dxgvmb_send_sync_msg_ntstatus (msg .channel ,
1438+ msg .hdr ,
1439+ msg .size );
1440+ if (ret < 0 ) {
1441+ pr_err ("failed to set existing pages: %x" , ret );
1442+ break ;
1443+ }
1444+ alloc_offset_in_pages += pages_to_send ;
1445+ }
1446+ }
13951447
13961448cleanup :
13971449 if (kmem )
0 commit comments