@@ -30,13 +30,19 @@ struct Vm {
3030 ualloc : Arc < Mutex < alloc:: DefaultAllocator > > ,
3131 ualloc_priv : Arc < Mutex < alloc:: DefaultAllocator > > ,
3232 vm : mmu:: Vm ,
33- dummy_obj : gem :: ObjectRef ,
33+ _dummy_mapping : mmu :: KernelMapping ,
3434}
3535
3636impl Drop for Vm {
3737 fn drop ( & mut self ) {
38- // Mappings create a reference loop, make sure to break it.
39- self . dummy_obj . drop_vm_mappings ( self . vm . id ( ) ) ;
38+ // When the user Vm is dropped, unmap everything in the user range
39+ if self
40+ . vm
41+ . unmap_range ( mmu:: IOVA_USER_BASE as u64 , VM_USER_END )
42+ . is_err ( )
43+ {
44+ pr_err ! ( "Vm::Drop: vm.unmap_range() failed\n " ) ;
45+ }
4046 }
4147}
4248
@@ -154,16 +160,16 @@ const VM_SHADER_END: u64 = 0x11_ffffffff;
154160/// Start address of the general user mapping region.
155161const VM_USER_START : u64 = 0x20_00000000 ;
156162/// End address of the general user mapping region.
157- const VM_USER_END : u64 = 0x5f_ffffffff ;
163+ const VM_USER_END : u64 = 0x6f_ffff0000 ;
158164
159165/// Start address of the kernel-managed GPU-only mapping region.
160- const VM_DRV_GPU_START : u64 = 0x60_00000000 ;
166+ const VM_DRV_GPU_START : u64 = 0x70_00000000 ;
161167/// End address of the kernel-managed GPU-only mapping region.
162- const VM_DRV_GPU_END : u64 = 0x60_ffffffff ;
168+ const VM_DRV_GPU_END : u64 = 0x70_ffffffff ;
163169/// Start address of the kernel-managed GPU/FW shared mapping region.
164- const VM_DRV_GPUFW_START : u64 = 0x61_00000000 ;
170+ const VM_DRV_GPUFW_START : u64 = 0x71_00000000 ;
165171/// End address of the kernel-managed GPU/FW shared mapping region.
166- const VM_DRV_GPUFW_END : u64 = 0x61_ffffffff ;
172+ const VM_DRV_GPUFW_END : u64 = 0x71_ffffffff ;
167173/// Address of a special dummy page?
168174const VM_UNK_PAGE : u64 = 0x6f_ffff8000 ;
169175
@@ -298,7 +304,7 @@ impl File {
298304
299305 let gpu = & device. data ( ) . gpu ;
300306 let file_id = file. inner ( ) . id ;
301- let vm = gpu. new_vm ( file_id ) ?;
307+ let vm = gpu. new_vm ( ) ?;
302308
303309 let resv = file. inner ( ) . vms ( ) . reserve ( ) ?;
304310 let id: u32 = resv. index ( ) . try_into ( ) ?;
@@ -343,15 +349,15 @@ impl File {
343349 ) ;
344350 let mut dummy_obj = gem:: new_kernel_object ( device, 0x4000 ) ?;
345351 dummy_obj. vmap ( ) ?. as_mut_slice ( ) . fill ( 0 ) ;
346- dummy_obj. map_at ( & vm, VM_UNK_PAGE , mmu:: PROT_GPU_SHARED_RW , true ) ?;
352+ let dummy_mapping = dummy_obj. map_at ( & vm, VM_UNK_PAGE , mmu:: PROT_GPU_SHARED_RW , true ) ?;
347353
348354 mod_dev_dbg ! ( device, "[File {} VM {}]: VM created\n " , file_id, id) ;
349355 resv. store ( Box :: new ( Vm {
350356 ualloc,
351357 ualloc_priv,
352358 vm,
353- dummy_obj ,
354- } ) ?) ?;
359+ _dummy_mapping : dummy_mapping ,
360+ } , GFP_KERNEL , ) ?) ?;
355361
356362 data. vm_id = id;
357363
@@ -492,15 +498,10 @@ impl File {
492498 data : & mut uapi:: drm_asahi_gem_bind ,
493499 file : & DrmFile ,
494500 ) -> Result < u32 > {
495- if data. offset != 0 {
496- pr_err ! ( "gem_bind: Offset not supported yet\n " ) ;
497- return Err ( EINVAL ) ; // Not supported yet
498- }
499-
500- if ( data. addr | data. range ) as usize & mmu:: UAT_PGMSK != 0 {
501+ if ( data. addr | data. range | data. offset ) as usize & mmu:: UAT_PGMSK != 0 {
501502 cls_pr_debug ! (
502503 Errors ,
503- "gem_bind: Addr/range not page aligned: {:#x} {:#x}\n " ,
504+ "gem_bind: Addr/range/offset not page aligned: {:#x} {:#x}\n " ,
504505 data. addr,
505506 data. range
506507 ) ;
@@ -512,12 +513,7 @@ impl File {
512513 return Err ( EINVAL ) ;
513514 }
514515
515- let mut bo = gem:: lookup_handle ( file, data. handle ) ?;
516-
517- if data. range != bo. size ( ) . try_into ( ) ? {
518- pr_err ! ( "gem_bind: Partial maps not supported yet\n " ) ;
519- return Err ( EINVAL ) ; // Not supported yet
520- }
516+ let bo = gem:: lookup_handle ( file, data. handle ) ?;
521517
522518 let start = data. addr ;
523519 let end = data. addr + data. range - 1 ;
@@ -590,11 +586,36 @@ impl File {
590586 . vm
591587 . clone ( ) ;
592588
593- bo . map_at ( & vm , start , prot , true ) ?;
589+ vm . bind_object ( & bo . gem , data . addr , data . range , data . offset , prot ) ?;
594590
595591 Ok ( 0 )
596592 }
597593
594+ pub ( crate ) fn unbind_gem_object ( file : & DrmFile , bo : & gem:: Object ) -> Result {
595+ let mut index = 0 ;
596+ loop {
597+ let item = file
598+ . inner ( )
599+ . vms ( )
600+ . find ( index, xarray:: XArray :: < Box < Vm > > :: MAX ) ;
601+ match item {
602+ Some ( ( idx, file_vm) ) => {
603+ // Clone since we can't hold the xarray spinlock while
604+ // calling drop_mappings()
605+ let vm = file_vm. borrow ( ) . vm . clone ( ) ;
606+ core:: mem:: drop ( file_vm) ;
607+ vm. drop_mappings ( bo) ?;
608+ if idx == xarray:: XArray :: < Box < Vm > > :: MAX {
609+ break ;
610+ }
611+ index = idx + 1 ;
612+ }
613+ None => break ,
614+ }
615+ }
616+ Ok ( ( ) )
617+ }
618+
598619 pub ( crate ) fn do_gem_unbind_all (
599620 _device : & AsahiDevice ,
600621 data : & mut uapi:: drm_asahi_gem_bind ,
@@ -605,20 +626,18 @@ impl File {
605626 return Err ( EINVAL ) ;
606627 }
607628
608- let mut bo = gem:: lookup_handle ( file, data. handle ) ?;
629+ let bo = gem:: lookup_handle ( file, data. handle ) ?;
609630
610631 if data. vm_id == 0 {
611- bo . drop_file_mappings ( file. inner ( ) . id ) ;
632+ Self :: unbind_gem_object ( file, & bo . gem ) ? ;
612633 } else {
613- let vm_id = file
614- . inner ( )
634+ file. inner ( )
615635 . vms ( )
616636 . get ( data. vm_id . try_into ( ) ?)
617637 . ok_or ( ENOENT ) ?
618638 . borrow ( )
619639 . vm
620- . id ( ) ;
621- bo. drop_vm_mappings ( vm_id) ;
640+ . drop_mappings ( & bo. gem ) ?;
622641 }
623642
624643 Ok ( 0 )
@@ -828,11 +847,6 @@ impl File {
828847 Ok ( _) => Ok ( 0 ) ,
829848 }
830849 }
831-
832- /// Returns the unique file ID for this `File`.
833- pub ( crate ) fn file_id ( & self ) -> u64 {
834- self . id
835- }
836850}
837851
838852impl Drop for File {
0 commit comments