@@ -1307,15 +1307,18 @@ int create_existing_sysmem(struct dxgdevice *device,
13071307 void * kmem = NULL ;
13081308 int ret = 0 ;
13091309 struct dxgkvmb_command_setexistingsysmemstore * set_store_command ;
1310+ struct dxgkvmb_command_setexistingsysmempages * set_pages_command ;
13101311 u64 alloc_size = host_alloc -> allocation_size ;
13111312 u32 npages = alloc_size >> PAGE_SHIFT ;
13121313 struct dxgvmbusmsg msg = {.hdr = NULL };
1313-
1314- ret = init_message (& msg , device -> adapter , device -> process ,
1315- sizeof (* set_store_command ));
1316- if (ret )
1317- goto cleanup ;
1318- set_store_command = (void * )msg .msg ;
1314+ const u32 max_pfns_in_message =
1315+ (DXG_MAX_VM_BUS_PACKET_SIZE - sizeof (* set_pages_command ) -
1316+ PAGE_SIZE ) / sizeof (__u64 );
1317+ u32 alloc_offset_in_pages = 0 ;
1318+ struct page * * page_in ;
1319+ u64 * pfn ;
1320+ u32 pages_to_send ;
1321+ u32 i ;
13191322
13201323 /*
13211324 * Create a guest physical address list and set it as the allocation
@@ -1326,6 +1329,7 @@ int create_existing_sysmem(struct dxgdevice *device,
13261329 dev_dbg (dxgglobaldev , " Alloc size: %lld" , alloc_size );
13271330
13281331 dxgalloc -> cpu_address = (void * )sysmem ;
1332+
13291333 dxgalloc -> pages = vzalloc (npages * sizeof (void * ));
13301334 if (dxgalloc -> pages == NULL ) {
13311335 pr_err ("failed to allocate pages" );
@@ -1343,31 +1347,79 @@ int create_existing_sysmem(struct dxgdevice *device,
13431347 ret = - ENOMEM ;
13441348 goto cleanup ;
13451349 }
1346- kmem = vmap (dxgalloc -> pages , npages , VM_MAP , PAGE_KERNEL );
1347- if (kmem == NULL ) {
1348- pr_err ("vmap failed" );
1349- ret = - ENOMEM ;
1350- goto cleanup ;
1351- }
1352- ret1 = vmbus_establish_gpadl (dxgglobal_get_vmbus (), kmem ,
1353- alloc_size , & dxgalloc -> gpadl );
1354- if (ret1 ) {
1355- pr_err ("establish_gpadl failed: %d" , ret1 );
1356- ret = - ENOMEM ;
1357- goto cleanup ;
1358- }
1359- dev_dbg (dxgglobaldev , "New gpadl %d" , dxgalloc -> gpadl );
1350+ if (!dxgglobal -> map_guest_pages_enabled ) {
1351+ ret = init_message (& msg , device -> adapter , device -> process ,
1352+ sizeof (* set_store_command ));
1353+ if (ret )
1354+ goto cleanup ;
1355+ set_store_command = (void * )msg .msg ;
13601356
1361- command_vgpu_to_host_init2 (& set_store_command -> hdr ,
1362- DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE ,
1363- device -> process -> host_handle );
1364- set_store_command -> device = device -> handle ;
1365- set_store_command -> device = device -> handle ;
1366- set_store_command -> allocation = host_alloc -> allocation ;
1367- set_store_command -> gpadl = dxgalloc -> gpadl ;
1368- ret = dxgvmb_send_sync_msg_ntstatus (msg .channel , msg .hdr , msg .size );
1369- if (ret < 0 )
1370- pr_err ("failed to set existing store: %x" , ret );
1357+ kmem = vmap (dxgalloc -> pages , npages , VM_MAP , PAGE_KERNEL );
1358+ if (kmem == NULL ) {
1359+ pr_err ("vmap failed" );
1360+ ret = - ENOMEM ;
1361+ goto cleanup ;
1362+ }
1363+ ret1 = vmbus_establish_gpadl (dxgglobal_get_vmbus (), kmem ,
1364+ alloc_size , & dxgalloc -> gpadl );
1365+ if (ret1 ) {
1366+ pr_err ("establish_gpadl failed: %d" , ret1 );
1367+ ret = - ENOMEM ;
1368+ goto cleanup ;
1369+ }
1370+ dev_dbg (dxgglobaldev , "New gpadl %d" , dxgalloc -> gpadl );
1371+
1372+ command_vgpu_to_host_init2 (& set_store_command -> hdr ,
1373+ DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE ,
1374+ device -> process -> host_handle );
1375+ set_store_command -> device = device -> handle ;
1376+ set_store_command -> allocation = host_alloc -> allocation ;
1377+ set_store_command -> gpadl = dxgalloc -> gpadl ;
1378+ ret = dxgvmb_send_sync_msg_ntstatus (msg .channel , msg .hdr ,
1379+ msg .size );
1380+ if (ret < 0 )
1381+ pr_err ("failed to set existing store: %x" , ret );
1382+ } else {
1383+ /*
1384+ * Send the list of the allocation PFNs to the host. The host
1385+ * will map the pages for GPU access.
1386+ */
1387+
1388+ ret = init_message (& msg , device -> adapter , device -> process ,
1389+ sizeof (* set_pages_command ) +
1390+ max_pfns_in_message * sizeof (u64 ));
1391+ if (ret )
1392+ goto cleanup ;
1393+ set_pages_command = (void * )msg .msg ;
1394+ command_vgpu_to_host_init2 (& set_pages_command -> hdr ,
1395+ DXGK_VMBCOMMAND_SETEXISTINGSYSMEMPAGES ,
1396+ device -> process -> host_handle );
1397+ set_pages_command -> device = device -> handle ;
1398+ set_pages_command -> allocation = host_alloc -> allocation ;
1399+
1400+ page_in = dxgalloc -> pages ;
1401+ while (alloc_offset_in_pages < npages ) {
1402+ pfn = (u64 * )((char * )msg .msg +
1403+ sizeof (* set_pages_command ));
1404+ pages_to_send = min (npages - alloc_offset_in_pages ,
1405+ max_pfns_in_message );
1406+ set_pages_command -> num_pages = pages_to_send ;
1407+ set_pages_command -> alloc_offset_in_pages =
1408+ alloc_offset_in_pages ;
1409+
1410+ for (i = 0 ; i < pages_to_send ; i ++ )
1411+ * pfn ++ = page_to_pfn (* page_in ++ );
1412+
1413+ ret = dxgvmb_send_sync_msg_ntstatus (msg .channel ,
1414+ msg .hdr ,
1415+ msg .size );
1416+ if (ret < 0 ) {
1417+ pr_err ("failed to set existing pages: %x" , ret );
1418+ break ;
1419+ }
1420+ alloc_offset_in_pages += pages_to_send ;
1421+ }
1422+ }
13711423
13721424cleanup :
13731425 if (kmem )
0 commit comments