Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3707958imu; Mon, 28 Jan 2019 09:23:17 -0800 (PST) X-Google-Smtp-Source: ALg8bN5Ko1gb6UpdxfkDlPW+DXE+S8dcv58KACkPjA9tr7GCvVT/1T9rHD/lFV1t3L8GBaBY+PrH X-Received: by 2002:a62:9f1b:: with SMTP id g27mr22034079pfe.87.1548696197108; Mon, 28 Jan 2019 09:23:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548696197; cv=none; d=google.com; s=arc-20160816; b=vzTyPEJ2RhQVJfLX0m3yqMeDPvSi2vjjShYz6JdRApa3RXa7B8sxh0oNevU/IOTDLZ TJrN8Fy3tyL1aCZxUDJPTD9XAPERgJOeTxqzLXyPxsueijhuyHQqNKj+r8TObDJ9xJWc iTE42SBv9ejANYwXM1ylTIVVeNGuZyGQO2SfDDcDRitbHP9Hs1r/NfZMeZ2v+zNdnJL/ MHTr9Ck1Fhf25W97sn6uOXC2f86Lj7IoTb106khGR1b+YvBi584LOClyT5L3uYRlDVw4 jzDPUhTfJG3/j4jJ4h8kAsMPDDdMTH5UvtIccQmZnW/pLYmPBAQigB2sDZ5/2maVexpx LdDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=hJnfjPxi//vIiVrdtZdLSsdG2+MIWI9hBWxIwMz8qcQ=; b=pT+xYd88ClBazXS0W6r0CZG5TwH35IVPXh6MUlSQKgizvW6rFNUozyStSAB1Av6kpk RD5JsZQXIGtPssA9SSBwV83BFr/znQ+G2K4NEVsCLKi6aSeBtb1I3ypuU35kXQniDAmF DGIK1V0G+kB4JcWk4/0Q7rVSE4Nr09ZMc2xsZ5mqB3QCIpJrHpMT9H2e67SHn0Pq6WkD R31hM5GxQHmK6nXmodBX0ZDR3HLzfo22Pbx8aPip2weh2nQTPiAeBGC2zcH/lACFk9lG yKINUEpwpN+KevnnzxJPd5c/mGegG8+XKnEj3WBJB4g0l41oH1M0/DLZPbEN+KWtzuHQ Bx3w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Vs55CTcz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f82si7221969pfa.221.2019.01.28.09.23.01; Mon, 28 Jan 2019 09:23:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Vs55CTcz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731531AbfA1RW6 (ORCPT + 99 others); Mon, 28 Jan 2019 12:22:58 -0500 Received: from mail.kernel.org ([198.145.29.99]:48470 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731322AbfA1QDK (ORCPT ); Mon, 28 Jan 2019 11:03:10 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2E14821916; Mon, 28 Jan 2019 16:03:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1548691389; bh=QO0Z/ugaU9XCwato60uHHqSOeQSYOYfR4+uT1EqhkAE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Vs55CTczDUyEYtt+ljqGKHYcLWD1nuzNNCz7E/lAKUjZ2ia7YoX8uinpqmJMsM0UE e6Kx/HvttimreOdoh67MRda7JJ08r+ZAWd//UT93UKNeqTqJeOvxBmyeKb7rg7e/lG BLpyBpVgwavlUmsAKuYbJo3h/mXyjRc7qBwIPJek= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Will Deacon , Benjamin Herrenschmidt , Arnd Bergmann , Sasha Levin Subject: [PATCH AUTOSEL 4.19 077/258] arm64: io: Ensure calls to delay routines are ordered against prior readX() Date: Mon, 28 Jan 2019 10:56:23 -0500 Message-Id: <20190128155924.51521-77-sashal@kernel.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190128155924.51521-1-sashal@kernel.org> References: <20190128155924.51521-1-sashal@kernel.org> MIME-Version: 1.0 X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Will Deacon [ Upstream commit 6460d32014717686d3b7963595950ba2c6d1bb5e ] A relatively standard idiom for ensuring that a pair of MMIO writes to a device arrive at that device with a specified minimum delay between them is as follows: writel_relaxed(42, dev_base + CTL1); readl(dev_base + CTL1); udelay(10); writel_relaxed(42, dev_base + CTL2); the intention being that the read-back from the device will push the prior write to CTL1, and the udelay will hold up the write to CTL1 until at least 10us have elapsed. Unfortunately, on arm64 where the underlying delay loop is implemented as a read of the architected counter, the CPU does not guarantee ordering from the readl() to the delay loop and therefore the delay loop could in theory be speculated and not provide the desired interval between the two writes. Fix this in a similar manner to PowerPC by introducing a dummy control dependency on the output of readX() which, combined with the ISB in the read of the architected counter, guarantees that a subsequent delay loop can not be executed until the readX() has returned its result. Cc: Benjamin Herrenschmidt Cc: Arnd Bergmann Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- arch/arm64/include/asm/io.h | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 35b2e50f17fb..b2bc7dbc1fa6 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -106,7 +106,22 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) } /* IO barriers */ -#define __iormb() rmb() +#define __iormb(v) \ +({ \ + unsigned long tmp; \ + \ + rmb(); \ + \ + /* \ + * Create a dummy control dependency from the IO read to any \ + * later instructions. This ensures that a subsequent call to \ + * udelay() will be ordered due to the ISB in get_cycles(). \ + */ \ + asm volatile("eor %0, %1, %1\n" \ + "cbnz %0, ." \ + : "=r" (tmp) : "r" (v) : "memory"); \ +}) + #define __iowmb() wmb() #define mmiowb() do { } while (0) @@ -131,10 +146,10 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) * following Normal memory access. Writes are ordered relative to any prior * Normal memory access. */ -#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) -#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) -#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) -#define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(); __v; }) +#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(__v); __v; }) +#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(__v); __v; }) +#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(__v); __v; }) +#define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(__v); __v; }) #define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); }) #define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); }) @@ -185,9 +200,9 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size); /* * io{read,write}{16,32,64}be() macros */ -#define ioread16be(p) ({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) -#define ioread32be(p) ({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) -#define ioread64be(p) ({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(); __v; }) +#define ioread16be(p) ({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(__v); __v; }) +#define ioread32be(p) ({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(__v); __v; }) +#define ioread64be(p) ({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(__v); __v; }) #define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); }) #define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); }) -- 2.19.1