@@ -1573,8 +1573,27 @@ process_allocation_handles(struct dxgprocess *process,
15731573 struct dxgresource * resource )
15741574{
15751575 int ret = 0 ;
1576- int i ;
1576+ int i = 0 ;
1577+ int k ;
1578+ struct dxgkvmb_command_allocinfo_return * host_alloc ;
15771579
1580+ /*
1581+ * Assign handle to the internal objects, so VM bus messages will be
1582+ * sent to the host to free them during object destruction.
1583+ */
1584+ if (args -> flags .create_resource )
1585+ resource -> handle = res -> resource ;
1586+ for (i = 0 ; i < args -> alloc_count ; i ++ ) {
1587+ host_alloc = & res -> allocation_info [i ];
1588+ dxgalloc [i ]-> alloc_handle = host_alloc -> allocation ;
1589+ }
1590+
1591+ /*
1592+ * Assign handle to the handle table.
1593+ * In case of a failure all handles should be freed.
1594+ * When the function returns, the objects could be destroyed by
1595+ * handle immediately.
1596+ */
15781597 hmgrtable_lock (& process -> handle_table , DXGLOCK_EXCL );
15791598 if (args -> flags .create_resource ) {
15801599 ret = hmgrtable_assign_handle (& process -> handle_table , resource ,
@@ -1583,14 +1602,12 @@ process_allocation_handles(struct dxgprocess *process,
15831602 if (ret < 0 ) {
15841603 DXG_ERR ("failed to assign resource handle %x" ,
15851604 res -> resource .v );
1605+ goto cleanup ;
15861606 } else {
1587- resource -> handle = res -> resource ;
15881607 resource -> handle_valid = 1 ;
15891608 }
15901609 }
15911610 for (i = 0 ; i < args -> alloc_count ; i ++ ) {
1592- struct dxgkvmb_command_allocinfo_return * host_alloc ;
1593-
15941611 host_alloc = & res -> allocation_info [i ];
15951612 ret = hmgrtable_assign_handle (& process -> handle_table ,
15961613 dxgalloc [i ],
@@ -1602,9 +1619,26 @@ process_allocation_handles(struct dxgprocess *process,
16021619 args -> alloc_count , i );
16031620 break ;
16041621 }
1605- dxgalloc [i ]-> alloc_handle = host_alloc -> allocation ;
16061622 dxgalloc [i ]-> handle_valid = 1 ;
16071623 }
1624+ if (ret < 0 ) {
1625+ if (args -> flags .create_resource ) {
1626+ hmgrtable_free_handle (& process -> handle_table ,
1627+ HMGRENTRY_TYPE_DXGRESOURCE ,
1628+ res -> resource );
1629+ resource -> handle_valid = 0 ;
1630+ }
1631+ for (k = 0 ; k < i ; k ++ ) {
1632+ host_alloc = & res -> allocation_info [i ];
1633+ hmgrtable_free_handle (& process -> handle_table ,
1634+ HMGRENTRY_TYPE_DXGALLOCATION ,
1635+ host_alloc -> allocation );
1636+ dxgalloc [i ]-> handle_valid = 0 ;
1637+ }
1638+ }
1639+
1640+ cleanup :
1641+
16081642 hmgrtable_unlock (& process -> handle_table , DXGLOCK_EXCL );
16091643
16101644 if (ret )
@@ -1705,18 +1739,17 @@ create_local_allocations(struct dxgprocess *process,
17051739 }
17061740 }
17071741
1708- ret = process_allocation_handles (process , device , args , result ,
1709- dxgalloc , resource );
1710- if (ret < 0 )
1711- goto cleanup ;
1712-
17131742 ret = copy_to_user (& input_args -> global_share , & args -> global_share ,
17141743 sizeof (struct d3dkmthandle ));
17151744 if (ret ) {
17161745 DXG_ERR ("failed to copy global share" );
17171746 ret = - EFAULT ;
1747+ goto cleanup ;
17181748 }
17191749
1750+ ret = process_allocation_handles (process , device , args , result ,
1751+ dxgalloc , resource );
1752+
17201753cleanup :
17211754
17221755 if (ret < 0 ) {
@@ -3576,22 +3609,6 @@ int dxgvmb_send_create_hwqueue(struct dxgprocess *process,
35763609 goto cleanup ;
35773610 }
35783611
3579- ret = hmgrtable_assign_handle_safe (& process -> handle_table , hwqueue ,
3580- HMGRENTRY_TYPE_DXGHWQUEUE ,
3581- command -> hwqueue );
3582- if (ret < 0 )
3583- goto cleanup ;
3584-
3585- ret = hmgrtable_assign_handle_safe (& process -> handle_table ,
3586- NULL ,
3587- HMGRENTRY_TYPE_MONITOREDFENCE ,
3588- command -> hwqueue_progress_fence );
3589- if (ret < 0 )
3590- goto cleanup ;
3591-
3592- hwqueue -> handle = command -> hwqueue ;
3593- hwqueue -> progress_fence_sync_object = command -> hwqueue_progress_fence ;
3594-
35953612 hwqueue -> progress_fence_mapped_address =
35963613 dxg_map_iospace ((u64 )command -> hwqueue_progress_fence_cpuva ,
35973614 PAGE_SIZE , PROT_READ | PROT_WRITE , true);
@@ -3641,6 +3658,22 @@ int dxgvmb_send_create_hwqueue(struct dxgprocess *process,
36413658 }
36423659 }
36433660
3661+ ret = hmgrtable_assign_handle_safe (& process -> handle_table ,
3662+ NULL ,
3663+ HMGRENTRY_TYPE_MONITOREDFENCE ,
3664+ command -> hwqueue_progress_fence );
3665+ if (ret < 0 )
3666+ goto cleanup ;
3667+
3668+ hwqueue -> progress_fence_sync_object = command -> hwqueue_progress_fence ;
3669+ hwqueue -> handle = command -> hwqueue ;
3670+
3671+ ret = hmgrtable_assign_handle_safe (& process -> handle_table , hwqueue ,
3672+ HMGRENTRY_TYPE_DXGHWQUEUE ,
3673+ command -> hwqueue );
3674+ if (ret < 0 )
3675+ hwqueue -> handle .v = 0 ;
3676+
36443677cleanup :
36453678 if (ret < 0 ) {
36463679 DXG_ERR ("failed %x" , ret );
0 commit comments