From nobody Mon Apr 6 09:46:29 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE266C54EE9 for ; Thu, 8 Sep 2022 23:34:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230393AbiIHXel (ORCPT ); Thu, 8 Sep 2022 19:34:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231331AbiIHXeA (ORCPT ); Thu, 8 Sep 2022 19:34:00 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38F1510E868 for ; Thu, 8 Sep 2022 16:31:42 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id oj13-20020a17090b4d8d00b002025cda7659so1949642pjb.0 for ; Thu, 08 Sep 2022 16:31:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date; bh=7Rae3f/XG8eHxbe+XI3rjEcvv9iBFaTeOYNpjRbfcJ8=; b=P1HVemU5Q8l1jHsQ63dpPPBxDNfL3tb1pUm8q4PL+UgH4QBu4+NtJgd8XkKKaIWo+4 k1CEKZkaGyuYGCVnuCKb4hFmgnLdIRztZGXNvIX5oVQBfUCzOqxLRf8mw1ERykDWH4NJ wy2ZzK0YQlXRJNHEoo7w63tqN+10/phJMQjAVrdtqo+M1nI1Jkl3130hL+fAKd+c0NMi BWLVTPqb+2OuhbG2Emeuiwo9CbXF8aCMNVNlaMCUNSMSp4E3NPdj9AdWmNb3LGydn4yg Y30xOFFHvJ1pOKV2OeWGI7rgXEs19ufmuhDW8TVCAPcnC1BoxH1cAR2Qw5FAO8v1478J wMaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date; bh=7Rae3f/XG8eHxbe+XI3rjEcvv9iBFaTeOYNpjRbfcJ8=; b=3SQ7/cm7HpH6/ptLW2CskG6g79yPFpmKZlPgpKswnTjpM/zEZys7wNLTcLt49KVuHf NwHbRE0hgS3jAAv4spS9cehQVd9vTIqq3cAEZnS9fsX72eszBAVMOdCvguOW4n6A0lfj UjCQVfelHznMtA7wnH1kbAFiyHnoefWs2GoBYzp9NC92GHXqkSXouEq7LFSJ/wZ70szx J4bxwCJmXtiVou67dLoa22fk4q5A0B0m4WMSw9vIdZbyVjPxvpuRANE2Nccfy+rjOjda Qh3GjySvfz+vSeTDqGB8GJgQG0cROe0HF+a4rzTdgzPsSOZDPVpRNRTBpSKu5Y2lh+6i mk6Q== X-Gm-Message-State: ACgBeo2Hy7npaEUL/BPbMDIuNpaFkxUTIS5xJi1xuj8jrd2knETdeKGO zGhz5p/fxGe1fPEbwhwbnJtlJzF0bCA= X-Google-Smtp-Source: AA6agR6+JFj4LISGeG3WjfMkkR4u9HVYWVC84UL5YJpClnQ7aQNZeM9iC7B6L5Hv/dEp8eGr9UV8LnDK+pw= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:90a:249:b0:1e0:a8a3:3c6c with SMTP id t9-20020a17090a024900b001e0a8a33c6cmr118873pje.0.1662679901039; Thu, 08 Sep 2022 16:31:41 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 8 Sep 2022 23:31:30 +0000 In-Reply-To: <20220908233134.3523339-1-seanjc@google.com> Mime-Version: 1.0 References: <20220908233134.3523339-1-seanjc@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog Message-ID: <20220908233134.3523339-2-seanjc@google.com> Subject: [PATCH 1/5] KVM: selftests: Implement memcmp(), memcpy(), and memset() for guest use From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Andrew Jones , Anup Patel , Atish Patra , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Sean Christopherson , Oliver Upton Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement memcmp(), memcpy(), and memset() to override the compiler's built-in versions in order to guarantee that the compiler won't generate out-of-line calls to external functions via the PLT. This allows the helpers to be safely used in guest code, as KVM selftests don't support dynamic loading of guest code. Steal the implementations from the kernel's generic versions, sans the optimizations in memcmp() for unaligned accesses. Put the utilities in a separate compilation unit and build with -ffreestanding to fudge around a gcc "feature" where it will optimize memset(), memcpy(), etc... by generating a recursive call. I.e. the compiler optimizes itself into infinite recursion. Alternatively, the individual functions could be tagged with optimize("no-tree-loop-distribute-patterns"), but using "optimize" for anything but debug is discouraged, and Linus NAK'd the use of the flag in the kernel proper[*]. https://lore.kernel.org/lkml/CAHk-=3Dwik-oXnUpfZ6Hw37uLykc-_P0Apyn2XuX-odh-= 3Nzop8w@mail.gmail.com Cc: Andrew Jones Cc: Anup Patel Cc: Atish Patra Cc: Christian Borntraeger Cc: Janosch Frank Cc: Claudio Imbrenda Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/Makefile | 8 ++++- .../selftests/kvm/include/kvm_util_base.h | 10 ++++++ tools/testing/selftests/kvm/lib/kvm_string.c | 33 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/lib/kvm_string.c diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests= /kvm/Makefile index 4c122f1b1737..92a0c05645b5 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -48,6 +48,8 @@ LIBKVM +=3D lib/rbtree.c LIBKVM +=3D lib/sparsebit.c LIBKVM +=3D lib/test_util.c =20 +LIBKVM_STRING +=3D lib/kvm_string.c + LIBKVM_x86_64 +=3D lib/x86_64/apic.c LIBKVM_x86_64 +=3D lib/x86_64/handlers.S LIBKVM_x86_64 +=3D lib/x86_64/perf_test_util.c @@ -220,7 +222,8 @@ LIBKVM_C :=3D $(filter %.c,$(LIBKVM)) LIBKVM_S :=3D $(filter %.S,$(LIBKVM)) LIBKVM_C_OBJ :=3D $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C)) LIBKVM_S_OBJ :=3D $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S)) -LIBKVM_OBJS =3D $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) +LIBKVM_STRING_OBJ :=3D $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING)) +LIBKVM_OBJS =3D $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ) =20 EXTRA_CLEAN +=3D $(LIBKVM_OBJS) cscope.* =20 @@ -231,6 +234,9 @@ $(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ =20 +$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@ + x :=3D $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))) $(TEST_GEN_PROGS): $(LIBKVM_OBJS) $(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 24fde97f6121..bdb751f4825c 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -173,6 +173,16 @@ struct vm_guest_mode_params { }; extern const struct vm_guest_mode_params vm_guest_mode_params[]; =20 +/* + * Override the "basic" built-in string helpers so that they can be used in + * guest code. KVM selftests don't support dynamic loading in guest code = and + * will jump into the weeds if the compiler decides to insert an out-of-li= ne + * call via the PLT. + */ +int memcmp(const void *cs, const void *ct, size_t count); +void *memcpy(void *dest, const void *src, size_t count); +void *memset(void *s, int c, size_t count); + int open_path_or_exit(const char *path, int flags); int open_kvm_dev_path_or_exit(void); unsigned int kvm_check_cap(long cap); diff --git a/tools/testing/selftests/kvm/lib/kvm_string.c b/tools/testing/s= elftests/kvm/lib/kvm_string.c new file mode 100644 index 000000000000..a60d56d4e5b8 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/kvm_string.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include "kvm_util.h" + +int memcmp(const void *cs, const void *ct, size_t count) +{ + const unsigned char *su1, *su2; + int res =3D 0; + + for (su1 =3D cs, su2 =3D ct; 0 < count; ++su1, ++su2, count--) { + if ((res =3D *su1 - *su2) !=3D 0) + break; + } + return res; +} + +void *memcpy(void *dest, const void *src, size_t count) +{ + char *tmp =3D dest; + const char *s =3D src; + + while (count--) + *tmp++ =3D *s++; + return dest; +} + +void *memset(void *s, int c, size_t count) +{ + char *xs =3D s; + + while (count--) + *xs++ =3D c; + return s; +} --=20 2.37.2.789.g6183377224-goog