Skip to content

Commit 7cbf7c3

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Drop pkvm_mem_transition for host/hyp sharing
Simplify the __pkvm_host_{un}share_hyp() paths by not using the pkvm_mem_transition machinery. As there are the last users of the do_share()/do_unshare(), remove all the now-unused code as well. No functional changes intended. Signed-off-by: Quentin Perret <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 7a06888 commit 7cbf7c3

File tree

1 file changed

+34
-285
lines changed

1 file changed

+34
-285
lines changed

arch/arm64/kvm/hyp/nvhe/mem_protect.c

Lines changed: 34 additions & 285 deletions
Original file line numberDiff line numberDiff line change
@@ -685,36 +685,6 @@ static int host_request_owned_transition(u64 *completer_addr,
685685
return __host_check_page_state_range(addr, size, PKVM_PAGE_OWNED);
686686
}
687687

688-
static int host_request_unshare(u64 *completer_addr,
689-
const struct pkvm_mem_transition *tx)
690-
{
691-
u64 size = tx->nr_pages * PAGE_SIZE;
692-
u64 addr = tx->initiator.addr;
693-
694-
*completer_addr = tx->initiator.host.completer_addr;
695-
return __host_check_page_state_range(addr, size, PKVM_PAGE_SHARED_OWNED);
696-
}
697-
698-
static int host_initiate_share(u64 *completer_addr,
699-
const struct pkvm_mem_transition *tx)
700-
{
701-
u64 size = tx->nr_pages * PAGE_SIZE;
702-
u64 addr = tx->initiator.addr;
703-
704-
*completer_addr = tx->initiator.host.completer_addr;
705-
return __host_set_page_state_range(addr, size, PKVM_PAGE_SHARED_OWNED);
706-
}
707-
708-
static int host_initiate_unshare(u64 *completer_addr,
709-
const struct pkvm_mem_transition *tx)
710-
{
711-
u64 size = tx->nr_pages * PAGE_SIZE;
712-
u64 addr = tx->initiator.addr;
713-
714-
*completer_addr = tx->initiator.host.completer_addr;
715-
return __host_set_page_state_range(addr, size, PKVM_PAGE_OWNED);
716-
}
717-
718688
static int host_initiate_donation(u64 *completer_addr,
719689
const struct pkvm_mem_transition *tx)
720690
{
@@ -802,31 +772,6 @@ static bool __hyp_ack_skip_pgtable_check(const struct pkvm_mem_transition *tx)
802772
tx->initiator.id != PKVM_ID_HOST);
803773
}
804774

805-
static int hyp_ack_share(u64 addr, const struct pkvm_mem_transition *tx,
806-
enum kvm_pgtable_prot perms)
807-
{
808-
u64 size = tx->nr_pages * PAGE_SIZE;
809-
810-
if (perms != PAGE_HYP)
811-
return -EPERM;
812-
813-
if (__hyp_ack_skip_pgtable_check(tx))
814-
return 0;
815-
816-
return __hyp_check_page_state_range(addr, size, PKVM_NOPAGE);
817-
}
818-
819-
static int hyp_ack_unshare(u64 addr, const struct pkvm_mem_transition *tx)
820-
{
821-
u64 size = tx->nr_pages * PAGE_SIZE;
822-
823-
if (tx->initiator.id == PKVM_ID_HOST && hyp_page_count((void *)addr))
824-
return -EBUSY;
825-
826-
return __hyp_check_page_state_range(addr, size,
827-
PKVM_PAGE_SHARED_BORROWED);
828-
}
829-
830775
static int hyp_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
831776
{
832777
u64 size = tx->nr_pages * PAGE_SIZE;
@@ -837,24 +782,6 @@ static int hyp_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
837782
return __hyp_check_page_state_range(addr, size, PKVM_NOPAGE);
838783
}
839784

840-
static int hyp_complete_share(u64 addr, const struct pkvm_mem_transition *tx,
841-
enum kvm_pgtable_prot perms)
842-
{
843-
void *start = (void *)addr, *end = start + (tx->nr_pages * PAGE_SIZE);
844-
enum kvm_pgtable_prot prot;
845-
846-
prot = pkvm_mkstate(perms, PKVM_PAGE_SHARED_BORROWED);
847-
return pkvm_create_mappings_locked(start, end, prot);
848-
}
849-
850-
static int hyp_complete_unshare(u64 addr, const struct pkvm_mem_transition *tx)
851-
{
852-
u64 size = tx->nr_pages * PAGE_SIZE;
853-
int ret = kvm_pgtable_hyp_unmap(&pkvm_pgtable, addr, size);
854-
855-
return (ret != size) ? -EFAULT : 0;
856-
}
857-
858785
static int hyp_complete_donation(u64 addr,
859786
const struct pkvm_mem_transition *tx)
860787
{
@@ -885,180 +812,6 @@ static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
885812
return check_page_state_range(&vm->pgt, addr, size, &d);
886813
}
887814

888-
static int check_share(struct pkvm_mem_share *share)
889-
{
890-
const struct pkvm_mem_transition *tx = &share->tx;
891-
u64 completer_addr;
892-
int ret;
893-
894-
switch (tx->initiator.id) {
895-
case PKVM_ID_HOST:
896-
ret = host_request_owned_transition(&completer_addr, tx);
897-
break;
898-
default:
899-
ret = -EINVAL;
900-
}
901-
902-
if (ret)
903-
return ret;
904-
905-
switch (tx->completer.id) {
906-
case PKVM_ID_HYP:
907-
ret = hyp_ack_share(completer_addr, tx, share->completer_prot);
908-
break;
909-
case PKVM_ID_FFA:
910-
/*
911-
* We only check the host; the secure side will check the other
912-
* end when we forward the FFA call.
913-
*/
914-
ret = 0;
915-
break;
916-
default:
917-
ret = -EINVAL;
918-
}
919-
920-
return ret;
921-
}
922-
923-
static int __do_share(struct pkvm_mem_share *share)
924-
{
925-
const struct pkvm_mem_transition *tx = &share->tx;
926-
u64 completer_addr;
927-
int ret;
928-
929-
switch (tx->initiator.id) {
930-
case PKVM_ID_HOST:
931-
ret = host_initiate_share(&completer_addr, tx);
932-
break;
933-
default:
934-
ret = -EINVAL;
935-
}
936-
937-
if (ret)
938-
return ret;
939-
940-
switch (tx->completer.id) {
941-
case PKVM_ID_HYP:
942-
ret = hyp_complete_share(completer_addr, tx, share->completer_prot);
943-
break;
944-
case PKVM_ID_FFA:
945-
/*
946-
* We're not responsible for any secure page-tables, so there's
947-
* nothing to do here.
948-
*/
949-
ret = 0;
950-
break;
951-
default:
952-
ret = -EINVAL;
953-
}
954-
955-
return ret;
956-
}
957-
958-
/*
959-
* do_share():
960-
*
961-
* The page owner grants access to another component with a given set
962-
* of permissions.
963-
*
964-
* Initiator: OWNED => SHARED_OWNED
965-
* Completer: NOPAGE => SHARED_BORROWED
966-
*/
967-
static int do_share(struct pkvm_mem_share *share)
968-
{
969-
int ret;
970-
971-
ret = check_share(share);
972-
if (ret)
973-
return ret;
974-
975-
return WARN_ON(__do_share(share));
976-
}
977-
978-
static int check_unshare(struct pkvm_mem_share *share)
979-
{
980-
const struct pkvm_mem_transition *tx = &share->tx;
981-
u64 completer_addr;
982-
int ret;
983-
984-
switch (tx->initiator.id) {
985-
case PKVM_ID_HOST:
986-
ret = host_request_unshare(&completer_addr, tx);
987-
break;
988-
default:
989-
ret = -EINVAL;
990-
}
991-
992-
if (ret)
993-
return ret;
994-
995-
switch (tx->completer.id) {
996-
case PKVM_ID_HYP:
997-
ret = hyp_ack_unshare(completer_addr, tx);
998-
break;
999-
case PKVM_ID_FFA:
1000-
/* See check_share() */
1001-
ret = 0;
1002-
break;
1003-
default:
1004-
ret = -EINVAL;
1005-
}
1006-
1007-
return ret;
1008-
}
1009-
1010-
static int __do_unshare(struct pkvm_mem_share *share)
1011-
{
1012-
const struct pkvm_mem_transition *tx = &share->tx;
1013-
u64 completer_addr;
1014-
int ret;
1015-
1016-
switch (tx->initiator.id) {
1017-
case PKVM_ID_HOST:
1018-
ret = host_initiate_unshare(&completer_addr, tx);
1019-
break;
1020-
default:
1021-
ret = -EINVAL;
1022-
}
1023-
1024-
if (ret)
1025-
return ret;
1026-
1027-
switch (tx->completer.id) {
1028-
case PKVM_ID_HYP:
1029-
ret = hyp_complete_unshare(completer_addr, tx);
1030-
break;
1031-
case PKVM_ID_FFA:
1032-
/* See __do_share() */
1033-
ret = 0;
1034-
break;
1035-
default:
1036-
ret = -EINVAL;
1037-
}
1038-
1039-
return ret;
1040-
}
1041-
1042-
/*
1043-
* do_unshare():
1044-
*
1045-
* The page owner revokes access from another component for a range of
1046-
* pages which were previously shared using do_share().
1047-
*
1048-
* Initiator: SHARED_OWNED => OWNED
1049-
* Completer: SHARED_BORROWED => NOPAGE
1050-
*/
1051-
static int do_unshare(struct pkvm_mem_share *share)
1052-
{
1053-
int ret;
1054-
1055-
ret = check_unshare(share);
1056-
if (ret)
1057-
return ret;
1058-
1059-
return WARN_ON(__do_unshare(share));
1060-
}
1061-
1062815
static int check_donation(struct pkvm_mem_donation *donation)
1063816
{
1064817
const struct pkvm_mem_transition *tx = &donation->tx;
@@ -1149,31 +902,29 @@ static int do_donate(struct pkvm_mem_donation *donation)
1149902

1150903
int __pkvm_host_share_hyp(u64 pfn)
1151904
{
905+
u64 phys = hyp_pfn_to_phys(pfn);
906+
void *virt = __hyp_va(phys);
907+
enum kvm_pgtable_prot prot;
908+
u64 size = PAGE_SIZE;
1152909
int ret;
1153-
u64 host_addr = hyp_pfn_to_phys(pfn);
1154-
u64 hyp_addr = (u64)__hyp_va(host_addr);
1155-
struct pkvm_mem_share share = {
1156-
.tx = {
1157-
.nr_pages = 1,
1158-
.initiator = {
1159-
.id = PKVM_ID_HOST,
1160-
.addr = host_addr,
1161-
.host = {
1162-
.completer_addr = hyp_addr,
1163-
},
1164-
},
1165-
.completer = {
1166-
.id = PKVM_ID_HYP,
1167-
},
1168-
},
1169-
.completer_prot = PAGE_HYP,
1170-
};
1171910

1172911
host_lock_component();
1173912
hyp_lock_component();
1174913

1175-
ret = do_share(&share);
914+
ret = __host_check_page_state_range(phys, size, PKVM_PAGE_OWNED);
915+
if (ret)
916+
goto unlock;
917+
if (IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) {
918+
ret = __hyp_check_page_state_range((u64)virt, size, PKVM_NOPAGE);
919+
if (ret)
920+
goto unlock;
921+
}
922+
923+
prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
924+
WARN_ON(pkvm_create_mappings_locked(virt, virt + size, prot));
925+
WARN_ON(__host_set_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED));
1176926

927+
unlock:
1177928
hyp_unlock_component();
1178929
host_unlock_component();
1179930

@@ -1182,31 +933,29 @@ int __pkvm_host_share_hyp(u64 pfn)
1182933

1183934
int __pkvm_host_unshare_hyp(u64 pfn)
1184935
{
936+
u64 phys = hyp_pfn_to_phys(pfn);
937+
u64 virt = (u64)__hyp_va(phys);
938+
u64 size = PAGE_SIZE;
1185939
int ret;
1186-
u64 host_addr = hyp_pfn_to_phys(pfn);
1187-
u64 hyp_addr = (u64)__hyp_va(host_addr);
1188-
struct pkvm_mem_share share = {
1189-
.tx = {
1190-
.nr_pages = 1,
1191-
.initiator = {
1192-
.id = PKVM_ID_HOST,
1193-
.addr = host_addr,
1194-
.host = {
1195-
.completer_addr = hyp_addr,
1196-
},
1197-
},
1198-
.completer = {
1199-
.id = PKVM_ID_HYP,
1200-
},
1201-
},
1202-
.completer_prot = PAGE_HYP,
1203-
};
1204940

1205941
host_lock_component();
1206942
hyp_lock_component();
1207943

1208-
ret = do_unshare(&share);
944+
ret = __host_check_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED);
945+
if (ret)
946+
goto unlock;
947+
ret = __hyp_check_page_state_range(virt, size, PKVM_PAGE_SHARED_BORROWED);
948+
if (ret)
949+
goto unlock;
950+
if (hyp_page_count((void *)virt)) {
951+
ret = -EBUSY;
952+
goto unlock;
953+
}
954+
955+
WARN_ON(kvm_pgtable_hyp_unmap(&pkvm_pgtable, virt, size) != size);
956+
WARN_ON(__host_set_page_state_range(phys, size, PKVM_PAGE_OWNED));
1209957

958+
unlock:
1210959
hyp_unlock_component();
1211960
host_unlock_component();
1212961

0 commit comments

Comments
 (0)