@@ -49,81 +49,52 @@ static void __crst_table_upgrade(void *arg)
4949 __tlb_flush_local ();
5050}
5151
52- int crst_table_upgrade (struct mm_struct * mm , unsigned long limit )
52+ int crst_table_upgrade (struct mm_struct * mm )
5353{
5454 unsigned long * table , * pgd ;
55- unsigned long entry ;
56- int flush ;
5755
58- BUG_ON ( limit > ( 1UL << 53 ));
59- flush = 0 ;
60- repeat :
56+ /* upgrade should only happen from 3 to 4 levels */
57+ BUG_ON ( mm -> context . asce_limit != ( 1UL << 42 )) ;
58+
6159 table = crst_table_alloc (mm );
6260 if (!table )
6361 return - ENOMEM ;
62+
6463 spin_lock_bh (& mm -> page_table_lock );
65- if (mm -> context .asce_limit < limit ) {
66- pgd = (unsigned long * ) mm -> pgd ;
67- if (mm -> context .asce_limit <= (1UL << 31 )) {
68- entry = _REGION3_ENTRY_EMPTY ;
69- mm -> context .asce_limit = 1UL << 42 ;
70- mm -> context .asce_bits = _ASCE_TABLE_LENGTH |
71- _ASCE_USER_BITS |
72- _ASCE_TYPE_REGION3 ;
73- } else {
74- entry = _REGION2_ENTRY_EMPTY ;
75- mm -> context .asce_limit = 1UL << 53 ;
76- mm -> context .asce_bits = _ASCE_TABLE_LENGTH |
77- _ASCE_USER_BITS |
78- _ASCE_TYPE_REGION2 ;
79- }
80- crst_table_init (table , entry );
81- pgd_populate (mm , (pgd_t * ) table , (pud_t * ) pgd );
82- mm -> pgd = (pgd_t * ) table ;
83- mm -> task_size = mm -> context .asce_limit ;
84- table = NULL ;
85- flush = 1 ;
86- }
64+ pgd = (unsigned long * ) mm -> pgd ;
65+ crst_table_init (table , _REGION2_ENTRY_EMPTY );
66+ pgd_populate (mm , (pgd_t * ) table , (pud_t * ) pgd );
67+ mm -> pgd = (pgd_t * ) table ;
68+ mm -> context .asce_limit = 1UL << 53 ;
69+ mm -> context .asce = __pa (mm -> pgd ) | _ASCE_TABLE_LENGTH |
70+ _ASCE_USER_BITS | _ASCE_TYPE_REGION2 ;
71+ mm -> task_size = mm -> context .asce_limit ;
8772 spin_unlock_bh (& mm -> page_table_lock );
88- if (table )
89- crst_table_free (mm , table );
90- if (mm -> context .asce_limit < limit )
91- goto repeat ;
92- if (flush )
93- on_each_cpu (__crst_table_upgrade , mm , 0 );
73+
74+ on_each_cpu (__crst_table_upgrade , mm , 0 );
9475 return 0 ;
9576}
9677
97- void crst_table_downgrade (struct mm_struct * mm , unsigned long limit )
78+ void crst_table_downgrade (struct mm_struct * mm )
9879{
9980 pgd_t * pgd ;
10081
82+ /* downgrade should only happen from 3 to 2 levels (compat only) */
83+ BUG_ON (mm -> context .asce_limit != (1UL << 42 ));
84+
10185 if (current -> active_mm == mm ) {
10286 clear_user_asce ();
10387 __tlb_flush_mm (mm );
10488 }
105- while (mm -> context .asce_limit > limit ) {
106- pgd = mm -> pgd ;
107- switch (pgd_val (* pgd ) & _REGION_ENTRY_TYPE_MASK ) {
108- case _REGION_ENTRY_TYPE_R2 :
109- mm -> context .asce_limit = 1UL << 42 ;
110- mm -> context .asce_bits = _ASCE_TABLE_LENGTH |
111- _ASCE_USER_BITS |
112- _ASCE_TYPE_REGION3 ;
113- break ;
114- case _REGION_ENTRY_TYPE_R3 :
115- mm -> context .asce_limit = 1UL << 31 ;
116- mm -> context .asce_bits = _ASCE_TABLE_LENGTH |
117- _ASCE_USER_BITS |
118- _ASCE_TYPE_SEGMENT ;
119- break ;
120- default :
121- BUG ();
122- }
123- mm -> pgd = (pgd_t * ) (pgd_val (* pgd ) & _REGION_ENTRY_ORIGIN );
124- mm -> task_size = mm -> context .asce_limit ;
125- crst_table_free (mm , (unsigned long * ) pgd );
126- }
89+
90+ pgd = mm -> pgd ;
91+ mm -> pgd = (pgd_t * ) (pgd_val (* pgd ) & _REGION_ENTRY_ORIGIN );
92+ mm -> context .asce_limit = 1UL << 31 ;
93+ mm -> context .asce = __pa (mm -> pgd ) | _ASCE_TABLE_LENGTH |
94+ _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT ;
95+ mm -> task_size = mm -> context .asce_limit ;
96+ crst_table_free (mm , (unsigned long * ) pgd );
97+
12798 if (current -> active_mm == mm )
12899 set_user_asce (mm );
129100}
0 commit comments