mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-18 22:14:16 +00:00 
			
		
		
		
	KVM: arm64: Enable retrieving protections attributes of PTEs
Introduce helper functions in the KVM stage-2 and stage-1 page-table manipulation library allowing to retrieve the enum kvm_pgtable_prot of a PTE. This will be useful to implement custom walkers outside of pgtable.c. Signed-off-by: Quentin Perret <qperret@google.com> Reviewed-by: Fuad Tabba <tabba@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20210809152448.1810400-17-qperret@google.com
This commit is contained in:
		
							parent
							
								
									e009dce129
								
							
						
					
					
						commit
						9024b3d006
					
				
					 2 changed files with 57 additions and 0 deletions
				
			
		|  | @ -507,4 +507,24 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, | |||
|  */ | ||||
| int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, | ||||
| 			 kvm_pte_t *ptep, u32 *level); | ||||
| 
 | ||||
| /**
 | ||||
|  * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a | ||||
|  *				   stage-2 Page-Table Entry. | ||||
|  * @pte:	Page-table entry | ||||
|  * | ||||
|  * Return: protection attributes of the page-table entry in the enum | ||||
|  *	   kvm_pgtable_prot format. | ||||
|  */ | ||||
| enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte); | ||||
| 
 | ||||
| /**
 | ||||
|  * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1 | ||||
|  *				Page-Table Entry. | ||||
|  * @pte:	Page-table entry | ||||
|  * | ||||
|  * Return: protection attributes of the page-table entry in the enum | ||||
|  *	   kvm_pgtable_prot format. | ||||
|  */ | ||||
| enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte); | ||||
| #endif	/* __ARM64_KVM_PGTABLE_H__ */ | ||||
|  |  | |||
|  | @ -363,6 +363,26 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte) | ||||
| { | ||||
| 	enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW; | ||||
| 	u32 ap; | ||||
| 
 | ||||
| 	if (!kvm_pte_valid(pte)) | ||||
| 		return prot; | ||||
| 
 | ||||
| 	if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN)) | ||||
| 		prot |= KVM_PGTABLE_PROT_X; | ||||
| 
 | ||||
| 	ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte); | ||||
| 	if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO) | ||||
| 		prot |= KVM_PGTABLE_PROT_R; | ||||
| 	else if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RW) | ||||
| 		prot |= KVM_PGTABLE_PROT_RW; | ||||
| 
 | ||||
| 	return prot; | ||||
| } | ||||
| 
 | ||||
| static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new) | ||||
| { | ||||
| 	/*
 | ||||
|  | @ -565,6 +585,23 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte) | ||||
| { | ||||
| 	enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW; | ||||
| 
 | ||||
| 	if (!kvm_pte_valid(pte)) | ||||
| 		return prot; | ||||
| 
 | ||||
| 	if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R) | ||||
| 		prot |= KVM_PGTABLE_PROT_R; | ||||
| 	if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W) | ||||
| 		prot |= KVM_PGTABLE_PROT_W; | ||||
| 	if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN)) | ||||
| 		prot |= KVM_PGTABLE_PROT_X; | ||||
| 
 | ||||
| 	return prot; | ||||
| } | ||||
| 
 | ||||
| static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new) | ||||
| { | ||||
| 	if (!kvm_pte_valid(old) || !kvm_pte_valid(new)) | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Quentin Perret
						Quentin Perret