@@ -506,20 +506,19 @@ impl AddrSpace {
506
506
// - shared pages (If there is a shared page in the vma)
507
507
// - cow
508
508
#[ cfg( feature = "cow" ) ]
509
- if let Ok ( ( paddr, _, page_size) ) = self . pt . query ( vaddr) {
510
- if !access_flags. contains ( MappingFlags :: WRITE ) {
511
- return false ;
509
+ if access_flags. contains ( MappingFlags :: WRITE ) {
510
+ if let Ok ( ( paddr, _, page_size) ) = self . pt . query ( vaddr) {
511
+ // 1. page fault caused by write
512
+ // 2. pte exists
513
+ // 3. Not shared memory
514
+ return Self :: handle_cow_fault (
515
+ vaddr,
516
+ paddr,
517
+ orig_flags,
518
+ page_size,
519
+ & mut self . pt ,
520
+ ) ;
512
521
}
513
- // 1. page fault caused by write
514
- // 2. pte exists
515
- // 3. Not shared memory
516
- return Self :: handle_cow_fault (
517
- vaddr,
518
- paddr,
519
- orig_flags,
520
- page_size,
521
- & mut self . pt ,
522
- ) ;
523
522
}
524
523
525
524
return area
@@ -562,92 +561,87 @@ impl AddrSpace {
562
561
Backend :: Alloc { populate : _, align } => {
563
562
// Forcing `populate = false` is to prevent the subsequent `new_aspace.areas.map`
564
563
// from mapping page table entries for the virtual addresses.
565
- & Backend :: new_alloc ( false , * align)
564
+ Backend :: new_alloc ( false , * align)
566
565
}
567
- other => other,
566
+ other => other. clone ( ) ,
568
567
} ;
569
568
570
569
// Remap the memory area in the new address space.
571
- let new_area =
572
- MemoryArea :: new ( area. start ( ) , area. size ( ) , area. flags ( ) , backend. clone ( ) ) ;
570
+ let new_area = MemoryArea :: new ( area. start ( ) , area. size ( ) , area. flags ( ) , backend) ;
573
571
new_aspace
574
572
. areas
575
573
. map ( new_area, & mut new_aspace. pt , false )
576
574
. map_err ( mapping_err_to_ax_err) ?;
577
575
578
- let align = match * backend {
579
- Backend :: Alloc { align, .. } => align,
576
+ let align = match area . backend ( ) {
577
+ Backend :: Alloc { align, .. } => * align,
580
578
// Linear-backed regions are usually allocated by the kernel and are shared
581
579
Backend :: Linear { .. } => continue ,
582
580
} ;
583
581
584
582
#[ cfg( feature = "cow" ) ]
585
- let flags = {
586
- let mut f = area. flags ( ) ;
587
- f. remove ( MappingFlags :: WRITE ) ;
588
- f
589
- } ;
583
+ let cow_flags = area. flags ( ) . clone ( ) - MappingFlags :: WRITE ;
590
584
591
585
for vaddr in PageIterWrapper :: new ( area. start ( ) , area. end ( ) , align)
592
586
. expect ( "Failed to create page iterator" )
593
587
{
594
- //If the page is mapped in the old page table:
595
- // - Update its permissions in the old page table using `flags`.
596
- // - Map the same physical page into the new page table at the same
597
- // virtual address, with the same page size and `flags`.
598
- #[ cfg( feature = "cow" ) ]
599
- {
600
- match self . pt . query ( vaddr) {
601
- Ok ( ( paddr, _, page_size) ) => {
588
+ // Copy data from old memory area to new memory area.
589
+ match self . pt . query ( vaddr) {
590
+ Ok ( ( paddr, _, page_size) ) => {
591
+ #[ cfg( not( feature = "cow" ) ) ]
592
+ {
593
+ let new_addr = match new_aspace. pt . query ( vaddr) {
594
+ Ok ( ( paddr, _, _) ) => paddr,
595
+ // If the page is not mapped, try map it.
596
+ Err ( PagingError :: NotMapped ) => {
597
+ if !area. backend ( ) . handle_page_fault (
598
+ vaddr,
599
+ area. flags ( ) ,
600
+ & mut new_aspace. pt ,
601
+ ) {
602
+ return Err ( AxError :: NoMemory ) ;
603
+ }
604
+ match new_aspace. pt . query ( vaddr) {
605
+ Ok ( ( paddr, _, _) ) => paddr,
606
+ Err ( _) => return Err ( AxError :: BadAddress ) ,
607
+ }
608
+ }
609
+ Err ( _) => return Err ( AxError :: BadAddress ) ,
610
+ } ;
611
+ unsafe {
612
+ core:: ptr:: copy_nonoverlapping (
613
+ phys_to_virt ( paddr) . as_ptr ( ) ,
614
+ phys_to_virt ( new_addr) . as_mut_ptr ( ) ,
615
+ page_size. into ( ) ,
616
+ )
617
+ } ;
618
+ }
619
+
620
+ //If the page is mapped in the old page table:
621
+ // - Update its permissions in the old page table using `flags`.
622
+ // - Map the same physical page into the new page table at the same
623
+ // virtual address, with the same page size and `flags`.
624
+ #[ cfg( feature = "cow" ) ]
625
+ {
602
626
frame_table ( ) . inc_ref ( paddr) ;
603
627
604
628
self . pt
605
- . protect ( vaddr, flags )
629
+ . protect ( vaddr, cow_flags )
606
630
. map ( |( _, tlb) | tlb. flush ( ) )
607
631
. expect ( "protect failed" ) ;
608
632
new_aspace
609
633
. pt
610
- . map ( vaddr, paddr, page_size, flags )
634
+ . map ( vaddr, paddr, page_size, cow_flags )
611
635
. map ( |tlb| tlb. flush ( ) )
612
636
. expect ( "map failed" ) ;
613
- }
614
- // If the page is not mapped, skip it.
615
- Err ( PagingError :: NotMapped ) => continue ,
616
- Err ( _) => return Err ( AxError :: BadAddress ) ,
617
- }
618
- }
619
637
620
- // Copy data from old memory area to new memory area.
621
- #[ cfg( not( feature = "cow" ) ) ]
622
- {
623
- let addr = match self . pt . query ( vaddr) {
624
- Ok ( ( paddr, _, _) ) => paddr,
625
- // If the page is not mapped, skip it.
626
- Err ( PagingError :: NotMapped ) => continue ,
627
- Err ( _) => return Err ( AxError :: BadAddress ) ,
628
- } ;
629
- let new_addr = match new_aspace. pt . query ( vaddr) {
630
- Ok ( ( paddr, _, _) ) => paddr,
631
- // If the page is not mapped, try map it.
632
- Err ( PagingError :: NotMapped ) => {
633
- if !backend. handle_page_fault ( vaddr, area. flags ( ) , & mut new_aspace. pt ) {
634
- return Err ( AxError :: NoMemory ) ;
635
- }
636
- match new_aspace. pt . query ( vaddr) {
637
- Ok ( ( paddr, _, _) ) => paddr,
638
- Err ( _) => return Err ( AxError :: BadAddress ) ,
639
- }
638
+ continue ;
640
639
}
641
- Err ( _) => return Err ( AxError :: BadAddress ) ,
642
- } ;
643
- unsafe {
644
- core:: ptr:: copy_nonoverlapping (
645
- phys_to_virt ( addr) . as_ptr ( ) ,
646
- phys_to_virt ( new_addr) . as_mut_ptr ( ) ,
647
- PAGE_SIZE_4K ,
648
- )
649
- } ;
650
- }
640
+ }
641
+ // If the page is not mapped, skip it.
642
+ Err ( PagingError :: NotMapped ) => continue ,
643
+ Err ( _) => return Err ( AxError :: BadAddress ) ,
644
+ } ;
651
645
}
652
646
}
653
647
Ok ( new_aspace)
0 commit comments