Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch kvm-arm64/ffa-1.2 into kvmarm-master/next

* kvm-arm64/ffa-1.2:
: .
: FFA 1.2 support for pKVM, courtesy of Per Larsen.
:
: From the cover letter at [1]:
:
: "The FF-A 1.2 specification introduces a new SEND_DIRECT2 ABI which
: allows registers x4-x17 to be used for the message payload. This patch
: set prevents the host from using a lower FF-A version than what has
: already been negotiated with the hypervisor. This is necessary because
: the hypervisor does not have the necessary compatibility paths to
: translate from the hypervisor FF-A version to a previous version."
:
: [1] https://lore.kernel.org/r/20250820-virtio-msg-ffa-v11-0-497ef43550a3@google.com
: .
KVM: arm64: Bump the supported version of FF-A to 1.2
KVM: arm64: Mask response to FFA_FEATURE call
KVM: arm64: Mark optional FF-A 1.2 interfaces as unsupported
KVM: arm64: Mark FFA_NOTIFICATION_* calls as unsupported
KVM: arm64: Use SMCCC 1.2 for FF-A initialization and in host handler
KVM: arm64: Correct return value on host version downgrade attempt

Signed-off-by: Marc Zyngier <maz@kernel.org>

+146 -73
+1
arch/arm64/kvm/hyp/nvhe/Makefile
··· 27 27 cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o ffa.o 28 28 hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ 29 29 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o 30 + hyp-obj-y += ../../../kernel/smccc-call.o 30 31 hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o 31 32 hyp-obj-y += $(lib-objs) 32 33
+144 -73
arch/arm64/kvm/hyp/nvhe/ffa.c
··· 71 71 static bool has_version_negotiated; 72 72 static hyp_spinlock_t version_lock; 73 73 74 - static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno) 74 + static void ffa_to_smccc_error(struct arm_smccc_1_2_regs *res, u64 ffa_errno) 75 75 { 76 - *res = (struct arm_smccc_res) { 76 + *res = (struct arm_smccc_1_2_regs) { 77 77 .a0 = FFA_ERROR, 78 78 .a2 = ffa_errno, 79 79 }; 80 80 } 81 81 82 - static void ffa_to_smccc_res_prop(struct arm_smccc_res *res, int ret, u64 prop) 82 + static void ffa_to_smccc_res_prop(struct arm_smccc_1_2_regs *res, int ret, u64 prop) 83 83 { 84 84 if (ret == FFA_RET_SUCCESS) { 85 - *res = (struct arm_smccc_res) { .a0 = FFA_SUCCESS, 86 - .a2 = prop }; 85 + *res = (struct arm_smccc_1_2_regs) { .a0 = FFA_SUCCESS, 86 + .a2 = prop }; 87 87 } else { 88 88 ffa_to_smccc_error(res, ret); 89 89 } 90 90 } 91 91 92 - static void ffa_to_smccc_res(struct arm_smccc_res *res, int ret) 92 + static void ffa_to_smccc_res(struct arm_smccc_1_2_regs *res, int ret) 93 93 { 94 94 ffa_to_smccc_res_prop(res, ret, 0); 95 95 } 96 96 97 97 static void ffa_set_retval(struct kvm_cpu_context *ctxt, 98 - struct arm_smccc_res *res) 98 + struct arm_smccc_1_2_regs *res) 99 99 { 100 100 cpu_reg(ctxt, 0) = res->a0; 101 101 cpu_reg(ctxt, 1) = res->a1; 102 102 cpu_reg(ctxt, 2) = res->a2; 103 103 cpu_reg(ctxt, 3) = res->a3; 104 + cpu_reg(ctxt, 4) = res->a4; 105 + cpu_reg(ctxt, 5) = res->a5; 106 + cpu_reg(ctxt, 6) = res->a6; 107 + cpu_reg(ctxt, 7) = res->a7; 108 + 109 + /* 110 + * DEN0028C 2.6: SMC32/HVC32 call from aarch64 must preserve x8-x30. 111 + * 112 + * In FF-A 1.2, we cannot rely on the function ID sent by the caller to 113 + * detect 32-bit calls because the CPU cycle management interfaces (e.g. 114 + * FFA_MSG_WAIT, FFA_RUN) are 32-bit only but can have 64-bit responses. 115 + * 116 + * FFA-1.3 introduces 64-bit variants of the CPU cycle management 117 + * interfaces. Moreover, FF-A 1.3 clarifies that SMC32 direct requests 118 + * complete with SMC32 direct reponses which *should* allow us use the 119 + * function ID sent by the caller to determine whether to return x8-x17. 120 + * 121 + * Note that we also cannot rely on function IDs in the response. 122 + * 123 + * Given the above, assume SMC64 and send back x0-x17 unconditionally 124 + * as the passthrough code (__kvm_hyp_host_forward_smc) does the same. 125 + */ 126 + cpu_reg(ctxt, 8) = res->a8; 127 + cpu_reg(ctxt, 9) = res->a9; 128 + cpu_reg(ctxt, 10) = res->a10; 129 + cpu_reg(ctxt, 11) = res->a11; 130 + cpu_reg(ctxt, 12) = res->a12; 131 + cpu_reg(ctxt, 13) = res->a13; 132 + cpu_reg(ctxt, 14) = res->a14; 133 + cpu_reg(ctxt, 15) = res->a15; 134 + cpu_reg(ctxt, 16) = res->a16; 135 + cpu_reg(ctxt, 17) = res->a17; 104 136 } 105 137 106 138 static bool is_ffa_call(u64 func_id) ··· 145 113 146 114 static int ffa_map_hyp_buffers(u64 ffa_page_count) 147 115 { 148 - struct arm_smccc_res res; 116 + struct arm_smccc_1_2_regs res; 149 117 150 - arm_smccc_1_1_smc(FFA_FN64_RXTX_MAP, 151 - hyp_virt_to_phys(hyp_buffers.tx), 152 - hyp_virt_to_phys(hyp_buffers.rx), 153 - ffa_page_count, 154 - 0, 0, 0, 0, 155 - &res); 118 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 119 + .a0 = FFA_FN64_RXTX_MAP, 120 + .a1 = hyp_virt_to_phys(hyp_buffers.tx), 121 + .a2 = hyp_virt_to_phys(hyp_buffers.rx), 122 + .a3 = ffa_page_count, 123 + }, &res); 156 124 157 125 return res.a0 == FFA_SUCCESS ? FFA_RET_SUCCESS : res.a2; 158 126 } 159 127 160 128 static int ffa_unmap_hyp_buffers(void) 161 129 { 162 - struct arm_smccc_res res; 130 + struct arm_smccc_1_2_regs res; 163 131 164 - arm_smccc_1_1_smc(FFA_RXTX_UNMAP, 165 - HOST_FFA_ID, 166 - 0, 0, 0, 0, 0, 0, 167 - &res); 132 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 133 + .a0 = FFA_RXTX_UNMAP, 134 + .a1 = HOST_FFA_ID, 135 + }, &res); 168 136 169 137 return res.a0 == FFA_SUCCESS ? FFA_RET_SUCCESS : res.a2; 170 138 } 171 139 172 - static void ffa_mem_frag_tx(struct arm_smccc_res *res, u32 handle_lo, 140 + static void ffa_mem_frag_tx(struct arm_smccc_1_2_regs *res, u32 handle_lo, 173 141 u32 handle_hi, u32 fraglen, u32 endpoint_id) 174 142 { 175 - arm_smccc_1_1_smc(FFA_MEM_FRAG_TX, 176 - handle_lo, handle_hi, fraglen, endpoint_id, 177 - 0, 0, 0, 178 - res); 143 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 144 + .a0 = FFA_MEM_FRAG_TX, 145 + .a1 = handle_lo, 146 + .a2 = handle_hi, 147 + .a3 = fraglen, 148 + .a4 = endpoint_id, 149 + }, res); 179 150 } 180 151 181 - static void ffa_mem_frag_rx(struct arm_smccc_res *res, u32 handle_lo, 152 + static void ffa_mem_frag_rx(struct arm_smccc_1_2_regs *res, u32 handle_lo, 182 153 u32 handle_hi, u32 fragoff) 183 154 { 184 - arm_smccc_1_1_smc(FFA_MEM_FRAG_RX, 185 - handle_lo, handle_hi, fragoff, HOST_FFA_ID, 186 - 0, 0, 0, 187 - res); 155 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 156 + .a0 = FFA_MEM_FRAG_RX, 157 + .a1 = handle_lo, 158 + .a2 = handle_hi, 159 + .a3 = fragoff, 160 + .a4 = HOST_FFA_ID, 161 + }, res); 188 162 } 189 163 190 - static void ffa_mem_xfer(struct arm_smccc_res *res, u64 func_id, u32 len, 164 + static void ffa_mem_xfer(struct arm_smccc_1_2_regs *res, u64 func_id, u32 len, 191 165 u32 fraglen) 192 166 { 193 - arm_smccc_1_1_smc(func_id, len, fraglen, 194 - 0, 0, 0, 0, 0, 195 - res); 167 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 168 + .a0 = func_id, 169 + .a1 = len, 170 + .a2 = fraglen, 171 + }, res); 196 172 } 197 173 198 - static void ffa_mem_reclaim(struct arm_smccc_res *res, u32 handle_lo, 174 + static void ffa_mem_reclaim(struct arm_smccc_1_2_regs *res, u32 handle_lo, 199 175 u32 handle_hi, u32 flags) 200 176 { 201 - arm_smccc_1_1_smc(FFA_MEM_RECLAIM, 202 - handle_lo, handle_hi, flags, 203 - 0, 0, 0, 0, 204 - res); 177 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 178 + .a0 = FFA_MEM_RECLAIM, 179 + .a1 = handle_lo, 180 + .a2 = handle_hi, 181 + .a3 = flags, 182 + }, res); 205 183 } 206 184 207 - static void ffa_retrieve_req(struct arm_smccc_res *res, u32 len) 185 + static void ffa_retrieve_req(struct arm_smccc_1_2_regs *res, u32 len) 208 186 { 209 - arm_smccc_1_1_smc(FFA_FN64_MEM_RETRIEVE_REQ, 210 - len, len, 211 - 0, 0, 0, 0, 0, 212 - res); 187 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 188 + .a0 = FFA_FN64_MEM_RETRIEVE_REQ, 189 + .a1 = len, 190 + .a2 = len, 191 + }, res); 213 192 } 214 193 215 - static void ffa_rx_release(struct arm_smccc_res *res) 194 + static void ffa_rx_release(struct arm_smccc_1_2_regs *res) 216 195 { 217 - arm_smccc_1_1_smc(FFA_RX_RELEASE, 218 - 0, 0, 219 - 0, 0, 0, 0, 0, 220 - res); 196 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 197 + .a0 = FFA_RX_RELEASE, 198 + }, res); 221 199 } 222 200 223 - static void do_ffa_rxtx_map(struct arm_smccc_res *res, 201 + static void do_ffa_rxtx_map(struct arm_smccc_1_2_regs *res, 224 202 struct kvm_cpu_context *ctxt) 225 203 { 226 204 DECLARE_REG(phys_addr_t, tx, ctxt, 1); ··· 309 267 goto out_unlock; 310 268 } 311 269 312 - static void do_ffa_rxtx_unmap(struct arm_smccc_res *res, 270 + static void do_ffa_rxtx_unmap(struct arm_smccc_1_2_regs *res, 313 271 struct kvm_cpu_context *ctxt) 314 272 { 315 273 DECLARE_REG(u32, id, ctxt, 1); ··· 410 368 return ret; 411 369 } 412 370 413 - static void do_ffa_mem_frag_tx(struct arm_smccc_res *res, 371 + static void do_ffa_mem_frag_tx(struct arm_smccc_1_2_regs *res, 414 372 struct kvm_cpu_context *ctxt) 415 373 { 416 374 DECLARE_REG(u32, handle_lo, ctxt, 1); ··· 469 427 } 470 428 471 429 static void __do_ffa_mem_xfer(const u64 func_id, 472 - struct arm_smccc_res *res, 430 + struct arm_smccc_1_2_regs *res, 473 431 struct kvm_cpu_context *ctxt) 474 432 { 475 433 DECLARE_REG(u32, len, ctxt, 1); ··· 563 521 __do_ffa_mem_xfer((fid), (res), (ctxt)); \ 564 522 } while (0); 565 523 566 - static void do_ffa_mem_reclaim(struct arm_smccc_res *res, 524 + static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res, 567 525 struct kvm_cpu_context *ctxt) 568 526 { 569 527 DECLARE_REG(u32, handle_lo, ctxt, 1); ··· 670 628 case FFA_RXTX_MAP: 671 629 case FFA_MEM_DONATE: 672 630 case FFA_MEM_RETRIEVE_REQ: 631 + /* Optional notification interfaces added in FF-A 1.1 */ 632 + case FFA_NOTIFICATION_BITMAP_CREATE: 633 + case FFA_NOTIFICATION_BITMAP_DESTROY: 634 + case FFA_NOTIFICATION_BIND: 635 + case FFA_NOTIFICATION_UNBIND: 636 + case FFA_NOTIFICATION_SET: 637 + case FFA_NOTIFICATION_GET: 638 + case FFA_NOTIFICATION_INFO_GET: 639 + /* Optional interfaces added in FF-A 1.2 */ 640 + case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */ 641 + case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */ 642 + case FFA_CONSOLE_LOG: /* Optional per 13.1: not in Table 13.1 */ 643 + case FFA_PARTITION_INFO_GET_REGS: /* Optional for virtual instances per 13.1 */ 673 644 return false; 674 645 } 675 646 676 647 return true; 677 648 } 678 649 679 - static bool do_ffa_features(struct arm_smccc_res *res, 650 + static bool do_ffa_features(struct arm_smccc_1_2_regs *res, 680 651 struct kvm_cpu_context *ctxt) 681 652 { 682 653 DECLARE_REG(u32, id, ctxt, 1); ··· 721 666 static int hyp_ffa_post_init(void) 722 667 { 723 668 size_t min_rxtx_sz; 724 - struct arm_smccc_res res; 669 + struct arm_smccc_1_2_regs res; 725 670 726 - arm_smccc_1_1_smc(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0, &res); 671 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs){ 672 + .a0 = FFA_ID_GET, 673 + }, &res); 727 674 if (res.a0 != FFA_SUCCESS) 728 675 return -EOPNOTSUPP; 729 676 730 677 if (res.a2 != HOST_FFA_ID) 731 678 return -EINVAL; 732 679 733 - arm_smccc_1_1_smc(FFA_FEATURES, FFA_FN64_RXTX_MAP, 734 - 0, 0, 0, 0, 0, 0, &res); 680 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs){ 681 + .a0 = FFA_FEATURES, 682 + .a1 = FFA_FN64_RXTX_MAP, 683 + }, &res); 735 684 if (res.a0 != FFA_SUCCESS) 736 685 return -EOPNOTSUPP; 737 686 738 - switch (res.a2) { 687 + switch (res.a2 & FFA_FEAT_RXTX_MIN_SZ_MASK) { 739 688 case FFA_FEAT_RXTX_MIN_SZ_4K: 740 689 min_rxtx_sz = SZ_4K; 741 690 break; ··· 759 700 return 0; 760 701 } 761 702 762 - static void do_ffa_version(struct arm_smccc_res *res, 703 + static void do_ffa_version(struct arm_smccc_1_2_regs *res, 763 704 struct kvm_cpu_context *ctxt) 764 705 { 765 706 DECLARE_REG(u32, ffa_req_version, ctxt, 1); ··· 771 712 772 713 hyp_spin_lock(&version_lock); 773 714 if (has_version_negotiated) { 774 - res->a0 = hyp_ffa_version; 715 + if (FFA_MINOR_VERSION(ffa_req_version) < FFA_MINOR_VERSION(hyp_ffa_version)) 716 + res->a0 = FFA_RET_NOT_SUPPORTED; 717 + else 718 + res->a0 = hyp_ffa_version; 775 719 goto unlock; 776 720 } 777 721 ··· 783 721 * first if TEE supports it. 784 722 */ 785 723 if (FFA_MINOR_VERSION(ffa_req_version) < FFA_MINOR_VERSION(hyp_ffa_version)) { 786 - arm_smccc_1_1_smc(FFA_VERSION, ffa_req_version, 0, 787 - 0, 0, 0, 0, 0, 788 - res); 724 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 725 + .a0 = FFA_VERSION, 726 + .a1 = ffa_req_version, 727 + }, res); 789 728 if (res->a0 == FFA_RET_NOT_SUPPORTED) 790 729 goto unlock; 791 730 ··· 803 740 hyp_spin_unlock(&version_lock); 804 741 } 805 742 806 - static void do_ffa_part_get(struct arm_smccc_res *res, 743 + static void do_ffa_part_get(struct arm_smccc_1_2_regs *res, 807 744 struct kvm_cpu_context *ctxt) 808 745 { 809 746 DECLARE_REG(u32, uuid0, ctxt, 1); ··· 819 756 goto out_unlock; 820 757 } 821 758 822 - arm_smccc_1_1_smc(FFA_PARTITION_INFO_GET, uuid0, uuid1, 823 - uuid2, uuid3, flags, 0, 0, 824 - res); 759 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 760 + .a0 = FFA_PARTITION_INFO_GET, 761 + .a1 = uuid0, 762 + .a2 = uuid1, 763 + .a3 = uuid2, 764 + .a4 = uuid3, 765 + .a5 = flags, 766 + }, res); 825 767 826 768 if (res->a0 != FFA_SUCCESS) 827 769 goto out_unlock; ··· 859 791 860 792 bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) 861 793 { 862 - struct arm_smccc_res res; 794 + struct arm_smccc_1_2_regs res; 863 795 864 796 /* 865 797 * There's no way we can tell what a non-standard SMC call might ··· 928 860 929 861 int hyp_ffa_init(void *pages) 930 862 { 931 - struct arm_smccc_res res; 863 + struct arm_smccc_1_2_regs res; 932 864 void *tx, *rx; 933 865 934 866 if (kvm_host_psci_config.smccc_version < ARM_SMCCC_VERSION_1_2) 935 867 return 0; 936 868 937 - arm_smccc_1_1_smc(FFA_VERSION, FFA_VERSION_1_1, 0, 0, 0, 0, 0, 0, &res); 869 + arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { 870 + .a0 = FFA_VERSION, 871 + .a1 = FFA_VERSION_1_2, 872 + }, &res); 938 873 if (res.a0 == FFA_RET_NOT_SUPPORTED) 939 874 return 0; 940 875 ··· 957 886 if (FFA_MAJOR_VERSION(res.a0) != 1) 958 887 return -EOPNOTSUPP; 959 888 960 - if (FFA_MINOR_VERSION(res.a0) < FFA_MINOR_VERSION(FFA_VERSION_1_1)) 889 + if (FFA_MINOR_VERSION(res.a0) < FFA_MINOR_VERSION(FFA_VERSION_1_2)) 961 890 hyp_ffa_version = res.a0; 962 891 else 963 - hyp_ffa_version = FFA_VERSION_1_1; 892 + hyp_ffa_version = FFA_VERSION_1_2; 964 893 965 894 tx = pages; 966 895 pages += KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE;
+1
include/linux/arm_ffa.h
··· 128 128 #define FFA_FEAT_RXTX_MIN_SZ_4K 0 129 129 #define FFA_FEAT_RXTX_MIN_SZ_64K 1 130 130 #define FFA_FEAT_RXTX_MIN_SZ_16K 2 131 + #define FFA_FEAT_RXTX_MIN_SZ_MASK GENMASK(1, 0) 131 132 132 133 /* FFA Bus/Device/Driver related */ 133 134 struct ffa_device {