From patchwork Thu Jul 13 12:57:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 13311996 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 24C01EB64DD for ; Thu, 13 Jul 2023 12:58:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:Message-ID: References:Mime-Version:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=XOCy0JAMvJBJd/DQVBCvvg4bhME366io48Ql4b1qAj8=; b=BOj0/D9g4DAfTQhFE8b9eAeM3I +DjLUvKniDRru3QznvkUqaRhXR1QgdytTkJ2RvA98PLLRz+uKQAjiamDkBgCssp23B/5afSNK+bDs p14meFZEJJaB2hq7WEIes31nRke8kVnM2kr+yk5BOHasqREPJgWTewOj5y0dcyFImTx7umuHOcXHA zziix7dzN/MxSrVfwr6LRfXseDOkwfLSDSR6IuSXkjxCDKStWCvh5inZx5YWu6ZksoCn/auMdzFbT aZpgbNYxhb5iqT8yITOCJJdtU/bO/fdVSkya/Mi+64wJpx5rA912aL8MfEP/qduqlvGrVdQ04tQvd eThi/ATA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qJvt8-003Jkw-1h; Thu, 13 Jul 2023 12:57:42 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qJvt5-003JjA-0Z for linux-arm-kernel@lists.infradead.org; Thu, 13 Jul 2023 12:57:40 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-bd69bb4507eso611585276.2 for ; Thu, 13 Jul 2023 05:57:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1689253058; x=1691845058; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=d0jpwRf4aooZIScI07t3xs6wVcncXV8ha+jtsM7z/nQ=; b=nFut6631mjTAOgoR2gmPO5GuPVrlue6cjFmK0Ckm5EHc1cyNxNvCm7zUisrJUudi1Q RaJfyJrG0ZyT23FTrv4ZQ2u3vCeDeY9i+LFL+UjY3Ji2cDc16BUgWsvwdFpI6dmskqxV zN/V0IGNr3ysyGnjLnXraW1y0c5RTebqiT/GgQ57HeRuBFGmUSpeB95fetfLdjYshFGb iiGAtpAwoa74rMDdCjZ1VL4Ta9wx8L6QFix6f8AyL/hxxrU7NhonaHUwja4szt1l38Yq yiTc6BEfBm1Fug9yt3vIEsAw7Abg6UTXnQGxowd/VeOy+l0ArYkwl7tAJuwQQ/E+b8wj Lorg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689253058; x=1691845058; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=d0jpwRf4aooZIScI07t3xs6wVcncXV8ha+jtsM7z/nQ=; b=XbPSGDZ3FOKNMgXaoReRiCyfvbGOtZfu8KPuTEmECXwgbnkGZ6uX6U+XXZL/xCNiXx QdqGxqSQe487gp0ER8Awo6D/HKvxf7ynaznP3AXhrECD0gNthMFC4QB0FNqnyBy8Bt// xqw7zoYpT1WnSIL+0iX4VAQm4D1quI7t8cEnDCh0rYR2uW+6lMLZWZ1T/3D5XYzdTyk6 eC2AW0zk13iPddrmxbJfBlNmVh9Gjjmh5vOuCn5/GMaPI2W4iwcE0DcfRCbhsYv34Kli nFspszpBqmATSbh/c9OdmccMNqHrCcd2WPXLIXlK26hiCrIdYmBwF48o5pgFABDESv7R WrqQ== X-Gm-Message-State: ABy/qLaFVXsjeWxxeq5Ut1NexqajTy2YagHfx9bcu2sELQwHqo6P2C9F h4V3W+EoJGuddmS9V4XpExYbf6hoGBQ= X-Google-Smtp-Source: APBJJlGyKCfFzAbGHoR0SCihpjFPmM7wQ7XzBgJh44FxsoaT+NNOt//wauHqSchSc/F7MrH99i2cdZIEd4c= X-Received: from glider.muc.corp.google.com ([2a00:79e0:9c:201:7a88:66b7:31e5:7d85]) (user=glider job=sendgmr) by 2002:a05:6902:1c4:b0:cab:9746:ef0e with SMTP id u4-20020a05690201c400b00cab9746ef0emr6467ybh.12.1689253058041; Thu, 13 Jul 2023 05:57:38 -0700 (PDT) Date: Thu, 13 Jul 2023 14:57:04 +0200 In-Reply-To: <20230713125706.2884502-1-glider@google.com> Mime-Version: 1.0 References: <20230713125706.2884502-1-glider@google.com> X-Mailer: git-send-email 2.41.0.255.g8b1d071c50-goog Message-ID: <20230713125706.2884502-5-glider@google.com> Subject: [v2 4/5] arm64: mte: add a test for MTE tags compression From: Alexander Potapenko To: glider@google.com, catalin.marinas@arm.com, will@kernel.org, pcc@google.com, andreyknvl@gmail.com, andriy.shevchenko@linux.intel.com, linux@rasmusvillemoes.dk, yury.norov@gmail.com Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, eugenis@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230713_055739_213529_344512EE X-CRM114-Status: GOOD ( 18.66 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Ensure that tag sequences containing alternating values are compressed to buffers of expected size and correctly decompressed afterwards. Signed-off-by: Alexander Potapenko --- arch/arm64/Kconfig | 10 ++ arch/arm64/mm/Makefile | 1 + arch/arm64/mm/test_mtecomp.c | 175 +++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 arch/arm64/mm/test_mtecomp.c diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 0aa727888e746..9473c1e2e8593 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2101,6 +2101,16 @@ config ARM64_MTE_COMP 128-byte tag buffers corresponding to 4K pages can be compressed using the EA0 algorithm to save heap memory. +config ARM64_MTE_COMP_KUNIT_TEST + tristate "Test tag compression for ARM64 MTE" if !KUNIT_ALL_TESTS + default KUNIT_ALL_TESTS + depends on KUNIT && ARM64_MTE_COMP + help + Test EA0 compression algorithm enabled by CONFIG_ARM64_MTE_COMP. + + Ensure that tag sequences containing alternating values are compressed + to buffers of expected size and correctly decompressed afterwards. + config ARM64_SVE bool "ARM Scalable Vector Extension support" default y diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile index 46778f6dd83c2..170dc62b010b9 100644 --- a/arch/arm64/mm/Makefile +++ b/arch/arm64/mm/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_TRANS_TABLE) += trans_pgd-asm.o obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o obj-$(CONFIG_ARM64_MTE) += mteswap.o obj-$(CONFIG_ARM64_MTE_COMP) += mtecomp.o +obj-$(CONFIG_ARM64_MTE_COMP_KUNIT_TEST) += test_mtecomp.o KASAN_SANITIZE_physaddr.o += n obj-$(CONFIG_KASAN) += kasan_init.o diff --git a/arch/arm64/mm/test_mtecomp.c b/arch/arm64/mm/test_mtecomp.c new file mode 100644 index 0000000000000..67bef6f28dac4 --- /dev/null +++ b/arch/arm64/mm/test_mtecomp.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test cases for EA0, the compression algorithm for MTE tags. + */ + +#include +#include +#include +#include + +/* + * Test that ea0_tags_to_ranges() produces a single range for a zero-filled tag + * buffer. + */ +static void test_tags_to_ranges_zero(struct kunit *test) +{ + u8 tags[128], dtags[128]; + short r_sizes[256]; + int r_len = 256; + u8 r_tags[256]; + + memset(tags, 0, 128); + ea0_tags_to_ranges(tags, r_tags, r_sizes, &r_len); + KUNIT_EXPECT_EQ(test, r_len, 1); + KUNIT_EXPECT_EQ(test, r_tags[0], 0); + KUNIT_EXPECT_EQ(test, r_sizes[0], 256); + ea0_ranges_to_tags(r_tags, r_sizes, r_len, dtags); + KUNIT_EXPECT_EQ(test, memcmp(tags, dtags, 128), 0); +} + +/* + * Test that a small number of different tags is correctly transformed into + * ranges. + */ +static void test_tags_to_ranges_simple(struct kunit *test) +{ + u8 tags[128], dtags[128]; + const u8 ex_tags[] = { 0xa, 0x0, 0xa, 0xb, 0x0 }; + const short ex_sizes[] = { 1, 2, 2, 1, 250 }; + short r_sizes[256]; + int r_len = 256; + u8 r_tags[256]; + + memset(tags, 0, 128); + tags[0] = 0xa0; + tags[1] = 0x0a; + tags[2] = 0xab; + ea0_tags_to_ranges(tags, r_tags, r_sizes, &r_len); + KUNIT_EXPECT_EQ(test, r_len, 5); + KUNIT_EXPECT_EQ(test, memcmp(r_tags, ex_tags, sizeof(ex_tags)), 0); + KUNIT_EXPECT_EQ(test, memcmp(r_sizes, ex_sizes, sizeof(ex_sizes)), 0); + ea0_ranges_to_tags(r_tags, r_sizes, r_len, dtags); + KUNIT_EXPECT_EQ(test, memcmp(tags, dtags, 128), 0); +} + +/* Test that repeated 0xa0 byte produces 256 ranges of length 1. */ +static void test_tags_to_ranges_repeated(struct kunit *test) +{ + u8 tags[128], dtags[128]; + short r_sizes[256]; + int r_len = 256; + u8 r_tags[256]; + + memset(tags, 0xa0, 128); + ea0_tags_to_ranges(tags, r_tags, r_sizes, &r_len); + KUNIT_EXPECT_EQ(test, r_len, 256); + ea0_ranges_to_tags(r_tags, r_sizes, r_len, dtags); + KUNIT_EXPECT_EQ(test, memcmp(tags, dtags, 128), 0); +} + +/* Test that a zero-filled array is compressed into inline storage. */ +static void test_compress_zero(struct kunit *test) +{ + u8 tags[128], dtags[128]; + u64 handle; + + memset(tags, 0, 128); + handle = ea0_compress(tags); + KUNIT_EXPECT_EQ(test, handle & BIT_ULL(63), 0); + /* Tags are stored inline. */ + KUNIT_EXPECT_EQ(test, ea0_storage_size(handle), 8); + KUNIT_EXPECT_TRUE(test, ea0_decompress(handle, dtags)); + KUNIT_EXPECT_EQ(test, memcmp(tags, dtags, 128), 0); +} + +/* + * Test that a very small number of tag ranges ends up compressed into 8 bytes. + */ +static void test_compress_simple(struct kunit *test) +{ + u8 tags[128], dtags[128]; + u64 handle; + + memset(tags, 0, 128); + tags[0] = 0xa0; + tags[1] = 0x0a; + tags[2] = 0xab; + + handle = ea0_compress(tags); + KUNIT_EXPECT_EQ(test, handle & BIT_ULL(63), 0); + /* Tags are stored inline. */ + KUNIT_EXPECT_EQ(test, ea0_storage_size(handle), 8); + KUNIT_EXPECT_TRUE(test, ea0_decompress(handle, dtags)); + KUNIT_EXPECT_EQ(test, memcmp(tags, dtags, 128), 0); +} + +/* + * Generate a buffer that will contain @nranges of tag ranges, test that it + * compresses into @exp_size bytes and decompresses into the original tag + * sequence. + */ +static void compress_range_helper(struct kunit *test, int nranges, int exp_size) +{ + u8 tags[128], dtags[128]; + u64 handle; + int i; + + memset(tags, 0, 128); + + if (nranges > 1) { + nranges--; + for (i = 0; i < nranges / 2; i++) + tags[i] = 0xab; + if (nranges % 2) + tags[nranges / 2] = 0xa0; + } + + handle = ea0_compress(tags); + KUNIT_EXPECT_EQ(test, handle & BIT_ULL(63), 0); + KUNIT_EXPECT_EQ(test, ea0_storage_size(handle), exp_size); + KUNIT_EXPECT_TRUE(test, ea0_decompress(handle, dtags)); + KUNIT_EXPECT_EQ(test, memcmp(tags, dtags, 128), 0); +} + +/* + * Test that every number of tag ranges is correctly compressed and + * decompressed. + */ +static void test_compress_ranges(struct kunit *test) +{ + int i, exp_size; + + for (i = 1; i <= 256; i++) { + if (i < 7) + exp_size = 8; + else if (i < 12) + exp_size = 16; + else if (i < 24) + exp_size = 32; + else if (i < 47) + exp_size = 64; + else + exp_size = 128; + compress_range_helper(test, i, exp_size); + } +} + +static struct kunit_case mtecomp_test_cases[] = { + KUNIT_CASE(test_tags_to_ranges_zero), + KUNIT_CASE(test_tags_to_ranges_simple), + KUNIT_CASE(test_tags_to_ranges_repeated), + KUNIT_CASE(test_compress_zero), + KUNIT_CASE(test_compress_simple), + KUNIT_CASE(test_compress_ranges), + {} +}; + +static struct kunit_suite mtecomp_test_suite = { + .name = "mtecomp", + .test_cases = mtecomp_test_cases, +}; +kunit_test_suites(&mtecomp_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alexander Potapenko ");