mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
ANDROID: KVM: arm64: Move pKVM host deprivilege to device_initcall
In preparation for early loading of pKVM modules (i.e. before deprivilege), move the pKVM finalization in device_initcall. This is needed as modules are found in the initramfs whom unpack starts in the previous initcall. A deprivilege failure now ends-up in erasing the PVM firmware and simply prevent loading of any protected VM. As an interesting side effect, it also allows us to mark the module loading functions as __init. Those functions will then be erased once the init is complete, reducing the attack surface. Bug: 254835242 Change-Id: Ifab4b9167b8924222bc8b6c2a0af529a3f8540c0 Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
This commit is contained in:
@@ -2271,20 +2271,6 @@ static int pkvm_drop_host_privileges(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int finalize_hyp_mode(void)
|
||||
{
|
||||
if (!is_protected_kvm_enabled())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Exclude HYP sections from kmemleak so that they don't get peeked
|
||||
* at, which would end badly once inaccessible.
|
||||
*/
|
||||
kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start);
|
||||
kmemleak_free_part_phys(hyp_mem_base, hyp_mem_size);
|
||||
return pkvm_drop_host_privileges();
|
||||
}
|
||||
|
||||
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
|
||||
{
|
||||
struct kvm_vcpu *vcpu;
|
||||
@@ -2400,12 +2386,6 @@ int kvm_arch_init(void *opaque)
|
||||
goto out_hyp;
|
||||
|
||||
if (!in_hyp_mode) {
|
||||
err = finalize_hyp_mode();
|
||||
if (err) {
|
||||
kvm_err("Failed to finalize Hyp protection\n");
|
||||
goto out_hyp;
|
||||
}
|
||||
|
||||
err = init_hyp_tracefs();
|
||||
if (err)
|
||||
kvm_err("Failed to initialize Hyp tracing\n");
|
||||
|
||||
@@ -433,7 +433,7 @@ static int __init pkvm_firmware_rmem_clear(void)
|
||||
void *addr;
|
||||
phys_addr_t size;
|
||||
|
||||
if (likely(!pkvm_firmware_mem) || is_protected_kvm_enabled())
|
||||
if (likely(!pkvm_firmware_mem))
|
||||
return 0;
|
||||
|
||||
kvm_info("Clearing unused pKVM firmware memory\n");
|
||||
@@ -447,7 +447,32 @@ static int __init pkvm_firmware_rmem_clear(void)
|
||||
memunmap(addr);
|
||||
return 0;
|
||||
}
|
||||
device_initcall_sync(pkvm_firmware_rmem_clear);
|
||||
|
||||
static int __init finalize_pkvm(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!is_protected_kvm_enabled()) {
|
||||
pkvm_firmware_rmem_clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exclude HYP sections from kmemleak so that they don't get peeked
|
||||
* at, which would end badly once inaccessible.
|
||||
*/
|
||||
kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start);
|
||||
kmemleak_free_part_phys(hyp_mem_base, hyp_mem_size);
|
||||
|
||||
ret = pkvm_drop_host_privileges();
|
||||
if (ret) {
|
||||
pr_err("Failed to de-privilege the host kernel: %d\n", ret);
|
||||
pkvm_firmware_rmem_clear();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
device_initcall_sync(finalize_pkvm);
|
||||
|
||||
static int pkvm_vm_ioctl_set_fw_ipa(struct kvm *kvm, u64 ipa)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user