From nobody Tue Oct 7 14:56:33 2025 Received: from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D18A4229B02; Wed, 9 Jul 2025 05:50:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=124.126.103.232 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040247; cv=none; b=oQLRP3K6r9cPa8oHnBUUz9A5LG1mDeIPSu8UI/2UbdseDCYZlvQQa/zsEVP33bCiYEnI2pSrqUklddyMeXsc4LmYgAND85cwkZbCzR4L4ufn4/mWaOpOYMJCbmIn+88goW4coq7W4DL0JvcBSoP4HvPn/ZxDddsqHu2vQ5Bl3H8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040247; c=relaxed/simple; bh=fN7JG2wvKqtYzju2CCYCwzesMOUwKL2EFMIPlYIgwhc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=InMKVvWScXjQDG90Q5YDr1XhKKdF1kGBDXFFaW0nRRlaF+hAI0nSDeayDxZmQi0SzInPc76hkEpd3p/Eqm34hdBzKD3tqDAdZ7Hz1NSgjMTuy7AOoXm4RfRf8ba/YxM01lWSXUIz7mE/lKyo3v8o9OVAYo4pkN4HZqg5tPkhyiU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=kylinos.cn; arc=none smtp.client-ip=124.126.103.232 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kylinos.cn X-UUID: a37f89a45c8811f0b29709d653e92f7d-20250709 X-CTIC-Tags: HR_CC_COUNT, HR_CC_DOMAIN_COUNT, HR_CC_NAME, HR_CC_NO_NAME, HR_CTE_8B HR_CTT_MISS, HR_DATE_H, HR_DATE_WKD, HR_DATE_ZONE, HR_FROM_NAME HR_SJ_DIGIT_LEN, HR_SJ_LANG, HR_SJ_LEN, HR_SJ_LETTER, HR_SJ_NOR_SYM HR_SJ_PHRASE, HR_SJ_PHRASE_LEN, HR_SJ_WS, HR_TO_COUNT, HR_TO_DOMAIN_COUNT HR_TO_NO_NAME, IP_TRUSTED, SRC_TRUSTED, DN_TRUSTED, SA_EXISTED SN_EXISTED, SPF_NOPASS, DKIM_NOPASS, DMARC_NOPASS, CIE_BAD CIE_GOOD, CIE_GOOD_SPF, GTI_FG_BS, GTI_RG_INFO, GTI_C_BU AMN_T1, AMN_GOOD, AMN_C_TI, AMN_C_BU, ABX_MISS_RDNS X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.45,REQID:21cc9189-9414-4ea9-b119-06724586c754,IP:10, URL:0,TC:0,Content:0,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACTI ON:release,TS:-5 X-CID-INFO: VERSION:1.1.45,REQID:21cc9189-9414-4ea9-b119-06724586c754,IP:10,UR L:0,TC:0,Content:0,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:-5 X-CID-META: VersionHash:6493067,CLOUDID:0b3ea1a163f44ead983e32d989ef690b,BulkI D:250709133925Q6SM2JA6,BulkQuantity:1,Recheck:0,SF:17|19|24|38|44|66|78|81 |82|102,TC:nil,Content:0|50,EDM:-3,IP:-2,URL:0,File:nil,RT:nil,Bulk:40,QS: nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,AR C:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_FAS,TF_CID_SPAM_FSD,TF_CID_SPAM_FSI X-UUID: a37f89a45c8811f0b29709d653e92f7d-20250709 X-User: duanchenghao@kylinos.cn Received: from localhost.localdomain [(223.70.159.239)] by mailgw.kylinos.cn (envelope-from ) (Generic MTA) with ESMTP id 1206877963; Wed, 09 Jul 2025 13:50:37 +0800 From: Chenghao Duan To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, yangtiezhu@loongson.cn, hengqi.chen@gmail.com, chenhuacai@kernel.org Cc: martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com, jolsa@kernel.org, kernel@xen0n.name, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, bpf@vger.kernel.org, guodongtai@kylinos.cn, duanchenghao@kylinos.cn, youling.tang@linux.dev, jianghaoran@kylinos.cn, Youling Tang Subject: [PATCH v3 1/5] LoongArch: Add the function to generate the beq and bne assembly instructions. Date: Wed, 9 Jul 2025 13:50:25 +0800 Message-Id: <20250709055029.723243-2-duanchenghao@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250709055029.723243-1-duanchenghao@kylinos.cn> References: <20250709055029.723243-1-duanchenghao@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add branch jump function: larch_insn_gen_beq larch_insn_gen_bne Co-developed-by: George Guo Signed-off-by: George Guo Co-developed-by: Youling Tang Signed-off-by: Youling Tang Signed-off-by: Chenghao Duan Tested-by: Tiezhu Yang --- arch/loongarch/include/asm/inst.h | 2 ++ arch/loongarch/kernel/inst.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm= /inst.h index 3089785ca..2ae96a35d 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -511,6 +511,8 @@ u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int im= m); u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm); u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, in= t imm); u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int = imm); +u32 larch_insn_gen_beq(enum loongarch_gpr rd, enum loongarch_gpr rj, int i= mm); +u32 larch_insn_gen_bne(enum loongarch_gpr rd, enum loongarch_gpr rj, int i= mm); =20 static inline bool signed_imm_check(long val, unsigned int bit) { diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index 14d7d700b..674e3b322 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -336,3 +336,31 @@ u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum lo= ongarch_gpr rj, int imm) =20 return insn.word; } + +u32 larch_insn_gen_beq(enum loongarch_gpr rd, enum loongarch_gpr rj, int i= mm) +{ + union loongarch_instruction insn; + + if ((imm & 3) || imm < -SZ_128K || imm >=3D SZ_128K) { + pr_warn("The generated beq instruction is out of range.\n"); + return INSN_BREAK; + } + + emit_beq(&insn, rj, rd, imm >> 2); + + return insn.word; +} + +u32 larch_insn_gen_bne(enum loongarch_gpr rd, enum loongarch_gpr rj, int i= mm) +{ + union loongarch_instruction insn; + + if ((imm & 3) || imm < -SZ_128K || imm >=3D SZ_128K) { + pr_warn("The generated bne instruction is out of range.\n"); + return INSN_BREAK; + } + + emit_bne(&insn, rj, rd, imm >> 2); + + return insn.word; +} --=20 2.43.0 From nobody Tue Oct 7 14:56:33 2025 Received: from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8454026AA91; Wed, 9 Jul 2025 05:50:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=124.126.103.232 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040253; cv=none; b=tXZaUBACAh82bXbWsICzssdpc4pG98t5d4v0SSs/wF/Jc1TmwTcsRov06NHM8JSoOiYZpjsVanM3o+UzuWsKOMpCSkwzUgnBSk+Py7Ip8qZyb16mlLVZreBsKxcI7LnFINkLX9kP2nfw4tEqKsAH4J1GZHGdcg2PfPj4D1mLq1Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040253; c=relaxed/simple; bh=/aoQ7q2KbTf36z6g5QeJFDdDvYGAM81wilyWf/NlQcQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bFI5sVW8TQmdytUoDpkvU1uNnlXQTqiEsZuyFMjqYCY8wUAJYW4r9laOdue0p/+3quCWacAteIYIJPrpfS1EP4AgU97l3Ac47dRKMPnBzlIvI2bN8bQKwGalvpAtOSkd2GkYh04AEiN0+2qJXpSthzwlfNotCvZ+fKuwP0GhrZs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=kylinos.cn; arc=none smtp.client-ip=124.126.103.232 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kylinos.cn X-UUID: a746838a5c8811f0b29709d653e92f7d-20250709 X-CTIC-Tags: HR_CC_COUNT, HR_CC_DOMAIN_COUNT, HR_CC_NO_NAME, HR_CTE_8B, HR_CTT_MISS HR_DATE_H, HR_DATE_WKD, HR_DATE_ZONE, HR_FROM_NAME, HR_SJ_DIGIT_LEN HR_SJ_LANG, HR_SJ_LEN, HR_SJ_LETTER, HR_SJ_NOR_SYM, HR_SJ_PHRASE HR_SJ_PHRASE_LEN, HR_SJ_WS, HR_TO_COUNT, HR_TO_DOMAIN_COUNT, HR_TO_NO_NAME IP_TRUSTED, SRC_TRUSTED, DN_TRUSTED, SA_EXISTED, SN_EXISTED SPF_NOPASS, DKIM_NOPASS, DMARC_NOPASS, CIE_BAD, CIE_GOOD CIE_GOOD_SPF, GTI_FG_BS, GTI_RG_INFO, GTI_C_BU, AMN_T1 AMN_GOOD, AMN_C_TI, AMN_C_BU, ABX_MISS_RDNS X-CID-CACHE: Type:Local,Time:202507091339+08,HitQuantity:1 X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.45,REQID:4c0676b5-77fa-4dee-a77d-090f85a94aa0,IP:10, URL:0,TC:0,Content:0,EDM:-30,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,AC TION:release,TS:-35 X-CID-INFO: VERSION:1.1.45,REQID:4c0676b5-77fa-4dee-a77d-090f85a94aa0,IP:10,UR L:0,TC:0,Content:0,EDM:-30,RT:0,SF:-15,FILE:0,BULK:0,RULE:EDM_GN8D19FE,ACT ION:release,TS:-35 X-CID-META: VersionHash:6493067,CLOUDID:d6db3cc7352ac1bfcd58bf73af8a777e,BulkI D:250709133928S88GGQZH,BulkQuantity:0,Recheck:0,SF:17|19|24|44|66|78|81|82 |102,TC:nil,Content:0|50,EDM:2,IP:-2,URL:0,File:nil,RT:nil,Bulk:nil,QS:nil ,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_FSI,TF_CID_SPAM_SNR,TF_CID_SPAM_FAS,TF_CID_SPAM_FSD X-UUID: a746838a5c8811f0b29709d653e92f7d-20250709 X-User: duanchenghao@kylinos.cn Received: from localhost.localdomain [(223.70.159.239)] by mailgw.kylinos.cn (envelope-from ) (Generic MTA) with ESMTP id 207230891; Wed, 09 Jul 2025 13:50:44 +0800 From: Chenghao Duan To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, yangtiezhu@loongson.cn, hengqi.chen@gmail.com, chenhuacai@kernel.org Cc: martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com, jolsa@kernel.org, kernel@xen0n.name, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, bpf@vger.kernel.org, guodongtai@kylinos.cn, duanchenghao@kylinos.cn, youling.tang@linux.dev, jianghaoran@kylinos.cn Subject: [PATCH v3 2/5] LoongArch: BPF: Update the code to rename validate_code to validate_ctx. Date: Wed, 9 Jul 2025 13:50:26 +0800 Message-Id: <20250709055029.723243-3-duanchenghao@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250709055029.723243-1-duanchenghao@kylinos.cn> References: <20250709055029.723243-1-duanchenghao@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Update the code to rename validate_code to validate_ctx. validate_code is used to check the validity of code. validate_ctx is used to check both code validity and table entry correctness. Co-developed-by: George Guo Signed-off-by: George Guo Signed-off-by: Chenghao Duan Tested-by: Tiezhu Yang --- arch/loongarch/net/bpf_jit.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index fa1500d4a..7032f11d3 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -1180,6 +1180,14 @@ static int validate_code(struct jit_ctx *ctx) return -1; } =20 + return 0; +} + +static int validate_ctx(struct jit_ctx *ctx) +{ + if (validate_code(ctx)) + return -1; + if (WARN_ON_ONCE(ctx->num_exentries !=3D ctx->prog->aux->num_exentries)) return -1; =20 @@ -1288,7 +1296,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog = *prog) build_epilogue(&ctx); =20 /* 3. Extra pass to validate JITed code */ - if (validate_code(&ctx)) { + if (validate_ctx(&ctx)) { bpf_jit_binary_free(header); prog =3D orig_prog; goto out_offset; --=20 2.43.0 From nobody Tue Oct 7 14:56:33 2025 Received: from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7280826C3AC; Wed, 9 Jul 2025 05:50:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=124.126.103.232 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040256; cv=none; b=UDu95c1PUQ65jyZdGBdVRPJT9Lhf3M3h5wVMnR2ES5sicZmkzHFQsnHEGcyHsrnuYsYIYj5jxgLTdRukZ5vJiHOHv2D4JAIRBTMVbITzHRZnIShK5RWGYHb6aPYJF1vSaEDjwfQrFnnS1OvsN1tDajVficTVdBHmTuTM2IU6qbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040256; c=relaxed/simple; bh=JDwvyRXA1pMKMQPPPvZsJkubYob77DLQltP+szHJIYs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BZcunrzdlAwgeqKdu8I18dTh7Ki+/cPw0wTOL0coFGGjQD9Fe7n3vpYDYENF8cvGmWXu3IZvxeMEPYmc8iGuaCHQQWH8Z26kNPsVI/ki48wyfM/32mhY5fR5a3w8i+2TXPNpcwfNqB8bkh0KgmcWcBq/bjveUYvY/7KqJkMx4Dc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=kylinos.cn; arc=none smtp.client-ip=124.126.103.232 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kylinos.cn X-UUID: a93f9b405c8811f0b29709d653e92f7d-20250709 X-CTIC-Tags: HR_CC_COUNT, HR_CC_DOMAIN_COUNT, HR_CC_NO_NAME, HR_CTE_8B, HR_CTT_MISS HR_DATE_H, HR_DATE_WKD, HR_DATE_ZONE, HR_FROM_NAME, HR_SJ_DIGIT_LEN HR_SJ_LANG, HR_SJ_LEN, HR_SJ_LETTER, HR_SJ_NOR_SYM, HR_SJ_PHRASE HR_SJ_PHRASE_LEN, HR_SJ_WS, HR_TO_COUNT, HR_TO_DOMAIN_COUNT, HR_TO_NO_NAME IP_TRUSTED, SRC_TRUSTED, DN_TRUSTED, SA_EXISTED, SN_EXISTED SPF_NOPASS, DKIM_NOPASS, DMARC_NOPASS, CIE_BAD, CIE_GOOD CIE_GOOD_SPF, GTI_FG_BS, GTI_RG_INFO, GTI_C_BU, AMN_T1 AMN_GOOD, AMN_C_TI, AMN_C_BU, ABX_MISS_RDNS X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.45,REQID:d1139b6c-85a2-4eb3-864f-324bc9cf8e8f,IP:10, URL:0,TC:0,Content:0,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACTI ON:release,TS:-5 X-CID-INFO: VERSION:1.1.45,REQID:d1139b6c-85a2-4eb3-864f-324bc9cf8e8f,IP:10,UR L:0,TC:0,Content:0,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:-5 X-CID-META: VersionHash:6493067,CLOUDID:ca8c70a8a70f33c6a9c7da1caf9886b7,BulkI D:250709133928MMIGHBVG,BulkQuantity:1,Recheck:0,SF:17|19|24|38|44|66|78|81 |82|102,TC:nil,Content:0|50,EDM:-3,IP:-2,URL:0,File:nil,RT:nil,Bulk:40,QS: nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,AR C:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_FAS,TF_CID_SPAM_FSD,TF_CID_SPAM_FSI X-UUID: a93f9b405c8811f0b29709d653e92f7d-20250709 X-User: duanchenghao@kylinos.cn Received: from localhost.localdomain [(223.70.159.239)] by mailgw.kylinos.cn (envelope-from ) (Generic MTA) with ESMTP id 530607172; Wed, 09 Jul 2025 13:50:47 +0800 From: Chenghao Duan To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, yangtiezhu@loongson.cn, hengqi.chen@gmail.com, chenhuacai@kernel.org Cc: martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com, jolsa@kernel.org, kernel@xen0n.name, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, bpf@vger.kernel.org, guodongtai@kylinos.cn, duanchenghao@kylinos.cn, youling.tang@linux.dev, jianghaoran@kylinos.cn Subject: [PATCH v3 3/5] LoongArch: BPF: Add EXECMEM_BPF memory to execmem subsystem Date: Wed, 9 Jul 2025 13:50:27 +0800 Message-Id: <20250709055029.723243-4-duanchenghao@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250709055029.723243-1-duanchenghao@kylinos.cn> References: <20250709055029.723243-1-duanchenghao@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The bpf_jit_alloc_exec function serves as the core mechanism for BPF memory allocation, invoking execmem_alloc(EXECMEM_BPF, size) to allocate memory. This change explicitly designates the allocation space for EXECMEM_BPF. Signed-off-by: Chenghao Duan Tested-by: Tiezhu Yang --- arch/loongarch/mm/init.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c index c3e4586a7..07cedd9ee 100644 --- a/arch/loongarch/mm/init.c +++ b/arch/loongarch/mm/init.c @@ -239,6 +239,12 @@ struct execmem_info __init *execmem_arch_setup(void) .pgprot =3D PAGE_KERNEL, .alignment =3D 1, }, + [EXECMEM_BPF] =3D { + .start =3D VMALLOC_START, + .end =3D VMALLOC_END, + .pgprot =3D PAGE_KERNEL, + .alignment =3D PAGE_SIZE, + }, }, }; =20 --=20 2.43.0 From nobody Tue Oct 7 14:56:33 2025 Received: from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9402526CE0F; Wed, 9 Jul 2025 05:50:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=124.126.103.232 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040256; cv=none; b=GZo1BqCLcfW6LsvQ8mM1ssgxMX86sF4P0LL4lk6i5+Ez1STUG3RtquuBn7Jn3Z7nIgk3F0AinJMjCcE2dBqjbbThsnOFs4uqRbrB3eJl/oqYXHo6aaQLgtc4/FcFLHwPp1WP+eAwqLXaRvNWI14aGoUdAEzKBQ6THgyALkpPvpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040256; c=relaxed/simple; bh=yIh92OUC3RZZuGnDpjEcdvvTgtx1+ze+floV3l6jjow=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cSlCMqNX6HJihiHqNcuyUQ9SnRBWIxl1npIA5D9W82mPbZRErC+ALTcTAK1RZOtxbP7HCRGyrtW9vp6rtH70ni7oiIXbOC7ZdSubUrKnWd3FccPuEv04ww2VSImmnvng4WDx+F0lSWO090RZ7k4/U9BDBrl+z3gIvyy/NQalutI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=kylinos.cn; arc=none smtp.client-ip=124.126.103.232 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kylinos.cn X-UUID: aa25ec8a5c8811f0b29709d653e92f7d-20250709 X-CTIC-Tags: HR_CC_COUNT, HR_CC_DOMAIN_COUNT, HR_CC_NO_NAME, HR_CTE_8B, HR_CTT_MISS HR_DATE_H, HR_DATE_WKD, HR_DATE_ZONE, HR_FROM_NAME, HR_SJ_DIGIT_LEN HR_SJ_LANG, HR_SJ_LEN, HR_SJ_LETTER, HR_SJ_NOR_SYM, HR_SJ_PHRASE HR_SJ_PHRASE_LEN, HR_SJ_WS, HR_TO_COUNT, HR_TO_DOMAIN_COUNT, HR_TO_NO_NAME IP_TRUSTED, SRC_TRUSTED, DN_TRUSTED, SA_EXISTED, SN_EXISTED SPF_NOPASS, DKIM_NOPASS, DMARC_NOPASS, CIE_BAD, CIE_GOOD CIE_GOOD_SPF, GTI_FG_BS, GTI_RG_INFO, GTI_C_BU, AMN_T1 AMN_GOOD, AMN_C_TI, AMN_C_BU, ABX_MISS_RDNS X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.45,REQID:222fca29-9234-46e3-99ed-bf716ca32668,IP:10, URL:0,TC:0,Content:-5,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACT ION:release,TS:-10 X-CID-INFO: VERSION:1.1.45,REQID:222fca29-9234-46e3-99ed-bf716ca32668,IP:10,UR L:0,TC:0,Content:-5,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-10 X-CID-META: VersionHash:6493067,CLOUDID:69bb04c642a24b1c67bce3b8f6145b43,BulkI D:250709133928L1ZCGIDC,BulkQuantity:1,Recheck:0,SF:17|19|24|38|44|66|78|81 |82|102,TC:nil,Content:0|50,EDM:-3,IP:-2,URL:0,File:nil,RT:nil,Bulk:40,QS: nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,AR C:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_FAS,TF_CID_SPAM_FSD,TF_CID_SPAM_FSI X-UUID: aa25ec8a5c8811f0b29709d653e92f7d-20250709 X-User: duanchenghao@kylinos.cn Received: from localhost.localdomain [(223.70.159.239)] by mailgw.kylinos.cn (envelope-from ) (Generic MTA) with ESMTP id 1188716383; Wed, 09 Jul 2025 13:50:48 +0800 From: Chenghao Duan To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, yangtiezhu@loongson.cn, hengqi.chen@gmail.com, chenhuacai@kernel.org Cc: martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com, jolsa@kernel.org, kernel@xen0n.name, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, bpf@vger.kernel.org, guodongtai@kylinos.cn, duanchenghao@kylinos.cn, youling.tang@linux.dev, jianghaoran@kylinos.cn Subject: [PATCH v3 4/5] LoongArch: BPF: Add bpf_arch_xxxxx support for Loongarch Date: Wed, 9 Jul 2025 13:50:28 +0800 Message-Id: <20250709055029.723243-5-duanchenghao@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250709055029.723243-1-duanchenghao@kylinos.cn> References: <20250709055029.723243-1-duanchenghao@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement the functions of bpf_arch_text_poke, bpf_arch_text_copy, and bpf_arch_text_invalidate on the LoongArch architecture. On LoongArch, since symbol addresses in the direct mapping region cannot be reached via relative jump instructions from the paged mapping region, we use the move_imm+jirl instruction pair as absolute jump instructions. These require 2-5 instructions, so we reserve 5 NOP instructions in the program as placeholders for function jumps. Co-developed-by: George Guo Signed-off-by: George Guo Signed-off-by: Chenghao Duan Tested-by: Tiezhu Yang --- arch/loongarch/include/asm/inst.h | 1 + arch/loongarch/kernel/inst.c | 32 +++++++++++ arch/loongarch/net/bpf_jit.c | 90 +++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm= /inst.h index 2ae96a35d..88bb73e46 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -497,6 +497,7 @@ void arch_simulate_insn(union loongarch_instruction ins= n, struct pt_regs *regs); int larch_insn_read(void *addr, u32 *insnp); int larch_insn_write(void *addr, u32 insn); int larch_insn_patch_text(void *addr, u32 insn); +int larch_insn_text_copy(void *dst, void *src, size_t len); =20 u32 larch_insn_gen_nop(void); u32 larch_insn_gen_b(unsigned long pc, unsigned long dest); diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index 674e3b322..8d6594968 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -4,6 +4,7 @@ */ #include #include +#include =20 #include #include @@ -218,6 +219,37 @@ int larch_insn_patch_text(void *addr, u32 insn) return ret; } =20 +int larch_insn_text_copy(void *dst, void *src, size_t len) +{ + unsigned long flags; + size_t wlen =3D 0; + size_t size; + void *ptr; + int ret =3D 0; + + set_memory_rw((unsigned long)dst, round_up(len, PAGE_SIZE) / PAGE_SIZE); + raw_spin_lock_irqsave(&patch_lock, flags); + while (wlen < len) { + ptr =3D dst + wlen; + size =3D min_t(size_t, PAGE_SIZE - offset_in_page(ptr), + len - wlen); + + ret =3D copy_to_kernel_nofault(ptr, src + wlen, size); + if (ret) { + pr_err("%s: operation failed\n", __func__); + break; + } + wlen +=3D size; + } + raw_spin_unlock_irqrestore(&patch_lock, flags); + set_memory_rox((unsigned long)dst, round_up(len, PAGE_SIZE) / PAGE_SIZE); + + if (!ret) + flush_icache_range((unsigned long)dst, (unsigned long)dst + len); + + return ret; +} + u32 larch_insn_gen_nop(void) { return INSN_NOP; diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 7032f11d3..9cb01f0b0 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -4,6 +4,7 @@ * * Copyright (C) 2022 Loongson Technology Corporation Limited */ +#include #include "bpf_jit.h" =20 #define REG_TCC LOONGARCH_GPR_A6 @@ -1367,3 +1368,92 @@ bool bpf_jit_supports_subprog_tailcalls(void) { return true; } + +static int emit_jump_and_link(struct jit_ctx *ctx, u8 rd, u64 ip, u64 targ= et) +{ + s64 offset =3D (s64)(target - ip); + + if (offset && (offset >=3D -SZ_128M && offset < SZ_128M)) { + emit_insn(ctx, bl, offset >> 2); + } else { + move_imm(ctx, LOONGARCH_GPR_T1, target, false); + emit_insn(ctx, jirl, rd, LOONGARCH_GPR_T1, 0); + } + + return 0; +} + +static int gen_jump_or_nops(void *target, void *ip, u32 *insns, bool is_ca= ll) +{ + struct jit_ctx ctx; + + ctx.idx =3D 0; + ctx.image =3D (union loongarch_instruction *)insns; + + if (!target) { + emit_insn((&ctx), nop); + emit_insn((&ctx), nop); + return 0; + } + + return emit_jump_and_link(&ctx, is_call ? LOONGARCH_GPR_T0 : LOONGARCH_GP= R_ZERO, + (unsigned long)ip, (unsigned long)target); +} + +int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type, + void *old_addr, void *new_addr) +{ + u32 old_insns[5] =3D {[0 ... 4] =3D INSN_NOP}; + u32 new_insns[5] =3D {[0 ... 4] =3D INSN_NOP}; + bool is_call =3D poke_type =3D=3D BPF_MOD_CALL; + int ret; + + if (!is_kernel_text((unsigned long)ip) && + !is_bpf_text_address((unsigned long)ip)) + return -ENOTSUPP; + + ret =3D gen_jump_or_nops(old_addr, ip, old_insns, is_call); + if (ret) + return ret; + + if (memcmp(ip, old_insns, 5 * 4)) + return -EFAULT; + + ret =3D gen_jump_or_nops(new_addr, ip, new_insns, is_call); + if (ret) + return ret; + + mutex_lock(&text_mutex); + if (memcmp(ip, new_insns, 5 * 4)) + ret =3D larch_insn_text_copy(ip, new_insns, 5 * 4); + mutex_unlock(&text_mutex); + return ret; +} + +int bpf_arch_text_invalidate(void *dst, size_t len) +{ + int i; + int ret =3D 0; + u32 *inst; + + inst =3D kvmalloc(len, GFP_KERNEL); + if (!inst) + return -ENOMEM; + + for (i =3D 0; i < (len/sizeof(u32)); i++) + inst[i] =3D INSN_BREAK; + + if (larch_insn_text_copy(dst, inst, len)) + ret =3D -EINVAL; + + kvfree(inst); + return ret; +} + +void *bpf_arch_text_copy(void *dst, void *src, size_t len) +{ + if (larch_insn_text_copy(dst, src, len)) + return ERR_PTR(-EINVAL); + + return dst; +} --=20 2.43.0 From nobody Tue Oct 7 14:56:33 2025 Received: from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B535226E6EE; Wed, 9 Jul 2025 05:50:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=124.126.103.232 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040260; cv=none; b=Zf3hLF/8NrJ147VIQL179gpLQzw3nb3Ptxybrx3o0buCxzxQhKDAC/VPR0ndFrt7y3pT/l3o+FSpuA7QpXFrcOY0cmQX53gaZ6diAeTjyZyeV6LHqSeUzQpw37WfSeR1+NSFtYE150X6kQDxcwERwoY/Jgugc7MO3+b5kndo2h4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752040260; c=relaxed/simple; bh=7dIQ/leGDKK6thopO48iZTGEvryif/yDLcOd6BCA6nk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=E6BarT0ShkJZ97QMPQHjI9w8J1Cm2TinzW1wPHV3BUlVJu2Hh4K39+GTZ3747EEQofGmjvw/7KY8FCXcNP67pb+xx029ZTAzI5gmoWExCVhQirthKiLRwwGPVIIh/ZX1nZz4kRMP04vOyoEnnLu2YKXsWSP2LkyFz788ZFZ/1W8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=kylinos.cn; arc=none smtp.client-ip=124.126.103.232 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kylinos.cn X-UUID: ab032e745c8811f0b29709d653e92f7d-20250709 X-CTIC-Tags: HR_CC_COUNT, HR_CC_DOMAIN_COUNT, HR_CC_NO_NAME, HR_CTE_8B, HR_CTT_MISS HR_DATE_H, HR_DATE_WKD, HR_DATE_ZONE, HR_FROM_NAME, HR_SJ_DIGIT_LEN HR_SJ_LANG, HR_SJ_LEN, HR_SJ_LETTER, HR_SJ_NOR_SYM, HR_SJ_PHRASE HR_SJ_PHRASE_LEN, HR_SJ_WS, HR_TO_COUNT, HR_TO_DOMAIN_COUNT, HR_TO_NO_NAME IP_TRUSTED, SRC_TRUSTED, DN_TRUSTED, SA_EXISTED, SN_EXISTED SPF_NOPASS, DKIM_NOPASS, DMARC_NOPASS, CIE_BAD, CIE_GOOD CIE_GOOD_SPF, GTI_FG_BS, GTI_RG_INFO, GTI_C_BU, AMN_T1 AMN_GOOD, AMN_C_TI, AMN_C_BU, ABX_MISS_RDNS X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.45,REQID:bea1b619-15ad-488c-afbe-8b61b607d38e,IP:10, URL:0,TC:0,Content:0,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACTI ON:release,TS:-5 X-CID-INFO: VERSION:1.1.45,REQID:bea1b619-15ad-488c-afbe-8b61b607d38e,IP:10,UR L:0,TC:0,Content:0,EDM:0,RT:0,SF:-15,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:-5 X-CID-META: VersionHash:6493067,CLOUDID:9c5ee8285cbc8de73470616d97ff573a,BulkI D:250709133931VX69ZZDH,BulkQuantity:1,Recheck:0,SF:17|19|24|38|44|66|78|81 |82|102,TC:nil,Content:0|50,EDM:-3,IP:-2,URL:0,File:nil,RT:nil,Bulk:40,QS: nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,AR C:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_FAS,TF_CID_SPAM_FSD,TF_CID_SPAM_FSI X-UUID: ab032e745c8811f0b29709d653e92f7d-20250709 X-User: duanchenghao@kylinos.cn Received: from localhost.localdomain [(223.70.159.239)] by mailgw.kylinos.cn (envelope-from ) (Generic MTA) with ESMTP id 27332970; Wed, 09 Jul 2025 13:50:50 +0800 From: Chenghao Duan To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, yangtiezhu@loongson.cn, hengqi.chen@gmail.com, chenhuacai@kernel.org Cc: martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com, jolsa@kernel.org, kernel@xen0n.name, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, bpf@vger.kernel.org, guodongtai@kylinos.cn, duanchenghao@kylinos.cn, youling.tang@linux.dev, jianghaoran@kylinos.cn Subject: [PATCH v3 5/5] LoongArch: BPF: Add bpf trampoline support for Loongarch Date: Wed, 9 Jul 2025 13:50:29 +0800 Message-Id: <20250709055029.723243-6-duanchenghao@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250709055029.723243-1-duanchenghao@kylinos.cn> References: <20250709055029.723243-1-duanchenghao@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" BPF trampoline is the critical infrastructure of the BPF subsystem, acting as a mediator between kernel functions and BPF programs. Numerous important features, such as using BPF program for zero overhead kernel introspection, rely on this key component. The related tests have passed, Including the following technical points: 1. fentry 2. fmod_ret 3. fexit Co-developed-by: George Guo Signed-off-by: George Guo Signed-off-by: Chenghao Duan Tested-by: Tiezhu Yang --- arch/loongarch/net/bpf_jit.c | 391 +++++++++++++++++++++++++++++++++++ arch/loongarch/net/bpf_jit.h | 6 + 2 files changed, 397 insertions(+) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 9cb01f0b0..6820558af 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -7,6 +7,10 @@ #include #include "bpf_jit.h" =20 +#define LOONGARCH_MAX_REG_ARGS 8 +#define LOONGARCH_FENTRY_NINSNS 2 +#define LOONGARCH_FENTRY_NBYTES (LOONGARCH_FENTRY_NINSNS * 4) + #define REG_TCC LOONGARCH_GPR_A6 #define TCC_SAVED LOONGARCH_GPR_S5 =20 @@ -1400,6 +1404,16 @@ static int gen_jump_or_nops(void *target, void *ip, = u32 *insns, bool is_call) (unsigned long)ip, (unsigned long)target); } =20 +static int emit_call(struct jit_ctx *ctx, u64 addr) +{ + u64 ip; + + if (addr && ctx->image && ctx->ro_image) + ip =3D (u64)(ctx->image + ctx->idx); + + return emit_jump_and_link(ctx, LOONGARCH_GPR_RA, ip, addr); +} + int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type, void *old_addr, void *new_addr) { @@ -1457,3 +1471,380 @@ void *bpf_arch_text_copy(void *dst, void *src, size= _t len) =20 return dst; } + +static void store_args(struct jit_ctx *ctx, int nargs, int args_off) +{ + int i; + + for (i =3D 0; i < nargs; i++) { + emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); + args_off -=3D 8; + } +} + +static void restore_args(struct jit_ctx *ctx, int nargs, int args_off) +{ + int i; + + for (i =3D 0; i < nargs; i++) { + emit_insn(ctx, ldd, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); + args_off -=3D 8; + } +} + +static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l, + int args_off, int retval_off, + int run_ctx_off, bool save_ret) +{ + int ret; + u32 *branch; + struct bpf_prog *p =3D l->link.prog; + int cookie_off =3D offsetof(struct bpf_tramp_run_ctx, bpf_cookie); + + if (l->cookie) { + move_imm(ctx, LOONGARCH_GPR_T1, l->cookie, false); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -run_ctx_off + c= ookie_off); + } else { + emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, + -run_ctx_off + cookie_off); + } + + /* arg1: prog */ + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)p, false); + /* arg2: &run_ctx */ + emit_insn(ctx, addid, LOONGARCH_GPR_A1, LOONGARCH_GPR_FP, -run_ctx_off); + ret =3D emit_call(ctx, (const u64)bpf_trampoline_enter(p)); + if (ret) + return ret; + + /* store prog start time */ + move_reg(ctx, LOONGARCH_GPR_S1, LOONGARCH_GPR_A0); + + /* if (__bpf_prog_enter(prog) =3D=3D 0) + * goto skip_exec_of_prog; + * + */ + branch =3D (u32 *)ctx->image + ctx->idx; + /* nop reserved for conditional jump */ + emit_insn(ctx, nop); + + /* arg1: &args_off */ + emit_insn(ctx, addid, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -args_off); + if (!p->jited) + move_imm(ctx, LOONGARCH_GPR_A1, (const s64)p->insnsi, false); + ret =3D emit_call(ctx, (const u64)p->bpf_func); + if (ret) + return ret; + + if (save_ret) { + emit_insn(ctx, std, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -retval_off); + emit_insn(ctx, std, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - = 8)); + } + + /* update branch with beqz */ + if (ctx->image) { + int offset =3D (void *)(&ctx->image[ctx->idx]) - (void *)branch; + *branch =3D larch_insn_gen_beq(LOONGARCH_GPR_A0, LOONGARCH_GPR_ZERO, off= set); + } + + /* arg1: prog */ + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)p, false); + /* arg2: prog start time */ + move_reg(ctx, LOONGARCH_GPR_A1, LOONGARCH_GPR_S1); + /* arg3: &run_ctx */ + emit_insn(ctx, addid, LOONGARCH_GPR_A2, LOONGARCH_GPR_FP, -run_ctx_off); + ret =3D emit_call(ctx, (const u64)bpf_trampoline_exit(p)); + + return ret; +} + +static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links= *tl, + int args_off, int retval_off, int run_ctx_off, u32 **branches) +{ + int i; + + emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off); + for (i =3D 0; i < tl->nr_links; i++) { + invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off, + run_ctx_off, true); + emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off); + branches[i] =3D (u32 *)ctx->image + ctx->idx; + emit_insn(ctx, nop); + } +} + +u64 bpf_jit_alloc_exec_limit(void) +{ + return VMALLOC_END - VMALLOC_START; +} + +void *arch_alloc_bpf_trampoline(unsigned int size) +{ + return bpf_prog_pack_alloc(size, jit_fill_hole); +} + +void arch_free_bpf_trampoline(void *image, unsigned int size) +{ + bpf_prog_pack_free(image, size); +} + +static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_t= ramp_image *im, + const struct btf_func_model *m, + struct bpf_tramp_links *tlinks, + void *func_addr, u32 flags) +{ + int i; + int stack_size =3D 0, nargs =3D 0; + int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off; + struct bpf_tramp_links *fentry =3D &tlinks[BPF_TRAMP_FENTRY]; + struct bpf_tramp_links *fexit =3D &tlinks[BPF_TRAMP_FEXIT]; + struct bpf_tramp_links *fmod_ret =3D &tlinks[BPF_TRAMP_MODIFY_RETURN]; + int ret, save_ret; + void *orig_call =3D func_addr; + u32 **branches =3D NULL; + + if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY)) + return -ENOTSUPP; + + /* + * FP + 8 [ RA to parent func ] return address to parent + * function + * FP + 0 [ FP of parent func ] frame pointer of parent + * function + * FP - 8 [ T0 to traced func ] return address of traced + * function + * FP - 16 [ FP of traced func ] frame pointer of traced + * function + * + * FP - retval_off [ return value ] BPF_TRAMP_F_CALL_ORIG or + * BPF_TRAMP_F_RET_FENTRY_RET + * [ argN ] + * [ ... ] + * FP - args_off [ arg1 ] + * + * FP - nargs_off [ regs count ] + * + * FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG + * + * FP - run_ctx_off [ bpf_tramp_run_ctx ] + * + * FP - sreg_off [ callee saved reg ] + * + */ + + if (m->nr_args > LOONGARCH_MAX_REG_ARGS) + return -ENOTSUPP; + + if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY)) + return -ENOTSUPP; + + stack_size =3D 0; + + /* room of trampoline frame to store return address and frame pointer */ + stack_size +=3D 16; + + save_ret =3D flags & (BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_RET_FENTRY_RET); + if (save_ret) { + /* Save BPF R0 and A0 */ + stack_size +=3D 16; + retval_off =3D stack_size; + } + + /* room of trampoline frame to store args */ + nargs =3D m->nr_args; + stack_size +=3D nargs * 8; + args_off =3D stack_size; + + /* room of trampoline frame to store args number */ + stack_size +=3D 8; + nargs_off =3D stack_size; + + /* room of trampoline frame to store ip address */ + if (flags & BPF_TRAMP_F_IP_ARG) { + stack_size +=3D 8; + ip_off =3D stack_size; + } + + /* room of trampoline frame to store struct bpf_tramp_run_ctx */ + stack_size +=3D round_up(sizeof(struct bpf_tramp_run_ctx), 8); + run_ctx_off =3D stack_size; + + stack_size +=3D 8; + sreg_off =3D stack_size; + + stack_size =3D round_up(stack_size, 16); + + /* For the trampoline called from function entry */ + /* RA and FP for parent function*/ + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -16); + emit_insn(ctx, std, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8); + emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0); + emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 16); + + /* RA and FP for traced function*/ + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_size); + emit_insn(ctx, std, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8); + emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16); + emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size); + + /* callee saved register S1 to pass start time */ + emit_insn(ctx, std, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off); + + /* store ip address of the traced function */ + if (flags & BPF_TRAMP_F_IP_ARG) { + move_imm(ctx, LOONGARCH_GPR_T1, (const s64)func_addr, false); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -ip_off); + } + + /* store nargs number*/ + move_imm(ctx, LOONGARCH_GPR_T1, nargs, false); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -nargs_off); + + store_args(ctx, nargs, args_off); + + /* To traced function */ + orig_call +=3D LOONGARCH_FENTRY_NBYTES; + if (flags & BPF_TRAMP_F_CALL_ORIG) { + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)im, false); + ret =3D emit_call(ctx, (const u64)__bpf_tramp_enter); + if (ret) + return ret; + } + + for (i =3D 0; i < fentry->nr_links; i++) { + ret =3D invoke_bpf_prog(ctx, fentry->links[i], args_off, retval_off, + run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET); + if (ret) + return ret; + } + if (fmod_ret->nr_links) { + branches =3D kcalloc(fmod_ret->nr_links, sizeof(u32 *), GFP_KERNEL); + if (!branches) + return -ENOMEM; + + invoke_bpf_mod_ret(ctx, fmod_ret, args_off, retval_off, + run_ctx_off, branches); + } + + if (flags & BPF_TRAMP_F_CALL_ORIG) { + restore_args(ctx, m->nr_args, args_off); + ret =3D emit_call(ctx, (const u64)orig_call); + if (ret) + goto out; + emit_insn(ctx, std, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -retval_off); + emit_insn(ctx, std, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - = 8)); + im->ip_after_call =3D ctx->ro_image + ctx->idx; + /* Reserve space for the move_imm + jirl instruction */ + emit_insn(ctx, nop); + emit_insn(ctx, nop); + emit_insn(ctx, nop); + emit_insn(ctx, nop); + emit_insn(ctx, nop); + } + + for (i =3D 0; ctx->image && i < fmod_ret->nr_links; i++) { + int offset =3D (void *)(&ctx->image[ctx->idx]) - (void *)branches[i]; + *branches[i] =3D larch_insn_gen_bne(LOONGARCH_GPR_T1, LOONGARCH_GPR_ZERO= , offset); + } + + for (i =3D 0; i < fexit->nr_links; i++) { + ret =3D invoke_bpf_prog(ctx, fexit->links[i], args_off, retval_off, + run_ctx_off, false); + if (ret) + goto out; + } + + if (flags & BPF_TRAMP_F_CALL_ORIG) { + im->ip_epilogue =3D ctx->ro_image + ctx->idx; + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)im, false); + ret =3D emit_call(ctx, (const u64)__bpf_tramp_exit); + if (ret) + goto out; + } + + if (flags & BPF_TRAMP_F_RESTORE_REGS) + restore_args(ctx, m->nr_args, args_off); + + if (save_ret) { + emit_insn(ctx, ldd, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -retval_off); + emit_insn(ctx, ldd, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - = 8)); + } + + emit_insn(ctx, ldd, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off); + + /* trampoline called from function entry */ + emit_insn(ctx, ldd, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8); + emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16); + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_size); + + emit_insn(ctx, ldd, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8); + emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0); + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, 16); + + if (flags & BPF_TRAMP_F_SKIP_FRAME) + /* return to parent function */ + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0); + else + /* return to traced function */ + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T0, 0); + + ret =3D ctx->idx; +out: + kfree(branches); + + return ret; +} + +int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image, + void *ro_image_end, const struct btf_func_model *m, + u32 flags, struct bpf_tramp_links *tlinks, + void *func_addr) +{ + int ret; + void *image, *tmp; + u32 size =3D ro_image_end - ro_image; + + image =3D kvmalloc(size, GFP_KERNEL); + if (!image) + return -ENOMEM; + + struct jit_ctx ctx =3D { + .image =3D (union loongarch_instruction *)image, + .ro_image =3D (union loongarch_instruction *)ro_image, + .idx =3D 0, + }; + + jit_fill_hole(image, (unsigned int)(ro_image_end - ro_image)); + ret =3D __arch_prepare_bpf_trampoline(&ctx, im, m, tlinks, func_addr, fla= gs); + if (ret > 0 && validate_code(&ctx) < 0) { + ret =3D -EINVAL; + goto out; + } + + tmp =3D bpf_arch_text_copy(ro_image, image, size); + if (IS_ERR(tmp)) { + ret =3D PTR_ERR(tmp); + goto out; + } + + bpf_flush_icache(ro_image, ro_image_end); +out: + kvfree(image); + return ret < 0 ? ret : size; +} + +int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags, + struct bpf_tramp_links *tlinks, void *func_addr) +{ + struct bpf_tramp_image im; + struct jit_ctx ctx; + int ret; + + ctx.image =3D NULL; + ctx.idx =3D 0; + + ret =3D __arch_prepare_bpf_trampoline(&ctx, &im, m, tlinks, func_addr, fl= ags); + + /* Page align */ + return ret < 0 ? ret : round_up(ret * LOONGARCH_INSN_SIZE, PAGE_SIZE); +} diff --git a/arch/loongarch/net/bpf_jit.h b/arch/loongarch/net/bpf_jit.h index f9c569f53..5697158fd 100644 --- a/arch/loongarch/net/bpf_jit.h +++ b/arch/loongarch/net/bpf_jit.h @@ -18,6 +18,7 @@ struct jit_ctx { u32 *offset; int num_exentries; union loongarch_instruction *image; + union loongarch_instruction *ro_image; u32 stack_size; }; =20 @@ -308,3 +309,8 @@ static inline int emit_tailcall_jmp(struct jit_ctx *ctx= , u8 cond, enum loongarch =20 return -EINVAL; } + +static inline void bpf_flush_icache(void *start, void *end) +{ + flush_icache_range((unsigned long)start, (unsigned long)end); +} --=20 2.43.0