Skip to content

Commit fe41a7f

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Unmap 'kvm_arm_hyp_percpu_base' from the host
When pKVM is enabled, the hypervisor at EL2 does not trust the host at EL1 and must therefore prevent it from having unrestricted access to internal hypervisor state. The 'kvm_arm_hyp_percpu_base' array holds the offsets for hypervisor per-cpu allocations, so move this this into the nVHE code where it cannot be modified by the untrusted host at EL1. Tested-by: Vincent Donnefort <[email protected]> Signed-off-by: Quentin Perret <[email protected]> Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f41dff4 commit fe41a7f

File tree

4 files changed

+8
-10
lines changed

4 files changed

+8
-10
lines changed

arch/arm64/include/asm/kvm_asm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ enum __kvm_host_smccc_func {
109109
#define per_cpu_ptr_nvhe_sym(sym, cpu) \
110110
({ \
111111
unsigned long base, off; \
112-
base = kvm_arm_hyp_percpu_base[cpu]; \
112+
base = kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu]; \
113113
off = (unsigned long)&CHOOSE_NVHE_SYM(sym) - \
114114
(unsigned long)&CHOOSE_NVHE_SYM(__per_cpu_start); \
115115
base ? (typeof(CHOOSE_NVHE_SYM(sym))*)(base + off) : NULL; \
@@ -214,7 +214,7 @@ DECLARE_KVM_HYP_SYM(__kvm_hyp_vector);
214214
#define __kvm_hyp_init CHOOSE_NVHE_SYM(__kvm_hyp_init)
215215
#define __kvm_hyp_vector CHOOSE_HYP_SYM(__kvm_hyp_vector)
216216

217-
extern unsigned long kvm_arm_hyp_percpu_base[NR_CPUS];
217+
extern unsigned long kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[];
218218
DECLARE_KVM_NVHE_SYM(__per_cpu_start);
219219
DECLARE_KVM_NVHE_SYM(__per_cpu_end);
220220

arch/arm64/kernel/image-vars.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ KVM_NVHE_ALIAS(gic_nonsecure_priorities);
8989
KVM_NVHE_ALIAS(__start___kvm_ex_table);
9090
KVM_NVHE_ALIAS(__stop___kvm_ex_table);
9191

92-
/* Array containing bases of nVHE per-CPU memory regions. */
93-
KVM_NVHE_ALIAS(kvm_arm_hyp_percpu_base);
94-
9592
/* PMU available static key */
9693
#ifdef CONFIG_HW_PERF_EVENTS
9794
KVM_NVHE_ALIAS(kvm_arm_pmu_available);

arch/arm64/kvm/arm.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ DEFINE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
5151
DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);
5252

5353
DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
54-
unsigned long kvm_arm_hyp_percpu_base[NR_CPUS];
5554
DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
5655

5756
static bool vgic_present;
@@ -1857,13 +1856,13 @@ static void teardown_hyp_mode(void)
18571856
free_hyp_pgds();
18581857
for_each_possible_cpu(cpu) {
18591858
free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
1860-
free_pages(kvm_arm_hyp_percpu_base[cpu], nvhe_percpu_order());
1859+
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
18611860
}
18621861
}
18631862

18641863
static int do_pkvm_init(u32 hyp_va_bits)
18651864
{
1866-
void *per_cpu_base = kvm_ksym_ref(kvm_arm_hyp_percpu_base);
1865+
void *per_cpu_base = kvm_ksym_ref(kvm_nvhe_sym(kvm_arm_hyp_percpu_base));
18671866
int ret;
18681867

18691868
preempt_disable();
@@ -1967,7 +1966,7 @@ static int init_hyp_mode(void)
19671966

19681967
page_addr = page_address(page);
19691968
memcpy(page_addr, CHOOSE_NVHE_SYM(__per_cpu_start), nvhe_percpu_size());
1970-
kvm_arm_hyp_percpu_base[cpu] = (unsigned long)page_addr;
1969+
kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu] = (unsigned long)page_addr;
19711970
}
19721971

19731972
/*
@@ -2060,7 +2059,7 @@ static int init_hyp_mode(void)
20602059
}
20612060

20622061
for_each_possible_cpu(cpu) {
2063-
char *percpu_begin = (char *)kvm_arm_hyp_percpu_base[cpu];
2062+
char *percpu_begin = (char *)kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu];
20642063
char *percpu_end = percpu_begin + nvhe_percpu_size();
20652064

20662065
/* Map Hyp percpu pages */

arch/arm64/kvm/hyp/nvhe/hyp-smp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ u64 cpu_logical_map(unsigned int cpu)
2323
return hyp_cpu_logical_map[cpu];
2424
}
2525

26+
unsigned long __ro_after_init kvm_arm_hyp_percpu_base[NR_CPUS];
27+
2628
unsigned long __hyp_per_cpu_offset(unsigned int cpu)
2729
{
2830
unsigned long *cpu_base_array;

0 commit comments

Comments
 (0)