Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp1303772rwb; Wed, 28 Sep 2022 16:38:52 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5NjVSkUc2FeP5EohTMtkxQP0uYNU1nykAzlUnrJ/troOlw6Rj4UcFPyZrgfiiLMSfNZNua X-Received: by 2002:a17:906:cc4b:b0:772:3844:6ab2 with SMTP id mm11-20020a170906cc4b00b0077238446ab2mr271260ejb.211.1664408332369; Wed, 28 Sep 2022 16:38:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664408332; cv=none; d=google.com; s=arc-20160816; b=Mtlt7u82jftUOv/Iy5azUqIPoF5+dQP7iroFk3GZEDDEx10zV7f7IXDThBnh47R/79 UBqWfzgV/FNIHnDmZshIUw+wFZ4r9HRdcTvUVKA97P94wxIS7vCcl+/V6RV5ETDaft1q +m6aNZ0Ua5UbesOslxWkTaAMhl0uFheZYTsWjvEzfR2f6ZXom947eZdgccJUETm38qWL PNY4ygmxRpRVsLL25T+Ru0NGdpA1iI3TBtnrHJCDdY1F7tDZcJKKHIFAzaTf9XNRo3HD b09do6Zeo9XciFqGG2/e6WRe4Sv2cHt1YP+6mLG2+6cpFvF9f/DAWfVxOkD8TanrPheD zAFg== 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=3Yq7CLybwWK+RFrws3rXKi2UuiysUZtk+qDRhATTop0=; b=iGY/Tp34efv7VrxuCGvTJR36jKaFJwm83eGYZKzfbNyoHO4hj9YTpAMHGwkIM0kjLH tp0bebAFuQt4cjrzCFOMXpvfiRabUVosCQltsdDNwqrr0pp/Cyz5vO5ciMgR1rHdp1uS v0khtJoDxrAytlWsUYZHCdHAR2vSsnKwoea+ctz9matSScbjJiHo02kbJEZg3D1Rev2F QlQiusz3blHc1sw/M1l/xll1eo7+QvItME69oUKWzTnyQAFQ5r6FmrQkpjYzj9VjJuLJ nz+svvBb3KBnVicmbdCTA6N7/QwSlGtSH3iimPElBPOch9VefF/pZMHpzia46jzGBLrU cMpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=Ea3Z5w53; 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 cr21-20020a170906d55500b007811e006b46si6465973ejc.470.2022.09.28.16.38.27; Wed, 28 Sep 2022 16:38:52 -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=Ea3Z5w53; 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 S233749AbiI1XhB (ORCPT + 99 others); Wed, 28 Sep 2022 19:37:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38078 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233739AbiI1Xg5 (ORCPT ); Wed, 28 Sep 2022 19:36:57 -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 8C396EFF53 for ; Wed, 28 Sep 2022 16:36:56 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id nl8-20020a17090b384800b00205f930565cso954286pjb.2 for ; Wed, 28 Sep 2022 16:36:56 -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=3Yq7CLybwWK+RFrws3rXKi2UuiysUZtk+qDRhATTop0=; b=Ea3Z5w53CFnMPujNQZAL9/uyD/3RiI7TVHdzhFSB9a8FOkzqbjbzGOxhA4f+pYpUWw kjvVsSZ6gIciDfWplCOpp7+3o4acPhjH6dc+IvjtH+lE5CWHG2Ea9+G+CE11ZFELwUZK OssDKu/flHUvN9766NJUh8fo/586Rqz/K4gn/pdCfbVVLA++Uj/lLB4kVvEAhA+/3wc3 wfvCwcDC1z9OuWx865t3SCfgnvkQ9d51HFyuFOuoelHQe+3oJDYrJMQe7P2gDorQH3zg XjCTtTjbD9jMb5aWKPys4tavSYdDCEPUg5Eq6Mjgt49Mt93NSLF3SUKoSd+FU11Koa3B y2tA== 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=3Yq7CLybwWK+RFrws3rXKi2UuiysUZtk+qDRhATTop0=; b=nDW98/+DIqfDFCyMIdwlPNwjAimSFZzmAn8TWD+HpdyFyEa/VXXVj5bkuNtSyaMoRC sEul0UJBicWGOuuonmN8VLmwWZBtG6dWiSndRNt2wJI2sHzAQ6YFbuinhWet8GxEgfTw 9OVWidteWjYOoKrgxHYwXP66/U2p1uCWSLWPyHdOSoI0bHQgreyOSHVM4iRSSzIySw2/ xiQPVPI4y29+8PN/tU9xlLsk2xpMnSF08nH1tv4rKUnVou90zDro7d4R61QZRFUvPSDq oialmUxn0lQHxUrpQgHQoCiE7omq6hFuShYc7gyZWDWPKPCMHpI4yydvh2sI50M+Y1lx pFyw== X-Gm-Message-State: ACrzQf2oAdkakPu5nSwzmFzEV67ayPcDGztU5LaN3/mDlJo5aWaCLdYB ng3Gir6JdroLDA2vbrBL6ArKDzVtqTY= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:903:32cc:b0:178:41c1:2e41 with SMTP id i12-20020a17090332cc00b0017841c12e41mr462492plr.126.1664408216145; Wed, 28 Sep 2022 16:36:56 -0700 (PDT) Reply-To: Sean Christopherson Date: Wed, 28 Sep 2022 23:36:46 +0000 In-Reply-To: <20220928233652.783504-1-seanjc@google.com> Mime-Version: 1.0 References: <20220928233652.783504-1-seanjc@google.com> X-Mailer: git-send-email 2.37.3.998.g577e59143f-goog Message-ID: <20220928233652.783504-2-seanjc@google.com> Subject: [PATCH v2 1/7] KVM: selftests: Implement memcmp(), memcpy(), and memset() for guest use From: Sean Christopherson To: Paolo Bonzini , Nathan Chancellor , Nick Desaulniers Cc: Tom Rix , kvm@vger.kernel.org, llvm@lists.linux.dev, linux-kernel@vger.kernel.org, Andrew Jones , Anup Patel , Atish Patra , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Sean Christopherson , Oliver Upton , Jim Mattson 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,USER_IN_DEF_DKIM_WL autolearn=ham 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 | 11 +++++- .../selftests/kvm/lib/string_override.c | 39 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/lib/string_override.c diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 8b1b32628ac8..681816df69cc 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/string_override.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 @@ -221,7 +223,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.* @@ -232,6 +235,12 @@ $(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ +# Compile the string overrides as freestanding to prevent the compiler from +# generating self-referential code, e.g. with "freestanding" the compiler may +# "optimize" memcmp() by invoking memcmp(), thus causing infinite recursion. +$(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/lib/string_override.c b/tools/testing/selftests/kvm/lib/string_override.c new file mode 100644 index 000000000000..632398adc229 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/string_override.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include + +/* + * 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) +{ + 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.3.998.g577e59143f-goog