mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
ANDROID: BACKPORT: KVM: arm64: Add FF-A helpers to share/unshare memory with secure world
Extend pKVM's memory protection code so that we can update the host's stage-2 page-table to track pages shared with secure world by the host using FF-A and prevent those pages from being mapped into a guest. Signed-off-by: Andrew Walbran <qwandor@google.com> Bug: 171706629 [willdeacon@: Moved 'pkvm_ffa_id' to nvhe/mem_protect.h] Signed-off-by: Will Deacon <willdeacon@google.com> Change-Id: Ib4d404cd1d4fa11d7bf8c1d0b8ec00838a8038a0
This commit is contained in:
committed by
Will Deacon
parent
f34679dc29
commit
1adb45e30d
@@ -57,7 +57,8 @@ extern struct host_kvm host_kvm;
|
||||
typedef u32 pkvm_id;
|
||||
static const pkvm_id pkvm_host_id = 0;
|
||||
static const pkvm_id pkvm_hyp_id = (1 << 16);
|
||||
static const pkvm_id pkvm_host_poison = pkvm_hyp_id + 1;
|
||||
static const pkvm_id pkvm_ffa_id = pkvm_hyp_id + 1; /* Secure world */
|
||||
static const pkvm_id pkvm_host_poison = pkvm_ffa_id + 1;
|
||||
|
||||
extern unsigned long hyp_nr_cpus;
|
||||
|
||||
@@ -71,6 +72,8 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct kvm_vcpu *vcpu);
|
||||
int __pkvm_host_donate_guest(u64 pfn, u64 gfn, struct kvm_vcpu *vcpu);
|
||||
int __pkvm_guest_share_host(struct kvm_vcpu *vcpu, u64 ipa);
|
||||
int __pkvm_guest_unshare_host(struct kvm_vcpu *vcpu, u64 ipa);
|
||||
int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
|
||||
int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
|
||||
int __pkvm_install_ioguard_page(struct kvm_vcpu *vcpu, u64 ipa);
|
||||
int __pkvm_remove_ioguard_page(struct kvm_vcpu *vcpu, u64 ipa);
|
||||
bool __pkvm_check_ioguard_page(struct kvm_vcpu *vcpu);
|
||||
|
||||
@@ -646,6 +646,7 @@ enum pkvm_component_id {
|
||||
PKVM_ID_HOST,
|
||||
PKVM_ID_HYP,
|
||||
PKVM_ID_GUEST,
|
||||
PKVM_ID_FFA,
|
||||
};
|
||||
|
||||
struct pkvm_mem_transition {
|
||||
@@ -1222,6 +1223,13 @@ static int check_share(struct pkvm_mem_share *share)
|
||||
case PKVM_ID_GUEST:
|
||||
ret = guest_ack_share(completer_addr, tx, share->completer_prot);
|
||||
break;
|
||||
case PKVM_ID_FFA:
|
||||
/*
|
||||
* We only check the host; the secure side will check the other
|
||||
* end when we forward the FFA call.
|
||||
*/
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@@ -1259,6 +1267,13 @@ static int __do_share(struct pkvm_mem_share *share)
|
||||
case PKVM_ID_GUEST:
|
||||
ret = guest_complete_share(completer_addr, tx, share->completer_prot);
|
||||
break;
|
||||
case PKVM_ID_FFA:
|
||||
/*
|
||||
* We're not responsible for any secure page-tables, so there's
|
||||
* nothing to do here.
|
||||
*/
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@@ -1313,6 +1328,10 @@ static int check_unshare(struct pkvm_mem_share *share)
|
||||
case PKVM_ID_HYP:
|
||||
ret = hyp_ack_unshare(completer_addr, tx);
|
||||
break;
|
||||
case PKVM_ID_FFA:
|
||||
/* See check_share() */
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@@ -1347,6 +1366,10 @@ static int __do_unshare(struct pkvm_mem_share *share)
|
||||
case PKVM_ID_HYP:
|
||||
ret = hyp_complete_unshare(completer_addr, tx);
|
||||
break;
|
||||
case PKVM_ID_FFA:
|
||||
/* See __do_share() */
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@@ -1778,6 +1801,52 @@ int __pkvm_host_donate_guest(u64 pfn, u64 gfn, struct kvm_vcpu *vcpu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages)
|
||||
{
|
||||
int ret;
|
||||
struct pkvm_mem_share share = {
|
||||
.tx = {
|
||||
.nr_pages = nr_pages,
|
||||
.initiator = {
|
||||
.id = PKVM_ID_HOST,
|
||||
.addr = hyp_pfn_to_phys(pfn),
|
||||
},
|
||||
.completer = {
|
||||
.id = PKVM_ID_FFA,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
host_lock_component();
|
||||
ret = do_share(&share);
|
||||
host_unlock_component();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
|
||||
{
|
||||
int ret;
|
||||
struct pkvm_mem_share share = {
|
||||
.tx = {
|
||||
.nr_pages = nr_pages,
|
||||
.initiator = {
|
||||
.id = PKVM_ID_HOST,
|
||||
.addr = hyp_pfn_to_phys(pfn),
|
||||
},
|
||||
.completer = {
|
||||
.id = PKVM_ID_FFA,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
host_lock_component();
|
||||
ret = do_unshare(&share);
|
||||
host_unlock_component();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hyp_zero_page(phys_addr_t phys)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
Reference in New Issue
Block a user