KVM: arm64: Patch kimage_voffset instead of loading the EL1 value
Directly using the kimage_voffset variable is fine for now, but will become more problematic as we start distrusting EL1. Instead, patch the kimage_voffset into the HYP text, ensuring we don't have to load an untrusted value later on. Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
7cd0aaafaa
commit
68b824e428
4 changed files with 30 additions and 7 deletions
|
@ -72,6 +72,28 @@ alternative_cb kvm_update_va_mask
|
||||||
alternative_cb_end
|
alternative_cb_end
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a kernel image address to a PA
|
||||||
|
* reg: kernel address to be converted in place
|
||||||
|
* tmp: temporary register
|
||||||
|
*
|
||||||
|
* The actual code generation takes place in kvm_get_kimage_voffset, and
|
||||||
|
* the instructions below are only there to reserve the space and
|
||||||
|
* perform the register allocation (kvm_get_kimage_voffset uses the
|
||||||
|
* specific registers encoded in the instructions).
|
||||||
|
*/
|
||||||
|
.macro kimg_pa reg, tmp
|
||||||
|
alternative_cb kvm_get_kimage_voffset
|
||||||
|
movz \tmp, #0
|
||||||
|
movk \tmp, #0, lsl #16
|
||||||
|
movk \tmp, #0, lsl #32
|
||||||
|
movk \tmp, #0, lsl #48
|
||||||
|
alternative_cb_end
|
||||||
|
|
||||||
|
/* reg = __pa(reg) */
|
||||||
|
sub \reg, \reg, \tmp
|
||||||
|
.endm
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <linux/pgtable.h>
|
#include <linux/pgtable.h>
|
||||||
|
|
|
@ -65,13 +65,11 @@ __efistub__ctype = _ctype;
|
||||||
KVM_NVHE_ALIAS(kvm_patch_vector_branch);
|
KVM_NVHE_ALIAS(kvm_patch_vector_branch);
|
||||||
KVM_NVHE_ALIAS(kvm_update_va_mask);
|
KVM_NVHE_ALIAS(kvm_update_va_mask);
|
||||||
KVM_NVHE_ALIAS(kvm_update_kimg_phys_offset);
|
KVM_NVHE_ALIAS(kvm_update_kimg_phys_offset);
|
||||||
|
KVM_NVHE_ALIAS(kvm_get_kimage_voffset);
|
||||||
|
|
||||||
/* Global kernel state accessed by nVHE hyp code. */
|
/* Global kernel state accessed by nVHE hyp code. */
|
||||||
KVM_NVHE_ALIAS(kvm_vgic_global_state);
|
KVM_NVHE_ALIAS(kvm_vgic_global_state);
|
||||||
|
|
||||||
/* Kernel constant needed to compute idmap addresses. */
|
|
||||||
KVM_NVHE_ALIAS(kimage_voffset);
|
|
||||||
|
|
||||||
/* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
|
/* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
|
||||||
KVM_NVHE_ALIAS(__hyp_panic_string);
|
KVM_NVHE_ALIAS(__hyp_panic_string);
|
||||||
KVM_NVHE_ALIAS(panic);
|
KVM_NVHE_ALIAS(panic);
|
||||||
|
|
|
@ -115,10 +115,7 @@ SYM_FUNC_END(__hyp_do_panic)
|
||||||
* Preserve x0-x4, which may contain stub parameters.
|
* Preserve x0-x4, which may contain stub parameters.
|
||||||
*/
|
*/
|
||||||
ldr x5, =__kvm_handle_stub_hvc
|
ldr x5, =__kvm_handle_stub_hvc
|
||||||
ldr_l x6, kimage_voffset
|
kimg_pa x5, x6
|
||||||
|
|
||||||
/* x5 = __pa(x5) */
|
|
||||||
sub x5, x5, x6
|
|
||||||
br x5
|
br x5
|
||||||
.L__vect_end\@:
|
.L__vect_end\@:
|
||||||
.if ((.L__vect_end\@ - .L__vect_start\@) > 0x80)
|
.if ((.L__vect_end\@ - .L__vect_start\@) > 0x80)
|
||||||
|
|
|
@ -251,3 +251,9 @@ void kvm_update_kimg_phys_offset(struct alt_instr *alt,
|
||||||
{
|
{
|
||||||
generate_mov_q(kimage_voffset + PHYS_OFFSET, origptr, updptr, nr_inst);
|
generate_mov_q(kimage_voffset + PHYS_OFFSET, origptr, updptr, nr_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_get_kimage_voffset(struct alt_instr *alt,
|
||||||
|
__le32 *origptr, __le32 *updptr, int nr_inst)
|
||||||
|
{
|
||||||
|
generate_mov_q(kimage_voffset, origptr, updptr, nr_inst);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue