Skip to content

Commit 6f91d31

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Drop pkvm_mem_transition for host/hyp donations
Simplify the __pkvm_host_donate_hyp() and pkvm_hyp_donate_host() paths by not using the pkvm_mem_transition machinery. As the last users of this, also remove all the now unused code. 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 7cbf7c3 commit 6f91d31

File tree

1 file changed

+32
-253
lines changed

1 file changed

+32
-253
lines changed

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

Lines changed: 32 additions & 253 deletions
Original file line numberDiff line numberDiff line change
@@ -583,39 +583,6 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
583583
BUG_ON(ret && ret != -EAGAIN);
584584
}
585585

586-
struct pkvm_mem_transition {
587-
u64 nr_pages;
588-
589-
struct {
590-
enum pkvm_component_id id;
591-
/* Address in the initiator's address space */
592-
u64 addr;
593-
594-
union {
595-
struct {
596-
/* Address in the completer's address space */
597-
u64 completer_addr;
598-
} host;
599-
struct {
600-
u64 completer_addr;
601-
} hyp;
602-
};
603-
} initiator;
604-
605-
struct {
606-
enum pkvm_component_id id;
607-
} completer;
608-
};
609-
610-
struct pkvm_mem_share {
611-
const struct pkvm_mem_transition tx;
612-
const enum kvm_pgtable_prot completer_prot;
613-
};
614-
615-
struct pkvm_mem_donation {
616-
const struct pkvm_mem_transition tx;
617-
};
618-
619586
struct check_walk_data {
620587
enum pkvm_page_state desired;
621588
enum pkvm_page_state (*get_page_state)(kvm_pte_t pte, u64 addr);
@@ -675,56 +642,6 @@ static int __host_set_page_state_range(u64 addr, u64 size,
675642
return 0;
676643
}
677644

678-
static int host_request_owned_transition(u64 *completer_addr,
679-
const struct pkvm_mem_transition *tx)
680-
{
681-
u64 size = tx->nr_pages * PAGE_SIZE;
682-
u64 addr = tx->initiator.addr;
683-
684-
*completer_addr = tx->initiator.host.completer_addr;
685-
return __host_check_page_state_range(addr, size, PKVM_PAGE_OWNED);
686-
}
687-
688-
static int host_initiate_donation(u64 *completer_addr,
689-
const struct pkvm_mem_transition *tx)
690-
{
691-
u8 owner_id = tx->completer.id;
692-
u64 size = tx->nr_pages * PAGE_SIZE;
693-
694-
*completer_addr = tx->initiator.host.completer_addr;
695-
return host_stage2_set_owner_locked(tx->initiator.addr, size, owner_id);
696-
}
697-
698-
static bool __host_ack_skip_pgtable_check(const struct pkvm_mem_transition *tx)
699-
{
700-
return !(IS_ENABLED(CONFIG_NVHE_EL2_DEBUG) ||
701-
tx->initiator.id != PKVM_ID_HYP);
702-
}
703-
704-
static int __host_ack_transition(u64 addr, const struct pkvm_mem_transition *tx,
705-
enum pkvm_page_state state)
706-
{
707-
u64 size = tx->nr_pages * PAGE_SIZE;
708-
709-
if (__host_ack_skip_pgtable_check(tx))
710-
return 0;
711-
712-
return __host_check_page_state_range(addr, size, state);
713-
}
714-
715-
static int host_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
716-
{
717-
return __host_ack_transition(addr, tx, PKVM_NOPAGE);
718-
}
719-
720-
static int host_complete_donation(u64 addr, const struct pkvm_mem_transition *tx)
721-
{
722-
u64 size = tx->nr_pages * PAGE_SIZE;
723-
u8 host_id = tx->completer.id;
724-
725-
return host_stage2_set_owner_locked(addr, size, host_id);
726-
}
727-
728645
static enum pkvm_page_state hyp_get_page_state(kvm_pte_t pte, u64 addr)
729646
{
730647
if (!kvm_pte_valid(pte))
@@ -745,52 +662,6 @@ static int __hyp_check_page_state_range(u64 addr, u64 size,
745662
return check_page_state_range(&pkvm_pgtable, addr, size, &d);
746663
}
747664

748-
static int hyp_request_donation(u64 *completer_addr,
749-
const struct pkvm_mem_transition *tx)
750-
{
751-
u64 size = tx->nr_pages * PAGE_SIZE;
752-
u64 addr = tx->initiator.addr;
753-
754-
*completer_addr = tx->initiator.hyp.completer_addr;
755-
return __hyp_check_page_state_range(addr, size, PKVM_PAGE_OWNED);
756-
}
757-
758-
static int hyp_initiate_donation(u64 *completer_addr,
759-
const struct pkvm_mem_transition *tx)
760-
{
761-
u64 size = tx->nr_pages * PAGE_SIZE;
762-
int ret;
763-
764-
*completer_addr = tx->initiator.hyp.completer_addr;
765-
ret = kvm_pgtable_hyp_unmap(&pkvm_pgtable, tx->initiator.addr, size);
766-
return (ret != size) ? -EFAULT : 0;
767-
}
768-
769-
static bool __hyp_ack_skip_pgtable_check(const struct pkvm_mem_transition *tx)
770-
{
771-
return !(IS_ENABLED(CONFIG_NVHE_EL2_DEBUG) ||
772-
tx->initiator.id != PKVM_ID_HOST);
773-
}
774-
775-
static int hyp_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
776-
{
777-
u64 size = tx->nr_pages * PAGE_SIZE;
778-
779-
if (__hyp_ack_skip_pgtable_check(tx))
780-
return 0;
781-
782-
return __hyp_check_page_state_range(addr, size, PKVM_NOPAGE);
783-
}
784-
785-
static int hyp_complete_donation(u64 addr,
786-
const struct pkvm_mem_transition *tx)
787-
{
788-
void *start = (void *)addr, *end = start + (tx->nr_pages * PAGE_SIZE);
789-
enum kvm_pgtable_prot prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_OWNED);
790-
791-
return pkvm_create_mappings_locked(start, end, prot);
792-
}
793-
794665
static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
795666
{
796667
if (!kvm_pte_valid(pte))
@@ -812,94 +683,6 @@ static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
812683
return check_page_state_range(&vm->pgt, addr, size, &d);
813684
}
814685

815-
static int check_donation(struct pkvm_mem_donation *donation)
816-
{
817-
const struct pkvm_mem_transition *tx = &donation->tx;
818-
u64 completer_addr;
819-
int ret;
820-
821-
switch (tx->initiator.id) {
822-
case PKVM_ID_HOST:
823-
ret = host_request_owned_transition(&completer_addr, tx);
824-
break;
825-
case PKVM_ID_HYP:
826-
ret = hyp_request_donation(&completer_addr, tx);
827-
break;
828-
default:
829-
ret = -EINVAL;
830-
}
831-
832-
if (ret)
833-
return ret;
834-
835-
switch (tx->completer.id) {
836-
case PKVM_ID_HOST:
837-
ret = host_ack_donation(completer_addr, tx);
838-
break;
839-
case PKVM_ID_HYP:
840-
ret = hyp_ack_donation(completer_addr, tx);
841-
break;
842-
default:
843-
ret = -EINVAL;
844-
}
845-
846-
return ret;
847-
}
848-
849-
static int __do_donate(struct pkvm_mem_donation *donation)
850-
{
851-
const struct pkvm_mem_transition *tx = &donation->tx;
852-
u64 completer_addr;
853-
int ret;
854-
855-
switch (tx->initiator.id) {
856-
case PKVM_ID_HOST:
857-
ret = host_initiate_donation(&completer_addr, tx);
858-
break;
859-
case PKVM_ID_HYP:
860-
ret = hyp_initiate_donation(&completer_addr, tx);
861-
break;
862-
default:
863-
ret = -EINVAL;
864-
}
865-
866-
if (ret)
867-
return ret;
868-
869-
switch (tx->completer.id) {
870-
case PKVM_ID_HOST:
871-
ret = host_complete_donation(completer_addr, tx);
872-
break;
873-
case PKVM_ID_HYP:
874-
ret = hyp_complete_donation(completer_addr, tx);
875-
break;
876-
default:
877-
ret = -EINVAL;
878-
}
879-
880-
return ret;
881-
}
882-
883-
/*
884-
* do_donate():
885-
*
886-
* The page owner transfers ownership to another component, losing access
887-
* as a consequence.
888-
*
889-
* Initiator: OWNED => NOPAGE
890-
* Completer: NOPAGE => OWNED
891-
*/
892-
static int do_donate(struct pkvm_mem_donation *donation)
893-
{
894-
int ret;
895-
896-
ret = check_donation(donation);
897-
if (ret)
898-
return ret;
899-
900-
return WARN_ON(__do_donate(donation));
901-
}
902-
903686
int __pkvm_host_share_hyp(u64 pfn)
904687
{
905688
u64 phys = hyp_pfn_to_phys(pfn);
@@ -964,30 +747,29 @@ int __pkvm_host_unshare_hyp(u64 pfn)
964747

965748
int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages)
966749
{
750+
u64 phys = hyp_pfn_to_phys(pfn);
751+
u64 size = PAGE_SIZE * nr_pages;
752+
void *virt = __hyp_va(phys);
753+
enum kvm_pgtable_prot prot;
967754
int ret;
968-
u64 host_addr = hyp_pfn_to_phys(pfn);
969-
u64 hyp_addr = (u64)__hyp_va(host_addr);
970-
struct pkvm_mem_donation donation = {
971-
.tx = {
972-
.nr_pages = nr_pages,
973-
.initiator = {
974-
.id = PKVM_ID_HOST,
975-
.addr = host_addr,
976-
.host = {
977-
.completer_addr = hyp_addr,
978-
},
979-
},
980-
.completer = {
981-
.id = PKVM_ID_HYP,
982-
},
983-
},
984-
};
985755

986756
host_lock_component();
987757
hyp_lock_component();
988758

989-
ret = do_donate(&donation);
759+
ret = __host_check_page_state_range(phys, size, PKVM_PAGE_OWNED);
760+
if (ret)
761+
goto unlock;
762+
if (IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) {
763+
ret = __hyp_check_page_state_range((u64)virt, size, PKVM_NOPAGE);
764+
if (ret)
765+
goto unlock;
766+
}
990767

768+
prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_OWNED);
769+
WARN_ON(pkvm_create_mappings_locked(virt, virt + size, prot));
770+
WARN_ON(host_stage2_set_owner_locked(phys, size, PKVM_ID_HYP));
771+
772+
unlock:
991773
hyp_unlock_component();
992774
host_unlock_component();
993775

@@ -996,30 +778,27 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages)
996778

997779
int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages)
998780
{
781+
u64 phys = hyp_pfn_to_phys(pfn);
782+
u64 size = PAGE_SIZE * nr_pages;
783+
u64 virt = (u64)__hyp_va(phys);
999784
int ret;
1000-
u64 host_addr = hyp_pfn_to_phys(pfn);
1001-
u64 hyp_addr = (u64)__hyp_va(host_addr);
1002-
struct pkvm_mem_donation donation = {
1003-
.tx = {
1004-
.nr_pages = nr_pages,
1005-
.initiator = {
1006-
.id = PKVM_ID_HYP,
1007-
.addr = hyp_addr,
1008-
.hyp = {
1009-
.completer_addr = host_addr,
1010-
},
1011-
},
1012-
.completer = {
1013-
.id = PKVM_ID_HOST,
1014-
},
1015-
},
1016-
};
1017785

1018786
host_lock_component();
1019787
hyp_lock_component();
1020788

1021-
ret = do_donate(&donation);
789+
ret = __hyp_check_page_state_range(virt, size, PKVM_PAGE_OWNED);
790+
if (ret)
791+
goto unlock;
792+
if (IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) {
793+
ret = __host_check_page_state_range(phys, size, PKVM_NOPAGE);
794+
if (ret)
795+
goto unlock;
796+
}
1022797

798+
WARN_ON(kvm_pgtable_hyp_unmap(&pkvm_pgtable, virt, size) != size);
799+
WARN_ON(host_stage2_set_owner_locked(phys, size, PKVM_ID_HOST));
800+
801+
unlock:
1023802
hyp_unlock_component();
1024803
host_unlock_component();
1025804

0 commit comments

Comments
 (0)