Skip to content

Commit 8579a18

Browse files
willdeaconMarc Zyngier
authored andcommitted
KVM: arm64: Reject stub hypercalls after pKVM has been initialised
The stub hypercalls provide mechanisms to reset and replace the EL2 code, so uninstall them once pKVM has been initialised in order to ensure the integrity of the hypervisor code. To ensure pKVM initialisation remains functional, split cpu_hyp_reinit() into two helper functions to separate usage of the stub from usage of pkvm hypercalls either side of __pkvm_init on the boot CPU. Cc: Marc Zyngier <[email protected]> Cc: 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 8f4566f commit 8579a18

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

arch/arm64/kvm/arm.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,25 +1579,33 @@ static void cpu_set_hyp_vector(void)
15791579
kvm_call_hyp_nvhe(__pkvm_cpu_set_vector, data->slot);
15801580
}
15811581

1582-
static void cpu_hyp_reinit(void)
1582+
static void cpu_hyp_init_context(void)
15831583
{
15841584
kvm_init_host_cpu_context(&this_cpu_ptr_hyp_sym(kvm_host_data)->host_ctxt);
15851585

1586-
cpu_hyp_reset();
1587-
1588-
if (is_kernel_in_hyp_mode())
1589-
kvm_timer_init_vhe();
1590-
else
1586+
if (!is_kernel_in_hyp_mode())
15911587
cpu_init_hyp_mode();
1588+
}
15921589

1590+
static void cpu_hyp_init_features(void)
1591+
{
15931592
cpu_set_hyp_vector();
1594-
15951593
kvm_arm_init_debug();
15961594

1595+
if (is_kernel_in_hyp_mode())
1596+
kvm_timer_init_vhe();
1597+
15971598
if (vgic_present)
15981599
kvm_vgic_init_cpu_hardware();
15991600
}
16001601

1602+
static void cpu_hyp_reinit(void)
1603+
{
1604+
cpu_hyp_reset();
1605+
cpu_hyp_init_context();
1606+
cpu_hyp_init_features();
1607+
}
1608+
16011609
static void _kvm_arch_hardware_enable(void *discard)
16021610
{
16031611
if (!__this_cpu_read(kvm_arm_hardware_enabled)) {
@@ -1788,10 +1796,17 @@ static int do_pkvm_init(u32 hyp_va_bits)
17881796
int ret;
17891797

17901798
preempt_disable();
1791-
hyp_install_host_vector();
1799+
cpu_hyp_init_context();
17921800
ret = kvm_call_hyp_nvhe(__pkvm_init, hyp_mem_base, hyp_mem_size,
17931801
num_possible_cpus(), kern_hyp_va(per_cpu_base),
17941802
hyp_va_bits);
1803+
cpu_hyp_init_features();
1804+
1805+
/*
1806+
* The stub hypercalls are now disabled, so set our local flag to
1807+
* prevent a later re-init attempt in kvm_arch_hardware_enable().
1808+
*/
1809+
__this_cpu_write(kvm_arm_hardware_enabled, 1);
17951810
preempt_enable();
17961811

17971812
return ret;

arch/arm64/kvm/hyp/nvhe/host.S

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,14 @@ SYM_FUNC_START(__hyp_do_panic)
110110
b __host_enter_for_panic
111111
SYM_FUNC_END(__hyp_do_panic)
112112

113-
.macro host_el1_sync_vect
114-
.align 7
115-
.L__vect_start\@:
116-
stp x0, x1, [sp, #-16]!
117-
mrs x0, esr_el2
118-
lsr x0, x0, #ESR_ELx_EC_SHIFT
119-
cmp x0, #ESR_ELx_EC_HVC64
120-
b.ne __host_exit
121-
113+
SYM_FUNC_START(__host_hvc)
122114
ldp x0, x1, [sp] // Don't fixup the stack yet
123115

116+
/* No stub for you, sonny Jim */
117+
alternative_if ARM64_KVM_PROTECTED_MODE
118+
b __host_exit
119+
alternative_else_nop_endif
120+
124121
/* Check for a stub HVC call */
125122
cmp x0, #HVC_STUB_HCALL_NR
126123
b.hs __host_exit
@@ -137,6 +134,17 @@ SYM_FUNC_END(__hyp_do_panic)
137134
ldr x5, =__kvm_handle_stub_hvc
138135
hyp_pa x5, x6
139136
br x5
137+
SYM_FUNC_END(__host_hvc)
138+
139+
.macro host_el1_sync_vect
140+
.align 7
141+
.L__vect_start\@:
142+
stp x0, x1, [sp, #-16]!
143+
mrs x0, esr_el2
144+
lsr x0, x0, #ESR_ELx_EC_SHIFT
145+
cmp x0, #ESR_ELx_EC_HVC64
146+
b.eq __host_hvc
147+
b __host_exit
140148
.L__vect_end\@:
141149
.if ((.L__vect_end\@ - .L__vect_start\@) > 0x80)
142150
.error "host_el1_sync_vect larger than vector entry"

0 commit comments

Comments
 (0)