diff options
Diffstat (limited to 'arch/tile/mm/fault.c')
-rw-r--r-- | arch/tile/mm/fault.c | 70 |
1 files changed, 17 insertions, 53 deletions
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c index 39c48cbe0a96..111d5a9b76f1 100644 --- a/arch/tile/mm/fault.c +++ b/arch/tile/mm/fault.c | |||
@@ -466,28 +466,15 @@ good_area: | |||
466 | } | 466 | } |
467 | } | 467 | } |
468 | 468 | ||
469 | #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() | ||
470 | /* | ||
471 | * If this was an asynchronous fault, | ||
472 | * restart the appropriate engine. | ||
473 | */ | ||
474 | switch (fault_num) { | ||
475 | #if CHIP_HAS_TILE_DMA() | 469 | #if CHIP_HAS_TILE_DMA() |
470 | /* If this was a DMA TLB fault, restart the DMA engine. */ | ||
471 | switch (fault_num) { | ||
476 | case INT_DMATLB_MISS: | 472 | case INT_DMATLB_MISS: |
477 | case INT_DMATLB_MISS_DWNCL: | 473 | case INT_DMATLB_MISS_DWNCL: |
478 | case INT_DMATLB_ACCESS: | 474 | case INT_DMATLB_ACCESS: |
479 | case INT_DMATLB_ACCESS_DWNCL: | 475 | case INT_DMATLB_ACCESS_DWNCL: |
480 | __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK); | 476 | __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK); |
481 | break; | 477 | break; |
482 | #endif | ||
483 | #if CHIP_HAS_SN_PROC() | ||
484 | case INT_SNITLB_MISS: | ||
485 | case INT_SNITLB_MISS_DWNCL: | ||
486 | __insn_mtspr(SPR_SNCTL, | ||
487 | __insn_mfspr(SPR_SNCTL) & | ||
488 | ~SPR_SNCTL__FRZPROC_MASK); | ||
489 | break; | ||
490 | #endif | ||
491 | } | 478 | } |
492 | #endif | 479 | #endif |
493 | 480 | ||
@@ -804,10 +791,6 @@ void do_page_fault(struct pt_regs *regs, int fault_num, | |||
804 | case INT_DMATLB_MISS: | 791 | case INT_DMATLB_MISS: |
805 | case INT_DMATLB_MISS_DWNCL: | 792 | case INT_DMATLB_MISS_DWNCL: |
806 | #endif | 793 | #endif |
807 | #if CHIP_HAS_SN_PROC() | ||
808 | case INT_SNITLB_MISS: | ||
809 | case INT_SNITLB_MISS_DWNCL: | ||
810 | #endif | ||
811 | is_page_fault = 1; | 794 | is_page_fault = 1; |
812 | break; | 795 | break; |
813 | 796 | ||
@@ -823,7 +806,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, | |||
823 | panic("Bad fault number %d in do_page_fault", fault_num); | 806 | panic("Bad fault number %d in do_page_fault", fault_num); |
824 | } | 807 | } |
825 | 808 | ||
826 | #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() | 809 | #if CHIP_HAS_TILE_DMA() |
827 | if (!user_mode(regs)) { | 810 | if (!user_mode(regs)) { |
828 | struct async_tlb *async; | 811 | struct async_tlb *async; |
829 | switch (fault_num) { | 812 | switch (fault_num) { |
@@ -835,12 +818,6 @@ void do_page_fault(struct pt_regs *regs, int fault_num, | |||
835 | async = ¤t->thread.dma_async_tlb; | 818 | async = ¤t->thread.dma_async_tlb; |
836 | break; | 819 | break; |
837 | #endif | 820 | #endif |
838 | #if CHIP_HAS_SN_PROC() | ||
839 | case INT_SNITLB_MISS: | ||
840 | case INT_SNITLB_MISS_DWNCL: | ||
841 | async = ¤t->thread.sn_async_tlb; | ||
842 | break; | ||
843 | #endif | ||
844 | default: | 821 | default: |
845 | async = NULL; | 822 | async = NULL; |
846 | } | 823 | } |
@@ -873,14 +850,22 @@ void do_page_fault(struct pt_regs *regs, int fault_num, | |||
873 | } | 850 | } |
874 | 851 | ||
875 | 852 | ||
876 | #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() | 853 | #if CHIP_HAS_TILE_DMA() |
877 | /* | 854 | /* |
878 | * Check an async_tlb structure to see if a deferred fault is waiting, | 855 | * This routine effectively re-issues asynchronous page faults |
879 | * and if so pass it to the page-fault code. | 856 | * when we are returning to user space. |
880 | */ | 857 | */ |
881 | static void handle_async_page_fault(struct pt_regs *regs, | 858 | void do_async_page_fault(struct pt_regs *regs) |
882 | struct async_tlb *async) | ||
883 | { | 859 | { |
860 | struct async_tlb *async = ¤t->thread.dma_async_tlb; | ||
861 | |||
862 | /* | ||
863 | * Clear thread flag early. If we re-interrupt while processing | ||
864 | * code here, we will reset it and recall this routine before | ||
865 | * returning to user space. | ||
866 | */ | ||
867 | clear_thread_flag(TIF_ASYNC_TLB); | ||
868 | |||
884 | if (async->fault_num) { | 869 | if (async->fault_num) { |
885 | /* | 870 | /* |
886 | * Clear async->fault_num before calling the page-fault | 871 | * Clear async->fault_num before calling the page-fault |
@@ -894,28 +879,7 @@ static void handle_async_page_fault(struct pt_regs *regs, | |||
894 | async->address, async->is_write); | 879 | async->address, async->is_write); |
895 | } | 880 | } |
896 | } | 881 | } |
897 | 882 | #endif /* CHIP_HAS_TILE_DMA() */ | |
898 | /* | ||
899 | * This routine effectively re-issues asynchronous page faults | ||
900 | * when we are returning to user space. | ||
901 | */ | ||
902 | void do_async_page_fault(struct pt_regs *regs) | ||
903 | { | ||
904 | /* | ||
905 | * Clear thread flag early. If we re-interrupt while processing | ||
906 | * code here, we will reset it and recall this routine before | ||
907 | * returning to user space. | ||
908 | */ | ||
909 | clear_thread_flag(TIF_ASYNC_TLB); | ||
910 | |||
911 | #if CHIP_HAS_TILE_DMA() | ||
912 | handle_async_page_fault(regs, ¤t->thread.dma_async_tlb); | ||
913 | #endif | ||
914 | #if CHIP_HAS_SN_PROC() | ||
915 | handle_async_page_fault(regs, ¤t->thread.sn_async_tlb); | ||
916 | #endif | ||
917 | } | ||
918 | #endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */ | ||
919 | 883 | ||
920 | 884 | ||
921 | void vmalloc_sync_all(void) | 885 | void vmalloc_sync_all(void) |