@@ -25,6 +25,46 @@ static inline u64 kvm_get_parange(u64 mmfr0)
25
25
26
26
typedef u64 kvm_pte_t ;
27
27
28
+ #define KVM_PTE_VALID BIT(0)
29
+
30
+ #define KVM_PTE_ADDR_MASK GENMASK(47, PAGE_SHIFT)
31
+ #define KVM_PTE_ADDR_51_48 GENMASK(15, 12)
32
+
33
+ static inline bool kvm_pte_valid (kvm_pte_t pte )
34
+ {
35
+ return pte & KVM_PTE_VALID ;
36
+ }
37
+
38
+ static inline u64 kvm_pte_to_phys (kvm_pte_t pte )
39
+ {
40
+ u64 pa = pte & KVM_PTE_ADDR_MASK ;
41
+
42
+ if (PAGE_SHIFT == 16 )
43
+ pa |= FIELD_GET (KVM_PTE_ADDR_51_48 , pte ) << 48 ;
44
+
45
+ return pa ;
46
+ }
47
+
48
+ static inline u64 kvm_granule_shift (u32 level )
49
+ {
50
+ /* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */
51
+ return ARM64_HW_PGTABLE_LEVEL_SHIFT (level );
52
+ }
53
+
54
+ static inline u64 kvm_granule_size (u32 level )
55
+ {
56
+ return BIT (kvm_granule_shift (level ));
57
+ }
58
+
59
+ static inline bool kvm_level_supports_block_mapping (u32 level )
60
+ {
61
+ /*
62
+ * Reject invalid block mappings and don't bother with 4TB mappings for
63
+ * 52-bit PAs.
64
+ */
65
+ return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1 ));
66
+ }
67
+
28
68
/**
29
69
* struct kvm_pgtable_mm_ops - Memory management callbacks.
30
70
* @zalloc_page: Allocate a single zeroed memory page.
@@ -75,53 +115,65 @@ enum kvm_pgtable_stage2_flags {
75
115
KVM_PGTABLE_S2_IDMAP = BIT (1 ),
76
116
};
77
117
78
- /**
79
- * struct kvm_pgtable - KVM page-table.
80
- * @ia_bits: Maximum input address size, in bits.
81
- * @start_level: Level at which the page-table walk starts.
82
- * @pgd: Pointer to the first top-level entry of the page-table.
83
- * @mm_ops: Memory management callbacks.
84
- * @mmu: Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
85
- */
86
- struct kvm_pgtable {
87
- u32 ia_bits ;
88
- u32 start_level ;
89
- kvm_pte_t * pgd ;
90
- struct kvm_pgtable_mm_ops * mm_ops ;
91
-
92
- /* Stage-2 only */
93
- struct kvm_s2_mmu * mmu ;
94
- enum kvm_pgtable_stage2_flags flags ;
95
- };
96
-
97
118
/**
98
119
* enum kvm_pgtable_prot - Page-table permissions and attributes.
99
120
* @KVM_PGTABLE_PROT_X: Execute permission.
100
121
* @KVM_PGTABLE_PROT_W: Write permission.
101
122
* @KVM_PGTABLE_PROT_R: Read permission.
102
123
* @KVM_PGTABLE_PROT_DEVICE: Device attributes.
124
+ * @KVM_PGTABLE_PROT_SW0: Software bit 0.
125
+ * @KVM_PGTABLE_PROT_SW1: Software bit 1.
126
+ * @KVM_PGTABLE_PROT_SW2: Software bit 2.
127
+ * @KVM_PGTABLE_PROT_SW3: Software bit 3.
103
128
*/
104
129
enum kvm_pgtable_prot {
105
130
KVM_PGTABLE_PROT_X = BIT (0 ),
106
131
KVM_PGTABLE_PROT_W = BIT (1 ),
107
132
KVM_PGTABLE_PROT_R = BIT (2 ),
108
133
109
134
KVM_PGTABLE_PROT_DEVICE = BIT (3 ),
135
+
136
+ KVM_PGTABLE_PROT_SW0 = BIT (55 ),
137
+ KVM_PGTABLE_PROT_SW1 = BIT (56 ),
138
+ KVM_PGTABLE_PROT_SW2 = BIT (57 ),
139
+ KVM_PGTABLE_PROT_SW3 = BIT (58 ),
110
140
};
111
141
112
- #define PAGE_HYP (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
142
+ #define KVM_PGTABLE_PROT_RW (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
143
+ #define KVM_PGTABLE_PROT_RWX (KVM_PGTABLE_PROT_RW | KVM_PGTABLE_PROT_X)
144
+
145
+ #define PKVM_HOST_MEM_PROT KVM_PGTABLE_PROT_RWX
146
+ #define PKVM_HOST_MMIO_PROT KVM_PGTABLE_PROT_RW
147
+
148
+ #define PAGE_HYP KVM_PGTABLE_PROT_RW
113
149
#define PAGE_HYP_EXEC (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X)
114
150
#define PAGE_HYP_RO (KVM_PGTABLE_PROT_R)
115
151
#define PAGE_HYP_DEVICE (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE)
116
152
153
+ typedef bool (* kvm_pgtable_force_pte_cb_t )(u64 addr , u64 end ,
154
+ enum kvm_pgtable_prot prot );
155
+
117
156
/**
118
- * struct kvm_mem_range - Range of Intermediate Physical Addresses
119
- * @start: Start of the range.
120
- * @end: End of the range.
157
+ * struct kvm_pgtable - KVM page-table.
158
+ * @ia_bits: Maximum input address size, in bits.
159
+ * @start_level: Level at which the page-table walk starts.
160
+ * @pgd: Pointer to the first top-level entry of the page-table.
161
+ * @mm_ops: Memory management callbacks.
162
+ * @mmu: Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
163
+ * @flags: Stage-2 page-table flags.
164
+ * @force_pte_cb: Function that returns true if page level mappings must
165
+ * be used instead of block mappings.
121
166
*/
122
- struct kvm_mem_range {
123
- u64 start ;
124
- u64 end ;
167
+ struct kvm_pgtable {
168
+ u32 ia_bits ;
169
+ u32 start_level ;
170
+ kvm_pte_t * pgd ;
171
+ struct kvm_pgtable_mm_ops * mm_ops ;
172
+
173
+ /* Stage-2 only */
174
+ struct kvm_s2_mmu * mmu ;
175
+ enum kvm_pgtable_stage2_flags flags ;
176
+ kvm_pgtable_force_pte_cb_t force_pte_cb ;
125
177
};
126
178
127
179
/**
@@ -216,21 +268,24 @@ int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
216
268
u64 kvm_get_vtcr (u64 mmfr0 , u64 mmfr1 , u32 phys_shift );
217
269
218
270
/**
219
- * kvm_pgtable_stage2_init_flags () - Initialise a guest stage-2 page-table.
271
+ * __kvm_pgtable_stage2_init () - Initialise a guest stage-2 page-table.
220
272
* @pgt: Uninitialised page-table structure to initialise.
221
273
* @arch: Arch-specific KVM structure representing the guest virtual
222
274
* machine.
223
275
* @mm_ops: Memory management callbacks.
224
276
* @flags: Stage-2 configuration flags.
277
+ * @force_pte_cb: Function that returns true if page level mappings must
278
+ * be used instead of block mappings.
225
279
*
226
280
* Return: 0 on success, negative error code on failure.
227
281
*/
228
- int kvm_pgtable_stage2_init_flags (struct kvm_pgtable * pgt , struct kvm_arch * arch ,
229
- struct kvm_pgtable_mm_ops * mm_ops ,
230
- enum kvm_pgtable_stage2_flags flags );
282
+ int __kvm_pgtable_stage2_init (struct kvm_pgtable * pgt , struct kvm_arch * arch ,
283
+ struct kvm_pgtable_mm_ops * mm_ops ,
284
+ enum kvm_pgtable_stage2_flags flags ,
285
+ kvm_pgtable_force_pte_cb_t force_pte_cb );
231
286
232
287
#define kvm_pgtable_stage2_init (pgt , arch , mm_ops ) \
233
- kvm_pgtable_stage2_init_flags (pgt, arch, mm_ops, 0)
288
+ __kvm_pgtable_stage2_init (pgt, arch, mm_ops, 0, NULL )
234
289
235
290
/**
236
291
* kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
@@ -374,7 +429,8 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr);
374
429
* If there is a valid, leaf page-table entry used to translate @addr, then
375
430
* relax the permissions in that entry according to the read, write and
376
431
* execute permissions specified by @prot. No permissions are removed, and
377
- * TLB invalidation is performed after updating the entry.
432
+ * TLB invalidation is performed after updating the entry. Software bits cannot
433
+ * be set or cleared using kvm_pgtable_stage2_relax_perms().
378
434
*
379
435
* Return: 0 on success, negative error code on failure.
380
436
*/
@@ -453,22 +509,22 @@ int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
453
509
kvm_pte_t * ptep , u32 * level );
454
510
455
511
/**
456
- * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical
457
- * Addresses with compatible permission
458
- * attributes.
459
- * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
460
- * @addr: Address that must be covered by the range.
461
- * @prot: Protection attributes that the range must be compatible with.
462
- * @range: Range structure used to limit the search space at call time and
463
- * that will hold the result.
512
+ * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a
513
+ * stage-2 Page-Table Entry.
514
+ * @pte: Page-table entry
464
515
*
465
- * The offset of @addr within a page is ignored. An IPA is compatible with @prot
466
- * iff its corresponding stage-2 page-table entry has default ownership and, if
467
- * valid, is mapped with protection attributes identical to @prot.
516
+ * Return: protection attributes of the page-table entry in the enum
517
+ * kvm_pgtable_prot format.
518
+ */
519
+ enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot (kvm_pte_t pte );
520
+
521
+ /**
522
+ * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1
523
+ * Page-Table Entry.
524
+ * @pte: Page-table entry
468
525
*
469
- * Return: 0 on success, negative error code on failure.
526
+ * Return: protection attributes of the page-table entry in the enum
527
+ * kvm_pgtable_prot format.
470
528
*/
471
- int kvm_pgtable_stage2_find_range (struct kvm_pgtable * pgt , u64 addr ,
472
- enum kvm_pgtable_prot prot ,
473
- struct kvm_mem_range * range );
529
+ enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot (kvm_pte_t pte );
474
530
#endif /* __ARM64_KVM_PGTABLE_H__ */
0 commit comments