From patchwork Thu Sep 2 18:52:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Almbladh X-Patchwork-Id: 12472311 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5DB33C4332F for ; Thu, 2 Sep 2021 18:52:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 45861610A0 for ; Thu, 2 Sep 2021 18:52:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347210AbhIBSx4 (ORCPT ); Thu, 2 Sep 2021 14:53:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347237AbhIBSxx (ORCPT ); Thu, 2 Sep 2021 14:53:53 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55129C061764 for ; Thu, 2 Sep 2021 11:52:52 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id q3so4402123edt.5 for ; Thu, 02 Sep 2021 11:52:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anyfinetworks-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xE2vatG15Bdcp+TUUj34HoSwRJXtzL9QIOGhWGZdLqU=; b=dAc3F1Sy7rI8V1OXc6APBRJzzt1ZbMG7WyWmajUal4fEcL/HCL//VgdByQ6ccrknwK GWvx+cpRFIMzQs6ybskOyqF9RgBikADu9N64GMPZgF5ofzSk4s5swyBrBEwALsKoOakn n0oZMIlOEfFdjkQaSPJdr3etEhxgR5xQmvumCUSz9+xcRjrc4NUuqx4lfW6Xf0XZpsz0 YbTYk+keCKRBGtxhzRtdQtmHsOpTqUgch7VV9fRG1zl43zipxgdRzrns9pKA0ixINLYG oowUAr3X1HLcKwRoRe3ZweIvo+ET8Q2JRaMe8DLyajH0Kg3JosZE1WzeCmd+hdS4vdDk hSjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xE2vatG15Bdcp+TUUj34HoSwRJXtzL9QIOGhWGZdLqU=; b=alhaH3r6g5mFjuHbNuxfg8NaEJUK69u3Lj5NylQ4t8KoXxCc7elMEeJfeDbrNOq8X6 3jO7Yt3trNvniyD9w3p3FiHIb3MauE+6LLktS+99rSfouN0C9Ow6IIagfg4fMz2xe/Bv ueMZzh3DGkDL/2A6IBjHNg51eDTjw5uLraicVV+01tKVgiKbDOjDNO6eQdKDzaGODkVr yKfXzgadgL0pB2fyMWC0v+fthuf2Ztuq2A27mBdTTbQbZqBuY/dRt3a7VvUoBUl5xpZ/ lb5Hi9MZYFjj6tUQDsY2OBrQUBLtsO3Atvknbyzp8pCnSlRILTdx1BUS7/jxFxsB7pL1 407A== X-Gm-Message-State: AOAM532owFOV2VIfQEgfQ/caTlyHBPJlbyuhj37nsEBO4yxqqRvYx4l3 xVk2TcdabGIneAjVK//Su/mJhy4hpgJRVc8uAQw= X-Google-Smtp-Source: ABdhPJx0sqsXWSyLujF4eAF2W5CiTadxaemDaIfm64gvpVpZWtPVI/N4+1H1NeItVhfRfoU+Ibuwpg== X-Received: by 2002:aa7:dd93:: with SMTP id g19mr4884801edv.262.1630608770988; Thu, 02 Sep 2021 11:52:50 -0700 (PDT) Received: from anpc2.lan (static-213-115-136-2.sme.telenor.se. [213.115.136.2]) by smtp.gmail.com with ESMTPSA id mb14sm1592235ejb.81.2021.09.02.11.52.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Sep 2021 11:52:50 -0700 (PDT) From: Johan Almbladh To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, iii@linux.ibm.com Cc: kafai@fb.com, songliubraving@fb.com, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Johan Almbladh Subject: [PATCH bpf-next 13/13] bpf/tests: Add tail call limit test with external function call Date: Thu, 2 Sep 2021 20:52:29 +0200 Message-Id: <20210902185229.1840281-14-johan.almbladh@anyfinetworks.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210902185229.1840281-1-johan.almbladh@anyfinetworks.com> References: <20210902185229.1840281-1-johan.almbladh@anyfinetworks.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This patch adds a tail call limit test where the program also emits a BPF_CALL to an external function prior to the tail call. Mainly testing that JITed programs preserve its internal register state, for example tail call count, across such external calls. Signed-off-by: Johan Almbladh --- lib/test_bpf.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/test_bpf.c b/lib/test_bpf.c index f138c6fad5ec..33c3fcc4c9f8 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -12257,6 +12257,20 @@ static struct tail_call_test tail_call_tests[] = { }, .result = MAX_TAIL_CALL_CNT + 1, }, + { + "Tail call count preserved across function calls", + .insns = { + BPF_ALU64_IMM(BPF_ADD, R1, 1), + BPF_STX_MEM(BPF_DW, R10, R1, -8), + BPF_CALL_REL(0), + BPF_LDX_MEM(BPF_DW, R1, R10, -8), + BPF_ALU32_REG(BPF_MOV, R0, R1), + TAIL_CALL(0), + BPF_EXIT_INSN(), + }, + .stack_depth = 8, + .result = MAX_TAIL_CALL_CNT + 1, + }, { "Tail call error path, NULL target", .insns = { @@ -12279,6 +12293,29 @@ static struct tail_call_test tail_call_tests[] = { }, }; +/* + * A test function to be called from a BPF program, clobbering a lot of + * CPU registers in the process. A JITed BPF program calling this function + * must save and restore any caller-saved registers it uses for internal + * state, for example the current tail call count. + */ +BPF_CALL_1(test_bpf_func, u64, arg) +{ + char buf[64]; + long a = 0; + long b = 1; + long c = 2; + long d = 3; + long e = 4; + long f = 5; + long g = 6; + long h = 7; + + return snprintf(buf, sizeof(buf), + "%ld %lu %lx %ld %lu %lx %ld %lu %x", + a, b, c, d, e, f, g, h, (int)arg); +} + static void __init destroy_tail_call_tests(struct bpf_array *progs) { int i; @@ -12332,16 +12369,17 @@ static __init int prepare_tail_call_tests(struct bpf_array **pprogs) for (i = 0; i < len; i++) { struct bpf_insn *insn = &fp->insnsi[i]; - if (insn->imm != TAIL_CALL_MARKER) - continue; - switch (insn->code) { case BPF_LD | BPF_DW | BPF_IMM: + if (insn->imm != TAIL_CALL_MARKER) + break; insn[0].imm = (u32)(long)progs; insn[1].imm = ((u64)(long)progs) >> 32; break; case BPF_ALU | BPF_MOV | BPF_K: + if (insn->imm != TAIL_CALL_MARKER) + break; if (insn->off == TAIL_CALL_NULL) insn->imm = ntests; else if (insn->off == TAIL_CALL_INVALID) @@ -12349,6 +12387,13 @@ static __init int prepare_tail_call_tests(struct bpf_array **pprogs) else insn->imm = which + insn->off; insn->off = 0; + break; + + case BPF_JMP | BPF_CALL: + if (insn->src_reg != BPF_PSEUDO_CALL) + break; + *insn = BPF_EMIT_CALL(test_bpf_func); + break; } }