From patchwork Tue Mar 7 11:28:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 659742 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c6:0:0:0:0:0 with SMTP id m6csp2337346wrb; Tue, 7 Mar 2023 03:30:28 -0800 (PST) X-Google-Smtp-Source: AK7set/qEd10wocLOTNYCyu6SCW94AI6SLoubPYXmblj4LIFGyxKMFPUsGJeLXHpkHWyevAwY1C7 X-Received: by 2002:a05:6214:246c:b0:56e:9f05:6267 with SMTP id im12-20020a056214246c00b0056e9f056267mr23684985qvb.48.1678188628505; Tue, 07 Mar 2023 03:30:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678188628; cv=none; d=google.com; s=arc-20160816; b=K6QMN8VhpQ96c2UNVwzMJzUTVJwALtjgNuSscUWfVPUO4NhaSzyBvszOxJ18zWH/fz ucnjdPPbt/OcL9vcHRAmzqO69wcsyRPUBAyr1OBNSWldAvOTW4tNQQx5qyuXZI5gJe6a Mjq+61zbIpCU7U+uP0EsMg7Bjv5TZfrRmsl3W8YF+QcrgI6i/N4PjoPqVDeRXkit99N7 TpDNdtg/szwAfAQaD99Zn2vNF/B4GXh7mvJ3NaPKSdL4HgaXjaqGCyGCWtdZ/QJs4BjX XyrOVIpQGp5YfYRdR3RUuGskfoZa2qOx7Jc3g58juJrvxTW6pL9rFBYI51RZjbCW1Bw3 Im6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=yM2KjYGD7orZo6AEu6pU16rn3FTr1UxycOe1pdtgZ0A=; b=IwcL60Xxsxq0LDff3FrkHbJPwOTdFdKEtVU183SpStivKMRaKlE6mjL/F0xdlcIQ53 WDGMnDjL2kFCyBqgnjkgfshvLMyjqvzMKOfhH0TBwHrrQiyicpBBKx30lmnX0FAACXEI m/DoJEr1sb/X92hjqVH6RC9wZaipI9AcJF9Iu0SFk22L2Lq0bMj2SQkmiNLXOJPfURVK /BW4LspWMbJDXW5CjvLiHGyhhHObrpuYwX+JCnxgYeHKfewiI8WEopJg7gwpHB2/NMQX Zhcl/jDJjOcys+ZLiPYzRYvM7M0zMpqTlBseg2agX151fXc228kZd62Akp8j53nCliYI jR1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CuiKwmsU; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id z2-20020a0cda82000000b0056eafd69749si9641411qvj.247.2023.03.07.03.30.28 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Mar 2023 03:30:28 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CuiKwmsU; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZVVD-0007Ub-Bn; Tue, 07 Mar 2023 06:29:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZVUx-0007HV-Sn for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:51 -0500 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pZVUu-0005gD-9W for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:51 -0500 Received: by mail-wm1-x330.google.com with SMTP id c18so7532932wmr.3 for ; Tue, 07 Mar 2023 03:28:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678188526; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yM2KjYGD7orZo6AEu6pU16rn3FTr1UxycOe1pdtgZ0A=; b=CuiKwmsUbs1gOBp7lmR93X4YFwAkwCqLH18nTj+qtUxbAcM4ElK5XPZq14ef1z2OaC NZsa4V8rz9PS2Vf/wHAa3u4O+gdlkogCyqk9Ih17YShaYv+sqfmI8w/sHyXKafRXgZW5 SpOruP7QCCOYG8nZdxqxKv5JTBsWbR60HcKBLPDqxPISm2VS8QhPp6n5/hM3s5/ayBXl nbNdWT9Dcyq8j6SwPf5kKtQCXtVKhayMdh4PVKBrH1h2T/C43gjQRpQnFgqu5gs0OJ26 5dF0hiipnwxX4XxnQl6wdxr+zvFvppsa8Afjdpc36n3ZkdRI8irs/SPQ+Z+023zV/zZK b6dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678188526; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yM2KjYGD7orZo6AEu6pU16rn3FTr1UxycOe1pdtgZ0A=; b=7oqIwX7d3hY/ci8KynziEeb8QngdT4tjQQtdwfuciA0EplQrcOznjHeAgWm33czi9R NUQGh93zzAaIsxbbHvNsDpNp5fOAc2hC3jnV86AfvH7RSUKueP1kHgF+TykhxcZ46uLu VFd3PONhuou51jBy2ZNWMUvvsoNzFZe1c4RDgmGyke808JZnt+chanoh++fwweNiAPTp UcB5QQwchdZKcV91FtYpzLbmkyU74gK7cHz0s264XLarWuITBX5aoTQI8TczEgwAj185 oUes1Tn+TDbR3NBPn8QuN3+2aDTfy9nF6qDuI3q9DMDko2f4hWyC3V6XisqSn80lpRKH xxhQ== X-Gm-Message-State: AO0yUKWuy4NaLtO3s8aNX9Fi7FVYRk2dFykfuhwejfnMeaOL1YtQQqfv jPNfsIUqIwGbyKSrJIhS+RB/xQ== X-Received: by 2002:a05:600c:35d2:b0:3ea:f6c4:5f2a with SMTP id r18-20020a05600c35d200b003eaf6c45f2amr11517830wmq.17.1678188526216; Tue, 07 Mar 2023 03:28:46 -0800 (PST) Received: from zen.linaroharston ([85.9.250.243]) by smtp.gmail.com with ESMTPSA id h6-20020a1ccc06000000b003e118684d56sm17047627wmb.45.2023.03.07.03.28.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 03:28:45 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 9FED91FFB8; Tue, 7 Mar 2023 11:28:45 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Thomas Huth , Andrew Jones , Paolo Bonzini , kvmarm@lists.linux.dev, qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [kvm-unit-tests PATCH v10 1/7] Makefile: add GNU global tags support Date: Tue, 7 Mar 2023 11:28:39 +0000 Message-Id: <20230307112845.452053-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230307112845.452053-1-alex.bennee@linaro.org> References: <20230307112845.452053-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::330; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x330.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org If you have ctags you might as well offer gtags as a target. Signed-off-by: Alex Bennée Message-Id: <20211118184650.661575-4-alex.bennee@linaro.org> Acked-by: Andrew Jones --- v10 - update .gitignore --- Makefile | 5 ++++- .gitignore | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6ed5deac..f22179de 100644 --- a/Makefile +++ b/Makefile @@ -145,6 +145,9 @@ cscope: -name '*.[chsS]' -exec realpath --relative-base=$(CURDIR) {} \; | sort -u > ./cscope.files cscope -bk -.PHONY: tags +.PHONY: tags gtags tags: ctags -R + +gtags: + gtags diff --git a/.gitignore b/.gitignore index 33529b65..4d5f460f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ tags patches .stgit-* cscope.* +GPATH +GRTAGS +GTAGS *.swp /lib/asm /lib/config.h From patchwork Tue Mar 7 11:28:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 659736 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c6:0:0:0:0:0 with SMTP id m6csp2336763wrb; Tue, 7 Mar 2023 03:29:01 -0800 (PST) X-Google-Smtp-Source: AK7set83TlafS3YFHoGOpjneCQP1U/eNZbmoSsOeTWo7/Q5Av/8GyEsBYAPwuyCui3OO7qs4BMK2 X-Received: by 2002:a05:6214:20eb:b0:577:5560:5b6c with SMTP id 11-20020a05621420eb00b0057755605b6cmr24184871qvk.41.1678188541412; Tue, 07 Mar 2023 03:29:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678188541; cv=none; d=google.com; s=arc-20160816; b=pxlDcUb4LrMope6Pi7pCQ63KKamTOs/ZkbgAtdtH4o4mYJsxQqrHlEjuDtyR1nwrcl jCWmT50JVZwe/HBMRToyja6WL2hTqsSccQj1HxLHzwmH535tfsGWZ9d3gxfjbMY6O6wh 5F0j09VJiVAXyDwh8lMHjcn8Sjm+XXU1sNVzIOxACvelGW0Dxdwv19nGD/e0lau2fOOc xxJiRfLmmZ2fJ2GgcuhniOI5KVaD2OvB/+HCb2hk9a2cWIUx7fBAt/q6+vY28emZWsxk M764LquXZwg8q0s6f7WvYVyAyplPqHiI5n+i2jEG1Md8Z5kn59GY0RSpqWiHCeQi18jD yO1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=/NpHgHHJcO9P9YY4y05zXj+B7UDNA2tYv+R1DwR2UQ0=; b=gpBRdf/jXyReHbHKQQ/aOEYKHQAHbCRqQdcX47DYFQuHB1H+J6SyVwy2B11YOEikzs tTbCQPqlTX+ZiQohPXcqMrtW5E0uJoc3Ci52SgPaw/pdj4P7ksh+w8rV8jjkWeQw5ZOh jnuymchtIZ7iKp0WWAFOLQ+6CuI7rnIqWJT66VJaYracIzJV0l9BNHXppTUfmrEc+7DY vh03aFeGmzACcUDUMH7k4oK2gNRCV1x2Wx01DYY5JoLJqcUR2v+EfouHPJwxHNEjPvjp tl11lgd4MBsZXCKX/DjjL3V/SMoQ5kYbKnVfxzzI6SXYYyiSZdIPK77Y28FiC9TU4+85 TfGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LDOhaUxA; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id c3-20020a0ce143000000b005721bd083edsi9770144qvl.409.2023.03.07.03.29.01 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Mar 2023 03:29:01 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LDOhaUxA; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZVUy-0007Hr-9s; Tue, 07 Mar 2023 06:28:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZVUw-0007HD-Vt for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:51 -0500 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pZVUu-0005gK-9W for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:50 -0500 Received: by mail-wm1-x330.google.com with SMTP id p23-20020a05600c1d9700b003ead4835046so757501wms.0 for ; Tue, 07 Mar 2023 03:28:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678188526; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/NpHgHHJcO9P9YY4y05zXj+B7UDNA2tYv+R1DwR2UQ0=; b=LDOhaUxAR+lE9e9uOQ4DrQ8xtL4H+V0Mq5qjEATE3EcyEoWE0CN7ARVyxZl5cCRhD9 2JqXf6skriwPvRTC7w+8DCIeNgpCSeuvzrPaRYXzBiNp7lggEZQeESfX9+3SPcxDPiOF YIUGUTl5GmiFPKNbY00Nnr40E3A1pymHgDI89JVx6/rfoN2iZTXrXGbWhqOMvN1Yv4Pe w1ocXTez46XorcVExritLrskAdAv1mAAknlUS9MK/q/zh5+HICh+/ORP2eqAYjbFT0tS 1OY5YYwYEeP5hkeETCd4WzsA0M54ZS9TnSq28txFc2Pyw55HARz59AQqMCKlMerSMULs UgZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678188526; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/NpHgHHJcO9P9YY4y05zXj+B7UDNA2tYv+R1DwR2UQ0=; b=A0GYk1oh8GyTpI9Vb59vTO18eEpLcrnSi9JZFx+uD4fZLO6RTucsY0yPFTNJByp16p 2o1dhUfcraAaY51VgYEyx//mbLUXBCRMACGY0kcZScjqN9pvcZXt9AR5JaOKg9FDnmR6 bOIc4tzmHX+mjdE5ZRY0enunZsxtJeX76bhUcLXYBG1ZeX+9Fhb1sViyhfL/81qRquxl mbNE2gR8ISI/MC3Xj12eipIKb6TQXeqH+EdopRNnwc4dGUq0z0Gy2UAbNGnsT30VR+a/ GtLR30uwcCM8clOexq/OD1pMEFcs15pbi9JYpMyr4Fuqmh5PTu8NCYxQA1lDfMRHU4Rd sqng== X-Gm-Message-State: AO0yUKXbP9jHT+7CAtSADYbMYxDyYQJFNfVSj9p/MoHsaaJI68w/g6ou ZD3szTYAHIAwYLal2k9aM2XlfA== X-Received: by 2002:a05:600c:3b95:b0:3eb:2da5:e19 with SMTP id n21-20020a05600c3b9500b003eb2da50e19mr12222106wms.27.1678188526577; Tue, 07 Mar 2023 03:28:46 -0800 (PST) Received: from zen.linaroharston ([85.9.250.243]) by smtp.gmail.com with ESMTPSA id h19-20020a05600c30d300b003db06224953sm12347034wmn.41.2023.03.07.03.28.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 03:28:46 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id B4A491FFBA; Tue, 7 Mar 2023 11:28:45 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Thomas Huth , Andrew Jones , Paolo Bonzini , kvmarm@lists.linux.dev, qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [kvm-unit-tests PATCH v10 2/7] add .gitpublish metadata Date: Tue, 7 Mar 2023 11:28:40 +0000 Message-Id: <20230307112845.452053-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230307112845.452053-1-alex.bennee@linaro.org> References: <20230307112845.452053-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::330; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x330.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org This allows for users of git-publish to have default routing for kvm and kvmarm patches. Signed-off-by: Alex Bennée Acked-by: Andrew Jones --- .gitpublish | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .gitpublish diff --git a/.gitpublish b/.gitpublish new file mode 100644 index 00000000..39130f93 --- /dev/null +++ b/.gitpublish @@ -0,0 +1,18 @@ +# +# Common git-publish profiles that can be used to send patches to QEMU upstream. +# +# See https://github.com/stefanha/git-publish for more information +# +[gitpublishprofile "default"] +base = master +to = kvm@vger.kernel.org +cc = qemu-devel@nongnu.org +cccmd = scripts/get_maintainer.pl --noroles --norolestats --nogit --nogit-fallback 2>/dev/null + +[gitpublishprofile "arm"] +base = master +to = kvmarm@lists.cs.columbia.edu +cc = kvm@vger.kernel.org +cc = qemu-devel@nongnu.org +cc = qemu-arm@nongnu.org +cccmd = scripts/get_maintainer.pl --noroles --norolestats --nogit --nogit-fallback 2>/dev/null From patchwork Tue Mar 7 11:28:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 659740 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c6:0:0:0:0:0 with SMTP id m6csp2337266wrb; Tue, 7 Mar 2023 03:30:19 -0800 (PST) X-Google-Smtp-Source: AK7set/dso5zYIHXB6h3WIN++vOqHdh3dr/Z1D4EG0tVdef0kAPGTuSGEr+DXcUj0yBpDRp2Bme7 X-Received: by 2002:a05:622a:1a01:b0:3bd:1a8a:8015 with SMTP id f1-20020a05622a1a0100b003bd1a8a8015mr21671571qtb.16.1678188619383; Tue, 07 Mar 2023 03:30:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678188619; cv=none; d=google.com; s=arc-20160816; b=d2Aioevs6yuhvXRy9aSXSDljCUtPF+3Somx5A1UUUXc0csQVwWsKsS0hDHPRK81RHp ZkmnYgZqzTEFNwQPIDEQcu6gZdKMINcc/zD1iulW1PfxgkfUZ93yMUWsEdBm9uWpvSqD zKLJ1Ezj0UMhF5nWx8l3auZv/6//mmoSvHNyLMK9SmDRux5baKsttQ4xM/cifv0fUv/m HDkJuZN3z+jAc5TXuU+mmrFFcwHlMJIxTynZs45X//twJiYmk8zwrEeuoijRGbgmdEBZ jUVvNGn3B7X9hD101EDxHh5r/bLbogOJyjQ1eSjn0OxPZ2IGZOkscHE2pX8W3xsuyeTh ruRA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=AOd0jSLOO+UI3WE+UlLsCxj1ZQ7pCFwHne+Nhyu5xhk=; b=TDmQrvjmBafi2x7X38SHM//du+95StOx5BAd8aH0fzW/bZVU5TkgsOf5gYEO8eL5uM WvHLXAfVZ7GcMJCgVqjZDkVfevYSe3fdWUnVEStMEuleZz2zGUvMg6XT1SOAONW9jg5R Fet6xqx5fIz70asKSgEtuUWAkEvGV7oYZHIe66XHwr1te0dh2metdHLlavgi7XKnX9Qk wZGo9PQyYKxZyTHPpRY576Ij0K5Oanu+ustZ9zbQCeQcySB7mgkazMG7d7LQ5whb4hiq ZH80p+P1WnSQXsg6iHULoGvOAglnCBv4NYSYi2xhw+jDDyukiKwrQHBk8vVxw21bL06v ct+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gHjEcNbX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id h18-20020ac85852000000b003ba31dc6246si9627686qth.736.2023.03.07.03.30.19 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Mar 2023 03:30:19 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gHjEcNbX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZVV3-0007Og-MU; Tue, 07 Mar 2023 06:28:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZVUz-0007Iy-PZ for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:53 -0500 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pZVUu-0005go-V0 for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:53 -0500 Received: by mail-wm1-x331.google.com with SMTP id p26so7516326wmc.4 for ; Tue, 07 Mar 2023 03:28:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678188527; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AOd0jSLOO+UI3WE+UlLsCxj1ZQ7pCFwHne+Nhyu5xhk=; b=gHjEcNbXhe7uK9JJYN0EsYFE+2awhLb8puf4HcnQmFza7dkHF8jQB7e9HUJXkc0beJ U95xvBBamLT6Jm9loFzt1AUuoTrwgnlQ5dx/vxtlKlwdiZqhLPOyXkVp3mE6tx3Atz/g 0dudl4MPffYYSPYBlaJym3awigKAf1lJsRvE2alkShpNuyNJoxvN2nWlSnmV74IVnwZX KHMht2lEggMBbX72i0YP2UMKch2EnEtFOXQ8KRuWqJ77oAQOi0hhzy6HjJPle7RVkq/1 7qlOMlUoxN0RXCoRqQ4fLQHI9/WFdGvhdgVXYjSYa3ezf9ODjzSepJG8Lpq9NBr8w48L SoMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678188527; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AOd0jSLOO+UI3WE+UlLsCxj1ZQ7pCFwHne+Nhyu5xhk=; b=peRMDziVvc2l+vimti/PuIB8NB6g6DDxJ3LvgLR+k2EXc5A7QvIQLH7cWXNgu4WUhn enxWx4K3Yg4bfJy0/WB0SzOTH9/FXZwHGD0DrTr+hi6YXJAAtt5yQnkCscYfvDp2lkhO WF+GQF6ohv1Ajwsrj17mYGchwziV7OOnEb2tKMT4Ztss4jzQMJQe+G4NsvZqC2ApdUH3 Jgrrv1+PBEYucaKULO0+Vpfec4PsFGbAF+wABFM8lpcCmrTo9GYJU3XybSsTVKp1nQ1R jRSt7XcBgHamnmfWrz8IzzOoewgBft9imALoobnsv1o+cHTA/qtdtetzjMCXqsuuImPo U8ag== X-Gm-Message-State: AO0yUKVQ39LEU2VPRM87bQKoZ7hHLVEha0Z10GAZirh1GaL3xFulFm1V 8KZOyLF8lMftU5Yb4FvB/wsi9A== X-Received: by 2002:a1c:7c16:0:b0:3df:9858:c02e with SMTP id x22-20020a1c7c16000000b003df9858c02emr12403339wmc.3.1678188527458; Tue, 07 Mar 2023 03:28:47 -0800 (PST) Received: from zen.linaroharston ([85.9.250.243]) by smtp.gmail.com with ESMTPSA id e4-20020a5d5304000000b002ce3cccda0bsm11786573wrv.81.2023.03.07.03.28.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 03:28:46 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id C91601FFBB; Tue, 7 Mar 2023 11:28:45 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Thomas Huth , Andrew Jones , Paolo Bonzini , kvmarm@lists.linux.dev, qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= , "Timothy B . Terriberry" , Andrew Jones Subject: [kvm-unit-tests PATCH v10 3/7] lib: add isaac prng library from CCAN Date: Tue, 7 Mar 2023 11:28:41 +0000 Message-Id: <20230307112845.452053-4-alex.bennee@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230307112845.452053-1-alex.bennee@linaro.org> References: <20230307112845.452053-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::331; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x331.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org It's often useful to introduce some sort of random variation when testing several racing CPU conditions. Instead of each test implementing some half-arsed PRNG bring in a a decent one which has good statistical randomness. Obviously it is deterministic for a given seed value which is likely the behaviour you want. I've pulled in the ISAAC library from CCAN: http://ccodearchive.net/info/isaac.html I shaved off the float related stuff which is less useful for unit testing and re-indented to fit the style. The original license was CC0 (Public Domain) which is compatible with the LGPL v2 of kvm-unit-tests. Signed-off-by: Alex Bennée CC: Timothy B. Terriberry Acked-by: Andrew Jones Acked-by: Thomas Huth Message-Id: <20211118184650.661575-6-alex.bennee@linaro.org> --- v9 - add SPDX CC0 tags --- arm/Makefile.common | 1 + lib/prng.h | 83 ++++++++++++++++++++++ lib/prng.c | 163 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 lib/prng.h create mode 100644 lib/prng.c diff --git a/arm/Makefile.common b/arm/Makefile.common index 1bbec64f..16f8c6df 100644 --- a/arm/Makefile.common +++ b/arm/Makefile.common @@ -45,6 +45,7 @@ cflatobjs += lib/pci-testdev.o cflatobjs += lib/virtio.o cflatobjs += lib/virtio-mmio.o cflatobjs += lib/chr-testdev.o +cflatobjs += lib/prng.o cflatobjs += lib/arm/io.o cflatobjs += lib/arm/setup.o cflatobjs += lib/arm/mmu.o diff --git a/lib/prng.h b/lib/prng.h new file mode 100644 index 00000000..4f9512f5 --- /dev/null +++ b/lib/prng.h @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: CC0-1.0 +/* + * PRNG Header + */ +#ifndef __PRNG_H__ +#define __PRNG_H__ + +# include + + + +typedef struct isaac_ctx isaac_ctx; + + + +/*This value may be lowered to reduce memory usage on embedded platforms, at + the cost of reducing security and increasing bias. + Quoting Bob Jenkins: "The current best guess is that bias is detectable after + 2**37 values for [ISAAC_SZ_LOG]=3, 2**45 for 4, 2**53 for 5, 2**61 for 6, + 2**69 for 7, and 2**77 values for [ISAAC_SZ_LOG]=8."*/ +#define ISAAC_SZ_LOG (8) +#define ISAAC_SZ (1< +#include "prng.h" + +#define ISAAC_MASK (0xFFFFFFFFU) + +/* Extract ISAAC_SZ_LOG bits (starting at bit 2). */ +static inline uint32_t lower_bits(uint32_t x) +{ + return (x & ((ISAAC_SZ-1) << 2)) >> 2; +} + +/* Extract next ISAAC_SZ_LOG bits (starting at bit ISAAC_SZ_LOG+2). */ +static inline uint32_t upper_bits(uint32_t y) +{ + return (y >> (ISAAC_SZ_LOG+2)) & (ISAAC_SZ-1); +} + +static void isaac_update(isaac_ctx *_ctx){ + uint32_t *m; + uint32_t *r; + uint32_t a; + uint32_t b; + uint32_t x; + uint32_t y; + int i; + m=_ctx->m; + r=_ctx->r; + a=_ctx->a; + b=_ctx->b+(++_ctx->c); + for(i=0;i>6)+m[i+ISAAC_SZ/2]; + m[i]=y=m[lower_bits(x)]+a+b; + r[i]=b=m[upper_bits(y)]+x; + x=m[++i]; + a=(a^a<<2)+m[i+ISAAC_SZ/2]; + m[i]=y=m[lower_bits(x)]+a+b; + r[i]=b=m[upper_bits(y)]+x; + x=m[++i]; + a=(a^a>>16)+m[i+ISAAC_SZ/2]; + m[i]=y=m[lower_bits(x)]+a+b; + r[i]=b=m[upper_bits(y)]+x; + } + for(i=ISAAC_SZ/2;i>6)+m[i-ISAAC_SZ/2]; + m[i]=y=m[lower_bits(x)]+a+b; + r[i]=b=m[upper_bits(y)]+x; + x=m[++i]; + a=(a^a<<2)+m[i-ISAAC_SZ/2]; + m[i]=y=m[lower_bits(x)]+a+b; + r[i]=b=m[upper_bits(y)]+x; + x=m[++i]; + a=(a^a>>16)+m[i-ISAAC_SZ/2]; + m[i]=y=m[lower_bits(x)]+a+b; + r[i]=b=m[upper_bits(y)]+x; + } + _ctx->b=b; + _ctx->a=a; + _ctx->n=ISAAC_SZ; +} + +static void isaac_mix(uint32_t _x[8]){ + static const unsigned char SHIFT[8]={11,2,8,16,10,4,8,9}; + int i; + for(i=0;i<8;i++){ + _x[i]^=_x[(i+1)&7]<>SHIFT[i]; + _x[(i+3)&7]+=_x[i]; + _x[(i+1)&7]+=_x[(i+2)&7]; + } +} + + +void isaac_init(isaac_ctx *_ctx,const unsigned char *_seed,int _nseed){ + _ctx->a=_ctx->b=_ctx->c=0; + memset(_ctx->r,0,sizeof(_ctx->r)); + isaac_reseed(_ctx,_seed,_nseed); +} + +void isaac_reseed(isaac_ctx *_ctx,const unsigned char *_seed,int _nseed){ + uint32_t *m; + uint32_t *r; + uint32_t x[8]; + int i; + int j; + m=_ctx->m; + r=_ctx->r; + if(_nseed>ISAAC_SEED_SZ_MAX)_nseed=ISAAC_SEED_SZ_MAX; + for(i=0;i<_nseed>>2;i++){ + r[i]^=(uint32_t)_seed[i<<2|3]<<24|(uint32_t)_seed[i<<2|2]<<16| + (uint32_t)_seed[i<<2|1]<<8|_seed[i<<2]; + } + _nseed-=i<<2; + if(_nseed>0){ + uint32_t ri; + ri=_seed[i<<2]; + for(j=1;j<_nseed;j++)ri|=(uint32_t)_seed[i<<2|j]<<(j<<3); + r[i++]^=ri; + } + x[0]=x[1]=x[2]=x[3]=x[4]=x[5]=x[6]=x[7]=0x9E3779B9U; + for(i=0;i<4;i++)isaac_mix(x); + for(i=0;in)isaac_update(_ctx); + return _ctx->r[--_ctx->n]; +} + +uint32_t isaac_next_uint(isaac_ctx *_ctx,uint32_t _n){ + uint32_t r; + uint32_t v; + uint32_t d; + do{ + r=isaac_next_uint32(_ctx); + v=r%_n; + d=r-v; + } + while(((d+_n-1)&ISAAC_MASK) X-Patchwork-Id: 659738 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c6:0:0:0:0:0 with SMTP id m6csp2337149wrb; Tue, 7 Mar 2023 03:30:04 -0800 (PST) X-Google-Smtp-Source: AK7set91RLv3+yBH5EluM2o1nPjU48XDQYbU9hZu3trNS50gHXw9vyK4PLkepu3yN/Rv3By/rRHG X-Received: by 2002:ac8:7d88:0:b0:3bf:da79:6703 with SMTP id c8-20020ac87d88000000b003bfda796703mr25087058qtd.3.1678188603992; Tue, 07 Mar 2023 03:30:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678188603; cv=none; d=google.com; s=arc-20160816; b=MlnFH+NTzBzXKTEVgPgoDm/Z3QhwubvKXtRNNGmduYozC0g83Z7emvNmJwdcxq+O3O 09FVZamCFmFdf4K4IB0UGySwQOPka5uHkmDaGcuwh4DTj/bzr3HAEq0IIBSRV+7n8RTJ I7QHailt0xaB0ZsM4jPkb+L1WTI49/weqf6j5o39uXFjifAwvol1xZsFist/arUzztIy Bmdx3bbbHXCDAJjNGzkxW5n3rJqYjvxMR7OBJWeQsr8O6cmmAiGI+b0bb0EXLG5H6pws UJXe2lSkDmz42YDLS16491kUwwjWpauG5KQ1ESRYtUISKGWDX7JpAoOTqTEAYM9Gz4LL apig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=bnIjeSc1FJePfsNSVfRIwqJW9N48Tra8RDl/0gXoxhE=; b=xyGI6HyYqMP4NT6oFl9uLAIej07ZaX1mJYTmG/0eEKJoqvpPG10NwT7cIOrxxCbly5 syX4lkpjj+mnOeCvOA4EccBNwtsbJ3voPobn3JP3mH/Z+lWcab+0/igHCDcXgBsJSoNb ovJfEbIt3DhFoABRi1F3ro/z2nDCR721gtjGQCh9L6bI7T1m3KGjRHd7Z8Dmd4/dfwis B5Y1sXtMvQ4f/kD9SVPfJ0OnpeEWMH4Tap2qS4F9Tfy5UeOmEO8ChmgmWW1WQJvg9HkM 691ue27VwBT/NwP7ZEvyxOV8Eg2kKEzK0MB9lflRj+LbJm02Y6IND4CpEaIHnBqRzqR1 aU5w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wGDT+w35; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id b6-20020ac87fc6000000b003b69418ad6csi9763739qtk.606.2023.03.07.03.30.03 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Mar 2023 03:30:03 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wGDT+w35; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZVV3-0007O0-LW; Tue, 07 Mar 2023 06:28:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZVUz-0007IL-Ca for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:53 -0500 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pZVUu-0005ge-SU for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:53 -0500 Received: by mail-wm1-x332.google.com with SMTP id ay29-20020a05600c1e1d00b003e9f4c2b623so10166771wmb.3 for ; Tue, 07 Mar 2023 03:28:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678188527; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bnIjeSc1FJePfsNSVfRIwqJW9N48Tra8RDl/0gXoxhE=; b=wGDT+w35u+rBSYyqsw8q1e/mzbhczTfQ89KcObYUmTM4dZQP0PRQ0X6eBIa4BW6Nq6 vNvCvwKIwU0G+kIp9k4/LEnq6kqPVpXRfDkXeVwEXsPvOtCQr/f11WUsVI2/lExCf0jI QQbytxW5o05sxcYaQz/NIwwGiECj0IfYHs8ReNZGKRaDog9Kk+LAJETKm+Fs6eNE8yaM Kt/zzm4cZI6unJ+oD3RGlAdkio+8Oi7u7aSod6hkIA5iZPI34ikslCzW22+0aIYgiP7Y bkdAKK5qBvT0oA9tpP5U/JANZ0wVZs0ofqJpBiCpG+HV0/IiClkxfMG+SUDI2R0MmUJT 3oqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678188527; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bnIjeSc1FJePfsNSVfRIwqJW9N48Tra8RDl/0gXoxhE=; b=4fW1hFSLYyak4JcwDFL+o93Hh0X9Cus6pqBjL5ZZWALpsTIdwcBdVae0NjwlR8PT16 7Y2dL9mlnCj8L7gpuPtk3POAwoLid7uBLODx18g54tVHiqQBgFAZ+shZ2h30ZVgbPIVv V4fyT6Y3q+C3WxUFw8l+u2l6k2rFazkWPFvdovlMXB5mJLOmWiO3EmqgrHakWR16JCwL +B5ms8IR83nbtSbwLPj2znt9naQOA6pFpl3JoItpyZd00O47LDt+Mav5do65KOdhX8TO hQXBoAVHWYlUlksRmgsNR+qxBfzeSfu5mzzxZzzw5kxWfc3eBhuHIHDRH8miOF4VGNWC 5K7w== X-Gm-Message-State: AO0yUKX/Clt1pgrywdPuyTLhJviWFsYIJVI+Wn30q49mRJGgTutFUfNX Rqq+mmlOZq49hV7qhzUaVzfLGA== X-Received: by 2002:a05:600c:548b:b0:3eb:39e7:3607 with SMTP id iv11-20020a05600c548b00b003eb39e73607mr13094175wmb.4.1678188527307; Tue, 07 Mar 2023 03:28:47 -0800 (PST) Received: from zen.linaroharston ([85.9.250.243]) by smtp.gmail.com with ESMTPSA id l21-20020a05600c47d500b003e11ad0750csm12337353wmo.47.2023.03.07.03.28.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 03:28:46 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id E11201FFBC; Tue, 7 Mar 2023 11:28:45 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Thomas Huth , Andrew Jones , Paolo Bonzini , kvmarm@lists.linux.dev, qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Mark Rutland Subject: [kvm-unit-tests PATCH v10 4/7] arm/tlbflush-code: TLB flush during code execution Date: Tue, 7 Mar 2023 11:28:42 +0000 Message-Id: <20230307112845.452053-5-alex.bennee@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230307112845.452053-1-alex.bennee@linaro.org> References: <20230307112845.452053-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::332; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x332.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org This adds a fairly brain dead torture test for TLB flushes intended for stressing the MTTCG QEMU build. It takes the usual -smp option for multiple CPUs. By default it CPU0 will do a TLBIALL flush after each cycle. You can pass options via -append to control additional aspects of the test: - "page" flush each page in turn (one per function) - "self" do the flush after each computation cycle - "verbose" report progress on each computation cycle Signed-off-by: Alex Bennée CC: Mark Rutland Message-Id: <20211118184650.661575-7-alex.bennee@linaro.org> --- v9 - move tests back into unittests.cfg (with nodefault mttcg) - replace printf with report_info - drop accel = tcg --- arm/Makefile.common | 1 + arm/tlbflush-code.c | 209 ++++++++++++++++++++++++++++++++++++++++++++ arm/unittests.cfg | 25 ++++++ 3 files changed, 235 insertions(+) create mode 100644 arm/tlbflush-code.c diff --git a/arm/Makefile.common b/arm/Makefile.common index 16f8c6df..2c4aad38 100644 --- a/arm/Makefile.common +++ b/arm/Makefile.common @@ -12,6 +12,7 @@ tests-common += $(TEST_DIR)/gic.flat tests-common += $(TEST_DIR)/psci.flat tests-common += $(TEST_DIR)/sieve.flat tests-common += $(TEST_DIR)/pl031.flat +tests-common += $(TEST_DIR)/tlbflush-code.flat tests-all = $(tests-common) $(tests) all: directories $(tests-all) diff --git a/arm/tlbflush-code.c b/arm/tlbflush-code.c new file mode 100644 index 00000000..bf9eb111 --- /dev/null +++ b/arm/tlbflush-code.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * TLB Flush Race Tests + * + * These tests are designed to test for incorrect TLB flush semantics + * under emulation. The initial CPU will set all the others working a + * compuation task and will then trigger TLB flushes across the + * system. It doesn't actually need to re-map anything but the flushes + * themselves will trigger QEMU's TCG self-modifying code detection + * which will invalidate any generated code causing re-translation. + * Eventually the code buffer will fill and a general tb_lush() will + * be triggered. + * + * Copyright (C) 2016-2021, Linaro, Alex Bennée + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ + +#include +#include +#include +#include +#include + +#define SEQ_LENGTH 10 +#define SEQ_HASH 0x7cd707fe + +static cpumask_t smp_test_complete; +static int flush_count = 1000000; +static bool flush_self; +static bool flush_page; +static bool flush_verbose; + +/* + * Work functions + * + * These work functions need to be: + * + * - page aligned, so we can flush one function at a time + * - have branches, so QEMU TCG generates multiple basic blocks + * - call across pages, so we exercise the TCG basic block slow path + */ + +/* Adler32 */ +__attribute__((aligned(PAGE_SIZE))) static +uint32_t hash_array(const void *buf, size_t buflen) +{ + const uint8_t *data = (uint8_t *) buf; + uint32_t s1 = 1; + uint32_t s2 = 0; + + for (size_t n = 0; n < buflen; n++) { + s1 = (s1 + data[n]) % 65521; + s2 = (s2 + s1) % 65521; + } + return (s2 << 16) | s1; +} + +__attribute__((aligned(PAGE_SIZE))) static +void create_fib_sequence(int length, unsigned int *array) +{ + int i; + + /* first two values */ + array[0] = 0; + array[1] = 1; + for (i = 2; i < length; i++) + array[i] = array[i-2] + array[i-1]; +} + +__attribute__((aligned(PAGE_SIZE))) static +unsigned long long factorial(unsigned int n) +{ + unsigned int i; + unsigned long long fac = 1; + + for (i = 1; i <= n; i++) + fac = fac * i; + return fac; +} + +__attribute__((aligned(PAGE_SIZE))) static +void factorial_array(unsigned int n, unsigned int *input, + unsigned long long *output) +{ + unsigned int i; + + for (i = 0; i < n; i++) + output[i] = factorial(input[i]); +} + +__attribute__((aligned(PAGE_SIZE))) static +unsigned int do_computation(void) +{ + unsigned int fib_array[SEQ_LENGTH]; + unsigned long long facfib_array[SEQ_LENGTH]; + uint32_t fib_hash, facfib_hash; + + create_fib_sequence(SEQ_LENGTH, &fib_array[0]); + fib_hash = hash_array(&fib_array[0], sizeof(fib_array)); + factorial_array(SEQ_LENGTH, &fib_array[0], &facfib_array[0]); + facfib_hash = hash_array(&facfib_array[0], sizeof(facfib_array)); + + return (fib_hash ^ facfib_hash); +} + +/* This provides a table of the work functions so we can flush each + * page individually + */ +static void *pages[] = {&hash_array, &create_fib_sequence, &factorial, + &factorial_array, &do_computation}; + +static void do_flush(int i) +{ + if (flush_page) + flush_tlb_page((unsigned long)pages[i % ARRAY_SIZE(pages)]); + else + flush_tlb_all(); +} + + +static void just_compute(void) +{ + int i, errors = 0; + int cpu = smp_processor_id(); + + uint32_t result; + + report_info("CPU%d online", cpu); + + for (i = 0 ; i < flush_count; i++) { + result = do_computation(); + + if (result != SEQ_HASH) { + errors++; + report_info("CPU%d: seq%d 0x%"PRIx32"!=0x%x", + cpu, i, result, SEQ_HASH); + } + + if (flush_verbose && (i % 1000) == 0) + report_info("CPU%d: seq%d", cpu, i); + + if (flush_self) + do_flush(i); + } + + report(errors == 0, "CPU%d: Done - Errors: %d", cpu, errors); + + cpumask_set_cpu(cpu, &smp_test_complete); + if (cpu != 0) + halt(); +} + +static void just_flush(void) +{ + int cpu = smp_processor_id(); + int i = 0; + + /* + * Set our CPU as done, keep flushing until everyone else + * finished + */ + cpumask_set_cpu(cpu, &smp_test_complete); + + while (!cpumask_full(&smp_test_complete)) + do_flush(i++); + + report_info("CPU%d: Done - Triggered %d flushes", cpu, i); +} + +int main(int argc, char **argv) +{ + int cpu, i; + char prefix[100]; + + for (i = 0; i < argc; i++) { + char *arg = argv[i]; + + if (strcmp(arg, "page") == 0) + flush_page = true; + + if (strcmp(arg, "self") == 0) + flush_self = true; + + if (strcmp(arg, "verbose") == 0) + flush_verbose = true; + } + + snprintf(prefix, sizeof(prefix), "tlbflush_%s_%s", + flush_page ? "page" : "all", + flush_self ? "self" : "other"); + report_prefix_push(prefix); + + for_each_present_cpu(cpu) { + if (cpu == 0) + continue; + smp_boot_secondary(cpu, just_compute); + } + + if (flush_self) + just_compute(); + else + just_flush(); + + while (!cpumask_full(&smp_test_complete)) + cpu_relax(); + + return report_summary(); +} diff --git a/arm/unittests.cfg b/arm/unittests.cfg index 5e67b558..ee21aef4 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -275,3 +275,28 @@ file = debug.flat arch = arm64 extra_params = -append 'ss-migration' groups = debug migration + +# TLB Torture Tests +[tlbflush-code::all_other] +file = tlbflush-code.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +groups = nodefault mttcg + +[tlbflush-code::page_other] +file = tlbflush-code.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'page' +groups = nodefault mttcg + +[tlbflush-code::all_self] +file = tlbflush-code.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'self' +groups = nodefault mttcg + +[tlbflush-code::page_self] +file = tlbflush-code.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'page self' +groups = nodefault mttcg + From patchwork Tue Mar 7 11:28:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 659741 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c6:0:0:0:0:0 with SMTP id m6csp2337321wrb; Tue, 7 Mar 2023 03:30:25 -0800 (PST) X-Google-Smtp-Source: AK7set8EvDVnbOsoif9ynjHtEQivqqS95YaOF4a7bItjVrgeTrnQvE/sNXlrAbRHt0i1k1ES2kP6 X-Received: by 2002:a05:622a:178a:b0:3b9:b6e3:c78e with SMTP id s10-20020a05622a178a00b003b9b6e3c78emr21443888qtk.8.1678188625161; Tue, 07 Mar 2023 03:30:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678188625; cv=none; d=google.com; s=arc-20160816; b=qXa48YWjAmxHuEvivDM0zFFizfJW4wLAQeChDTW8RsNRa0sPE+Qh3yJecMX5evzMMR H6BBzsgacATmdp8Yyi/vL22tKUAo3Mzt0AycsdJ9bMCHaKDfXzuKkl6BjuG57ZGou1TM ET2Xqh9f0TmZNrLGad0KYZL1vP21lVBOc7fARzGr5Qq24Kp7CdDof/UkyL2fLDQy/ZYl iwzGGo8Pg2/LX3N5ZYQp4otKI2OhXS8bMcXBVl++wFosh5LPRxVWSNg3O80OKQv22jBZ 43tp7cwERLtztGgUhP5opJY9/CMD+ZFgHPKskGzEs0KLHimQoBJRPpVMCS3l4UklxWwX gZPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=cRctlh9akpwrufJyXwUzP4xfjZlbVf4MGU45m1EN2tU=; b=GYJRyGqCKFHCSRjnlYyFGQ92caIw4gwFlSJupgO95fEB+Zs+3iZBMU+4rTjt0Oa6pq +BhRNxyDkJ4KBJCr2opX7sBoHS0XmbFFKDESd5eaS5mwrlbRgLI8M5RoRiFcsOnczijY tdQKl1uEMZt+XTI5uqiIMzwzZvHvs9wKZOsz1b/BnXQXVLKlEZvt2Kp4rZCoW5ElHTGZ WUbvP0DOCnB0e/DJ2jZKkKQsPFjniLYeRfU0Kql8WiqdV2UTOlfDhUU6AcorLwi6a6+g S9G+hgWhII9ZFmgueqR8A8yTTiP8wKyzUD7SxYj1/fx6P6PeOaTgskTGmiZU0OuPOuoI T6mQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Mlva9JTN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id r22-20020ac85c96000000b003b9ba906cb4si9772485qta.538.2023.03.07.03.30.24 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Mar 2023 03:30:25 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Mlva9JTN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZVVH-0007bT-FI; Tue, 07 Mar 2023 06:29:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZVV4-0007PU-1D for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:59 -0500 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pZVUv-0005gt-Un for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:54 -0500 Received: by mail-wr1-x430.google.com with SMTP id l1so11718363wry.12 for ; Tue, 07 Mar 2023 03:28:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678188528; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cRctlh9akpwrufJyXwUzP4xfjZlbVf4MGU45m1EN2tU=; b=Mlva9JTNZLWZRHBNBeHk+cT30qPYw6xL4GCywJpoKQ39cj61DvxQM5ST1EogoZ1AlT nO1YkZNmhHZ9TV/Sl4dUvWkWJl1a3Ngh41mCGAmsS5bKdeDG1yJMT2fJZDF4Og6vJ9jM 2q6oUJd1Pikf0Rylc1HrDXP46aStPgMwWnbXp128aL1Dhnzv/u1XWh9t/am/xof0z/rE 33SdVhqxUBG6q8eMzAJB8cY3GtJiHhzamD47sv9w9aqEP4rj7pfzfPqcLQOFlE0MjSGA oKcae72YlHbzJq8rRtNimGfhnK3CfnSUzE8/+j8d1X0C1so9X0Fi1VJUtPwsqE+5XjH5 ClLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678188528; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cRctlh9akpwrufJyXwUzP4xfjZlbVf4MGU45m1EN2tU=; b=ZtXz2LaeJSPehDO9zOXjrqApPwj2xSLe3MHKfqVdj4NC0dCrnAULz0uPQlOMrEdc2q wy7t7+UQLqsqKzzi5JI+Ej5JJ56mQ6I9oSIZWganAyY88IeF+IDTW44ZSG9bWPR0kSER 6a+VHNpZvPTWQtqm57NKHovZqvfS6CgWQBvkUJmXubH1fi7oidS/oCpxn1RNzuUwWAso EzBcpq2xrDiV55Kal0ZkMzTIu+cho+N98PLU9EZG1Z5U596AA0r6JkA2y7Sdbs0pSH/C ERnRWWjbpda4TUupY7PSsuJ2Yj9+QoKKIAJBQ9FHgvmTSNhc6YDRrfGFqP3d7CQHZPDL Uczg== X-Gm-Message-State: AO0yUKXcQGjXzdrM1ALgZWwekWv/ZXTAtRyfEQgWnZsKsnSXX85TDTsr atgDi+VT6nIW/vWUQb293pWDsw== X-Received: by 2002:a5d:614d:0:b0:2c7:d6a:cca9 with SMTP id y13-20020a5d614d000000b002c70d6acca9mr9240330wrt.23.1678188527744; Tue, 07 Mar 2023 03:28:47 -0800 (PST) Received: from zen.linaroharston ([85.9.250.243]) by smtp.gmail.com with ESMTPSA id r22-20020a05600c435600b003eae73ee4a1sm12716650wme.17.2023.03.07.03.28.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 03:28:47 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 02F431FFBD; Tue, 7 Mar 2023 11:28:46 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Thomas Huth , Andrew Jones , Paolo Bonzini , kvmarm@lists.linux.dev, qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [kvm-unit-tests PATCH v10 5/7] arm/locking-tests: add comprehensive locking test Date: Tue, 7 Mar 2023 11:28:43 +0000 Message-Id: <20230307112845.452053-6-alex.bennee@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230307112845.452053-1-alex.bennee@linaro.org> References: <20230307112845.452053-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org This test has been written mainly to stress multi-threaded TCG behaviour but will demonstrate failure by default on real hardware. The test takes the following parameters: - "lock" use GCC's locking semantics - "atomic" use GCC's __atomic primitives - "wfelock" use WaitForEvent sleep - "excl" use load/store exclusive semantics Also two more options allow the test to be tweaked - "noshuffle" disables the memory shuffling - "count=%ld" set your own per-CPU increment count Signed-off-by: Alex Bennée Message-Id: <20211118184650.661575-8-alex.bennee@linaro.org> --- v9 - move back to unittests.cfg, drop accel=tcg - s/printf/report_info v10 - dropped spare extra line in shuffle_memory --- arm/Makefile.common | 2 +- arm/locking-test.c | 321 ++++++++++++++++++++++++++++++++++++++++++++ arm/spinlock-test.c | 87 ------------ arm/unittests.cfg | 30 +++++ 4 files changed, 352 insertions(+), 88 deletions(-) create mode 100644 arm/locking-test.c delete mode 100644 arm/spinlock-test.c diff --git a/arm/Makefile.common b/arm/Makefile.common index 2c4aad38..3089e3bf 100644 --- a/arm/Makefile.common +++ b/arm/Makefile.common @@ -5,7 +5,6 @@ # tests-common = $(TEST_DIR)/selftest.flat -tests-common += $(TEST_DIR)/spinlock-test.flat tests-common += $(TEST_DIR)/pci-test.flat tests-common += $(TEST_DIR)/pmu.flat tests-common += $(TEST_DIR)/gic.flat @@ -13,6 +12,7 @@ tests-common += $(TEST_DIR)/psci.flat tests-common += $(TEST_DIR)/sieve.flat tests-common += $(TEST_DIR)/pl031.flat tests-common += $(TEST_DIR)/tlbflush-code.flat +tests-common += $(TEST_DIR)/locking-test.flat tests-all = $(tests-common) $(tests) all: directories $(tests-all) diff --git a/arm/locking-test.c b/arm/locking-test.c new file mode 100644 index 00000000..a49c2fd1 --- /dev/null +++ b/arm/locking-test.c @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Locking Test + * + * This test allows us to stress the various atomic primitives of a VM + * guest. A number of methods are available that use various patterns + * to implement a lock. + * + * Copyright (C) 2017 Linaro + * Author: Alex Bennée + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include + +#define MAX_CPUS 8 + +/* Test definition structure + * + * A simple structure that describes the test name, expected pass and + * increment function. + */ + +/* Function pointers for test */ +typedef void (*inc_fn)(int cpu); + +typedef struct { + const char *test_name; + bool should_pass; + inc_fn main_fn; +} test_descr_t; + +/* How many increments to do */ +static int increment_count = 1000000; +static bool do_shuffle = true; + +/* Shared value all the tests attempt to safely increment using + * various forms of atomic locking and exclusive behaviour. + */ +static unsigned int shared_value; + +/* PAGE_SIZE * uint32_t means we span several pages */ +__attribute__((aligned(PAGE_SIZE))) static uint32_t memory_array[PAGE_SIZE]; + +/* We use the alignment of the following to ensure accesses to locking + * and synchronisation primatives don't interfere with the page of the + * shared value + */ +__attribute__((aligned(PAGE_SIZE))) static unsigned int per_cpu_value[MAX_CPUS]; +__attribute__((aligned(PAGE_SIZE))) static cpumask_t smp_test_complete; +__attribute__((aligned(PAGE_SIZE))) struct isaac_ctx prng_context[MAX_CPUS]; + +/* Some of the approaches use a global lock to prevent contention. */ +static int global_lock; + +/* In any SMP setting this *should* fail due to cores stepping on + * each other updating the shared variable + */ +static void increment_shared(int cpu) +{ + (void)cpu; + + shared_value++; +} + +/* GCC __sync primitives are deprecated in favour of __atomic */ +static void increment_shared_with_lock(int cpu) +{ + (void)cpu; + + while (__sync_lock_test_and_set(&global_lock, 1)); + + shared_value++; + + __sync_lock_release(&global_lock); +} + +/* + * In practice even __ATOMIC_RELAXED uses ARM's ldxr/stex exclusive + * semantics + */ +static void increment_shared_with_atomic(int cpu) +{ + (void)cpu; + + __atomic_add_fetch(&shared_value, 1, __ATOMIC_SEQ_CST); +} + + +/* + * Load/store exclusive with WFE (wait-for-event) + * + * See ARMv8 ARM examples: + * Use of Wait For Event (WFE) and Send Event (SEV) with locks + */ + +static void increment_shared_with_wfelock(int cpu) +{ + (void)cpu; + +#if defined(__aarch64__) + asm volatile( + " mov w1, #1\n" + " sevl\n" + " prfm PSTL1KEEP, [%[lock]]\n" + "1: wfe\n" + " ldaxr w0, [%[lock]]\n" + " cbnz w0, 1b\n" + " stxr w0, w1, [%[lock]]\n" + " cbnz w0, 1b\n" + /* lock held */ + " ldr w0, [%[sptr]]\n" + " add w0, w0, #0x1\n" + " str w0, [%[sptr]]\n" + /* now release */ + " stlr wzr, [%[lock]]\n" + : /* out */ + : [lock] "r" (&global_lock), [sptr] "r" (&shared_value) /* in */ + : "w0", "w1", "cc"); +#else + asm volatile( + " mov r1, #1\n" + "1: ldrex r0, [%[lock]]\n" + " cmp r0, #0\n" + " wfene\n" + " strexeq r0, r1, [%[lock]]\n" + " cmpeq r0, #0\n" + " bne 1b\n" + " dmb\n" + /* lock held */ + " ldr r0, [%[sptr]]\n" + " add r0, r0, #0x1\n" + " str r0, [%[sptr]]\n" + /* now release */ + " mov r0, #0\n" + " dmb\n" + " str r0, [%[lock]]\n" + " dsb\n" + " sev\n" + : /* out */ + : [lock] "r" (&global_lock), [sptr] "r" (&shared_value) /* in */ + : "r0", "r1", "cc"); +#endif +} + + +/* + * Hand-written version of the load/store exclusive + */ +static void increment_shared_with_excl(int cpu) +{ + (void)cpu; + +#if defined(__aarch64__) + asm volatile( + "1: ldxr w0, [%[sptr]]\n" + " add w0, w0, #0x1\n" + " stxr w1, w0, [%[sptr]]\n" + " cbnz w1, 1b\n" + : /* out */ + : [sptr] "r" (&shared_value) /* in */ + : "w0", "w1", "cc"); +#else + asm volatile( + "1: ldrex r0, [%[sptr]]\n" + " add r0, r0, #0x1\n" + " strex r1, r0, [%[sptr]]\n" + " cmp r1, #0\n" + " bne 1b\n" + : /* out */ + : [sptr] "r" (&shared_value) /* in */ + : "r0", "r1", "cc"); +#endif +} + +/* Test array */ +static test_descr_t tests[] = { + { "none", false, increment_shared }, + { "lock", true, increment_shared_with_lock }, + { "atomic", true, increment_shared_with_atomic }, + { "wfelock", true, increment_shared_with_wfelock }, + { "excl", true, increment_shared_with_excl } +}; + +/* The idea of this is just to generate some random load/store + * activity which may or may not race with an un-barried incremented + * of the shared counter + */ +static void shuffle_memory(int cpu) +{ + int i; + uint32_t lspat = isaac_next_uint32(&prng_context[cpu]); + uint32_t seq = isaac_next_uint32(&prng_context[cpu]); + int count = seq & 0x1f; + uint32_t val = 0; + + seq >>= 5; + + for (i = 0; i < count; i++) { + int index = seq & ~PAGE_MASK; + + if (lspat & 1) + val ^= memory_array[index]; + else + memory_array[index] = val; + + seq >>= PAGE_SHIFT; + seq ^= lspat; + lspat >>= 1; + } +} + +static inc_fn increment_function; + +static void do_increment(void) +{ + int i; + int cpu = smp_processor_id(); + + report_info("CPU%d: online and ++ing", cpu); + + for (i = 0; i < increment_count; i++) { + per_cpu_value[cpu]++; + increment_function(cpu); + + if (do_shuffle) + shuffle_memory(cpu); + } + + report_info("CPU%d: Done, %d incs\n", cpu, per_cpu_value[cpu]); + + cpumask_set_cpu(cpu, &smp_test_complete); + if (cpu != 0) + halt(); +} + +static void setup_and_run_test(test_descr_t *test) +{ + unsigned int i, sum = 0; + int cpu, cpu_cnt = 0; + + increment_function = test->main_fn; + + /* fill our random page */ + for (i = 0; i < PAGE_SIZE; i++) + memory_array[i] = isaac_next_uint32(&prng_context[0]); + + for_each_present_cpu(cpu) { + uint32_t seed2 = isaac_next_uint32(&prng_context[0]); + + cpu_cnt++; + if (cpu == 0) + continue; + + isaac_init(&prng_context[cpu], (unsigned char *) &seed2, sizeof(seed2)); + smp_boot_secondary(cpu, do_increment); + } + + do_increment(); + + while (!cpumask_full(&smp_test_complete)) + cpu_relax(); + + /* All CPUs done, do we add up */ + for_each_present_cpu(cpu) { + sum += per_cpu_value[cpu]; + } + + if (test->should_pass) + report(sum == shared_value, "total incs %d", shared_value); + else + report_xfail(true, sum == shared_value, "total incs %d", shared_value); +} + +int main(int argc, char **argv) +{ + static const unsigned char seed[] = "myseed"; + test_descr_t *test = &tests[0]; + int i; + unsigned int j; + + isaac_init(&prng_context[0], &seed[0], sizeof(seed)); + + for (i = 0; i < argc; i++) { + char *arg = argv[i]; + + /* Check for test name */ + for (j = 0; j < ARRAY_SIZE(tests); j++) { + if (strcmp(arg, tests[j].test_name) == 0) + test = &tests[j]; + } + + /* Test modifiers */ + if (strcmp(arg, "noshuffle") == 0) { + do_shuffle = false; + report_prefix_push("noshuffle"); + } else if (strstr(arg, "count=") != NULL) { + char *p = strstr(arg, "="); + + increment_count = atol(p+1); + } else { + isaac_reseed(&prng_context[0], (unsigned char *) arg, strlen(arg)); + } + } + + if (test) + setup_and_run_test(test); + else + report(false, "Unknown test"); + + return report_summary(); +} diff --git a/arm/spinlock-test.c b/arm/spinlock-test.c deleted file mode 100644 index 73aea76a..00000000 --- a/arm/spinlock-test.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Spinlock test - * - * This code is based on code from the tcg_baremetal_tests. - * - * Copyright (C) 2015 Virtual Open Systems SAS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -#define LOOP_SIZE 10000000 - -struct lock_ops { - void (*lock)(int *v); - void (*unlock)(int *v); -}; -static struct lock_ops lock_ops; - -static void gcc_builtin_lock(int *lock_var) -{ - while (__sync_lock_test_and_set(lock_var, 1)); -} -static void gcc_builtin_unlock(int *lock_var) -{ - __sync_lock_release(lock_var); -} -static void none_lock(int *lock_var) -{ - while (*(volatile int *)lock_var != 0); - *(volatile int *)lock_var = 1; -} -static void none_unlock(int *lock_var) -{ - *(volatile int *)lock_var = 0; -} - -static int global_a, global_b; -static int global_lock; - -static void test_spinlock(void *data __unused) -{ - int i, errors = 0; - int cpu = smp_processor_id(); - - printf("CPU%d online\n", cpu); - - for (i = 0; i < LOOP_SIZE; i++) { - - lock_ops.lock(&global_lock); - - if (global_a == (cpu + 1) % 2) { - global_a = 1; - global_b = 0; - } else { - global_a = 0; - global_b = 1; - } - - if (global_a == global_b) - errors++; - - lock_ops.unlock(&global_lock); - } - report(errors == 0, "CPU%d: Done - Errors: %d", cpu, errors); -} - -int main(int argc, char **argv) -{ - report_prefix_push("spinlock"); - if (argc > 1 && strcmp(argv[1], "bad") != 0) { - lock_ops.lock = gcc_builtin_lock; - lock_ops.unlock = gcc_builtin_unlock; - } else { - lock_ops.lock = none_lock; - lock_ops.unlock = none_unlock; - } - - on_cpus(test_spinlock, NULL); - - return report_summary(); -} diff --git a/arm/unittests.cfg b/arm/unittests.cfg index ee21aef4..45ac61c8 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -300,3 +300,33 @@ smp = $(($MAX_SMP>4?4:$MAX_SMP)) extra_params = -append 'page self' groups = nodefault mttcg +# Locking tests +[locking::none] +file = locking-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +groups = nodefault mttcg locking + +[locking::lock] +file = locking-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'lock' +groups = nodefault mttcg locking + +[locking::atomic] +file = locking-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'atomic' +groups = nodefault mttcg locking + +[locking::wfelock] +file = locking-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'wfelock' +groups = nodefault mttcg locking + +[locking::excl] +file = locking-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'excl' +groups = nodefault mttcg locking + From patchwork Tue Mar 7 11:28:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 659739 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c6:0:0:0:0:0 with SMTP id m6csp2337210wrb; Tue, 7 Mar 2023 03:30:12 -0800 (PST) X-Google-Smtp-Source: AK7set/Y8DkpmZ2sgODlX9Btmcjy6psv+LViMvkRhduoDoKg3D+VqtDdOngfSe4FlCalnKRqoXl0 X-Received: by 2002:ac8:5c90:0:b0:3b6:9c63:5ca1 with SMTP id r16-20020ac85c90000000b003b69c635ca1mr23896449qta.43.1678188612352; Tue, 07 Mar 2023 03:30:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678188612; cv=none; d=google.com; s=arc-20160816; b=AyO8dExY78/gpXpEAy3ap/80G0TMYLMe56REAb2v8CeSzO96kj4zpwfwJJclNNFna4 5FjjFTWayBeQCVnXVIoO7YuEffrCgYIRJKTMDMmiN/ykYG+PkblheJ0CaluD+f9oW7W2 yJLuyWlv3hnByUsPvsKkIjfzyFX0P1ez+oqOVaiMsweXC6rq1yuwVpPFmRjd/I/HjsnH rpPLZeTL5JgY9Dm2s3CaQPOy6AZ4vgsaGZLuj87uFnFchw9cBVAwAehEWw7Qi7guJzn5 0E/I/oB8O+nqAhA715XyRAJdBfhLggU7CYiwcm+L35X2zgdOqNQfVWoaUOcBJx1/WYvq cWmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=zvU4odtmFG0yriCdCjX1llQlR53t2clwEw3b2MaCF30=; b=mpA3E6NHzxS41SipxfoMo6cAR8lq2euSsTVLT5leAmsNwDaaSwaUhEgFbxHSatMKA/ PxrvNtRBvm6BAvkG4lpTcNNEAesXBa3v6MOziIGxOezj1TViJizzY+iWHc1cqb+qAB0g zXHIvwZ/lCEy9GLkMDclVhyu/JfS+Q2/gfu+xV3ZHa155223irNqYvm1mqpUhHLuxd6Z bRryiEYhReceeXsZl6aXZobM/2ZHeoj+BgtfvrIY64KqZ1ukKMAPsDCmAaMxAzJKOjtl fuVR4ijLRIbCp7ZPPDkvCGcv4daXKKBlkJGHwWpuMmceSGFtOa/PWz1OhQWVJth9JrWk yzAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GCUZMqJd; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id v10-20020ac8578a000000b003a689910c02si9799262qta.746.2023.03.07.03.30.12 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Mar 2023 03:30:12 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GCUZMqJd; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZVVG-0007at-RC; Tue, 07 Mar 2023 06:29:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZVV3-0007PR-W4 for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:59 -0500 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pZVUw-0005hJ-3c for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:56 -0500 Received: by mail-wr1-x431.google.com with SMTP id e13so11732683wro.10 for ; Tue, 07 Mar 2023 03:28:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678188529; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zvU4odtmFG0yriCdCjX1llQlR53t2clwEw3b2MaCF30=; b=GCUZMqJdfw1a7fk1JDHPv+Htzinnh8j+FRq/z4hykmiROq+bXKtGu8omqQJ1dGn545 1zTEOPOHtwlskLuy4D+kJzonfs6zkylh1LLzcv+J+KjIyCw9YgegHBlURpSI7qN7MGeC 8cAsHB1UoSeeizX7gut65eRhL0kjcQAEmYZeSb2T5wKVZhOLD9G56pwsgVo8g6IVTZEi RfWKleFSAZxZzUCgBRvdzdkwXpQzxnM132P4DfgXvv50FkVOsheNqOZRHxrWsYHlLziT H6GH/5kf94Tz2Yw0L1ZRtdMGetLuE7ee+c5ke63iiSosvf2+Y0DSPaGui3QS4FX4ZZg1 nS6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678188529; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zvU4odtmFG0yriCdCjX1llQlR53t2clwEw3b2MaCF30=; b=u/lNsUfmBJQW0kgGGICxO3fhh4mtDF4E03Uj5Wyh8qB0SlsC01kp/K0K/KurZFldq5 yPyZBvTmE2H1ncOePkR9IryCLnvMvkkEUDwQOAwgGhqkJq7meuBhdD1mB2oPoSRGJlzO JHOZi14S8rh8LapmSMo+/So53UZQMqcw6UC7OB0/WLrxm5E3bXq82nDoCJzQKf2Fzlej OSivohPBlPjw9GtLdjMzQBT8eA8wA4ySySyQ/W6tdcxjDDGauLxZLQj4F/3CaiVJp4D2 QZGlMRMYK5HiMk/tPhs44Y5CAyRf8RgEASqK+SH6aEW1suVM9K45rA7thtVrplV9xdv3 TG1g== X-Gm-Message-State: AO0yUKV73AGIM7uZ5M8K8iIiTCv3G8t6lulaUOgcPVtMo5hdhSdIVnls nMLGEFrT5f/8NE2iAsGdE3sLpw== X-Received: by 2002:a5d:45c2:0:b0:2c7:1b4c:da75 with SMTP id b2-20020a5d45c2000000b002c71b4cda75mr8599072wrs.69.1678188528647; Tue, 07 Mar 2023 03:28:48 -0800 (PST) Received: from zen.linaroharston ([85.9.250.243]) by smtp.gmail.com with ESMTPSA id o1-20020a5d4081000000b002c71a32394dsm12415137wrp.64.2023.03.07.03.28.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 03:28:47 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 18A801FFBE; Tue, 7 Mar 2023 11:28:46 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Thomas Huth , Andrew Jones , Paolo Bonzini , kvmarm@lists.linux.dev, qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Will Deacon Subject: [kvm-unit-tests PATCH v10 6/7] arm/barrier-litmus-tests: add simple mp and sal litmus tests Date: Tue, 7 Mar 2023 11:28:44 +0000 Message-Id: <20230307112845.452053-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230307112845.452053-1-alex.bennee@linaro.org> References: <20230307112845.452053-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org This adds a framework for adding simple barrier litmus tests against ARM. The litmus tests aren't as comprehensive as the academic exercises which will attempt to do all sorts of things to keep racing CPUs synced up. These tests do honour the "sync" parameter to do a poor-mans equivalent. The two litmus tests are: - message passing - store-after-load They both have case that should fail (although won't on single-threaded TCG setups). If barriers aren't working properly the store-after-load test will fail even on an x86 backend as x86 allows re-ording of non aliased stores. I've imported a few more of the barrier primatives from the Linux source tree so we consistently use macros. The arm64 barrier primitives trip up on -Wstrict-aliasing so this is disabled in the Makefile. Signed-off-by: Alex Bennée CC: Will Deacon Message-Id: <20211118184650.661575-9-alex.bennee@linaro.org> --- v9 - return to unittests.cfg, drop accel=tcg - use compiler.h for barriers instead of defining outselves - s/printf/report_info/ v10 - use compiler WRITE/READ_ONCE macros --- arm/Makefile.common | 1 + lib/arm/asm/barrier.h | 19 ++ lib/arm64/asm/barrier.h | 50 +++++ arm/barrier-litmus-test.c | 450 ++++++++++++++++++++++++++++++++++++++ arm/unittests.cfg | 31 +++ 5 files changed, 551 insertions(+) create mode 100644 arm/barrier-litmus-test.c diff --git a/arm/Makefile.common b/arm/Makefile.common index 3089e3bf..0a2bdcfc 100644 --- a/arm/Makefile.common +++ b/arm/Makefile.common @@ -13,6 +13,7 @@ tests-common += $(TEST_DIR)/sieve.flat tests-common += $(TEST_DIR)/pl031.flat tests-common += $(TEST_DIR)/tlbflush-code.flat tests-common += $(TEST_DIR)/locking-test.flat +tests-common += $(TEST_DIR)/barrier-litmus-test.flat tests-all = $(tests-common) $(tests) all: directories $(tests-all) diff --git a/lib/arm/asm/barrier.h b/lib/arm/asm/barrier.h index 7f868314..0f3670b8 100644 --- a/lib/arm/asm/barrier.h +++ b/lib/arm/asm/barrier.h @@ -8,6 +8,9 @@ * This work is licensed under the terms of the GNU GPL, version 2. */ +#include +#include + #define sev() asm volatile("sev" : : : "memory") #define wfe() asm volatile("wfe" : : : "memory") #define wfi() asm volatile("wfi" : : : "memory") @@ -25,4 +28,20 @@ #define smp_rmb() smp_mb() #define smp_wmb() dmb(ishst) +extern void abort(void); + +#define smp_store_release(p, v) \ +do { \ + smp_mb(); \ + WRITE_ONCE(*p, v); \ +} while (0) + + +#define smp_load_acquire(p) \ +({ \ + typeof(*p) ___p1 = READ_ONCE(*p); \ + smp_mb(); \ + ___p1; \ +}) + #endif /* _ASMARM_BARRIER_H_ */ diff --git a/lib/arm64/asm/barrier.h b/lib/arm64/asm/barrier.h index 0e1904cf..5e405190 100644 --- a/lib/arm64/asm/barrier.h +++ b/lib/arm64/asm/barrier.h @@ -24,4 +24,54 @@ #define smp_rmb() dmb(ishld) #define smp_wmb() dmb(ishst) +#define smp_store_release(p, v) \ +do { \ + switch (sizeof(*p)) { \ + case 1: \ + asm volatile ("stlrb %w1, %0" \ + : "=Q" (*p) : "r" (v) : "memory"); \ + break; \ + case 2: \ + asm volatile ("stlrh %w1, %0" \ + : "=Q" (*p) : "r" (v) : "memory"); \ + break; \ + case 4: \ + asm volatile ("stlr %w1, %0" \ + : "=Q" (*p) : "r" (v) : "memory"); \ + break; \ + case 8: \ + asm volatile ("stlr %1, %0" \ + : "=Q" (*p) : "r" (v) : "memory"); \ + break; \ + } \ +} while (0) + +#define smp_load_acquire(p) \ +({ \ + union { typeof(*p) __val; char __c[1]; } __u; \ + switch (sizeof(*p)) { \ + case 1: \ + asm volatile ("ldarb %w0, %1" \ + : "=r" (*(u8 *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + case 2: \ + asm volatile ("ldarh %w0, %1" \ + : "=r" (*(u16 *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + case 4: \ + asm volatile ("ldar %w0, %1" \ + : "=r" (*(u32 *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + case 8: \ + asm volatile ("ldar %0, %1" \ + : "=r" (*(u64 *)__u.__c) \ + : "Q" (*p) : "memory"); \ + break; \ + } \ + __u.__val; \ +}) + #endif /* _ASMARM64_BARRIER_H_ */ diff --git a/arm/barrier-litmus-test.c b/arm/barrier-litmus-test.c new file mode 100644 index 00000000..5d7e61d1 --- /dev/null +++ b/arm/barrier-litmus-test.c @@ -0,0 +1,450 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * ARM Barrier Litmus Tests + * + * This test provides a framework for testing barrier conditions on + * the processor. It's simpler than the more involved barrier testing + * frameworks as we are looking for simple failures of QEMU's TCG not + * weird edge cases the silicon gets wrong. + */ + +#include +#include +#include +#include +#include + +#define MAX_CPUS 8 + +/* Array size and access controls */ +static int array_size = 100000; +static int wait_if_ahead; + +static cpumask_t cpu_mask; + +/* + * These test_array_* structures are a contiguous array modified by two or more + * competing CPUs. The padding is to ensure the variables do not share + * cache lines. + * + * All structures start zeroed. + */ + +typedef struct test_array { + volatile unsigned int x; + uint8_t dummy[64]; + volatile unsigned int y; + uint8_t dummy2[64]; + volatile unsigned int r[MAX_CPUS]; +} test_array; + +volatile test_array *array; + +/* Test definition structure + * + * The first function will always run on the primary CPU, it is + * usually the one that will detect any weirdness and trigger the + * failure of the test. + */ + +typedef void (*test_fn)(void); + +typedef struct { + const char *test_name; + bool should_pass; + test_fn main_fn; + test_fn secondary_fns[MAX_CPUS-1]; +} test_descr_t; + +/* Litmus tests */ + +static unsigned long sync_start(void) +{ + const unsigned long gate_mask = ~0x3ffff; + unsigned long gate, now; + + gate = get_cntvct() & gate_mask; + do { + now = get_cntvct(); + } while ((now & gate_mask) == gate); + + return now; +} + +/* Simple Message Passing + * + * x is the message data + * y is the flag to indicate the data is ready + * + * Reading x == 0 when y == 1 is a failure. + */ + +static void message_passing_write(void) +{ + int i; + + sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + + entry->x = 1; + entry->y = 1; + } + + halt(); +} + +static void message_passing_read(void) +{ + int i; + int errors = 0, ready = 0; + + sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + unsigned int x, y; + + y = entry->y; + x = entry->x; + + if (y && !x) + errors++; + ready += y; + } + + /* + * We expect this to fail but with STO backends you often get + * away with it. Fudge xfail if we did actually pass. + */ + report_xfail(errors == 0 ? false : true, errors == 0, + "mp: %d errors, %d ready", errors, ready); +} + +/* Simple Message Passing with barriers */ +static void message_passing_write_barrier(void) +{ + int i; + + sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + + entry->x = 1; + smp_wmb(); + entry->y = 1; + } + + halt(); +} + +static void message_passing_read_barrier(void) +{ + int i; + int errors = 0, ready = 0, not_ready = 0; + + sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + unsigned int x, y; + + y = entry->y; + smp_rmb(); + x = entry->x; + + if (y && !x) + errors++; + + if (y) { + ready++; + } else { + not_ready++; + + if (not_ready > 2) { + entry = &array[i+1]; + do { + not_ready = 0; + } while (wait_if_ahead && !entry->y); + } + } + } + + report(errors == 0, "mp barrier: %d errors, %d ready", errors, ready); +} + +/* Simple Message Passing with Acquire/Release */ +static void message_passing_write_release(void) +{ + int i; + + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + + entry->x = 1; + smp_store_release(&entry->y, 1); + } + + halt(); +} + +static void message_passing_read_acquire(void) +{ + int i; + int errors = 0, ready = 0, not_ready = 0; + + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + unsigned int x, y; + + y = smp_load_acquire(&entry->y); + x = entry->x; + + if (y && !x) + errors++; + + if (y) { + ready++; + } else { + not_ready++; + + if (not_ready > 2) { + entry = &array[i+1]; + do { + not_ready = 0; + } while (wait_if_ahead && !entry->y); + } + } + } + + report(errors == 0, "mp acqrel: %d errors, %d ready", errors, ready); +} + +/* + * Store after load + * + * T1: write 1 to x, load r from y + * T2: write 1 to y, load r from x + * + * Without memory fence r[0] && r[1] == 0 + * With memory fence both == 0 should be impossible + */ + +static void check_store_and_load_results(const char *name, int thread, + bool xfail, unsigned long start, + unsigned long end) +{ + int i; + int neither = 0; + int only_first = 0; + int only_second = 0; + int both = 0; + + for ( i= 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + + if (entry->r[0] == 0 && + entry->r[1] == 0) + neither++; + else if (entry->r[0] && + entry->r[1]) + both++; + else if (entry->r[0]) + only_first++; + else + only_second++; + } + + report_info("T%d: %08lx->%08lx neither=%d only_t1=%d only_t2=%d both=%d\n", + thread, start, end, neither, only_first, only_second, both); + + if (thread == 1) + report_xfail(xfail, neither==0, "%s: errors=%d", name, neither); + +} + +/* + * This attempts to synchronise the start of both threads to roughly + * the same time. On real hardware there is a little latency as the + * secondary vCPUs are powered up however this effect it much more + * exaggerated on a TCG host. + * + * Busy waits until the we pass a future point in time, returns final + * start time. + */ + +static void store_and_load_1(void) +{ + int i; + unsigned long start, end; + + start = sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + unsigned int r; + + entry->x = 1; + r = entry->y; + entry->r[0] = r; + } + end = get_cntvct(); + + smp_mb(); + + while (!cpumask_test_cpu(1, &cpu_mask)) + cpu_relax(); + + check_store_and_load_results("sal", 1, true, start, end); +} + +static void store_and_load_2(void) +{ + int i; + unsigned long start, end; + + start = sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + unsigned int r; + + entry->y = 1; + r = entry->x; + entry->r[1] = r; + } + end = get_cntvct(); + + check_store_and_load_results("sal", 2, true, start, end); + + cpumask_set_cpu(1, &cpu_mask); + + halt(); +} + +static void store_and_load_barrier_1(void) +{ + int i; + unsigned long start, end; + + start = sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + unsigned int r; + + entry->x = 1; + smp_mb(); + r = entry->y; + entry->r[0] = r; + } + end = get_cntvct(); + + smp_mb(); + + while (!cpumask_test_cpu(1, &cpu_mask)) + cpu_relax(); + + check_store_and_load_results("sal_barrier", 1, false, start, end); +} + +static void store_and_load_barrier_2(void) +{ + int i; + unsigned long start, end; + + start = sync_start(); + for (i = 0; i < array_size; i++) { + volatile test_array *entry = &array[i]; + unsigned int r; + + entry->y = 1; + smp_mb(); + r = entry->x; + entry->r[1] = r; + } + end = get_cntvct(); + + check_store_and_load_results("sal_barrier", 2, false, start, end); + + cpumask_set_cpu(1, &cpu_mask); + + halt(); +} + + +/* Test array */ +static test_descr_t tests[] = { + + { "mp", false, + message_passing_read, + { message_passing_write } + }, + + { "mp_barrier", true, + message_passing_read_barrier, + { message_passing_write_barrier } + }, + + { "mp_acqrel", true, + message_passing_read_acquire, + { message_passing_write_release } + }, + + { "sal", false, + store_and_load_1, + { store_and_load_2 } + }, + + { "sal_barrier", true, + store_and_load_barrier_1, + { store_and_load_barrier_2 } + }, +}; + + +static void setup_and_run_litmus(test_descr_t *test) +{ + array = calloc(array_size, sizeof(test_array)); + + if (array) { + int i = 0; + + report_info("Allocated test array @ %p", array); + + while (test->secondary_fns[i]) { + smp_boot_secondary(i+1, test->secondary_fns[i]); + i++; + } + + test->main_fn(); + } else + report(false, "%s: failed to allocate memory", test->test_name); +} + +int main(int argc, char **argv) +{ + int i; + unsigned int j; + test_descr_t *test = NULL; + + for (i = 0; i < argc; i++) { + char *arg = argv[i]; + + for (j = 0; j < ARRAY_SIZE(tests); j++) { + if (strcmp(arg, tests[j].test_name) == 0) + test = &tests[j]; + } + + /* Test modifiers */ + if (strstr(arg, "count=") != NULL) { + char *p = strstr(arg, "="); + + array_size = atol(p+1); + } else if (strcmp(arg, "wait") == 0) { + wait_if_ahead = 1; + } + } + + if (test) + setup_and_run_litmus(test); + else + report(false, "Unknown test"); + + return report_summary(); +} diff --git a/arm/unittests.cfg b/arm/unittests.cfg index 45ac61c8..3d73e308 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -330,3 +330,34 @@ smp = $(($MAX_SMP>4?4:$MAX_SMP)) extra_params = -append 'excl' groups = nodefault mttcg locking +# Barrier Litmus tests +[barrier-litmus::mp] +file = barrier-litmus-test.flat +smp = 2 +extra_params = -append 'mp' +groups = nodefault mttcg barrier + +[barrier-litmus::mp-barrier] +file = barrier-litmus-test.flat +smp = 2 +extra_params = -append 'mp_barrier' +groups = nodefault mttcg barrier + +[barrier-litmus::mp-acqrel] +file = barrier-litmus-test.flat +smp = 2 +extra_params = -append 'mp_acqrel' +groups = nodefault mttcg barrier + +[barrier-litmus::sal] +file = barrier-litmus-test.flat +smp = 2 +extra_params = -append 'sal' +groups = nodefault mttcg barrier + +[barrier-litmus::sal-barrier] +file = barrier-litmus-test.flat +smp = 2 +extra_params = -append 'sal_barrier' +groups = nodefault mttcg barrier + From patchwork Tue Mar 7 11:28:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 659737 Delivered-To: patch@linaro.org Received: by 2002:adf:a3c6:0:0:0:0:0 with SMTP id m6csp2337109wrb; Tue, 7 Mar 2023 03:30:00 -0800 (PST) X-Google-Smtp-Source: AK7set9bI7A4S5WCdD4DXXr4xS8i4GXq1pQHZPQBU5GV9VCuVIhkxOlocuqrA/rPYU7ECbBH4CKp X-Received: by 2002:a05:622a:206:b0:3b0:b9a4:a20f with SMTP id b6-20020a05622a020600b003b0b9a4a20fmr23665817qtx.4.1678188600080; Tue, 07 Mar 2023 03:30:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678188600; cv=none; d=google.com; s=arc-20160816; b=Ffn890KBrGWsOSViYkUVbtdH0nzKNi4fsmxSHUdGwE00uCz88ZoY4UydWVAIR6OdpK 5VQyW0/gfkRFaSgp+3GYEVQA5bwwRJjfb+m6QUUiSVhxFVv2sgBXii6qZ4O2NW0WrX0Q MiC5456R57UX1rcEs2El1QCo3paD8GxypGmUlFU5pvONFqHZiJmxi0ctULRVANocJOon yrAxA83LEgvtgemwQz8rkpUitJ4eVo6nprJmlKlqj2N1rdPgrX996mtQ4zLv5kpz773W P3FtJ2ve1l3W5ib1o6bnIZh/hwFn3wieOEQYpOGRHwRkIgyHwx/j93Y0LSBKZUMe8mdO fmhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=09uqZm0w18GChoUZWmG8uQ1lR/P11PH+uuK+IHEB5NE=; b=yutUSFaAn+BQQ5vXb4DBZmuU3/XGcLFdmc/CT7UrQcQJEKQb9mOrxVekZPLOhKCqU+ h/v7s482tFeM6gFyunDstkgChUlsjGxP0/Dtl3sHYbm75OWCaFFfx2RnO8EM17xLnH7v aj5eXU1pyzc6R+8H0zgIM0hmAZhe/oOxI1piYv9ri/u/qIIyBEp/ONfJHOCsngDb+0MQ T62tagO5TpO6WHeRJ04Y2kekD+qPBPzy0HFW/CjoHPg/kAsfPRI08JxVTseLYAv6IFpu yrKUHXGQgR0iXYEUaWqFA0a9FpTqc+Sf63KVHCdl5okmE2GOkTqQR9tsF6KhqJ8mtPHl 3YYA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OSOYkBjI; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id m19-20020a05622a055300b003b859f1e967si9372746qtx.176.2023.03.07.03.29.59 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Mar 2023 03:30:00 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OSOYkBjI; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZVVE-0007Vs-Nq; Tue, 07 Mar 2023 06:29:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZVV4-0007PV-1X for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:59 -0500 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pZVUw-0005hI-3j for qemu-devel@nongnu.org; Tue, 07 Mar 2023 06:28:56 -0500 Received: by mail-wr1-x436.google.com with SMTP id v16so11825574wrn.0 for ; Tue, 07 Mar 2023 03:28:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678188528; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=09uqZm0w18GChoUZWmG8uQ1lR/P11PH+uuK+IHEB5NE=; b=OSOYkBjI7TC+Rm2aaHOSqHqWHa7HylcG523CaFhQiH6wt0GvgOMdduYPHz24MPbFBY A2aK7Gca5+7GRKyJHRNA60/7+B+d25TQodCJ6iAbkYFR/tnJp8B8RX5o83XpMldgr9BP dlTKCeUCDDJoG91LoM/U9eaPig118njBDp97Iovex+0y0HM9mRFIWg0CHXKxZlHdJ4Xa F0eT2QFaElaAzUnIqDK0T8iqrXqWc8qWAn3JwfdbU4H1RGBiUdzv47yjrraX114+9wA7 kWnNAAJlBdJu/g77+SZRE5Ze6fMjgCWOex6RwaKwdJ5iX1ePW9MFFQNG9zCYhrolCPgh 740Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678188528; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=09uqZm0w18GChoUZWmG8uQ1lR/P11PH+uuK+IHEB5NE=; b=NV4OlT7TUHb1QxZBxJj71fm7Z4m2v2WXUEtY8ZAsjElAaCF1eaXUIDw6ClJ2CRz1oA fjMps0in3GttUYi9dUtAFNP9sbfyMqLBhTjnafjJH9dGUVoFULI+mPjnisaPLfcMAjZd nkshyfVdpa1ASTd9ozrGNvfL8XAFNvvhvVEJrljQ7MqI23I9tTOfdrITL4gtcEFSq4Zk SX7IMBqCgb5iDbAYSiPfP/1S+J0jqwingpW7S/HZuzJ+3f8iKhgFq4eAv+68vRsMd8Bc OJx9ArxqhKAmY1fTjv5/Lh67DK8llLFu5owF2zEc5cYy2kBOz4Sw45Ge8f+WhnysMBcT d4lw== X-Gm-Message-State: AO0yUKU7D+It6lDNlZ+9Ja98aDe7IXIWLKVCFDBUkkIn0/nnXEiWGEBy dTDUUD0soonvpwPsXP6Bkc/X1y0wQXD2fSNjRo8= X-Received: by 2002:adf:eece:0:b0:2c6:2ac4:66ee with SMTP id a14-20020adfeece000000b002c62ac466eemr9425099wrp.39.1678188528453; Tue, 07 Mar 2023 03:28:48 -0800 (PST) Received: from zen.linaroharston ([85.9.250.243]) by smtp.gmail.com with ESMTPSA id f2-20020adfdb42000000b002c54fb024b2sm12192159wrj.61.2023.03.07.03.28.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 03:28:47 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 2EF1B1FFBF; Tue, 7 Mar 2023 11:28:46 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, Thomas Huth , Andrew Jones , Paolo Bonzini , kvmarm@lists.linux.dev, qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [kvm-unit-tests PATCH v10 7/7] arm/tcg-test: some basic TCG exercising tests Date: Tue, 7 Mar 2023 11:28:45 +0000 Message-Id: <20230307112845.452053-8-alex.bennee@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230307112845.452053-1-alex.bennee@linaro.org> References: <20230307112845.452053-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x436.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org These tests are not really aimed at KVM at all but exist to stretch QEMU's TCG code generator. In particular these exercise the ability of the TCG to: * Chain TranslationBlocks together (tight) * Handle heavy usage of the tb_jump_cache (paged) * Pathological case of computed local jumps (computed) In addition the tests can be varied by adding IPI IRQs or SMC sequences into the mix to stress the tcg_exit and invalidation mechanisms. To explicitly stress the tb_flush() mechanism you can use the mod/rounds parameters to force more frequent tb invalidation. Combined with setting -tb-size 1 in QEMU to limit the code generation buffer size. Signed-off-by: Alex Bennée Message-Id: <20211118184650.661575-11-alex.bennee@linaro.org> --- v9 - moved back to unittests.cfg - fixed some missing accel tags - s/printf/report_info/ - clean up some comment blocks --- arm/Makefile.arm | 2 + arm/Makefile.arm64 | 2 + arm/Makefile.common | 1 + arm/tcg-test-asm.S | 171 ++++++++++++++++++++++ arm/tcg-test-asm64.S | 170 ++++++++++++++++++++++ arm/tcg-test.c | 340 +++++++++++++++++++++++++++++++++++++++++++ arm/unittests.cfg | 84 +++++++++++ 7 files changed, 770 insertions(+) create mode 100644 arm/tcg-test-asm.S create mode 100644 arm/tcg-test-asm64.S create mode 100644 arm/tcg-test.c diff --git a/arm/Makefile.arm b/arm/Makefile.arm index 01fd4c7b..6af61033 100644 --- a/arm/Makefile.arm +++ b/arm/Makefile.arm @@ -37,4 +37,6 @@ tests = include $(SRCDIR)/$(TEST_DIR)/Makefile.common +$(TEST_DIR)/tcg-test.elf: $(cstart.o) $(TEST_DIR)/tcg-test.o $(TEST_DIR)/tcg-test-asm.o + arch_clean: arm_clean diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64 index 42e18e77..72da5033 100644 --- a/arm/Makefile.arm64 +++ b/arm/Makefile.arm64 @@ -35,5 +35,7 @@ tests += $(TEST_DIR)/debug.flat include $(SRCDIR)/$(TEST_DIR)/Makefile.common +$(TEST_DIR)/tcg-test.elf: $(cstart.o) $(TEST_DIR)/tcg-test.o $(TEST_DIR)/tcg-test-asm64.o + arch_clean: arm_clean $(RM) lib/arm64/.*.d diff --git a/arm/Makefile.common b/arm/Makefile.common index 0a2bdcfc..0b81fa72 100644 --- a/arm/Makefile.common +++ b/arm/Makefile.common @@ -14,6 +14,7 @@ tests-common += $(TEST_DIR)/pl031.flat tests-common += $(TEST_DIR)/tlbflush-code.flat tests-common += $(TEST_DIR)/locking-test.flat tests-common += $(TEST_DIR)/barrier-litmus-test.flat +tests-common += $(TEST_DIR)/tcg-test.flat tests-all = $(tests-common) $(tests) all: directories $(tests-all) diff --git a/arm/tcg-test-asm.S b/arm/tcg-test-asm.S new file mode 100644 index 00000000..f58fac08 --- /dev/null +++ b/arm/tcg-test-asm.S @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * TCG Test assembler functions for armv7 tests. + * + * Copyright (C) 2016, Linaro Ltd, Alex Bennée + * + * These helper functions are written in pure asm to control the size + * of the basic blocks and ensure they fit neatly into page + * aligned chunks. The pattern of branches they follow is determined by + * the 32 bit seed they are passed. It should be the same for each set. + * + * Calling convention + * - r0, iterations + * - r1, jump pattern + * - r2-r3, scratch + * + * Returns r0 + */ + +.arm + +.section .text + +/* + * Tight - all blocks should quickly be patched and should run + * very fast unless irqs or smc gets in the way + */ + +.global tight_start +tight_start: + subs r0, r0, #1 + beq tight_end + + ror r1, r1, #1 + tst r1, #1 + beq tightA + b tight_start + +tightA: + subs r0, r0, #1 + beq tight_end + + ror r1, r1, #1 + tst r1, #1 + beq tightB + b tight_start + +tightB: + subs r0, r0, #1 + beq tight_end + + ror r1, r1, #1 + tst r1, #1 + beq tight_start + b tightA + +.global tight_end +tight_end: + mov pc, lr + +/* + * Computed jumps cannot be hardwired into the basic blocks so each one + * will either cause an exit for the main execution loop or trigger an + * inline look up for the next block. + * + * There is some caching which should ameliorate the cost a little. + */ + + /* Align << 13 == 4096 byte alignment */ + .align 13 + .global computed_start +computed_start: + subs r0, r0, #1 + beq computed_end + + /* Jump table */ + ror r1, r1, #1 + and r2, r1, #1 + adr r3, computed_jump_table + ldr r2, [r3, r2, lsl #2] + mov pc, r2 + + b computed_err + +computed_jump_table: + .word computed_start + .word computedA + +computedA: + subs r0, r0, #1 + beq computed_end + + /* Jump into code */ + ror r1, r1, #1 + and r2, r1, #1 + adr r3, 1f + add r3, r2, lsl #2 + mov pc, r3 +1: b computed_start + b computedB + + b computed_err + + +computedB: + subs r0, r0, #1 + beq computed_end + ror r1, r1, #1 + + /* Conditional register load */ + adr r3, computedA + tst r1, #1 + adreq r3, computed_start + mov pc, r3 + + b computed_err + +computed_err: + mov r0, #1 + .global computed_end +computed_end: + mov pc, lr + + +/* + * Page hoping + * + * Each block is in a different page, hence the blocks never get joined + */ + /* Align << 13 == 4096 byte alignment */ + .align 13 + .global paged_start +paged_start: + subs r0, r0, #1 + beq paged_end + + ror r1, r1, #1 + tst r1, #1 + beq pagedA + b paged_start + + /* Align << 13 == 4096 byte alignment */ + .align 13 +pagedA: + subs r0, r0, #1 + beq paged_end + + ror r1, r1, #1 + tst r1, #1 + beq pagedB + b paged_start + + /* Align << 13 == 4096 byte alignment */ + .align 13 +pagedB: + subs r0, r0, #1 + beq paged_end + + ror r1, r1, #1 + tst r1, #1 + beq paged_start + b pagedA + + /* Align << 13 == 4096 byte alignment */ + .align 13 +.global paged_end +paged_end: + mov pc, lr + +.global test_code_end +test_code_end: diff --git a/arm/tcg-test-asm64.S b/arm/tcg-test-asm64.S new file mode 100644 index 00000000..e69a8c72 --- /dev/null +++ b/arm/tcg-test-asm64.S @@ -0,0 +1,170 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * TCG Test assembler functions for armv8 tests. + * + * Copyright (C) 2016, Linaro Ltd, Alex Bennée + * + * These helper functions are written in pure asm to control the size + * of the basic blocks and ensure they fit neatly into page + * aligned chunks. The pattern of branches they follow is determined by + * the 32 bit seed they are passed. It should be the same for each set. + * + * Calling convention + * - x0, iterations + * - x1, jump pattern + * - x2-x3, scratch + * + * Returns x0 + */ + +.section .text + +/* + * Tight - all blocks should quickly be patched and should run + * very fast unless irqs or smc gets in the way + */ + +.global tight_start +tight_start: + subs x0, x0, #1 + beq tight_end + + ror x1, x1, #1 + tst x1, #1 + beq tightA + b tight_start + +tightA: + subs x0, x0, #1 + beq tight_end + + ror x1, x1, #1 + tst x1, #1 + beq tightB + b tight_start + +tightB: + subs x0, x0, #1 + beq tight_end + + ror x1, x1, #1 + tst x1, #1 + beq tight_start + b tightA + +.global tight_end +tight_end: + ret + +/* + * Computed jumps cannot be hardwired into the basic blocks so each one + * will either cause an exit for the main execution loop or trigger an + * inline look up for the next block. + * + * There is some caching which should ameliorate the cost a little. + */ + + /* Align << 13 == 4096 byte alignment */ + .align 13 + .global computed_start +computed_start: + subs x0, x0, #1 + beq computed_end + + /* Jump table */ + ror x1, x1, #1 + and x2, x1, #1 + adr x3, computed_jump_table + ldr x2, [x3, x2, lsl #3] + br x2 + + b computed_err + +computed_jump_table: + .quad computed_start + .quad computedA + +computedA: + subs x0, x0, #1 + beq computed_end + + /* Jump into code */ + ror x1, x1, #1 + and x2, x1, #1 + adr x3, 1f + add x3, x3, x2, lsl #2 + br x3 +1: b computed_start + b computedB + + b computed_err + + +computedB: + subs x0, x0, #1 + beq computed_end + ror x1, x1, #1 + + /* Conditional register load */ + adr x2, computedA + adr x3, computed_start + tst x1, #1 + csel x2, x3, x2, eq + br x2 + + b computed_err + +computed_err: + mov x0, #1 + .global computed_end +computed_end: + ret + + +/* + * Page hoping + * + * Each block is in a different page, hence the blocks never get joined + */ + /* Align << 13 == 4096 byte alignment */ + .align 13 + .global paged_start +paged_start: + subs x0, x0, #1 + beq paged_end + + ror x1, x1, #1 + tst x1, #1 + beq pagedA + b paged_start + + /* Align << 13 == 4096 byte alignment */ + .align 13 +pagedA: + subs x0, x0, #1 + beq paged_end + + ror x1, x1, #1 + tst x1, #1 + beq pagedB + b paged_start + + /* Align << 13 == 4096 byte alignment */ + .align 13 +pagedB: + subs x0, x0, #1 + beq paged_end + + ror x1, x1, #1 + tst x1, #1 + beq paged_start + b pagedA + + /* Align << 13 == 4096 byte alignment */ + .align 13 +.global paged_end +paged_end: + ret + +.global test_code_end +test_code_end: diff --git a/arm/tcg-test.c b/arm/tcg-test.c new file mode 100644 index 00000000..d04d56e4 --- /dev/null +++ b/arm/tcg-test.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * ARM TCG Tests + * + * These tests are explicitly aimed at stretching the QEMU TCG engine. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_CPUS 8 + +/* These entry points are in the assembly code */ +extern int tight_start(uint32_t count, uint32_t pattern); +extern int computed_start(uint32_t count, uint32_t pattern); +extern int paged_start(uint32_t count, uint32_t pattern); +extern uint32_t tight_end; +extern uint32_t computed_end; +extern uint32_t paged_end; +extern unsigned long test_code_end; + +typedef int (*test_fn)(uint32_t count, uint32_t pattern); + +typedef struct { + const char *test_name; + bool should_pass; + test_fn start_fn; + uint32_t *code_end; +} test_descr_t; + +/* Test array */ +static test_descr_t tests[] = { + /* + * Tight chain. + * + * These are a bunch of basic blocks that have fixed branches in + * a page aligned space. The branches taken are decided by a + * psuedo-random bitmap for each CPU. + * + * Once the basic blocks have been chained together by the TCG they + * should run until they reach their block count. This will be the + * most efficient mode in which generated code is run. The only other + * exits will be caused by interrupts or TB invalidation. + */ + { "tight", true, tight_start, &tight_end }, + /* + * Computed jumps. + * + * A bunch of basic blocks which just do computed jumps so the basic + * block is never chained but they are all within a page (maybe not + * required). This will exercise the cache lookup but not the new + * generation. + */ + { "computed", true, computed_start, &computed_end }, + /* + * Page ping pong. + * + * Have the blocks are separated by PAGE_SIZE so they can never + * be chained together. + * + */ + { "paged", true, paged_start, &paged_end} +}; + +static test_descr_t *test; + +static int iterations = 1000000; +static int rounds = 1000; +static int mod_freq = 5; +static uint32_t pattern[MAX_CPUS]; + +/* control flags */ +static int smc; +static int irq; +static int check_irq; + +/* IRQ accounting */ +#define MAX_IRQ_IDS 16 +static int irqv; +static unsigned long irq_sent_ts[MAX_CPUS][MAX_CPUS][MAX_IRQ_IDS]; + +static int irq_recv[MAX_CPUS]; +static int irq_sent[MAX_CPUS]; +static int irq_overlap[MAX_CPUS]; /* if ts > now, i.e a race */ +static int irq_slow[MAX_CPUS]; /* if delay > threshold */ +static unsigned long irq_latency[MAX_CPUS]; /* cumulative time */ + +static int errors[MAX_CPUS]; + +static cpumask_t smp_test_complete; + +static cpumask_t ready; + +static void wait_on_ready(void) +{ + cpumask_set_cpu(smp_processor_id(), &ready); + while (!cpumask_full(&ready)) + cpu_relax(); +} + +/* + * This triggers TCGs SMC detection by writing values to the executing + * code pages. We are not actually modifying the instructions and the + * underlying code will remain unchanged. However this should trigger + * invalidation of the Translation Blocks + */ + +static void trigger_smc_detection(uint32_t *start, uint32_t *end) +{ + volatile uint32_t *ptr = start; + + while (ptr < end) { + uint32_t inst = *ptr; + *ptr++ = inst; + } +} + +/* Handler for receiving IRQs */ + +static void irq_handler(struct pt_regs *regs __unused) +{ + unsigned long then, now = get_cntvct(); + int cpu = smp_processor_id(); + u32 irqstat = gic_read_iar(); + u32 irqnr = gic_iar_irqnr(irqstat); + + if (irqnr != GICC_INT_SPURIOUS) { + unsigned int src_cpu = (irqstat >> 10) & 0x7; + + gic_write_eoir(irqstat); + irq_recv[cpu]++; + + then = irq_sent_ts[src_cpu][cpu][irqnr]; + + if (then > now) { + irq_overlap[cpu]++; + } else { + unsigned long latency = (now - then); + + if (latency > 30000) + irq_slow[cpu]++; + else + irq_latency[cpu] += latency; + } + } +} + +/* + * This triggers cross-CPU IRQs. Each IRQ should cause the basic block + * execution to finish the main run-loop get entered again. + */ +static int send_cross_cpu_irqs(int this_cpu, int irq) +{ + int cpu, sent = 0; + cpumask_t mask; + + cpumask_copy(&mask, &cpu_present_mask); + + for_each_present_cpu(cpu) { + if (cpu != this_cpu) { + irq_sent_ts[this_cpu][cpu][irq] = get_cntvct(); + cpumask_clear_cpu(cpu, &mask); + sent++; + } + } + + gic_ipi_send_mask(irq, &mask); + + return sent; +} + +static void do_test(void) +{ + int cpu = smp_processor_id(); + int i, irq_id = 0; + + report_info("CPU%d: online and setting up with pattern 0x%"PRIx32, + cpu, pattern[cpu]); + + if (irq) { + gic_enable_defaults(); +#ifdef __arm__ + install_exception_handler(EXCPTN_IRQ, irq_handler); +#else + install_irq_handler(EL1H_IRQ, irq_handler); +#endif + local_irq_enable(); + + wait_on_ready(); + } + + for (i = 0; i < rounds; i++) { + /* Enter the blocks */ + errors[cpu] += test->start_fn(iterations, pattern[cpu]); + + if ((i + cpu) % mod_freq == 0) { + if (smc) + trigger_smc_detection((uint32_t *) test->start_fn, + test->code_end); + + if (irq) { + irq_sent[cpu] += send_cross_cpu_irqs(cpu, irq_id); + irq_id++; + irq_id = irq_id % 15; + } + } + } + + /* ensure everything complete before we finish */ + smp_wmb(); + + cpumask_set_cpu(cpu, &smp_test_complete); + if (cpu != 0) + halt(); +} + +static void report_irq_stats(int cpu) +{ + int recv = irq_recv[cpu]; + int race = irq_overlap[cpu]; + int slow = irq_slow[cpu]; + + unsigned long avg_latency = irq_latency[cpu] / (recv - (race + slow)); + + report_info("CPU%d: %d irqs (%d races, %d slow, %ld ticks avg latency)", + cpu, recv, race, slow, avg_latency); +} + + +static void setup_and_run_tcg_test(void) +{ + static const unsigned char seed[] = "tcg-test"; + struct isaac_ctx prng_context; + int cpu; + int total_err = 0, total_sent = 0, total_recv = 0; + + isaac_init(&prng_context, &seed[0], sizeof(seed)); + + /* boot other CPUs */ + for_each_present_cpu(cpu) { + pattern[cpu] = isaac_next_uint32(&prng_context); + + if (cpu == 0) + continue; + + smp_boot_secondary(cpu, do_test); + } + + do_test(); + + while (!cpumask_full(&smp_test_complete)) + cpu_relax(); + + /* Ensure everything completes before we check the data */ + smp_mb(); + + /* Now total up errors and irqs */ + for_each_present_cpu(cpu) { + total_err += errors[cpu]; + total_sent += irq_sent[cpu]; + total_recv += irq_recv[cpu]; + + if (check_irq) + report_irq_stats(cpu); + } + + if (check_irq) + report(total_sent == total_recv && total_err == 0, + "%d IRQs sent, %d received, %d errors\n", + total_sent, total_recv, total_err == 0); + else + report(total_err == 0, "%d errors, IRQs not checked", total_err); +} + +int main(int argc, char **argv) +{ + int i; + unsigned int j; + + for (i = 0; i < argc; i++) { + char *arg = argv[i]; + + for (j = 0; j < ARRAY_SIZE(tests); j++) { + if (strcmp(arg, tests[j].test_name) == 0) + test = &tests[j]; + } + + /* Test modifiers */ + if (strstr(arg, "mod=") != NULL) { + char *p = strstr(arg, "="); + + mod_freq = atol(p+1); + } + + if (strstr(arg, "rounds=") != NULL) { + char *p = strstr(arg, "="); + + rounds = atol(p+1); + } + + if (strcmp(arg, "smc") == 0) { + unsigned long test_start = (unsigned long) &tight_start; + unsigned long test_end = (unsigned long) &test_code_end; + + smc = 1; + mmu_set_range_ptes(mmu_idmap, test_start, test_start, + test_end, __pgprot(PTE_WBWA)); + + report_prefix_push("smc"); + } + + if (strcmp(arg, "irq") == 0) { + irq = 1; + if (!gic_init()) + report_abort("No supported gic present!"); + irqv = gic_version(); + report_prefix_push("irq"); + } + + if (strcmp(arg, "check_irq") == 0) + check_irq = 1; + } + + if (test) { + /* ensure args visible to all cores */ + smp_mb(); + setup_and_run_tcg_test(); + } else { + report(false, "Unknown test"); + } + + return report_summary(); +} diff --git a/arm/unittests.cfg b/arm/unittests.cfg index 3d73e308..5b46ff5b 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -361,3 +361,87 @@ smp = 2 extra_params = -append 'sal_barrier' groups = nodefault mttcg barrier +# TCG Tests +[tcg::tight] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'tight' +groups = nodefault mttcg +accel = tcg + +[tcg::tight-smc] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'tight smc' -accel tcg,tb-size=1 +groups = nodefault mttcg +accel = tcg + +[tcg::tight-irq] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'tight irq' +groups = nodefault mttcg +accel = tcg + +[tcg::tight-smc-irq] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'tight smc irq' +groups = nodefault mttcg +accel = tcg + +[tcg::computed] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'computed' +groups = nodefault mttcg +accel = tcg + +[tcg::computed-smc] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'computed smc' +groups = nodefault mttcg +accel = tcg + +[tcg::computed-irq] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'computed irq' +groups = nodefault mttcg +accel = tcg + +[tcg::computed-smc-irq] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'computed smc irq' +groups = nodefault mttcg +accel = tcg + +[tcg::paged] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'paged' +groups = nodefault mttcg +accel = tcg + +[tcg::paged-smc] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'paged smc' +groups = nodefault mttcg +accel = tcg + +[tcg::paged-irq] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'paged irq' +groups = nodefault mttcg +accel = tcg + +[tcg::paged-smc-irq] +file = tcg-test.flat +smp = $(($MAX_SMP>4?4:$MAX_SMP)) +extra_params = -append 'paged smc irq' +groups = nodefault mttcg +accel = tcg