From patchwork Sat Sep 9 07:05:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 811918 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xq4xC1RNkz9sBW for ; Sat, 9 Sep 2017 17:06:39 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3xq4xC0dNTzDrpF for ; Sat, 9 Sep 2017 17:06:39 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3xq4wR68TyzDrcg for ; Sat, 9 Sep 2017 17:05:59 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id v8975TdY025373; Sat, 9 Sep 2017 02:05:46 -0500 From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Sat, 9 Sep 2017 17:05:25 +1000 Message-Id: <20170909070525.8154-7-benh@kernel.crashing.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909070525.8154-1-benh@kernel.crashing.org> References: <20170909070525.8154-1-benh@kernel.crashing.org> Subject: [Skiboot] [PATCH 7/7] xive: Workaround HW issue with scrub facility X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Without this, we sometimes don't observe from a CPU the values written to the ENDs or NVTs via the cache watch. Signed-off-by: Benjamin Herrenschmidt --- hw/xive.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/xive.c b/hw/xive.c index d1fae1a3..a81d2b8e 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -1232,6 +1232,12 @@ enum xive_cache_type { xive_cache_vpc, }; +static int64_t __xive_cache_watch(struct xive *x, enum xive_cache_type ctype, + uint64_t block, uint64_t idx, + uint32_t start_dword, uint32_t dword_count, + void *new_data, bool light_watch, + bool synchronous); + static int64_t __xive_cache_scrub(struct xive *x, enum xive_cache_type ctype, uint64_t block, uint64_t idx, bool want_inval, bool want_disable) @@ -1239,6 +1245,17 @@ static int64_t __xive_cache_scrub(struct xive *x, enum xive_cache_type ctype, uint64_t sreg, sregx, mreg, mregx; uint64_t mval, sval; + /* Workaround a HW bug in XIVE where the scrub completion + * isn't ordered by loads, thus the data might still be + * in a queue and may not have reached coherency. + * + * The workaround is two folds: We force the scrub to also + * invalidate, then after the scrub, we do a dummy cache + * watch which will make the HW read the data back, which + * should be ordered behind all the preceding stores. + */ + want_inval = true; + switch (ctype) { case xive_cache_ivc: sreg = VC_IVC_SCRUB_TRIG; @@ -1293,6 +1310,9 @@ static int64_t __xive_cache_scrub(struct xive *x, enum xive_cache_type ctype, time_wait(100); } sync(); + + /* Workaround for HW bug described above */ + __xive_cache_watch(x, ctype, block, idx, 0, 0, NULL, true, false); return 0; } @@ -1304,7 +1324,6 @@ static int64_t xive_ivc_scrub(struct xive *x, uint64_t block, uint64_t idx) static int64_t xive_vpc_scrub_clean(struct xive *x, uint64_t block, uint64_t idx) { - /* IVC has no "want_inval" bit, it always invalidates */ return __xive_cache_scrub(x, xive_cache_vpc, block, idx, true, false); } @@ -1348,6 +1367,14 @@ static int64_t __xive_cache_watch(struct xive *x, enum xive_cache_type ctype, /* Load data0 register to populate the watch */ dval0 = __xive_regr(x, dreg0, dreg0x, NULL); + /* If new_data is NULL, this is a dummy watch used as a + * workaround for a HW bug + */ + if (!new_data) { + __xive_regw(x, dreg0, dreg0x, dval0, NULL); + return 0; + } + /* Write the words into the watch facility. We write in reverse * order in case word 0 is part of it as it must be the last * one written.