26
26
#include <asm/page-states.h>
27
27
28
28
static inline void ptep_ipte_local (struct mm_struct * mm , unsigned long addr ,
29
- pte_t * ptep )
29
+ pte_t * ptep , int nodat )
30
30
{
31
31
unsigned long opt , asce ;
32
32
33
33
if (MACHINE_HAS_TLB_GUEST ) {
34
34
opt = 0 ;
35
35
asce = READ_ONCE (mm -> context .gmap_asce );
36
- if (asce == 0UL )
36
+ if (asce == 0UL || nodat )
37
37
opt |= IPTE_NODAT ;
38
38
if (asce != -1UL ) {
39
39
asce = asce ? : mm -> context .asce ;
@@ -46,14 +46,14 @@ static inline void ptep_ipte_local(struct mm_struct *mm, unsigned long addr,
46
46
}
47
47
48
48
static inline void ptep_ipte_global (struct mm_struct * mm , unsigned long addr ,
49
- pte_t * ptep )
49
+ pte_t * ptep , int nodat )
50
50
{
51
51
unsigned long opt , asce ;
52
52
53
53
if (MACHINE_HAS_TLB_GUEST ) {
54
54
opt = 0 ;
55
55
asce = READ_ONCE (mm -> context .gmap_asce );
56
- if (asce == 0UL )
56
+ if (asce == 0UL || nodat )
57
57
opt |= IPTE_NODAT ;
58
58
if (asce != -1UL ) {
59
59
asce = asce ? : mm -> context .asce ;
@@ -66,7 +66,8 @@ static inline void ptep_ipte_global(struct mm_struct *mm, unsigned long addr,
66
66
}
67
67
68
68
static inline pte_t ptep_flush_direct (struct mm_struct * mm ,
69
- unsigned long addr , pte_t * ptep )
69
+ unsigned long addr , pte_t * ptep ,
70
+ int nodat )
70
71
{
71
72
pte_t old ;
72
73
@@ -76,15 +77,16 @@ static inline pte_t ptep_flush_direct(struct mm_struct *mm,
76
77
atomic_inc (& mm -> context .flush_count );
77
78
if (MACHINE_HAS_TLB_LC &&
78
79
cpumask_equal (mm_cpumask (mm ), cpumask_of (smp_processor_id ())))
79
- ptep_ipte_local (mm , addr , ptep );
80
+ ptep_ipte_local (mm , addr , ptep , nodat );
80
81
else
81
- ptep_ipte_global (mm , addr , ptep );
82
+ ptep_ipte_global (mm , addr , ptep , nodat );
82
83
atomic_dec (& mm -> context .flush_count );
83
84
return old ;
84
85
}
85
86
86
87
static inline pte_t ptep_flush_lazy (struct mm_struct * mm ,
87
- unsigned long addr , pte_t * ptep )
88
+ unsigned long addr , pte_t * ptep ,
89
+ int nodat )
88
90
{
89
91
pte_t old ;
90
92
@@ -97,7 +99,7 @@ static inline pte_t ptep_flush_lazy(struct mm_struct *mm,
97
99
pte_val (* ptep ) |= _PAGE_INVALID ;
98
100
mm -> context .flush_mm = 1 ;
99
101
} else
100
- ptep_ipte_global (mm , addr , ptep );
102
+ ptep_ipte_global (mm , addr , ptep , nodat );
101
103
atomic_dec (& mm -> context .flush_count );
102
104
return old ;
103
105
}
@@ -269,10 +271,12 @@ pte_t ptep_xchg_direct(struct mm_struct *mm, unsigned long addr,
269
271
{
270
272
pgste_t pgste ;
271
273
pte_t old ;
274
+ int nodat ;
272
275
273
276
preempt_disable ();
274
277
pgste = ptep_xchg_start (mm , addr , ptep );
275
- old = ptep_flush_direct (mm , addr , ptep );
278
+ nodat = !!(pgste_val (pgste ) & _PGSTE_GPS_NODAT );
279
+ old = ptep_flush_direct (mm , addr , ptep , nodat );
276
280
old = ptep_xchg_commit (mm , addr , ptep , pgste , old , new );
277
281
preempt_enable ();
278
282
return old ;
@@ -284,10 +288,12 @@ pte_t ptep_xchg_lazy(struct mm_struct *mm, unsigned long addr,
284
288
{
285
289
pgste_t pgste ;
286
290
pte_t old ;
291
+ int nodat ;
287
292
288
293
preempt_disable ();
289
294
pgste = ptep_xchg_start (mm , addr , ptep );
290
- old = ptep_flush_lazy (mm , addr , ptep );
295
+ nodat = !!(pgste_val (pgste ) & _PGSTE_GPS_NODAT );
296
+ old = ptep_flush_lazy (mm , addr , ptep , nodat );
291
297
old = ptep_xchg_commit (mm , addr , ptep , pgste , old , new );
292
298
preempt_enable ();
293
299
return old ;
@@ -299,10 +305,12 @@ pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr,
299
305
{
300
306
pgste_t pgste ;
301
307
pte_t old ;
308
+ int nodat ;
302
309
303
310
preempt_disable ();
304
311
pgste = ptep_xchg_start (mm , addr , ptep );
305
- old = ptep_flush_lazy (mm , addr , ptep );
312
+ nodat = !!(pgste_val (pgste ) & _PGSTE_GPS_NODAT );
313
+ old = ptep_flush_lazy (mm , addr , ptep , nodat );
306
314
if (mm_has_pgste (mm )) {
307
315
pgste = pgste_update_all (old , pgste , mm );
308
316
pgste_set (ptep , pgste );
@@ -557,7 +565,7 @@ int ptep_force_prot(struct mm_struct *mm, unsigned long addr,
557
565
{
558
566
pte_t entry ;
559
567
pgste_t pgste ;
560
- int pte_i , pte_p ;
568
+ int pte_i , pte_p , nodat ;
561
569
562
570
pgste = pgste_get_lock (ptep );
563
571
entry = * ptep ;
@@ -570,13 +578,14 @@ int ptep_force_prot(struct mm_struct *mm, unsigned long addr,
570
578
return - EAGAIN ;
571
579
}
572
580
/* Change access rights and set pgste bit */
581
+ nodat = !!(pgste_val (pgste ) & _PGSTE_GPS_NODAT );
573
582
if (prot == PROT_NONE && !pte_i ) {
574
- ptep_flush_direct (mm , addr , ptep );
583
+ ptep_flush_direct (mm , addr , ptep , nodat );
575
584
pgste = pgste_update_all (entry , pgste , mm );
576
585
pte_val (entry ) |= _PAGE_INVALID ;
577
586
}
578
587
if (prot == PROT_READ && !pte_p ) {
579
- ptep_flush_direct (mm , addr , ptep );
588
+ ptep_flush_direct (mm , addr , ptep , nodat );
580
589
pte_val (entry ) &= ~_PAGE_INVALID ;
581
590
pte_val (entry ) |= _PAGE_PROTECT ;
582
591
}
@@ -616,10 +625,12 @@ int ptep_shadow_pte(struct mm_struct *mm, unsigned long saddr,
616
625
void ptep_unshadow_pte (struct mm_struct * mm , unsigned long saddr , pte_t * ptep )
617
626
{
618
627
pgste_t pgste ;
628
+ int nodat ;
619
629
620
630
pgste = pgste_get_lock (ptep );
621
631
/* notifier is called by the caller */
622
- ptep_flush_direct (mm , saddr , ptep );
632
+ nodat = !!(pgste_val (pgste ) & _PGSTE_GPS_NODAT );
633
+ ptep_flush_direct (mm , saddr , ptep , nodat );
623
634
/* don't touch the storage key - it belongs to parent pgste */
624
635
pgste = pgste_set_pte (ptep , pgste , __pte (_PAGE_INVALID ));
625
636
pgste_set_unlock (ptep , pgste );
@@ -692,6 +703,7 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr)
692
703
pte_t * ptep ;
693
704
pte_t pte ;
694
705
bool dirty ;
706
+ int nodat ;
695
707
696
708
pgd = pgd_offset (mm , addr );
697
709
p4d = p4d_alloc (mm , pgd , addr );
@@ -720,7 +732,8 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr)
720
732
pte = * ptep ;
721
733
if (dirty && (pte_val (pte ) & _PAGE_PRESENT )) {
722
734
pgste = pgste_pte_notify (mm , addr , ptep , pgste );
723
- ptep_ipte_global (mm , addr , ptep );
735
+ nodat = !!(pgste_val (pgste ) & _PGSTE_GPS_NODAT );
736
+ ptep_ipte_global (mm , addr , ptep , nodat );
724
737
if (MACHINE_HAS_ESOP || !(pte_val (pte ) & _PAGE_WRITE ))
725
738
pte_val (pte ) |= _PAGE_PROTECT ;
726
739
else
0 commit comments