Received: by 2002:a05:6358:489b:b0:bb:da1:e618 with SMTP id x27csp1272741rwn; Thu, 8 Sep 2022 16:46:31 -0700 (PDT) X-Google-Smtp-Source: AA6agR7acGhVg/6wXQEN5mI48D5iEVisJ17SIeUiV9W1IVZx+hFyaSbzakh7/SDywJknbo11lK/x X-Received: by 2002:a05:651c:1a2b:b0:269:1aae:3f0f with SMTP id by43-20020a05651c1a2b00b002691aae3f0fmr3472208ljb.457.1662680791208; Thu, 08 Sep 2022 16:46:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1662680791; cv=none; d=google.com; s=arc-20160816; b=l4VG2HGvTCU9jnS0Gyf0MD0Au5efMveZ9kGd3ZukUcnu/L8nzBv4GABkAaGfYWYeUj 7tnEO4OlZkoV08ef2NAT8DCL2zvl2SjmoeZRHirA8kdvtUvPCR1CUJqnisNoswo4ISTU nSf8ubk22JlfYvbsB21l2fYiLenZB51Hsw7G918b4TwdpLofvbYDYUfUoLBWwciURCEr ZbXS2rAys5jIr4XHOJDFg885idEG/NievK5/hrQM2D0Ea38ZN7ee9ICoTSxfQvEYmdoR m78sSYvKgxF0b8H2/gVabWsQ00K52dMZgG4Gg4ytwNvpyXiwSWmRCp8FFhQA4sR+9HzL CDJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:reply-to:dkim-signature; bh=7Rae3f/XG8eHxbe+XI3rjEcvv9iBFaTeOYNpjRbfcJ8=; b=OPKJsnfxIFAdugtEc43RArLeFCWe9gDkOWptEijV/devuAx37WN01Pydn1Kzp6S1CJ cfyiNyVF75DVdZYUUtbS3xzeMWyVIeRXulP2QqqBltaMBwikoleprW8OZ90DIUM7zMMC b2Rv+LIM8HQcx6OWehrGlVmcD8H9hJTUZB2JbZ5OKV68JMOoXF90HE8JTWOw0hmXE5y4 li6P8KFzwq/uLU900Njkx7bAtCXCsMb4gakJ2xAI5INRW5rixAZ57PIvziBWHoqcub8C vdUCHSrgKEoo0wwyc4BICNgYN2VONCOIFPWDTiTQxQvYRQ/HA1MTkdhnPLpwPwhq1v3z iZog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=P1HVemU5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bd10-20020a05651c168a00b0026a9a624f71si99642ljb.214.2022.09.08.16.46.01; Thu, 08 Sep 2022 16:46:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=P1HVemU5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230389AbiIHXek (ORCPT + 99 others); Thu, 8 Sep 2022 19:34:40 -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-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 Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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-=wik-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 += lib/rbtree.c LIBKVM += lib/sparsebit.c LIBKVM += lib/test_util.c +LIBKVM_STRING += lib/kvm_string.c + LIBKVM_x86_64 += lib/x86_64/apic.c LIBKVM_x86_64 += lib/x86_64/handlers.S LIBKVM_x86_64 += lib/x86_64/perf_test_util.c @@ -220,7 +222,8 @@ LIBKVM_C := $(filter %.c,$(LIBKVM)) LIBKVM_S := $(filter %.S,$(LIBKVM)) LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C)) LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S)) -LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) +LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING)) +LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ) EXTRA_CLEAN += $(LIBKVM_OBJS) cscope.* @@ -231,6 +234,9 @@ $(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ +$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@ + x := $(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/testing/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[]; +/* + * 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-line + * 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/selftests/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 = 0; + + for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) { + if ((res = *su1 - *su2) != 0) + break; + } + return res; +} + +void *memcpy(void *dest, const void *src, size_t count) +{ + char *tmp = dest; + const char *s = src; + + while (count--) + *tmp++ = *s++; + return dest; +} + +void *memset(void *s, int c, size_t count) +{ + char *xs = s; + + while (count--) + *xs++ = c; + return s; +} -- 2.37.2.789.g6183377224-goog