mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
ANDROID: KVM: arm64: Check IPA range for pvmfw during guest donation
When donating pages to the guest, we only check the first IPA in the range against the pvmfw loading range. Although this is fine for the page-at-a-time faulting path, it doesn't fit with the rest of the mem protection logic, which deals with the possibility of an arbitrarily sized contiguous address range. Rework the logic so that we check the whole IPA range during guest donation and trigger the pvmfw loading path if any of the pages intersect with the pvmfw region. Signed-off-by: Will Deacon <will@kernel.org> Bug: 254819795 Change-Id: I6fef9f1898e65a95cab7f6a0ffa8aa422a8d5a91 Signed-off-by: Will Deacon <willdeacon@google.com> Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
committed by
Quentin Perret
parent
677980a696
commit
22c8a338c7
@@ -121,14 +121,16 @@ static inline bool pkvm_hyp_vm_has_pvmfw(struct pkvm_hyp_vm *vm)
|
||||
return vm->kvm.arch.pkvm.pvmfw_load_addr != PVMFW_INVALID_LOAD_ADDR;
|
||||
}
|
||||
|
||||
static inline bool pkvm_ipa_in_pvmfw_region(struct pkvm_hyp_vm *vm, u64 ipa)
|
||||
static inline bool pkvm_ipa_range_has_pvmfw(struct pkvm_hyp_vm *vm,
|
||||
u64 ipa_start, u64 ipa_end)
|
||||
{
|
||||
struct kvm_protected_vm *pkvm = &vm->kvm.arch.pkvm;
|
||||
u64 pvmfw_load_end = pkvm->pvmfw_load_addr + pvmfw_size;
|
||||
|
||||
if (!pkvm_hyp_vm_has_pvmfw(vm))
|
||||
return false;
|
||||
|
||||
return ipa - pkvm->pvmfw_load_addr < pvmfw_size;
|
||||
return ipa_end > pkvm->pvmfw_load_addr && ipa_start < pvmfw_load_end;
|
||||
}
|
||||
|
||||
int pkvm_load_pvmfw_pages(struct pkvm_hyp_vm *vm, u64 ipa, phys_addr_t phys,
|
||||
|
||||
@@ -1078,11 +1078,11 @@ static int guest_complete_donation(u64 addr, const struct pkvm_mem_transition *t
|
||||
u64 size = tx->nr_pages * PAGE_SIZE;
|
||||
int err;
|
||||
|
||||
if (tx->initiator.id == PKVM_ID_HOST &&
|
||||
pkvm_ipa_in_pvmfw_region(vm, addr)) {
|
||||
if (pkvm_ipa_range_has_pvmfw(vm, addr, addr + size)) {
|
||||
if (WARN_ON(!pkvm_hyp_vcpu_is_protected(vcpu)))
|
||||
return -EPERM;
|
||||
|
||||
WARN_ON(tx->initiator.id != PKVM_ID_HOST);
|
||||
err = pkvm_load_pvmfw_pages(vm, addr, phys, size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
Reference in New Issue
Block a user