mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
ANDROID: KVM: arm64: Allow tweaking HFGWTR_EL2 from modules
pKVM modules may need to enable fine grain traps. To allow this use-case, expose a function allowing to manipulate HFGWTR_EL2 on the current CPU. This configuration will be persistent across power management cycles and such as it is propagated all the way to the init params per-cpu struct. Bug: 245034629 Change-Id: If9c29849df50847d3a796345927bd51c37c358bc Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
committed by
Carlos Llamas
parent
92c988d752
commit
085255b984
@@ -221,6 +221,7 @@ struct kvm_nvhe_init_params {
|
|||||||
unsigned long stack_pa;
|
unsigned long stack_pa;
|
||||||
phys_addr_t pgd_pa;
|
phys_addr_t pgd_pa;
|
||||||
unsigned long hcr_el2;
|
unsigned long hcr_el2;
|
||||||
|
unsigned long hfgwtr_el2;
|
||||||
unsigned long vttbr;
|
unsigned long vttbr;
|
||||||
unsigned long vtcr;
|
unsigned long vtcr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ struct pkvm_module_ops {
|
|||||||
void (*linear_unmap_early)(void *addr, size_t size);
|
void (*linear_unmap_early)(void *addr, size_t size);
|
||||||
void (*flush_dcache_to_poc)(void *addr, size_t size);
|
void (*flush_dcache_to_poc)(void *addr, size_t size);
|
||||||
void (*update_hcr_el2)(unsigned long set_mask, unsigned long clear_mask);
|
void (*update_hcr_el2)(unsigned long set_mask, unsigned long clear_mask);
|
||||||
|
void (*update_hfgwtr_el2)(unsigned long set_mask, unsigned long clear_mask);
|
||||||
int (*register_host_perm_fault_handler)(int (*cb)(struct kvm_cpu_context *ctxt, u64 esr, u64 addr));
|
int (*register_host_perm_fault_handler)(int (*cb)(struct kvm_cpu_context *ctxt, u64 esr, u64 addr));
|
||||||
int (*host_stage2_mod_prot)(u64 pfn, enum kvm_pgtable_prot prot);
|
int (*host_stage2_mod_prot)(u64 pfn, enum kvm_pgtable_prot prot);
|
||||||
int (*host_stage2_get_leaf)(phys_addr_t phys, kvm_pte_t *ptep, u32 *level);
|
int (*host_stage2_get_leaf)(phys_addr_t phys, kvm_pte_t *ptep, u32 *level);
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ int main(void)
|
|||||||
DEFINE(NVHE_INIT_STACK_HYP_VA, offsetof(struct kvm_nvhe_init_params, stack_hyp_va));
|
DEFINE(NVHE_INIT_STACK_HYP_VA, offsetof(struct kvm_nvhe_init_params, stack_hyp_va));
|
||||||
DEFINE(NVHE_INIT_PGD_PA, offsetof(struct kvm_nvhe_init_params, pgd_pa));
|
DEFINE(NVHE_INIT_PGD_PA, offsetof(struct kvm_nvhe_init_params, pgd_pa));
|
||||||
DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2));
|
DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2));
|
||||||
|
DEFINE(NVHE_INIT_HFGWTR_EL2, offsetof(struct kvm_nvhe_init_params, hfgwtr_el2));
|
||||||
DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr));
|
DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr));
|
||||||
DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr));
|
DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -95,6 +95,9 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init)
|
|||||||
ldr x1, [x0, #NVHE_INIT_HCR_EL2]
|
ldr x1, [x0, #NVHE_INIT_HCR_EL2]
|
||||||
msr hcr_el2, x1
|
msr hcr_el2, x1
|
||||||
|
|
||||||
|
ldr x1, [x0, #NVHE_INIT_HFGWTR_EL2]
|
||||||
|
msr_s SYS_HFGWTR_EL2, x1
|
||||||
|
|
||||||
ldr x1, [x0, #NVHE_INIT_VTTBR]
|
ldr x1, [x0, #NVHE_INIT_VTTBR]
|
||||||
msr vttbr_el2, x1
|
msr vttbr_el2, x1
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,16 @@ static void __update_hcr_el2(unsigned long set_mask, unsigned long clear_mask)
|
|||||||
write_sysreg(params->hcr_el2, hcr_el2);
|
write_sysreg(params->hcr_el2, hcr_el2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __update_hfgwtr_el2(unsigned long set_mask, unsigned long clear_mask)
|
||||||
|
{
|
||||||
|
struct kvm_nvhe_init_params *params = this_cpu_ptr(&kvm_init_params);
|
||||||
|
|
||||||
|
params->hfgwtr_el2 |= set_mask;
|
||||||
|
params->hfgwtr_el2 &= ~clear_mask;
|
||||||
|
__kvm_flush_dcache_to_poc(params, sizeof(*params));
|
||||||
|
write_sysreg_s(params->hfgwtr_el2, SYS_HFGWTR_EL2);
|
||||||
|
}
|
||||||
|
|
||||||
static atomic_t early_lm_pages;
|
static atomic_t early_lm_pages;
|
||||||
static void *__pkvm_linear_map_early(phys_addr_t phys, size_t size, enum kvm_pgtable_prot prot)
|
static void *__pkvm_linear_map_early(phys_addr_t phys, size_t size, enum kvm_pgtable_prot prot)
|
||||||
{
|
{
|
||||||
@@ -89,6 +99,7 @@ const struct pkvm_module_ops module_ops = {
|
|||||||
.linear_unmap_early = __pkvm_linear_unmap_early,
|
.linear_unmap_early = __pkvm_linear_unmap_early,
|
||||||
.flush_dcache_to_poc = __kvm_flush_dcache_to_poc,
|
.flush_dcache_to_poc = __kvm_flush_dcache_to_poc,
|
||||||
.update_hcr_el2 = __update_hcr_el2,
|
.update_hcr_el2 = __update_hcr_el2,
|
||||||
|
.update_hfgwtr_el2 = __update_hfgwtr_el2,
|
||||||
.register_host_perm_fault_handler = hyp_register_host_perm_fault_handler,
|
.register_host_perm_fault_handler = hyp_register_host_perm_fault_handler,
|
||||||
.host_stage2_mod_prot = module_change_host_page_prot,
|
.host_stage2_mod_prot = module_change_host_page_prot,
|
||||||
.host_stage2_get_leaf = host_stage2_get_leaf,
|
.host_stage2_get_leaf = host_stage2_get_leaf,
|
||||||
|
|||||||
Reference in New Issue
Block a user