* [PATCH v2 3/4] arm64: dts: allwinner: h6: Add IOMMU
From: Maxime Ripard @ 2020-02-20 18:15 UTC (permalink / raw)
To: Joerg Roedel, Chen-Yu Tsai, Maxime Ripard, Mark Rutland,
Rob Herring, Frank Rowand
Cc: devicetree, iommu, Maxime Ripard, linux-arm-kernel
In-Reply-To: <cover.a31c229a83f1d92e6928ae2adb70887da0fd44b3.1582222496.git-series.maxime@cerno.tech>
Now that we have a driver for the IOMMU, let's start using it.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 3329283e38ab..2d0777ad39aa 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -131,6 +131,7 @@
clock-names = "bus",
"mod";
resets = <&display_clocks RST_MIXER0>;
+ iommus = <&iommu 0>;
ports {
#address-cells = <1>;
@@ -370,6 +371,15 @@
#interrupt-cells = <3>;
};
+ iommu: iommu@30f0000 {
+ compatible = "allwinner,sun50i-h6-iommu";
+ reg = <0x030f0000 0x10000>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_IOMMU>;
+ resets = <&ccu RST_BUS_IOMMU>;
+ #iommu-cells = <1>;
+ };
+
mmc0: mmc@4020000 {
compatible = "allwinner,sun50i-h6-mmc",
"allwinner,sun50i-a64-mmc";
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 2/4] iommu: Add Allwinner H6 IOMMU driver
From: Maxime Ripard @ 2020-02-20 18:15 UTC (permalink / raw)
To: Joerg Roedel, Chen-Yu Tsai, Maxime Ripard, Mark Rutland,
Rob Herring, Frank Rowand
Cc: devicetree, iommu, Maxime Ripard, linux-arm-kernel
In-Reply-To: <cover.a31c229a83f1d92e6928ae2adb70887da0fd44b3.1582222496.git-series.maxime@cerno.tech>
The Allwinner H6 has introduced an IOMMU for a few DMA controllers, mostly
video related: the display engine, the video decoders / encoders, the
camera capture controller, etc.
The design is pretty simple compared to other IOMMUs found in SoCs: there's
a single instance, controlling all the masters, with a single address
space.
It also features a performance monitoring unit that allows to retrieve
various informations (per-master and global TLB accesses, hits and misses,
access latency, etc) that isn't supported at the moment.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/iommu/Kconfig | 9 +-
drivers/iommu/Makefile | 1 +-
drivers/iommu/sun50i-iommu.c | 1072 +++++++++++++++++++++++++++++++++++-
3 files changed, 1082 insertions(+)
create mode 100644 drivers/iommu/sun50i-iommu.c
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d2fade984999..87677ea98427 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -302,6 +302,15 @@ config ROCKCHIP_IOMMU
Say Y here if you are using a Rockchip SoC that includes an IOMMU
device.
+config SUN50I_IOMMU
+ bool "Allwinner H6 IOMMU Support"
+ depends on ARCH_SUNXI || COMPILE_TEST
+ select ARM_DMA_USE_IOMMU
+ select IOMMU_API
+ select IOMMU_DMA
+ help
+ Support for the IOMMU introduced in the Allwinner H6 SoCs.
+
config TEGRA_IOMMU_GART
bool "Tegra GART IOMMU Support"
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 2104fb8afc06..dd1ff336b9b9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o
obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
+obj-$(CONFIG_SUN50I_IOMMU) += sun50i-iommu.o
obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
new file mode 100644
index 000000000000..81ba5f562bd2
--- /dev/null
+++ b/drivers/iommu/sun50i-iommu.c
@@ -0,0 +1,1072 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+// Copyright (C) 2016-2018, Allwinner Technology CO., LTD.
+// Copyright (C) 2019-2020, Cerno
+
+#include <linux/bitfield.h>
+#include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-iommu.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/iommu.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define IOMMU_RESET_REG 0x010
+#define IOMMU_ENABLE_REG 0x020
+#define IOMMU_ENABLE_ENABLE BIT(0)
+
+#define IOMMU_BYPASS_REG 0x030
+#define IOMMU_AUTO_GATING_REG 0x040
+#define IOMMU_AUTO_GATING_ENABLE BIT(0)
+
+#define IOMMU_WBUF_CTRL_REG 0x044
+#define IOMMU_OOO_CTRL_REG 0x048
+#define IOMMU_4KB_BDY_PRT_CTRL_REG 0x04c
+#define IOMMU_TTB_REG 0x050
+#define IOMMU_TLB_ENABLE_REG 0x060
+#define IOMMU_TLB_PREFETCH_REG 0x070
+#define IOMMU_TLB_PREFETCH_MASTER_ENABLE(m) BIT(m)
+
+#define IOMMU_TLB_FLUSH_REG 0x080
+#define IOMMU_TLB_FLUSH_PTW_CACHE BIT(17)
+#define IOMMU_TLB_FLUSH_MACRO_TLB BIT(16)
+#define IOMMU_TLB_FLUSH_MICRO_TLB(i) (BIT(i) & GENMASK(5, 0))
+
+#define IOMMU_TLB_IVLD_ADDR_REG 0x090
+#define IOMMU_TLB_IVLD_ADDR_MASK_REG 0x094
+#define IOMMU_TLB_IVLD_ENABLE_REG 0x098
+#define IOMMU_TLB_IVLD_ENABLE_ENABLE BIT(0)
+
+#define IOMMU_PC_IVLD_ADDR_REG 0x0a0
+#define IOMMU_PC_IVLD_ENABLE_REG 0x0a8
+#define IOMMU_PC_IVLD_ENABLE_ENABLE BIT(0)
+
+#define IOMMU_DM_AUT_CTRL_REG(d) (0x0b0 + ((d) / 2) * 4)
+#define IOMMU_DM_AUT_CTRL_RD_UNAVAIL(d, m) (1 << (((d & 1) * 16) + ((m) * 2)))
+#define IOMMU_DM_AUT_CTRL_WR_UNAVAIL(d, m) (1 << (((d & 1) * 16) + ((m) * 2) + 1))
+
+#define IOMMU_DM_AUT_OVWT_REG 0x0d0
+#define IOMMU_INT_ENABLE_REG 0x100
+#define IOMMU_INT_CLR_REG 0x104
+#define IOMMU_INT_STA_REG 0x108
+#define IOMMU_INT_ERR_ADDR_REG(i) (0x110 + (i) * 4)
+#define IOMMU_INT_ERR_ADDR_L1_REG 0x130
+#define IOMMU_INT_ERR_ADDR_L2_REG 0x134
+#define IOMMU_INT_ERR_DATA_REG(i) (0x150 + (i) * 4)
+#define IOMMU_L1PG_INT_REG 0x0180
+#define IOMMU_L2PG_INT_REG 0x0184
+
+#define IOMMU_INT_INVALID_L2PG BIT(17)
+#define IOMMU_INT_INVALID_L1PG BIT(16)
+#define IOMMU_INT_MASTER_PERMISSION(m) BIT(m)
+#define IOMMU_INT_MASTER_MASK (IOMMU_INT_MASTER_PERMISSION(0) | \
+ IOMMU_INT_MASTER_PERMISSION(1) | \
+ IOMMU_INT_MASTER_PERMISSION(2) | \
+ IOMMU_INT_MASTER_PERMISSION(3) | \
+ IOMMU_INT_MASTER_PERMISSION(4) | \
+ IOMMU_INT_MASTER_PERMISSION(5))
+#define IOMMU_INT_MASK (IOMMU_INT_INVALID_L1PG | \
+ IOMMU_INT_INVALID_L2PG | \
+ IOMMU_INT_MASTER_MASK)
+
+#define PT_ENTRY_SIZE sizeof(u32)
+
+#define NUM_DT_ENTRIES 4096
+#define DT_SIZE (NUM_DT_ENTRIES * PT_ENTRY_SIZE)
+
+#define NUM_PT_ENTRIES 256
+#define PT_SIZE (NUM_PT_ENTRIES * PT_ENTRY_SIZE)
+
+struct sun50i_iommu {
+ struct iommu_device iommu;
+
+ /* Lock to modify the IOMMU registers */
+ spinlock_t iommu_lock;
+
+ struct device *dev;
+ void __iomem *base;
+ struct reset_control *reset;
+ struct clk *clk;
+
+ struct iommu_domain *domain;
+ struct iommu_group *group;
+ struct kmem_cache *pt_pool;
+};
+
+struct sun50i_iommu_domain {
+ struct iommu_domain domain;
+
+ /* Number of devices attached to the domain */
+ refcount_t refcnt;
+
+ /* Lock to modify the Directory Table */
+ spinlock_t dt_lock;
+
+ /* L1 Page Table */
+ u32 *dt;
+ dma_addr_t dt_dma;
+
+ struct sun50i_iommu *iommu;
+};
+
+static struct sun50i_iommu_domain *to_sun50i_domain(struct iommu_domain *domain)
+{
+ return container_of(domain, struct sun50i_iommu_domain, domain);
+}
+
+static struct sun50i_iommu *sun50i_iommu_from_dev(struct device *dev)
+{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+ if (!fwspec)
+ return NULL;
+
+ return fwspec->iommu_priv;
+}
+
+static u32 iommu_read(struct sun50i_iommu *iommu, u32 offset)
+{
+ return readl(iommu->base + offset);
+}
+
+static void iommu_write(struct sun50i_iommu *iommu, u32 offset, u32 value)
+{
+ writel(value, iommu->base + offset);
+}
+
+/*
+ * The Allwinner H6 IOMMU uses a 2-level page table.
+ *
+ * The first level is the usual Directory Table (DT), that consists of
+ * 4096 4-bytes Directory Table Entries (DTE), each pointing to a Page
+ * Table (PT).
+ *
+ * Each PT consits of 256 4-bytes Page Table Entries (PTE), each
+ * pointing to a 4kB page of physical memory.
+ *
+ * The IOMMU supports a single DT, pointed by the IOMMU_TTB_REG
+ * register that contains its physical address.
+ */
+
+#define SUN50I_IOVA_DTE_MASK GENMASK(31, 20)
+#define SUN50I_IOVA_PTE_MASK GENMASK(19, 12)
+#define SUN50I_IOVA_PAGE_MASK GENMASK(11, 0)
+
+static u32 sun50i_iova_get_dte_index(dma_addr_t iova)
+{
+ return FIELD_GET(SUN50I_IOVA_DTE_MASK, iova);
+}
+
+static u32 sun50i_iova_get_pte_index(dma_addr_t iova)
+{
+ return FIELD_GET(SUN50I_IOVA_PTE_MASK, iova);
+}
+
+static u32 sun50i_iova_get_page_offset(dma_addr_t iova)
+{
+ return FIELD_GET(SUN50I_IOVA_PAGE_MASK, iova);
+}
+
+/*
+ * Each Directory Table Entry has a Page Table address and a valid
+ * bit:
+
+ * +---------------------+-----------+-+
+ * | PT address | Reserved |V|
+ * +---------------------+-----------+-+
+ * 31:10 - Page Table address
+ * 9:2 - Reserved
+ * 1:0 - 1 if the entry is valid
+ */
+
+#define SUN50I_DTE_PT_ADDRESS_MASK GENMASK(31, 10)
+#define SUN50I_DTE_PT_ATTRS GENMASK(1, 0)
+#define SUN50I_DTE_PT_VALID 1
+
+static phys_addr_t sun50i_dte_get_pt_address(u32 dte)
+{
+ return (phys_addr_t)dte & SUN50I_DTE_PT_ADDRESS_MASK;
+}
+
+static bool sun50i_dte_is_pt_valid(u32 dte)
+{
+ return (dte & SUN50I_DTE_PT_ATTRS) == SUN50I_DTE_PT_VALID;
+}
+
+static u32 sun50i_mk_dte(dma_addr_t pt_dma)
+{
+ return (pt_dma & SUN50I_DTE_PT_ADDRESS_MASK) | SUN50I_DTE_PT_VALID;
+}
+
+/*
+ * Each PTE has a Page address, an authority index and a valid bit:
+ *
+ * +----------------+-----+-----+-----+---+-----+
+ * | Page address | Rsv | ACI | Rsv | V | Rsv |
+ * +----------------+-----+-----+-----+---+-----+
+ * 31:12 - Page address
+ * 11:8 - Reserved
+ * 7:4 - Authority Control Index
+ * 3:2 - Reserved
+ * 1 - 1 if the entry is valid
+ * 0 - Reserved
+ *
+ * The way permissions work is that the IOMMU has 16 "domains" that
+ * can be configured to give each masters either read or write
+ * permissions through the IOMMU_DM_AUT_CTRL_REG registers. The domain
+ * 0 seems like the default domain, and its permissions in the
+ * IOMMU_DM_AUT_CTRL_REG are only read-only, so it's not really
+ * useful to enforce any particular permission.
+ *
+ * Each page entry will then have a reference to the domain they are
+ * affected to, so that we can actually enforce them on a per-page
+ * basis.
+ *
+ * In order to make it work with the IOMMU framework, we will be using
+ * 4 different domains, starting at 1: RD_WR, RD, WR and NONE
+ * depending on the permission we want to enforce. Each domain will
+ * have each master setup in the same way, since the IOMMU framework
+ * doesn't seem to restrict page access on a per-device basis. And
+ * then we will use the relevant domain index when generating the page
+ * table entry depending on the permissions we want to be enforced.
+ */
+
+enum sun50i_iommu_aci {
+ SUN50I_IOMMU_ACI_DO_NOT_USE = 0,
+ SUN50I_IOMMU_ACI_NONE,
+ SUN50I_IOMMU_ACI_RD,
+ SUN50I_IOMMU_ACI_WR,
+ SUN50I_IOMMU_ACI_RD_WR,
+};
+
+#define SUN50I_PTE_PAGE_ADDRESS_MASK GENMASK(31, 12)
+#define SUN50I_PTE_ACI_MASK GENMASK(7, 4)
+#define SUN50I_PTE_PAGE_VALID BIT(1)
+
+static phys_addr_t sun50i_pte_get_page_address(u32 pte)
+{
+ return (phys_addr_t)pte & SUN50I_PTE_PAGE_ADDRESS_MASK;
+}
+
+static enum sun50i_iommu_aci sun50i_get_pte_aci(u32 pte)
+{
+ return FIELD_GET(SUN50I_PTE_ACI_MASK, pte);
+}
+
+static bool sun50i_pte_is_page_valid(u32 pte)
+{
+ return pte & SUN50I_PTE_PAGE_VALID;
+}
+
+static u32 sun50i_mk_pte(phys_addr_t page, int prot)
+{
+ enum sun50i_iommu_aci aci;
+ u32 flags = 0;
+
+ if (prot & (IOMMU_READ | IOMMU_WRITE))
+ aci = SUN50I_IOMMU_ACI_RD_WR;
+ else if (prot & IOMMU_READ)
+ aci = SUN50I_IOMMU_ACI_RD;
+ else if (prot & IOMMU_WRITE)
+ aci = SUN50I_IOMMU_ACI_WR;
+ else
+ aci = SUN50I_IOMMU_ACI_NONE;
+
+ flags |= FIELD_PREP(SUN50I_PTE_ACI_MASK, aci);
+ page &= SUN50I_PTE_PAGE_ADDRESS_MASK;
+ return page | flags | SUN50I_PTE_PAGE_VALID;
+}
+
+static void sun50i_table_flush(struct sun50i_iommu_domain *sun50i_domain,
+ void *vaddr, unsigned int count)
+{
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ dma_addr_t dma = virt_to_phys(vaddr);
+ size_t size = count * PT_ENTRY_SIZE;
+
+ dma_sync_single_for_device(iommu->dev, dma, size, DMA_TO_DEVICE);
+}
+
+static int sun50i_iommu_flush_all_tlb(struct sun50i_iommu *iommu)
+{
+ u32 reg;
+ int ret;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ iommu_write(iommu,
+ IOMMU_TLB_FLUSH_REG,
+ IOMMU_TLB_FLUSH_PTW_CACHE |
+ IOMMU_TLB_FLUSH_MACRO_TLB |
+ IOMMU_TLB_FLUSH_MICRO_TLB(5) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(4) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(3) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(2) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(1) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(0));
+
+ ret = readl_poll_timeout(iommu->base + IOMMU_TLB_FLUSH_REG,
+ reg, !reg,
+ 1, 2000);
+ if (ret)
+ dev_err(iommu->dev, "Enable flush all request timed out\n");
+
+ return ret;
+}
+
+static int sun50i_iommu_tlb_invalidate(struct sun50i_iommu *iommu,
+ dma_addr_t iova)
+{
+ int ret;
+ u32 reg;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ iommu_write(iommu, IOMMU_TLB_IVLD_ADDR_REG, iova);
+ iommu_write(iommu, IOMMU_TLB_IVLD_ADDR_MASK_REG,
+ SUN50I_PTE_PAGE_ADDRESS_MASK);
+ iommu_write(iommu, IOMMU_TLB_IVLD_ENABLE_REG,
+ IOMMU_TLB_IVLD_ENABLE_ENABLE);
+
+ ret = readl_poll_timeout(iommu->base + IOMMU_TLB_IVLD_ENABLE_REG,
+ reg, !(reg & IOMMU_TLB_IVLD_ENABLE_ENABLE),
+ 1, 2000);
+ if (ret)
+ dev_err(iommu->dev, "TLB Invalid timed out\n");
+
+ return ret;
+}
+
+static int sun50i_iommu_ptw_invalidate(struct sun50i_iommu *iommu,
+ dma_addr_t iova)
+{
+ int ret;
+ u32 reg;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ iommu_write(iommu, IOMMU_PC_IVLD_ADDR_REG, iova);
+ iommu_write(iommu, IOMMU_PC_IVLD_ENABLE_REG,
+ IOMMU_PC_IVLD_ENABLE_ENABLE);
+
+ ret = readl_poll_timeout(iommu->base + IOMMU_PC_IVLD_ENABLE_REG,
+ reg, !(reg & IOMMU_PC_IVLD_ENABLE_ENABLE),
+ 1, 2000);
+ if (ret)
+ dev_err(iommu->dev, "PTW cache invalid timed out\n");
+
+ return ret;
+}
+
+static int sun50i_iommu_enable(struct sun50i_iommu *iommu)
+{
+ struct sun50i_iommu_domain *sun50i_domain;
+ unsigned long flags;
+ int ret;
+
+ if (!iommu->domain)
+ return 0;
+
+ sun50i_domain = to_sun50i_domain(iommu->domain);
+
+ ret = reset_control_deassert(iommu->reset);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(iommu->clk);
+ if (ret)
+ goto err_reset_assert;
+
+ spin_lock_irqsave(&iommu->iommu_lock, flags);
+
+ iommu_write(iommu, IOMMU_TTB_REG, sun50i_domain->dt_dma);
+ iommu_write(iommu, IOMMU_TLB_PREFETCH_REG,
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(0) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(1) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(2) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(3) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(4) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(5));
+ iommu_write(iommu, IOMMU_INT_ENABLE_REG, IOMMU_INT_MASK);
+ iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_NONE),
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 1) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 1) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 2) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 2) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 3) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 3) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 4) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 4) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 5) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 5));
+
+ iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_RD),
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 0) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 1) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 2) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 3) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 4) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 5));
+
+ iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_WR),
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 0) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 1) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 2) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 3) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 4) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 5));
+
+ ret = sun50i_iommu_flush_all_tlb(iommu);
+ if (ret) {
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+ goto err_clk_disable;
+ }
+
+ iommu_write(iommu, IOMMU_AUTO_GATING_REG, IOMMU_AUTO_GATING_ENABLE);
+ iommu_write(iommu, IOMMU_ENABLE_REG, IOMMU_ENABLE_ENABLE);
+
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+
+ return 0;
+
+err_clk_disable:
+ clk_disable_unprepare(iommu->clk);
+
+err_reset_assert:
+ reset_control_assert(iommu->reset);
+
+ return ret;
+}
+
+static void sun50i_iommu_disable(struct sun50i_iommu *iommu)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&iommu->iommu_lock, flags);
+
+ iommu_write(iommu, IOMMU_ENABLE_REG, 0);
+ iommu_write(iommu, IOMMU_TTB_REG, 0);
+
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+
+ clk_disable_unprepare(iommu->clk);
+ reset_control_assert(iommu->reset);
+}
+
+static u32 *sun50i_dte_get_page_table(struct sun50i_iommu_domain *sun50i_domain,
+ dma_addr_t iova, gfp_t gfp)
+{
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ unsigned long flags;
+ dma_addr_t pt_dma;
+ u32 *page_table;
+ u32 *dte_addr;
+ u32 dte;
+
+ assert_spin_locked(&sun50i_domain->dt_lock);
+
+ dte_addr = &sun50i_domain->dt[sun50i_iova_get_dte_index(iova)];
+ dte = *dte_addr;
+ if (sun50i_dte_is_pt_valid(dte)) {
+ phys_addr_t pt_phys = sun50i_dte_get_pt_address(dte);
+ return (u32 *)phys_to_virt(pt_phys);
+ }
+
+ page_table = kmem_cache_zalloc(iommu->pt_pool, gfp);
+ if (!page_table)
+ return ERR_PTR(-ENOMEM);
+
+ pt_dma = dma_map_single(iommu->dev, page_table, PT_SIZE, DMA_TO_DEVICE);
+ if (dma_mapping_error(iommu->dev, pt_dma)) {
+ dev_err(iommu->dev, "Couldn't map L2 Page Table\n");
+ kmem_cache_free(iommu->pt_pool, page_table);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* We rely on the physical address and DMA address being the same */
+ WARN_ON(pt_dma != virt_to_phys(page_table));
+
+ dte = sun50i_mk_dte(pt_dma);
+ *dte_addr = dte;
+ sun50i_table_flush(sun50i_domain, page_table, PT_SIZE);
+ sun50i_table_flush(sun50i_domain, dte_addr, 1);
+
+ spin_lock_irqsave(&iommu->iommu_lock, flags);
+ sun50i_iommu_ptw_invalidate(iommu, iova);
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+
+ return page_table;
+}
+
+static int sun50i_iommu_map(struct iommu_domain *domain, unsigned long iova,
+ phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ u32 pte_index;
+ u32 *page_table, *pte_addr;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&sun50i_domain->dt_lock, flags);
+ page_table = sun50i_dte_get_page_table(sun50i_domain, iova, gfp);
+ if (IS_ERR(page_table)) {
+ ret = PTR_ERR(page_table);
+ goto out;
+ }
+
+ pte_index = sun50i_iova_get_pte_index(iova);
+ pte_addr = &page_table[pte_index];
+ if (sun50i_pte_is_page_valid(*pte_addr)) {
+ phys_addr_t page_phys = sun50i_pte_get_page_address(*pte_addr);
+ dev_err(iommu->dev,
+ "iova %pad already mapped to %pa cannot remap to %pa prot: %#x\n",
+ &iova, &page_phys, &paddr, prot);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ *pte_addr = sun50i_mk_pte(paddr, prot);
+ sun50i_table_flush(sun50i_domain, pte_addr, 1);
+
+ spin_lock_irqsave(&iommu->iommu_lock, flags);
+ sun50i_iommu_tlb_invalidate(iommu, iova);
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+
+out:
+ spin_unlock_irqrestore(&sun50i_domain->dt_lock, flags);
+ return ret;
+}
+
+static size_t sun50i_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+ size_t size, struct iommu_iotlb_gather *gather)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ unsigned long flags;
+ phys_addr_t pt_phys;
+ dma_addr_t pte_dma;
+ u32 *pte_addr;
+ u32 dte;
+
+ spin_lock_irqsave(&sun50i_domain->dt_lock, flags);
+
+ dte = sun50i_domain->dt[sun50i_iova_get_dte_index(iova)];
+ if (!sun50i_dte_is_pt_valid(dte)) {
+ spin_unlock_irqrestore(&sun50i_domain->dt_lock, flags);
+ return 0;
+ }
+
+ pt_phys = sun50i_dte_get_pt_address(dte);
+ pte_addr = (u32 *)phys_to_virt(pt_phys) + sun50i_iova_get_pte_index(iova);
+ pte_dma = pt_phys + sun50i_iova_get_pte_index(iova) * PT_ENTRY_SIZE;
+
+ if (!sun50i_pte_is_page_valid(*pte_addr)) {
+ spin_unlock_irqrestore(&sun50i_domain->dt_lock, flags);
+ return 0;
+ }
+
+ memset(pte_addr, 0, sizeof(*pte_addr));
+ sun50i_table_flush(sun50i_domain, pte_addr, 1);
+
+ spin_lock(&iommu->iommu_lock);
+ sun50i_iommu_tlb_invalidate(iommu, iova);
+ sun50i_iommu_ptw_invalidate(iommu, iova);
+ spin_unlock(&iommu->iommu_lock);
+
+ spin_unlock_irqrestore(&sun50i_domain->dt_lock, flags);
+
+ return SZ_4K;
+}
+
+static phys_addr_t sun50i_iommu_iova_to_phys(struct iommu_domain *domain,
+ dma_addr_t iova)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ phys_addr_t pt_phys, phys = 0;
+ unsigned long flags;
+ u32 *page_table;
+ u32 dte, pte;
+
+ spin_lock_irqsave(&sun50i_domain->dt_lock, flags);
+
+ dte = sun50i_domain->dt[sun50i_iova_get_dte_index(iova)];
+ if (!sun50i_dte_is_pt_valid(dte))
+ goto out;
+
+ pt_phys = sun50i_dte_get_pt_address(dte);
+ page_table = (u32 *)phys_to_virt(pt_phys);
+ pte = page_table[sun50i_iova_get_pte_index(iova)];
+ if (!sun50i_pte_is_page_valid(pte))
+ goto out;
+
+ phys = sun50i_pte_get_page_address(pte) +
+ sun50i_iova_get_page_offset(iova);
+
+out:
+ spin_unlock_irqrestore(&sun50i_domain->dt_lock, flags);
+ return phys;
+}
+
+static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
+{
+ struct sun50i_iommu_domain *sun50i_domain;
+
+ if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED)
+ return NULL;
+
+ sun50i_domain = kzalloc(sizeof(*sun50i_domain), GFP_KERNEL);
+ if (!sun50i_domain)
+ return NULL;
+
+ if (type == IOMMU_DOMAIN_DMA &&
+ iommu_get_dma_cookie(&sun50i_domain->domain))
+ goto err_free_domain;
+
+ sun50i_domain->dt = (u32 *)__get_free_pages(GFP_KERNEL,
+ get_order(DT_SIZE));
+ if (!sun50i_domain->dt)
+ goto err_put_cookie;
+ memset(sun50i_domain->dt, 0, DT_SIZE);
+
+ refcount_set(&sun50i_domain->refcnt, 1);
+ spin_lock_init(&sun50i_domain->dt_lock);
+
+ sun50i_domain->domain.geometry.aperture_start = 0;
+ sun50i_domain->domain.geometry.aperture_end = DMA_BIT_MASK(32);
+ sun50i_domain->domain.geometry.force_aperture = true;
+
+ return &sun50i_domain->domain;
+
+err_put_cookie:
+ if (type == IOMMU_DOMAIN_DMA)
+ iommu_put_dma_cookie(&sun50i_domain->domain);
+
+err_free_domain:
+ kfree(sun50i_domain);
+
+ return NULL;
+}
+
+static void sun50i_iommu_domain_free(struct iommu_domain *domain)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ unsigned long flags;
+
+ spin_lock_irqsave(&sun50i_domain->dt_lock, flags);
+ free_pages((unsigned long)sun50i_domain->dt, get_order(DT_SIZE));
+ sun50i_domain->dt = NULL;
+
+ spin_unlock_irqrestore(&sun50i_domain->dt_lock, flags);
+ iommu_put_dma_cookie(domain);
+
+ kfree(sun50i_domain);
+}
+
+static int sun50i_iommu_attach_domain(struct sun50i_iommu *iommu,
+ struct sun50i_iommu_domain *sun50i_domain)
+{
+ iommu->domain = &sun50i_domain->domain;
+ sun50i_domain->iommu = iommu;
+
+ sun50i_domain->dt_dma = dma_map_single(iommu->dev, sun50i_domain->dt,
+ DT_SIZE, DMA_TO_DEVICE);
+ if (dma_mapping_error(iommu->dev, sun50i_domain->dt_dma)) {
+ dev_err(iommu->dev, "Couldn't map L1 Page Table\n");
+ return -ENOMEM;
+ }
+
+ return sun50i_iommu_enable(iommu);
+}
+
+static void sun50i_iommu_detach_domain(struct sun50i_iommu *iommu,
+ struct sun50i_iommu_domain *sun50i_domain)
+{
+ unsigned long flags;
+ unsigned int i;
+
+ spin_lock_irqsave(&sun50i_domain->dt_lock, flags);
+
+ for (i = 0; i < NUM_DT_ENTRIES; i++) {
+ phys_addr_t pt_phys;
+ u32 *page_table;
+ u32 *dte_addr;
+ u32 dte;
+
+ dte_addr = &sun50i_domain->dt[i];
+ dte = *dte_addr;
+ if (!sun50i_dte_is_pt_valid(dte))
+ continue;
+
+ memset(dte_addr, 0, sizeof(*dte_addr));
+ sun50i_table_flush(sun50i_domain, dte_addr, 1);
+
+ pt_phys = sun50i_dte_get_pt_address(dte);
+ dma_unmap_single(iommu->dev, pt_phys, PT_SIZE, DMA_TO_DEVICE);
+
+ page_table = phys_to_virt(pt_phys);
+ kmem_cache_free(iommu->pt_pool, page_table);
+ }
+
+ spin_unlock_irqrestore(&sun50i_domain->dt_lock, flags);
+
+ sun50i_iommu_disable(iommu);
+
+ dma_unmap_single(iommu->dev, virt_to_phys(sun50i_domain->dt),
+ DT_SIZE, DMA_TO_DEVICE);
+
+ iommu->domain = NULL;
+}
+
+static void sun50i_iommu_detach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct sun50i_iommu *iommu = fwspec->iommu_priv;
+
+ dev_dbg(dev, "Detaching from IOMMU domain\n");
+
+ if (iommu->domain != domain)
+ return;
+
+ if (refcount_dec_and_test(&sun50i_domain->refcnt))
+ sun50i_iommu_detach_domain(iommu, sun50i_domain);
+}
+
+static int sun50i_iommu_attach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct sun50i_iommu *iommu;
+
+ iommu = sun50i_iommu_from_dev(dev);
+ if (!iommu)
+ return -ENODEV;
+
+ dev_dbg(dev, "Attaching to IOMMU domain\n");
+
+ refcount_inc(&sun50i_domain->refcnt);
+
+ if (iommu->domain == domain)
+ return 0;
+
+ if (iommu->domain)
+ sun50i_iommu_detach_device(iommu->domain, dev);
+
+ sun50i_iommu_attach_domain(iommu, sun50i_domain);
+
+ return 0;
+}
+
+static int sun50i_iommu_add_device(struct device *dev)
+{
+ struct sun50i_iommu *iommu;
+ struct iommu_group *group;
+
+ iommu = sun50i_iommu_from_dev(dev);
+ if (!iommu)
+ return -ENODEV;
+
+ group = iommu_group_get_for_dev(dev);
+ if (IS_ERR(group))
+ return PTR_ERR(group);
+
+ iommu_group_put(group);
+
+ return 0;
+}
+
+static void sun50i_iommu_remove_device(struct device *dev)
+{
+ iommu_group_remove_device(dev);
+}
+
+static struct iommu_group *sun50i_iommu_device_group(struct device *dev)
+{
+ struct sun50i_iommu *iommu = sun50i_iommu_from_dev(dev);
+
+ return iommu_group_ref_get(iommu->group);
+}
+
+static int sun50i_iommu_of_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
+ unsigned id = args->args[0];
+
+ fwspec->iommu_priv = platform_get_drvdata(iommu_pdev);
+
+ return iommu_fwspec_add_ids(dev, &id, 1);
+}
+
+static struct iommu_ops sun50i_iommu_ops = {
+ .pgsize_bitmap = SZ_4K,
+ .map = sun50i_iommu_map,
+ .unmap = sun50i_iommu_unmap,
+ .domain_alloc = sun50i_iommu_domain_alloc,
+ .domain_free = sun50i_iommu_domain_free,
+ .attach_dev = sun50i_iommu_attach_device,
+ .detach_dev = sun50i_iommu_detach_device,
+ .add_device = sun50i_iommu_add_device,
+ .remove_device = sun50i_iommu_remove_device,
+ .device_group = sun50i_iommu_device_group,
+ .of_xlate = sun50i_iommu_of_xlate,
+ .iova_to_phys = sun50i_iommu_iova_to_phys,
+};
+
+static void sun50i_iommu_report_fault(struct sun50i_iommu *iommu,
+ unsigned master, phys_addr_t iova,
+ unsigned prot)
+{
+ dev_err(iommu->dev, "Page fault for %pad (master %d, dir %s)\n",
+ &iova, master, (prot == IOMMU_FAULT_WRITE) ? "wr" : "rd");
+
+ if (iommu->domain)
+ report_iommu_fault(iommu->domain, iommu->dev, iova, prot);
+ else
+ dev_err(iommu->dev, "Page fault while iommu not attached to any domain?\n");
+}
+
+static phys_addr_t sun50i_iommu_handle_pt_irq(struct sun50i_iommu *iommu,
+ unsigned addr_reg,
+ unsigned blame_reg)
+{
+ phys_addr_t iova;
+ unsigned master;
+ u32 blame;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ iova = iommu_read(iommu, addr_reg);
+ blame = iommu_read(iommu, blame_reg);
+ master = ilog2(blame & IOMMU_INT_MASTER_MASK);
+
+ /*
+ * If the address is not in the page table, we can't get what
+ * operation triggered the fault. Assume it's a read
+ * operation.
+ */
+ sun50i_iommu_report_fault(iommu, master, iova, IOMMU_FAULT_READ);
+
+ return iova;
+}
+
+static phys_addr_t sun50i_iommu_handle_perm_irq(struct sun50i_iommu *iommu)
+{
+ enum sun50i_iommu_aci aci;
+ phys_addr_t iova;
+ unsigned master;
+ unsigned dir;
+ u32 blame;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ blame = iommu_read(iommu, IOMMU_INT_STA_REG);
+ master = ilog2(blame & IOMMU_INT_MASTER_MASK);
+ iova = iommu_read(iommu, IOMMU_INT_ERR_ADDR_REG(master));
+ aci = sun50i_get_pte_aci(iommu_read(iommu,
+ IOMMU_INT_ERR_DATA_REG(master)));
+
+ switch (aci) {
+ /*
+ * If we are in the read-only domain, then it means we
+ * tried to write.
+ */
+ case SUN50I_IOMMU_ACI_RD:
+ dir = IOMMU_FAULT_WRITE;
+ break;
+
+ /*
+ * If we are in the write-only domain, then it means
+ * we tried to read.
+ */
+ case SUN50I_IOMMU_ACI_WR:
+
+ /*
+ * If we are in the domain without any permission, we
+ * can't really tell. Let's default to a read
+ * operation.
+ */
+ case SUN50I_IOMMU_ACI_NONE:
+
+ /* WTF? */
+ case SUN50I_IOMMU_ACI_RD_WR:
+ default:
+ dir = IOMMU_FAULT_READ;
+ break;
+ }
+
+ /*
+ * If the address is not in the page table, we can't get what
+ * operation triggered the fault. Assume it's a read
+ * operation.
+ */
+ sun50i_iommu_report_fault(iommu, master, iova, dir);
+
+ return iova;
+}
+
+static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+{
+ struct sun50i_iommu *iommu = dev_id;
+ phys_addr_t iova;
+ u32 status;
+
+ spin_lock(&iommu->iommu_lock);
+
+ status = iommu_read(iommu, IOMMU_INT_STA_REG);
+ if (!(status & IOMMU_INT_MASK)) {
+ spin_unlock(&iommu->iommu_lock);
+ return IRQ_NONE;
+ }
+
+ if (status & IOMMU_INT_INVALID_L2PG)
+ iova = sun50i_iommu_handle_pt_irq(iommu,
+ IOMMU_INT_ERR_ADDR_L2_REG,
+ IOMMU_L2PG_INT_REG);
+ else if (status & IOMMU_INT_INVALID_L1PG)
+ iova = sun50i_iommu_handle_pt_irq(iommu,
+ IOMMU_INT_ERR_ADDR_L1_REG,
+ IOMMU_L1PG_INT_REG);
+ else
+ iova = sun50i_iommu_handle_perm_irq(iommu);
+
+ sun50i_iommu_tlb_invalidate(iommu, iova);
+ sun50i_iommu_ptw_invalidate(iommu, iova);
+
+ iommu_write(iommu, IOMMU_INT_CLR_REG, status);
+
+ iommu_write(iommu, IOMMU_RESET_REG, ~status);
+ iommu_write(iommu, IOMMU_RESET_REG, status);
+
+ spin_unlock(&iommu->iommu_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int sun50i_iommu_probe(struct platform_device *pdev)
+{
+ struct sun50i_iommu *iommu;
+ int ret, irq;
+
+ iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL);
+ if (!iommu)
+ return -ENOMEM;
+ spin_lock_init(&iommu->iommu_lock);
+ platform_set_drvdata(pdev, iommu);
+ iommu->dev = &pdev->dev;
+
+ iommu->pt_pool = kmem_cache_create(dev_name(&pdev->dev),
+ PT_SIZE, PT_SIZE,
+ SLAB_HWCACHE_ALIGN,
+ NULL);
+ if (!iommu->pt_pool)
+ return -ENOMEM;
+
+ iommu->group = iommu_group_alloc();
+ if (IS_ERR(iommu->group)) {
+ ret = PTR_ERR(iommu->group);
+ goto err_free_cache;
+ }
+
+ iommu->base = devm_platform_ioremap_resource(pdev, 0);
+ if (!iommu->base) {
+ ret = PTR_ERR(iommu->base);
+ goto err_free_group;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ ret = irq;
+ goto err_free_group;
+ }
+
+ iommu->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(iommu->clk)) {
+ dev_err(&pdev->dev, "Couldn't get our clock.\n");
+ ret = PTR_ERR(iommu->clk);
+ goto err_free_group;
+ }
+
+ iommu->reset = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(iommu->reset)) {
+ dev_err(&pdev->dev, "Couldn't get our reset line.\n");
+ ret = PTR_ERR(iommu->reset);
+ goto err_free_group;
+ }
+
+ ret = iommu_device_sysfs_add(&iommu->iommu, &pdev->dev,
+ NULL, dev_name(&pdev->dev));
+ if (ret)
+ goto err_free_group;
+
+ iommu_device_set_ops(&iommu->iommu, &sun50i_iommu_ops);
+ iommu_device_set_fwnode(&iommu->iommu, &pdev->dev.of_node->fwnode);
+
+ ret = iommu_device_register(&iommu->iommu);
+ if (ret)
+ goto err_remove_sysfs;
+
+ ret = devm_request_irq(&pdev->dev, irq, sun50i_iommu_irq, 0,
+ dev_name(&pdev->dev), iommu);
+ if (ret < 0)
+ goto err_unregister;
+
+ bus_set_iommu(&platform_bus_type, &sun50i_iommu_ops);
+
+ return 0;
+
+err_unregister:
+ iommu_device_unregister(&iommu->iommu);
+
+err_remove_sysfs:
+ iommu_device_sysfs_remove(&iommu->iommu);
+
+err_free_group:
+ iommu_group_put(iommu->group);
+
+err_free_cache:
+ kmem_cache_destroy(iommu->pt_pool);
+
+ return ret;
+}
+
+static const struct of_device_id sun50i_iommu_dt[] = {
+ { .compatible = "allwinner,sun50i-h6-iommu", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sun50i_iommu_dt);
+
+static struct platform_driver sun50i_iommu_driver = {
+ .driver = {
+ .name = "sun50i-iommu",
+ .of_match_table = sun50i_iommu_dt,
+ .suppress_bind_attrs = true,
+ }
+};
+builtin_platform_driver_probe(sun50i_iommu_driver, sun50i_iommu_probe);
+
+MODULE_DESCRIPTION("Allwinner H6 IOMMU driver");
+MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_AUTHOR("zhuxianbin <zhuxianbin@allwinnertech.com>");
+MODULE_LICENSE("Dual BSD/GPL");
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 4/4] drm/sun4i: mixer: Call of_dma_configure if there's an IOMMU
From: Maxime Ripard @ 2020-02-20 18:15 UTC (permalink / raw)
To: Joerg Roedel, Chen-Yu Tsai, Maxime Ripard, Mark Rutland,
Rob Herring, Frank Rowand
Cc: devicetree, iommu, Maxime Ripard, linux-arm-kernel
In-Reply-To: <cover.a31c229a83f1d92e6928ae2adb70887da0fd44b3.1582222496.git-series.maxime@cerno.tech>
The main DRM device is actually a virtual device so it doesn't have the
iommus property, which is instead on the DMA masters, in this case the
mixers.
Add a call to of_dma_configure with the mixers DT node but on the DRM
virtual device to configure it in the same way than the mixers.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 7c24f8f832a5..85b8930e334c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -372,6 +372,19 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
mixer->engine.ops = &sun8i_engine_ops;
mixer->engine.node = dev->of_node;
+ if (of_find_property(dev->of_node, "iommus", NULL)) {
+ /*
+ * This assume we have the same DMA constraints for
+ * all our the mixers in our pipeline. This sounds
+ * bad, but it has always been the case for us, and
+ * DRM doesn't do per-device allocation either, so we
+ * would need to fix DRM first...
+ */
+ ret = of_dma_configure(drm->dev, dev->of_node, true);
+ if (ret)
+ return ret;
+ }
+
/*
* While this function can fail, we shouldn't do anything
* if this happens. Some early DE2 DT entries don't provide
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [v2 PATCH] mm: shmem: allow split THP when truncating THP partially
From: Alexander Duyck @ 2020-02-20 18:16 UTC (permalink / raw)
To: Yang Shi, Michael S. Tsirkin, David Hildenbrand
Cc: Hugh Dickins, Kirill A. Shutemov, Andrea Arcangeli, Andrew Morton,
linux-mm, LKML
In-Reply-To: <1575420174-19171-1-git-send-email-yang.shi@linux.alibaba.com>
On Tue, Dec 3, 2019 at 4:43 PM Yang Shi <yang.shi@linux.alibaba.com> wrote:
>
> Currently when truncating shmem file, if the range is partial of THP
> (start or end is in the middle of THP), the pages actually will just get
> cleared rather than being freed unless the range cover the whole THP.
> Even though all the subpages are truncated (randomly or sequentially),
> the THP may still be kept in page cache. This might be fine for some
> usecases which prefer preserving THP.
>
> But, when doing balloon inflation in QEMU, QEMU actually does hole punch
> or MADV_DONTNEED in base page size granulairty if hugetlbfs is not used.
> So, when using shmem THP as memory backend QEMU inflation actually doesn't
> work as expected since it doesn't free memory. But, the inflation
> usecase really needs get the memory freed. Anonymous THP will not get
> freed right away too but it will be freed eventually when all subpages are
> unmapped, but shmem THP would still stay in page cache.
>
> Split THP right away when doing partial hole punch, and if split fails
> just clear the page so that read to the hole punched area would return
> zero.
>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Signed-off-by: Yang Shi <yang.shi@linux.alibaba.com>
One question I would have is if this is really the desired behavior we
are looking for?
By proactively splitting the THP you are likely going to see a
performance regression with the virtio-balloon driver enabled in QEMU.
I would suspect the response to that would be to update the QEMU code
to identify the page size of the shared memory ramblock. At that
point I suspect it would start behaving the same as how it currently
handles anonymous memory, and the work done here would essentially
have been wasted other than triggering the desire to resolve this in
QEMU to avoid a performance regression.
The code for inflating a the balloon in virtio-balloon in QEMU can be
found here:
https://github.com/qemu/qemu/blob/master/hw/virtio/virtio-balloon.c#L66
If there is a way for us to just populate the value obtained via
qemu_ram_pagesize with the THP page size instead of leaving it at 4K,
which is the size I am assuming it is at since you indicated that it
is just freeing the base page size, then we could address the same
issue and likely get the desired outcome of freeing the entire THP
page when it is no longer used.
- Alex
^ permalink raw reply
* Re: RFC: Split EPT huge pages in advance of dirty logging
From: Peter Xu @ 2020-02-20 18:17 UTC (permalink / raw)
To: Ben Gardon
Cc: Zhoujian (jay), Junaid Shahid, kvm@vger.kernel.org,
qemu-devel@nongnu.org, pbonzini@redhat.com, dgilbert@redhat.com,
quintela@redhat.com, Liujinsong (Paul), linfeng (M), wangxin (U),
Huangweidong (C)
In-Reply-To: <CANgfPd-P_=GqcMiwLSSkUhZDt42aMLUsCJt+CPdUN5yR3RLHmQ@mail.gmail.com>
On Thu, Feb 20, 2020 at 09:34:52AM -0800, Ben Gardon wrote:
> On Thu, Feb 20, 2020 at 5:53 AM Zhoujian (jay) <jianjay.zhou@huawei.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Peter Xu [mailto:peterx@redhat.com]
> > > Sent: Thursday, February 20, 2020 1:19 AM
> > > To: Zhoujian (jay) <jianjay.zhou@huawei.com>
> > > Cc: kvm@vger.kernel.org; qemu-devel@nongnu.org; pbonzini@redhat.com;
> > > dgilbert@redhat.com; quintela@redhat.com; Liujinsong (Paul)
> > > <liu.jinsong@huawei.com>; linfeng (M) <linfeng23@huawei.com>; wangxin (U)
> > > <wangxinxin.wang@huawei.com>; Huangweidong (C)
> > > <weidong.huang@huawei.com>
> > > Subject: Re: RFC: Split EPT huge pages in advance of dirty logging
> > >
> > > On Wed, Feb 19, 2020 at 01:19:08PM +0000, Zhoujian (jay) wrote:
> > > > Hi Peter,
> > > >
> > > > > -----Original Message-----
> > > > > From: Peter Xu [mailto:peterx@redhat.com]
> > > > > Sent: Wednesday, February 19, 2020 1:43 AM
> > > > > To: Zhoujian (jay) <jianjay.zhou@huawei.com>
> > > > > Cc: kvm@vger.kernel.org; qemu-devel@nongnu.org;
> > > pbonzini@redhat.com;
> > > > > dgilbert@redhat.com; quintela@redhat.com; Liujinsong (Paul)
> > > > > <liu.jinsong@huawei.com>; linfeng (M) <linfeng23@huawei.com>;
> > > > > wangxin (U) <wangxinxin.wang@huawei.com>; Huangweidong (C)
> > > > > <weidong.huang@huawei.com>
> > > > > Subject: Re: RFC: Split EPT huge pages in advance of dirty logging
> > > > >
> > > > > On Tue, Feb 18, 2020 at 01:13:47PM +0000, Zhoujian (jay) wrote:
> > > > > > Hi all,
> > > > > >
> > > > > > We found that the guest will be soft-lockup occasionally when live
> > > > > > migrating a 60 vCPU, 512GiB huge page and memory sensitive VM. The
> > > > > > reason is clear, almost all of the vCPUs are waiting for the KVM
> > > > > > MMU spin-lock to create 4K SPTEs when the huge pages are write
> > > > > > protected. This
> > > > > phenomenon is also described in this patch set:
> > > > > > https://patchwork.kernel.org/cover/11163459/
> > > > > > which aims to handle page faults in parallel more efficiently.
> > > > > >
> > > > > > Our idea is to use the migration thread to touch all of the guest
> > > > > > memory in the granularity of 4K before enabling dirty logging. To
> > > > > > be more specific, we split all the PDPE_LEVEL SPTEs into
> > > > > > DIRECTORY_LEVEL SPTEs as the first step, and then split all the
> > > > > > DIRECTORY_LEVEL SPTEs into
> > > > > PAGE_TABLE_LEVEL SPTEs as the following step.
> > > > >
> > > > > IIUC, QEMU will prefer to use huge pages for all the anonymous
> > > > > ramblocks (please refer to ram_block_add):
> > > > >
> > > > > qemu_madvise(new_block->host, new_block->max_length,
> > > > > QEMU_MADV_HUGEPAGE);
> > > >
> > > > Yes, you're right
> > > >
> > > > >
> > > > > Another alternative I can think of is to add an extra parameter to
> > > > > QEMU to explicitly disable huge pages (so that can even be
> > > > > MADV_NOHUGEPAGE instead of MADV_HUGEPAGE). However that
> > > should also
> > > > > drag down the performance for the whole lifecycle of the VM.
> > > >
> > > > From the performance point of view, it is better to keep the huge
> > > > pages when the VM is not in the live migration state.
> > > >
> > > > > A 3rd option is to make a QMP
> > > > > command to dynamically turn huge pages on/off for ramblocks globally.
> > > >
> > > > We're searching a dynamic method too.
> > > > We plan to add two new flags for each memory slot, say
> > > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES and
> > > > KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES. These flags can be set through
> > > > KVM_SET_USER_MEMORY_REGION ioctl.
[1]
> > > >
> > > > The mapping_level which is called by tdp_page_fault in the kernel side
> > > > will return PT_DIRECTORY_LEVEL if the
> > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES
> > > > flag of the memory slot is set, and return PT_PAGE_TABLE_LEVEL if the
> > > > KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES flag is set.
> > > >
> > > > The key steps to split the huge pages in advance of enabling dirty log
> > > > is as follows:
> > > > 1. The migration thread in user space uses
> > > KVM_SET_USER_MEMORY_REGION
> > > > ioctl to set the KVM_MEM_FORCE_PT_DIRECTORY_PAGES flag for each
> > > memory
> > > > slot.
> > > > 2. The migration thread continues to use the KVM_SPLIT_HUGE_PAGES
> > > > ioctl (which is newly added) to do the splitting of large pages in the
> > > > kernel side.
> > > > 3. A new vCPU is created temporally(do some initialization but will
> > > > not
> > > > run) to help to do the work, i.e. as the parameter of the tdp_page_fault.
> > > > 4. Collect the GPA ranges of all the memory slots with the
> > > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES flag set.
> > > > 5. Split the 1G huge pages(collected in step 4) into 2M by calling
> > > > tdp_page_fault, since the mapping_level will return
> > > > PT_DIRECTORY_LEVEL. Here is the main difference from the usual path
> > > > which is caused by the Guest side(EPT violation/misconfig etc), we
> > > > call it directly in the hypervisor side.
> > > > 6. Do some cleanups, i.e. free the vCPU related resources 7. The
> > > > KVM_SPLIT_HUGE_PAGES ioctl returned to the user space side.
> > > > 8. Using KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES instread of
> > > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES to repeat step 1 ~ step 7, in step
> > > 5
> > > > the 2M huge pages will be splitted into 4K pages.
> > > > 9. Clear the KVM_MEM_FORCE_PT_DIRECTORY_PAGES and
> > > > KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES flags for each memory slot.
> > > > 10. Then the migration thread calls the log_start ioctl to enable the
> > > > dirty logging, and the remaining thing is the same.
> > >
> > > I'm not sure... I think it would be good if there is a way to have finer granularity
> > > control on using huge pages for any process, then KVM can directly leverage
> > > that because KVM page tables should always respect the mm configurations on
> > > these (so e.g. when huge page split, KVM gets notifications via mmu notifiers).
> > > Have you thought of such a more general way?
> >
> > I did have thought of this, if we split the huge pages into 4K of a process, I'm
> > afraid it will not be workable for the huge pages sharing scenario, e.g. DPDK,
> > SPDK etc. So, only split the EPT page table and keep the VM process page table
> > (e.g. qemu) untouched is the goal.
Ah I see your point now.
> >
> > >
> > > (And I just noticed that MADV_NOHUGEPAGE is only a hint to khugepaged
> > > and probably won't split any huge page at all after madvise() returns..)
> > > To tell the truth I'm still confused on how split of huge pages helped in your
> > > case...
> >
> > I'm sorry if the meaning is not expressed clearly, and thanks for your patience.
> >
> > > If I read it right the test reduced some execution time from 9s to a
> > > few ms after your splittion of huge pages.
> >
> > Yes
> >
> > > The thing is I don't see how split of
> > > huge pages could solve the mmu_lock contention with the huge VM, because
> > > IMO even if we split the huge pages into smaller ones, those pages should still
> > > be write-protected and need merely the same number of page faults to resolve
> > > when accessed/written? And I thought that should only be fixed with
> > > solutions like what Ben has proposed with the MMU rework. Could you show
> > > me what I've missed?
> >
> > Let me try to describe the reason of mmu_lock contention more clearly and the
> > effort we tried to do...
> > The huge VM only has EPT >= level 2 sptes, and level 1 sptes don't
> > exist at the beginning. Write protect all the huge pages will trigger EPT
> > violation to create level 1 sptes for all the vCPUs which want to write the
> > content of the memory. Different vCPU write the different areas of
> > the memory, but they need the same kvm->mmu_lock to create the level 1
> > sptes, this situation will be worse if the number of vCPU and the memory of
> > VM is large(in our case 60U512G), meanwhile the VM has
> > memory-write-intensive work to do. In order to reduce the mmu_lock
> > contention, we try to: write protect VM memory gradually in small chunks,
> > such as 1G or 2M. Using a vCPU temporary creately by migration thread to
> > split 1G to 2M as the first step, and to split 2M to 4K as the second step
> > (this is a little hacking...and I do not know any side effect will be triggered
> > indeed).
> > Comparing to write protect all VM memory in one go, the write
> > protected range is limited in this way and only the vCPUs write this limited
> > range will be involved to take the mmu_lock. The contention will be reduced
> > since the memory range is small and the number of vCPU involved is small
> > too.
> >
> > Of course, it will take some extra time to split all the huge pages into 4K
> > page before the real migration started, about 60s for 512G in my experiment.
> >
> > During the memory iterative copy phase, PML will do the dirty logging work
> > (not write protected case for 4K), or IIRC using fast_page_fault to mark page
> > dirty if PML is not supported, which case the mmu_lock does not needed.
Yes I missed both of these. Thanks for explaining!
Then it makes sense at least to me with your idea. Though instead of
the KVM_MEM_FORCE_PT_* naming [1], we can also embed allowed page
sizes for the memslot into the flags using a few bits, with another
new kvm cap.
> >
> > Regards,
> > Jay Zhou
>
> (Ah I top-posted I'm sorry. Re-sending at the bottom.)
>
> FWIW, we currently do this eager splitting at Google for live
> migration. When the log-dirty-memory flag is set on a memslot we
> eagerly split all pages in the slot down to 4k granularity.
> As Jay said, this does not cause crippling lock contention because the
> vCPU page faults generated by write protection / splitting can be
> resolved in the fast page fault path without acquiring the MMU lock.
> I believe +Junaid Shahid tried to upstream this approach at some point
> in the past, but the patch set didn't make it in. (This was before my
> time, so I'm hoping he has a link.)
> I haven't done the analysis to know if eager splitting is more or less
> efficient with parallel slow-path page faults, but it's definitely
> faster under the MMU lock.
Yes, totally agreed. Though comparing to eager splitting (which might
still need a new capabilility for the changed behavior after all, not
sure...), the per-memslot hint solution looks slightly nicer to me,
imho, because it can offer more mechanism than policy.
Thanks,
--
Peter Xu
^ permalink raw reply
* Re: [Intel-gfx] [PATCH 07/12] drm: Shrink mode->type to u8
From: Daniel Vetter @ 2020-02-20 18:17 UTC (permalink / raw)
To: Ville Syrjala; +Cc: intel-gfx, dri-devel
In-Reply-To: <20200219203544.31013-8-ville.syrjala@linux.intel.com>
On Wed, Feb 19, 2020 at 10:35:39PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> We only have 7 bits defined for mode->type. Shrink the storage to u8.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
> include/drm/drm_modes.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
> index 2bb2b1a8592a..5c20285cc317 100644
> --- a/include/drm/drm_modes.h
> +++ b/include/drm/drm_modes.h
> @@ -270,7 +270,7 @@ struct drm_display_mode {
> * which are stuck around for hysterical raisins only. No one has an
> * idea what they were meant for. Don't use.
> */
> - unsigned int type;
> + u8 type;
Unfortunately DRM_MODE_TYPE_DRIVER is the largest and still in use,
otherwise we could have cut off a few more bits here :-)
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> /**
> * @clock:
> --
> 2.24.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [Intel-gfx] [PATCH 07/12] drm: Shrink mode->type to u8
From: Daniel Vetter @ 2020-02-20 18:17 UTC (permalink / raw)
To: Ville Syrjala; +Cc: intel-gfx, dri-devel
In-Reply-To: <20200219203544.31013-8-ville.syrjala@linux.intel.com>
On Wed, Feb 19, 2020 at 10:35:39PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> We only have 7 bits defined for mode->type. Shrink the storage to u8.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
> include/drm/drm_modes.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
> index 2bb2b1a8592a..5c20285cc317 100644
> --- a/include/drm/drm_modes.h
> +++ b/include/drm/drm_modes.h
> @@ -270,7 +270,7 @@ struct drm_display_mode {
> * which are stuck around for hysterical raisins only. No one has an
> * idea what they were meant for. Don't use.
> */
> - unsigned int type;
> + u8 type;
Unfortunately DRM_MODE_TYPE_DRIVER is the largest and still in use,
otherwise we could have cut off a few more bits here :-)
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> /**
> * @clock:
> --
> 2.24.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* Re: RFC: Split EPT huge pages in advance of dirty logging
From: Peter Xu @ 2020-02-20 18:17 UTC (permalink / raw)
To: Ben Gardon
Cc: Junaid Shahid, Liujinsong (Paul), linfeng (M),
kvm@vger.kernel.org, quintela@redhat.com, wangxin (U),
dgilbert@redhat.com, qemu-devel@nongnu.org, Zhoujian (jay),
pbonzini@redhat.com, Huangweidong (C)
In-Reply-To: <CANgfPd-P_=GqcMiwLSSkUhZDt42aMLUsCJt+CPdUN5yR3RLHmQ@mail.gmail.com>
On Thu, Feb 20, 2020 at 09:34:52AM -0800, Ben Gardon wrote:
> On Thu, Feb 20, 2020 at 5:53 AM Zhoujian (jay) <jianjay.zhou@huawei.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Peter Xu [mailto:peterx@redhat.com]
> > > Sent: Thursday, February 20, 2020 1:19 AM
> > > To: Zhoujian (jay) <jianjay.zhou@huawei.com>
> > > Cc: kvm@vger.kernel.org; qemu-devel@nongnu.org; pbonzini@redhat.com;
> > > dgilbert@redhat.com; quintela@redhat.com; Liujinsong (Paul)
> > > <liu.jinsong@huawei.com>; linfeng (M) <linfeng23@huawei.com>; wangxin (U)
> > > <wangxinxin.wang@huawei.com>; Huangweidong (C)
> > > <weidong.huang@huawei.com>
> > > Subject: Re: RFC: Split EPT huge pages in advance of dirty logging
> > >
> > > On Wed, Feb 19, 2020 at 01:19:08PM +0000, Zhoujian (jay) wrote:
> > > > Hi Peter,
> > > >
> > > > > -----Original Message-----
> > > > > From: Peter Xu [mailto:peterx@redhat.com]
> > > > > Sent: Wednesday, February 19, 2020 1:43 AM
> > > > > To: Zhoujian (jay) <jianjay.zhou@huawei.com>
> > > > > Cc: kvm@vger.kernel.org; qemu-devel@nongnu.org;
> > > pbonzini@redhat.com;
> > > > > dgilbert@redhat.com; quintela@redhat.com; Liujinsong (Paul)
> > > > > <liu.jinsong@huawei.com>; linfeng (M) <linfeng23@huawei.com>;
> > > > > wangxin (U) <wangxinxin.wang@huawei.com>; Huangweidong (C)
> > > > > <weidong.huang@huawei.com>
> > > > > Subject: Re: RFC: Split EPT huge pages in advance of dirty logging
> > > > >
> > > > > On Tue, Feb 18, 2020 at 01:13:47PM +0000, Zhoujian (jay) wrote:
> > > > > > Hi all,
> > > > > >
> > > > > > We found that the guest will be soft-lockup occasionally when live
> > > > > > migrating a 60 vCPU, 512GiB huge page and memory sensitive VM. The
> > > > > > reason is clear, almost all of the vCPUs are waiting for the KVM
> > > > > > MMU spin-lock to create 4K SPTEs when the huge pages are write
> > > > > > protected. This
> > > > > phenomenon is also described in this patch set:
> > > > > > https://patchwork.kernel.org/cover/11163459/
> > > > > > which aims to handle page faults in parallel more efficiently.
> > > > > >
> > > > > > Our idea is to use the migration thread to touch all of the guest
> > > > > > memory in the granularity of 4K before enabling dirty logging. To
> > > > > > be more specific, we split all the PDPE_LEVEL SPTEs into
> > > > > > DIRECTORY_LEVEL SPTEs as the first step, and then split all the
> > > > > > DIRECTORY_LEVEL SPTEs into
> > > > > PAGE_TABLE_LEVEL SPTEs as the following step.
> > > > >
> > > > > IIUC, QEMU will prefer to use huge pages for all the anonymous
> > > > > ramblocks (please refer to ram_block_add):
> > > > >
> > > > > qemu_madvise(new_block->host, new_block->max_length,
> > > > > QEMU_MADV_HUGEPAGE);
> > > >
> > > > Yes, you're right
> > > >
> > > > >
> > > > > Another alternative I can think of is to add an extra parameter to
> > > > > QEMU to explicitly disable huge pages (so that can even be
> > > > > MADV_NOHUGEPAGE instead of MADV_HUGEPAGE). However that
> > > should also
> > > > > drag down the performance for the whole lifecycle of the VM.
> > > >
> > > > From the performance point of view, it is better to keep the huge
> > > > pages when the VM is not in the live migration state.
> > > >
> > > > > A 3rd option is to make a QMP
> > > > > command to dynamically turn huge pages on/off for ramblocks globally.
> > > >
> > > > We're searching a dynamic method too.
> > > > We plan to add two new flags for each memory slot, say
> > > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES and
> > > > KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES. These flags can be set through
> > > > KVM_SET_USER_MEMORY_REGION ioctl.
[1]
> > > >
> > > > The mapping_level which is called by tdp_page_fault in the kernel side
> > > > will return PT_DIRECTORY_LEVEL if the
> > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES
> > > > flag of the memory slot is set, and return PT_PAGE_TABLE_LEVEL if the
> > > > KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES flag is set.
> > > >
> > > > The key steps to split the huge pages in advance of enabling dirty log
> > > > is as follows:
> > > > 1. The migration thread in user space uses
> > > KVM_SET_USER_MEMORY_REGION
> > > > ioctl to set the KVM_MEM_FORCE_PT_DIRECTORY_PAGES flag for each
> > > memory
> > > > slot.
> > > > 2. The migration thread continues to use the KVM_SPLIT_HUGE_PAGES
> > > > ioctl (which is newly added) to do the splitting of large pages in the
> > > > kernel side.
> > > > 3. A new vCPU is created temporally(do some initialization but will
> > > > not
> > > > run) to help to do the work, i.e. as the parameter of the tdp_page_fault.
> > > > 4. Collect the GPA ranges of all the memory slots with the
> > > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES flag set.
> > > > 5. Split the 1G huge pages(collected in step 4) into 2M by calling
> > > > tdp_page_fault, since the mapping_level will return
> > > > PT_DIRECTORY_LEVEL. Here is the main difference from the usual path
> > > > which is caused by the Guest side(EPT violation/misconfig etc), we
> > > > call it directly in the hypervisor side.
> > > > 6. Do some cleanups, i.e. free the vCPU related resources 7. The
> > > > KVM_SPLIT_HUGE_PAGES ioctl returned to the user space side.
> > > > 8. Using KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES instread of
> > > > KVM_MEM_FORCE_PT_DIRECTORY_PAGES to repeat step 1 ~ step 7, in step
> > > 5
> > > > the 2M huge pages will be splitted into 4K pages.
> > > > 9. Clear the KVM_MEM_FORCE_PT_DIRECTORY_PAGES and
> > > > KVM_MEM_FORCE_PT_PAGE_TABLE_PAGES flags for each memory slot.
> > > > 10. Then the migration thread calls the log_start ioctl to enable the
> > > > dirty logging, and the remaining thing is the same.
> > >
> > > I'm not sure... I think it would be good if there is a way to have finer granularity
> > > control on using huge pages for any process, then KVM can directly leverage
> > > that because KVM page tables should always respect the mm configurations on
> > > these (so e.g. when huge page split, KVM gets notifications via mmu notifiers).
> > > Have you thought of such a more general way?
> >
> > I did have thought of this, if we split the huge pages into 4K of a process, I'm
> > afraid it will not be workable for the huge pages sharing scenario, e.g. DPDK,
> > SPDK etc. So, only split the EPT page table and keep the VM process page table
> > (e.g. qemu) untouched is the goal.
Ah I see your point now.
> >
> > >
> > > (And I just noticed that MADV_NOHUGEPAGE is only a hint to khugepaged
> > > and probably won't split any huge page at all after madvise() returns..)
> > > To tell the truth I'm still confused on how split of huge pages helped in your
> > > case...
> >
> > I'm sorry if the meaning is not expressed clearly, and thanks for your patience.
> >
> > > If I read it right the test reduced some execution time from 9s to a
> > > few ms after your splittion of huge pages.
> >
> > Yes
> >
> > > The thing is I don't see how split of
> > > huge pages could solve the mmu_lock contention with the huge VM, because
> > > IMO even if we split the huge pages into smaller ones, those pages should still
> > > be write-protected and need merely the same number of page faults to resolve
> > > when accessed/written? And I thought that should only be fixed with
> > > solutions like what Ben has proposed with the MMU rework. Could you show
> > > me what I've missed?
> >
> > Let me try to describe the reason of mmu_lock contention more clearly and the
> > effort we tried to do...
> > The huge VM only has EPT >= level 2 sptes, and level 1 sptes don't
> > exist at the beginning. Write protect all the huge pages will trigger EPT
> > violation to create level 1 sptes for all the vCPUs which want to write the
> > content of the memory. Different vCPU write the different areas of
> > the memory, but they need the same kvm->mmu_lock to create the level 1
> > sptes, this situation will be worse if the number of vCPU and the memory of
> > VM is large(in our case 60U512G), meanwhile the VM has
> > memory-write-intensive work to do. In order to reduce the mmu_lock
> > contention, we try to: write protect VM memory gradually in small chunks,
> > such as 1G or 2M. Using a vCPU temporary creately by migration thread to
> > split 1G to 2M as the first step, and to split 2M to 4K as the second step
> > (this is a little hacking...and I do not know any side effect will be triggered
> > indeed).
> > Comparing to write protect all VM memory in one go, the write
> > protected range is limited in this way and only the vCPUs write this limited
> > range will be involved to take the mmu_lock. The contention will be reduced
> > since the memory range is small and the number of vCPU involved is small
> > too.
> >
> > Of course, it will take some extra time to split all the huge pages into 4K
> > page before the real migration started, about 60s for 512G in my experiment.
> >
> > During the memory iterative copy phase, PML will do the dirty logging work
> > (not write protected case for 4K), or IIRC using fast_page_fault to mark page
> > dirty if PML is not supported, which case the mmu_lock does not needed.
Yes I missed both of these. Thanks for explaining!
Then it makes sense at least to me with your idea. Though instead of
the KVM_MEM_FORCE_PT_* naming [1], we can also embed allowed page
sizes for the memslot into the flags using a few bits, with another
new kvm cap.
> >
> > Regards,
> > Jay Zhou
>
> (Ah I top-posted I'm sorry. Re-sending at the bottom.)
>
> FWIW, we currently do this eager splitting at Google for live
> migration. When the log-dirty-memory flag is set on a memslot we
> eagerly split all pages in the slot down to 4k granularity.
> As Jay said, this does not cause crippling lock contention because the
> vCPU page faults generated by write protection / splitting can be
> resolved in the fast page fault path without acquiring the MMU lock.
> I believe +Junaid Shahid tried to upstream this approach at some point
> in the past, but the patch set didn't make it in. (This was before my
> time, so I'm hoping he has a link.)
> I haven't done the analysis to know if eager splitting is more or less
> efficient with parallel slow-path page faults, but it's definitely
> faster under the MMU lock.
Yes, totally agreed. Though comparing to eager splitting (which might
still need a new capabilility for the changed behavior after all, not
sure...), the per-memslot hint solution looks slightly nicer to me,
imho, because it can offer more mechanism than policy.
Thanks,
--
Peter Xu
^ permalink raw reply
* Re: [PATCH 1/5] drm/sun4i: tcon: Introduce LVDS setup routine setting
From: Andrey Lebedev @ 2020-02-20 18:19 UTC (permalink / raw)
To: Maxime Ripard, Andrey Lebedev
Cc: wens, airlied, daniel, dri-devel, linux-arm-kernel, linux-kernel,
linux-sunxi
In-Reply-To: <20200220172154.22gw55s2mzyr45tj@gilmour.lan>
On 2/20/20 7:21 PM, Maxime Ripard wrote:
>> + regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
>> + SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
>> + SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
>> +
>> +}
>> +
> There's an extra blank line here that was reported by checkpatch. I've
> fixed it up while applying.
Weird, checkpatch didn't warn me about that:
./scripts/checkpatch.pl
patches/0001-drm-sun4i-tcon-Introduce-LVDS-setup-routine-setting.patch
total: 0 errors, 0 warnings, 103 lines checked
patches/0001-drm-sun4i-tcon-Introduce-LVDS-setup-routine-setting.patch
has no obvious style problems and is ready for submission.
In any case, thanks for correcting it!
--
Andrey Lebedev aka -.- . -.. -.. . .-.
Software engineer
Homepage: http://lebedev.lt/
^ permalink raw reply
* Re: [PATCH 1/5] drm/sun4i: tcon: Introduce LVDS setup routine setting
From: Andrey Lebedev @ 2020-02-20 18:19 UTC (permalink / raw)
To: Maxime Ripard, Andrey Lebedev
Cc: airlied, linux-sunxi, linux-kernel, dri-devel, wens, daniel,
linux-arm-kernel
In-Reply-To: <20200220172154.22gw55s2mzyr45tj@gilmour.lan>
On 2/20/20 7:21 PM, Maxime Ripard wrote:
>> + regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
>> + SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
>> + SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
>> +
>> +}
>> +
> There's an extra blank line here that was reported by checkpatch. I've
> fixed it up while applying.
Weird, checkpatch didn't warn me about that:
./scripts/checkpatch.pl
patches/0001-drm-sun4i-tcon-Introduce-LVDS-setup-routine-setting.patch
total: 0 errors, 0 warnings, 103 lines checked
patches/0001-drm-sun4i-tcon-Introduce-LVDS-setup-routine-setting.patch
has no obvious style problems and is ready for submission.
In any case, thanks for correcting it!
--
Andrey Lebedev aka -.- . -.. -.. . .-.
Software engineer
Homepage: http://lebedev.lt/
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [Intel-gfx] [PATCH 09/12] drm: Shrink drm_display_mode timings
From: Daniel Vetter @ 2020-02-20 18:19 UTC (permalink / raw)
To: Ville Syrjala; +Cc: intel-gfx, dri-devel
In-Reply-To: <20200219203544.31013-10-ville.syrjala@linux.intel.com>
On Wed, Feb 19, 2020 at 10:35:41PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Store the timings (apart from the clock) as u16. The uapi mode
> struct already uses u16 for everything so using something bigger
> internally doesn't really help us.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Makes sense I guess. This could mean some implicit pointer math is now no
longer auto-upgraded to big enough integers though ...
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
> drivers/gpu/drm/drm_modes.c | 7 ------
> include/drm/drm_modes.h | 46 ++++++++++++++++++-------------------
> 2 files changed, 23 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 0e7c9ba241c4..cc9fc52f9f7c 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1917,13 +1917,6 @@ EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode);
> void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
> const struct drm_display_mode *in)
> {
> - WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
> - in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
> - in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
> - in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
> - in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
> - "timing values too large for mode info\n");
> -
> out->clock = in->clock;
> out->hdisplay = in->hdisplay;
> out->hsync_start = in->hsync_start;
> diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
> index b28c0234fcd7..b585074945b5 100644
> --- a/include/drm/drm_modes.h
> +++ b/include/drm/drm_modes.h
> @@ -278,16 +278,16 @@ struct drm_display_mode {
> * Pixel clock in kHz.
> */
> int clock; /* in kHz */
> - int hdisplay;
> - int hsync_start;
> - int hsync_end;
> - int htotal;
> - int hskew;
> - int vdisplay;
> - int vsync_start;
> - int vsync_end;
> - int vtotal;
> - int vscan;
> + u16 hdisplay;
> + u16 hsync_start;
> + u16 hsync_end;
> + u16 htotal;
> + u16 hskew;
> + u16 vdisplay;
> + u16 vsync_start;
> + u16 vsync_end;
> + u16 vtotal;
> + u16 vscan;
> /**
> * @flags:
> *
> @@ -356,19 +356,19 @@ struct drm_display_mode {
> * difference is exactly a factor of 10.
> */
> int crtc_clock;
> - int crtc_hdisplay;
> - int crtc_hblank_start;
> - int crtc_hblank_end;
> - int crtc_hsync_start;
> - int crtc_hsync_end;
> - int crtc_htotal;
> - int crtc_hskew;
> - int crtc_vdisplay;
> - int crtc_vblank_start;
> - int crtc_vblank_end;
> - int crtc_vsync_start;
> - int crtc_vsync_end;
> - int crtc_vtotal;
> + u16 crtc_hdisplay;
> + u16 crtc_hblank_start;
> + u16 crtc_hblank_end;
> + u16 crtc_hsync_start;
> + u16 crtc_hsync_end;
> + u16 crtc_htotal;
> + u16 crtc_hskew;
> + u16 crtc_vdisplay;
> + u16 crtc_vblank_start;
> + u16 crtc_vblank_end;
> + u16 crtc_vsync_start;
> + u16 crtc_vsync_end;
> + u16 crtc_vtotal;
>
> /**
> * @private_flags:
> --
> 2.24.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* Re: [Intel-gfx] [PATCH 09/12] drm: Shrink drm_display_mode timings
From: Daniel Vetter @ 2020-02-20 18:19 UTC (permalink / raw)
To: Ville Syrjala; +Cc: intel-gfx, dri-devel
In-Reply-To: <20200219203544.31013-10-ville.syrjala@linux.intel.com>
On Wed, Feb 19, 2020 at 10:35:41PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Store the timings (apart from the clock) as u16. The uapi mode
> struct already uses u16 for everything so using something bigger
> internally doesn't really help us.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Makes sense I guess. This could mean some implicit pointer math is now no
longer auto-upgraded to big enough integers though ...
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
> drivers/gpu/drm/drm_modes.c | 7 ------
> include/drm/drm_modes.h | 46 ++++++++++++++++++-------------------
> 2 files changed, 23 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 0e7c9ba241c4..cc9fc52f9f7c 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1917,13 +1917,6 @@ EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode);
> void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
> const struct drm_display_mode *in)
> {
> - WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
> - in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
> - in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
> - in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
> - in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
> - "timing values too large for mode info\n");
> -
> out->clock = in->clock;
> out->hdisplay = in->hdisplay;
> out->hsync_start = in->hsync_start;
> diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
> index b28c0234fcd7..b585074945b5 100644
> --- a/include/drm/drm_modes.h
> +++ b/include/drm/drm_modes.h
> @@ -278,16 +278,16 @@ struct drm_display_mode {
> * Pixel clock in kHz.
> */
> int clock; /* in kHz */
> - int hdisplay;
> - int hsync_start;
> - int hsync_end;
> - int htotal;
> - int hskew;
> - int vdisplay;
> - int vsync_start;
> - int vsync_end;
> - int vtotal;
> - int vscan;
> + u16 hdisplay;
> + u16 hsync_start;
> + u16 hsync_end;
> + u16 htotal;
> + u16 hskew;
> + u16 vdisplay;
> + u16 vsync_start;
> + u16 vsync_end;
> + u16 vtotal;
> + u16 vscan;
> /**
> * @flags:
> *
> @@ -356,19 +356,19 @@ struct drm_display_mode {
> * difference is exactly a factor of 10.
> */
> int crtc_clock;
> - int crtc_hdisplay;
> - int crtc_hblank_start;
> - int crtc_hblank_end;
> - int crtc_hsync_start;
> - int crtc_hsync_end;
> - int crtc_htotal;
> - int crtc_hskew;
> - int crtc_vdisplay;
> - int crtc_vblank_start;
> - int crtc_vblank_end;
> - int crtc_vsync_start;
> - int crtc_vsync_end;
> - int crtc_vtotal;
> + u16 crtc_hdisplay;
> + u16 crtc_hblank_start;
> + u16 crtc_hblank_end;
> + u16 crtc_hsync_start;
> + u16 crtc_hsync_end;
> + u16 crtc_htotal;
> + u16 crtc_hskew;
> + u16 crtc_vdisplay;
> + u16 crtc_vblank_start;
> + u16 crtc_vblank_end;
> + u16 crtc_vsync_start;
> + u16 crtc_vsync_end;
> + u16 crtc_vtotal;
>
> /**
> * @private_flags:
> --
> 2.24.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [REGRESSION] gpio hogging fails with pinctrl gpio drivers
From: Russell King - ARM Linux admin @ 2020-02-20 18:19 UTC (permalink / raw)
To: Andrey Smirnov
Cc: Linus Walleij, open list:GPIO SUBSYSTEM, Peter Rosin, Linux ARM
In-Reply-To: <CAHQ1cqFeMKrb-MxnifVJXfGciQH8wsjS1dSSeTTc0R06jLT+Cw@mail.gmail.com>
On Thu, Feb 20, 2020 at 09:28:14AM -0800, Andrey Smirnov wrote:
> On Thu, Feb 20, 2020 at 12:18 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> >
> > On Thu, Feb 6, 2020 at 6:33 PM Russell King - ARM Linux admin
> > <linux@armlinux.org.uk> wrote:
> >
> > > It seems that sometime between 4.20 and 5.5, something has broken the
> > > ability to specify gpio-hogs in DT for GPIOs that are written around
> > > pinctrl drivers.
> > (explanation that makes perfect sense)
> > > Consequently, adding a gpio-hog to DT for this driver results in the
> > > driver endlessly returning -EPROBE_DEFER.
> >
> > I suspect this is sx150x-specific and suspect these two commits:
> >
> > 1a1d39e1b8dd pinctrl: sx150x: Register pinctrl before adding the gpiochip
> > b930151e5b55 pinctrl: sx150x: Add a static gpio/pinctrl pin range mapping
> >
> > I suppose people weren't using hogs very much with the sx150x and
> > it didn't turn up in testing so far.
> >
> > I don't think for example pinctrl-stmfx.c has this problem, as it registers
> > the pin ranges from the device tree as part of the core code.
> > But other drivers calling gpiochip_add_pin_range() may be experiencing
> > this.
> >
> > Peter/Andrey, do you have some idea? Have you tested this usecase (hogs)
> > with the sx150x?
> >
>
> Haven't done any GPIO hogging on sx150x, unfortunately. My use-cases were:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
>
> and
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/vf610-zii-scu4-aib.dts
>
> which didn't have any hogs so far (there's a chance Russell is using
> the former for his experiments, so maybe that'll change). I don't any
> useful input on this regression, sorry. I do have Rev C. board readily
> available, so I can provide Tested-by's if I am CC'd on fixes.
The ZII dev rev C is where I had the hog as a means of kicking the
88x3310 PHY out of reset.
I've now converted it to a proper MDIO bus-level reset, so I no
longer have the hog, and I no longer care about the regression - but
that's not to say it shouldn't be fixed, as the code is wrong.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
^ permalink raw reply
* Re: [meta-oe][PATCH 2/2] s3c24xx-gpio, s3c64xx-gpio, sjf2410-linux-native, usbpath, wmiconfig: remove old recipes
From: Khem Raj @ 2020-02-20 18:19 UTC (permalink / raw)
To: Martin Jansa, openembedded-devel
In-Reply-To: <20200220175235.367-2-Martin.Jansa@gmail.com>
On 2/20/20 9:52 AM, Martin Jansa wrote:
> * I don't expect anyone nowadays actually using these recipes which I've
> imported from meta-smartphone in 2011.
>
> Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
> ---
> .../packagegroups/packagegroup-meta-oe.bb | 8 +-
> .../0001-ppt.c-Do-not-include-sys-io.h.patch | 28 -
> .../samsung-soc-utils/s3c24xx-gpio_git.bb | 21 -
> .../samsung-soc-utils/s3c64xx-gpio_git.bb | 21 -
> .../sjf2410-linux-native_git.bb | 39 --
> .../usbpath/usbpath/configure.patch | 11 -
> .../recipes-support/usbpath/usbpath_git.bb | 21 -
> ...0001-makefile-Pass-CFLAGS-to-compile.patch | 26 -
> ...02-fix-err-API-to-have-format-string.patch | 656 ------------------
> .../wmiconfig/wmiconfig_git.bb | 24 -
> 10 files changed, 4 insertions(+), 851 deletions(-)
> delete mode 100644 meta-oe/recipes-support/samsung-soc-utils/files/0001-ppt.c-Do-not-include-sys-io.h.patch
> delete mode 100644 meta-oe/recipes-support/samsung-soc-utils/s3c24xx-gpio_git.bb
> delete mode 100644 meta-oe/recipes-support/samsung-soc-utils/s3c64xx-gpio_git.bb
> delete mode 100644 meta-oe/recipes-support/samsung-soc-utils/sjf2410-linux-native_git.bb
> delete mode 100644 meta-oe/recipes-support/usbpath/usbpath/configure.patch
> delete mode 100644 meta-oe/recipes-support/usbpath/usbpath_git.bb
> delete mode 100644 meta-oe/recipes-support/wmiconfig/wmiconfig/0001-makefile-Pass-CFLAGS-to-compile.patch
> delete mode 100644 meta-oe/recipes-support/wmiconfig/wmiconfig/0002-fix-err-API-to-have-format-string.patch
> delete mode 100644 meta-oe/recipes-support/wmiconfig/wmiconfig_git.bb
>
I had to manually apply is on master-next, please check master-next if
all is fine or else send a rebase on top of master-next
> diff --git a/meta-oe/recipes-core/packagegroups/packagegroup-meta-oe.bb b/meta-oe/recipes-core/packagegroups/packagegroup-meta-oe.bb
> index bad4aa769e..a8040fb799 100644
> --- a/meta-oe/recipes-core/packagegroups/packagegroup-meta-oe.bb
> +++ b/meta-oe/recipes-core/packagegroups/packagegroup-meta-oe.bb
> @@ -251,13 +251,13 @@ RDEPENDS_packagegroup-meta-oe-support ="\
> multipath-tools nano neon nmon numactl onig openct openldap \
> opensc wbxml2 p910nd pcsc-lite picocom libotr pidgin \
> pngcheck poco poppler poppler-data portaudio-v19 pps-tools \
> - pv pxaregs raptor2 rdfind read-edid rsnapshot s3c24xx-gpio s3c64xx-gpio \
> - sjf2410-linux-native satyr sdparm pty-forward-native serial-forward \
> + pv pxaregs raptor2 rdfind read-edid rsnapshot \
> + satyr sdparm pty-forward-native serial-forward \
> sg3-utils sharutils smem spitools srecord ssiapi stm32flash \
> syslog-ng system-config-keyboard tbb thin-provisioning-tools tokyocabinet \
> tree uhubctl unixodbc uriparser usb-modeswitch \
> - usb-modeswitch-data usbpath uthash utouch-evemu utouch-frame \
> - vim vim-tiny websocketpp wmiconfig xdelta3 xdg-user-dirs xmlstarlet \
> + usb-modeswitch-data uthash utouch-evemu utouch-frame \
> + vim vim-tiny websocketpp xdelta3 xdg-user-dirs xmlstarlet \
> zbar zile \
> ${@bb.utils.contains("DISTRO_FEATURES", "x11", "geis toscoterm uim synergy utouch-mtview links-x11 fltk pidgin-otr", "", d)} \
> libcanberra \
> diff --git a/meta-oe/recipes-support/samsung-soc-utils/files/0001-ppt.c-Do-not-include-sys-io.h.patch b/meta-oe/recipes-support/samsung-soc-utils/files/0001-ppt.c-Do-not-include-sys-io.h.patch
> deleted file mode 100644
> index 4e6c250415..0000000000
> --- a/meta-oe/recipes-support/samsung-soc-utils/files/0001-ppt.c-Do-not-include-sys-io.h.patch
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -From fd244ae648789591f0fb79e74d2b8f6c5b15d6e8 Mon Sep 17 00:00:00 2001
> -From: Khem Raj <raj.khem@gmail.com>
> -Date: Tue, 6 Aug 2019 00:47:14 +0000
> -Subject: [PATCH] ppt.c: Do not include sys/io.h
> -
> -newer versions of glibc has removed it
> -
> -Upstream-Status: Pending
> -Signed-off-by: Khem Raj <raj.khem@gmail.com>
> ----
> - ppt.c | 1 -
> - 1 file changed, 1 deletion(-)
> -
> -diff --git a/ppt.c b/ppt.c
> -index 0bae2d0..0ef279f 100644
> ---- a/ppt.c
> -+++ b/ppt.c
> -@@ -5,7 +5,6 @@
> - #else
> - #include <unistd.h>
> - #include <stdlib.h>
> --#include <sys/io.h>
> - #include <linux/parport.h>
> - #include <linux/ppdev.h>
> - #include <sys/ioctl.h>
> ---
> -2.17.1
> -
> diff --git a/meta-oe/recipes-support/samsung-soc-utils/s3c24xx-gpio_git.bb b/meta-oe/recipes-support/samsung-soc-utils/s3c24xx-gpio_git.bb
> deleted file mode 100644
> index 98573a062c..0000000000
> --- a/meta-oe/recipes-support/samsung-soc-utils/s3c24xx-gpio_git.bb
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -SUMMARY = "A user-space tool to show and modify the state of GPIOs on the S3c24xx platform"
> -SECTION = "console/utils"
> -AUTHOR = "Werner Almesberger <werner@openmoko.org>"
> -LICENSE = "GPLv2+"
> -LIC_FILES_CHKSUM = "file://gpio.c;endline=12;md5=cfb91c686857b2e60852b4925d90a3e1"
> -PV = "1.0+git${SRCPV}"
> -
> -SRCREV = "0bde889e6fc09a330d0e0b9eb9808b20b2bf13d1"
> -SRC_URI = "git://github.com/openmoko/openmoko-svn.git;protocol=https;subpath=src/target/gpio"
> -S = "${WORKDIR}/gpio"
> -
> -CLEANBROKEN = "1"
> -
> -do_compile() {
> - ${CC} ${CFLAGS} ${LDFLAGS} -o ${PN} gpio.c
> -}
> -
> -do_install() {
> - install -d ${D}${sbindir}
> - install -m 0755 ${PN} ${D}${sbindir}
> -}
> diff --git a/meta-oe/recipes-support/samsung-soc-utils/s3c64xx-gpio_git.bb b/meta-oe/recipes-support/samsung-soc-utils/s3c64xx-gpio_git.bb
> deleted file mode 100644
> index 99781718c8..0000000000
> --- a/meta-oe/recipes-support/samsung-soc-utils/s3c64xx-gpio_git.bb
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -SUMMARY = "A user-space tool to show and modify the state of GPIOs on the S3c64xx platform"
> -SECTION = "console/utils"
> -AUTHOR = "Werner Almesberger <werner@openmoko.org>"
> -LICENSE = "GPLv2+"
> -LIC_FILES_CHKSUM = "file://gpio-s3c6410.c;endline=12;md5=060cda1be945ad9194593f11d56d55c7"
> -PV = "1.0+git${SRCPV}"
> -
> -SRCREV = "0bde889e6fc09a330d0e0b9eb9808b20b2bf13d1"
> -SRC_URI = "git://github.com/openmoko/openmoko-svn.git;protocol=https;subpath=src/target/gpio"
> -S = "${WORKDIR}/gpio"
> -
> -CLEANBROKEN = "1"
> -
> -do_compile() {
> - ${CC} ${CFLAGS} ${LDFLAGS} -o ${PN} gpio-s3c6410.c
> -}
> -
> -do_install() {
> - install -d ${D}${sbindir}
> - install -m 0755 ${PN} ${D}${sbindir}
> -}
> diff --git a/meta-oe/recipes-support/samsung-soc-utils/sjf2410-linux-native_git.bb b/meta-oe/recipes-support/samsung-soc-utils/sjf2410-linux-native_git.bb
> deleted file mode 100644
> index 283740396b..0000000000
> --- a/meta-oe/recipes-support/samsung-soc-utils/sjf2410-linux-native_git.bb
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -SUMMARY = "JTAG utility to interface w/ a S3C2410 device"
> -SECTION = "devel"
> -AUTHOR = "Harald Welte <laforge@openmoko.org>"
> -LICENSE = "GPLv2+"
> -LIC_FILES_CHKSUM = "file://parport.c;endline=19;md5=b5681091b0fd8c5f7068835c441bf0c8"
> -PV = "1.0+git${SRCPV}"
> -
> -SRCREV = "0bde889e6fc09a330d0e0b9eb9808b20b2bf13d1"
> -SRC_URI = "git://github.com/openmoko/openmoko-svn.git;protocol=https;subpath=src/host/sjf2410-linux \
> - file://0001-ppt.c-Do-not-include-sys-io.h.patch \
> -"
> -S = "${WORKDIR}/sjf2410-linux"
> -
> -inherit native deploy
> -
> -CFLAGS += "-DLINUX_PPDEV"
> -
> -do_compile() {
> - oe_runmake
> -}
> -
> -do_install() {
> - install -d ${D}/${bindir}
> - install -m 0755 sjf2410 ${D}/${bindir}
> -}
> -
> -do_deploy() {
> - install -m 0755 sjf2410 ${DEPLOYDIR}/sjf2410-${PV}
> -}
> -
> -addtask deploy before do_build after do_install
> -
> -do_deploy[sstate-outputdirs] = "${DEPLOY_DIR_TOOLS}"
> -# cleandirs should possibly be in deploy.bbclass but we need it
> -do_deploy[cleandirs] = "${DEPLOYDIR}"
> -# clear stamp-extra-info since MACHINE_ARCH is normally put there by
> -# deploy.bbclass
> -do_deploy[stamp-extra-info] = ""
> -
> diff --git a/meta-oe/recipes-support/usbpath/usbpath/configure.patch b/meta-oe/recipes-support/usbpath/usbpath/configure.patch
> deleted file mode 100644
> index 271e6a53ad..0000000000
> --- a/meta-oe/recipes-support/usbpath/usbpath/configure.patch
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -Index: usbpath/configure.ac
> -===================================================================
> ---- usbpath.orig/configure.ac 2014-07-17 20:40:26.000000000 +0000
> -+++ usbpath/configure.ac 2014-07-18 07:01:40.933474420 +0000
> -@@ -1,5 +1,5 @@
> - AC_INIT([usbpath],[0.1])
> --AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
> -+AM_INIT_AUTOMAKE([foreign])
> -
> - AC_PROG_CC
> - AC_PROG_RANLIB
> diff --git a/meta-oe/recipes-support/usbpath/usbpath_git.bb b/meta-oe/recipes-support/usbpath/usbpath_git.bb
> deleted file mode 100644
> index a3c75901fb..0000000000
> --- a/meta-oe/recipes-support/usbpath/usbpath_git.bb
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -SUMMARY = "Convert the physical locations of a USB device to/from its number"
> -AUTHOR = "Werner Almesberger <werner@openmoko.org>"
> -SECTION = "console/utils"
> -LICENSE = "GPLv2+"
> -LIC_FILES_CHKSUM = "file://usbpath.c;endline=20;md5=0aa8c7d2af9110c78a99fbf9a504dc3f"
> -DEPENDS = "virtual/libusb0"
> -DEPENDS_class-native = "virtual/libusb0-native"
> -
> -BBCLASSEXTEND = "native"
> -
> -PV = "1.0+git${SRCPV}"
> -
> -SRCREV = "0bde889e6fc09a330d0e0b9eb9808b20b2bf13d1"
> -SRC_URI = "git://github.com/openmoko/openmoko-svn.git;protocol=https;subpath=src/host/usbpath \
> - file://configure.patch \
> -"
> -S = "${WORKDIR}/usbpath"
> -
> -inherit autotools pkgconfig
> -
> -RDEPENDS_${PN} += "perl"
> diff --git a/meta-oe/recipes-support/wmiconfig/wmiconfig/0001-makefile-Pass-CFLAGS-to-compile.patch b/meta-oe/recipes-support/wmiconfig/wmiconfig/0001-makefile-Pass-CFLAGS-to-compile.patch
> deleted file mode 100644
> index 90eff5bb0f..0000000000
> --- a/meta-oe/recipes-support/wmiconfig/wmiconfig/0001-makefile-Pass-CFLAGS-to-compile.patch
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -From 0378cbb323c662a565f7f3de2dee3d8a646e7bd1 Mon Sep 17 00:00:00 2001
> -From: Khem Raj <raj.khem@gmail.com>
> -Date: Tue, 27 Jun 2017 09:32:42 -0700
> -Subject: [PATCH 1/2] makefile: Pass CFLAGS to compile
> -
> -Set CC if not already set
> -
> -Signed-off-by: Khem Raj <raj.khem@gmail.com>
> ----
> - host/tools/wmiconfig/Makefile | 4 ++--
> - 1 file changed, 2 insertions(+), 2 deletions(-)
> -
> -diff --git a/host/tools/wmiconfig/Makefile b/host/tools/wmiconfig/Makefile
> -index c6738c5..3253a7e 100644
> ---- a/Makefile
> -+++ b/Makefile
> -@@ -1,4 +1,4 @@
> --CC :=$(ATH_CROSS_COMPILE_TYPE)gcc
> -+CC ?= $(ATH_CROSS_COMPILE_TYPE)gcc
> -
> - all:
> -- $(CC) -Wall -DUSER_KEYS -g $(LDFLAGS) -I../../include -I../../../include -I../../wlan/include -I../../os/linux/include wmiconfig.c -o wmiconfig
> -+ $(CC) -Wall -DUSER_KEYS -g $(CFLAGS) $(LDFLAGS) -I../../include -I../../../include -I../../wlan/include -I../../os/linux/include wmiconfig.c -o wmiconfig
> ---
> -2.13.2
> -
> diff --git a/meta-oe/recipes-support/wmiconfig/wmiconfig/0002-fix-err-API-to-have-format-string.patch b/meta-oe/recipes-support/wmiconfig/wmiconfig/0002-fix-err-API-to-have-format-string.patch
> deleted file mode 100644
> index f67f784c1f..0000000000
> --- a/meta-oe/recipes-support/wmiconfig/wmiconfig/0002-fix-err-API-to-have-format-string.patch
> +++ /dev/null
> @@ -1,656 +0,0 @@
> -From 909ebdde4ee2233d65de8fa01fde8e9a3bec12b7 Mon Sep 17 00:00:00 2001
> -From: Khem Raj <raj.khem@gmail.com>
> -Date: Tue, 27 Jun 2017 09:33:26 -0700
> -Subject: [PATCH 2/2] fix err() API to have format string
> -
> -Fixes errors with hardening flags
> -
> -Signed-off-by: Khem Raj <raj.khem@gmail.com>
> ----
> - host/tools/wmiconfig/wmiconfig.c | 148 +++++++++++++++++++--------------------
> - 1 file changed, 74 insertions(+), 74 deletions(-)
> -
> -diff --git a/host/tools/wmiconfig/wmiconfig.c b/host/tools/wmiconfig/wmiconfig.c
> -index 21c9dcd..a6ec481 100644
> ---- a/wmiconfig.c
> -+++ b/wmiconfig.c
> -@@ -483,7 +483,7 @@ main (int argc, char **argv)
> - strcpy(ifname, ethIf);
> - s = socket(AF_INET, SOCK_DGRAM, 0);
> - if (s < 0) {
> -- err(1, "socket");
> -+ err(1, "%s", "socket");
> - }
> -
> - while (1) {
> -@@ -1506,28 +1506,28 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)filterCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SETBSSFILTER, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_POWER_MODE:
> - ifr.ifr_data = (void *)pwrCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SETPWR, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_PM_PARAMS:
> - ifr.ifr_data = (void *)pmParamCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_PMPARAMS, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_IBSS_PM_CAPS:
> - ifr.ifr_data = (void *)adhocPmCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_ERROR_DETECTION:
> -@@ -1535,7 +1535,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_HB_CHALLENGE_RESP:
> -@@ -1543,7 +1543,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - #ifdef USER_KEYS
> -@@ -1554,7 +1554,7 @@ main (int argc, char **argv)
> -
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> -
> - break;
> -@@ -1575,7 +1575,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)sParamCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SETSCAN, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_VERSION:
> -@@ -1586,7 +1586,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)revinfo;
> - if (ioctl(s, AR6000_IOCTL_WMI_GETREV, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - printf("Host Rev = 0x%x(%u.%u.%u.%u), Target Rev = 0x%x(%u.%u.%u.%u)\n",
> - revinfo->host_ver,
> -@@ -1606,14 +1606,14 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)listenCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SETLISTENINT, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_BMISS_TIME:
> - ifr.ifr_data = (void *)bmissCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_BMISS_TIME, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_RSSI_THRESHOLDS:
> -@@ -1621,14 +1621,14 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_SNR_THRESHOLDS:
> - ifr.ifr_data = (void *)snrThresholdParam;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_SNRTHRESHOLD, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_CLR_RSSISNR:
> -@@ -1636,7 +1636,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_LQ_THRESHOLDS:
> -@@ -1644,7 +1644,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_CHANNEL:
> -@@ -1693,18 +1693,18 @@ main (int argc, char **argv)
> -
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_CHANNELPARAMS, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_SSID:
> - if (index > MAX_PROBED_SSID_INDEX) {
> - printf("num option for ssid command too large\n");
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - break;
> - }
> - if (strlen((char *)ssid) > sizeof (ssidCmd->ssid)) {
> - printf("ssid name too large\n");
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - break;
> - }
> - ssidCmd->entryIndex = index;
> -@@ -1722,7 +1722,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)ssidCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_PROBEDSSID, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_BADAP:
> -@@ -1735,7 +1735,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)badApCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_BADAP, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_CREATE_QOS:
> -@@ -1794,7 +1794,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)crePStreamCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_CREATE_QOS, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_TARGET_STATS:
> -@@ -1807,7 +1807,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)&tgtStatsCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_GET_TARGET_STATS, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - printTargetStats(&(tgtStatsCmd.targetStats));
> - break;
> -@@ -1815,7 +1815,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)pBitMask;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_DELETE_QOS:
> -@@ -1824,7 +1824,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)delPStreamCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_DELETE_QOS, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_QOS_QUEUE:
> -@@ -1840,7 +1840,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)getQosQueueCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_GET_QOS_QUEUE, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> -
> - printf("Active TSIDs \n");
> -@@ -1855,7 +1855,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)ieInfo;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_ASSOC_INFO, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_AC_PARAMS:
> -@@ -1871,14 +1871,14 @@ main (int argc, char **argv)
> - ifr.ifr_data = (void *)acParamsCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_ACCESS_PARAMS, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_DISC_TIMEOUT:
> - ifr.ifr_data = (void *)discCmd;
> - if (ioctl(s, AR6000_IOCTL_WMI_SET_DISC_TIMEOUT, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_ADHOC_BSSID:
> -@@ -1887,7 +1887,7 @@ main (int argc, char **argv)
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> - printf("fail to set adhoc bssid \n");
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_OPT_MODE:
> -@@ -1895,7 +1895,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_OPT_SEND_FRAME:
> -@@ -1903,7 +1903,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_BEACON_INT:
> -@@ -1911,7 +1911,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_VOICE_PKT_SIZE:
> -@@ -1919,7 +1919,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_MAX_SP:
> -@@ -1927,7 +1927,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_ROAM_TBL:
> -@@ -1935,7 +1935,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_ROAM_CTRL:
> -@@ -1943,7 +1943,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_POWERSAVE_TIMERS:
> -@@ -1951,7 +1951,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_POWER_MODE:
> -@@ -1959,7 +1959,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - printf("Power mode is %s\n",
> - (getPowerMode->powerMode == MAX_PERF_POWER) ? "maxperf" : "rec");
> -@@ -1969,7 +1969,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_ROAM_DATA:
> -@@ -1977,7 +1977,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_BT_STATUS:
> -@@ -1985,7 +1985,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_BT_PARAMS:
> -@@ -1993,7 +1993,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_RETRYLIMITS:
> -@@ -2001,14 +2001,14 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_START_SCAN:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_STARTSCAN;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_FIX_RATES:
> -@@ -2031,14 +2031,14 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_FIX_RATES:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_GETFIXRATES;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - } else {
> - int i;
> - printf("Fix rate set index:");
> -@@ -2057,7 +2057,7 @@ main (int argc, char **argv)
> - index--;
> - setAuthMode->mode = atoi(argv[index]);
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_REASSOC_MODE:
> -@@ -2067,42 +2067,42 @@ main (int argc, char **argv)
> - index--;
> - setReassocMode->mode = atoi(argv[index]);
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_LPREAMBLE:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_LPREAMBLE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_RTS:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_RTS;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_WMM:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_WMM;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_TXOP:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_TXOP;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case DIAG_READ:
> - ((int *)buf)[0] = AR6000_XIOCTL_DIAG_READ;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - printf("diagdata: 0x%x\n", *diagdata);
> - break;
> -@@ -2110,7 +2110,7 @@ main (int argc, char **argv)
> - ((int *)buf)[0] = AR6000_XIOCTL_DIAG_WRITE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_RD:
> -@@ -2118,7 +2118,7 @@ main (int argc, char **argv)
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0)
> - {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - else
> - {
> -@@ -2139,14 +2139,14 @@ main (int argc, char **argv)
> - index--;
> - setKeepAlive->keepaliveInterval = atoi(argv[index]);
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_KEEPALIVE:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_GET_KEEPALIVE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - printf("Keepalive interval is %d secs and AP is %s\n",
> - getKeepAlive->keepaliveInterval, (getKeepAlive->configured ?
> -@@ -2156,63 +2156,63 @@ main (int argc, char **argv)
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_APPIE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_MGMT_FRM_RX_FILTER:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_DBGLOG_CFG_MODULE:
> - ((int *)buf)[0] = AR6000_XIOCTL_DBGLOG_CFG_MODULE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_DBGLOG_GET_DEBUG_LOGS:
> - ((int *)buf)[0] = AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_HOST_SLEEP_MODE:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_WOW_MODE:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_WOW_MODE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_ADD_WOW_PATTERN:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_ADD_WOW_PATTERN;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_DEL_WOW_PATTERN:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_DEL_WOW_PATTERN;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_GET_WOW_LIST:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_GET_WOW_LIST;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case DIAG_DUMP_CHIP_MEM:
> -@@ -2225,7 +2225,7 @@ main (int argc, char **argv)
> - ((int *)buf)[0] = AR6000_XIOCTL_DIAG_READ;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - printf("0x%04x:0x%04x\n", *diagaddr, *diagdata);
> - }
> -@@ -2237,21 +2237,21 @@ main (int argc, char **argv)
> - index = optind - 1;
> - *connectCtrlFlags = strtoul(argv[index], NULL, 0);
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case DUMP_HTC_CREDITS:
> - ((int *)buf)[0] = AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_AKMP_INFO:
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_AKMP_PARAMS;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_PMKID_LIST:
> -@@ -2259,7 +2259,7 @@ main (int argc, char **argv)
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_SET_PMKID_LIST;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - } else {
> - printf("No PMKIDs entered\n");
> -@@ -2269,7 +2269,7 @@ main (int argc, char **argv)
> - ((int *)buf)[0] = AR6000_XIOCTL_WMI_GET_PMKID_LIST;
> - ifr.ifr_data = buf;
> - if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - case WMI_SET_BSS_PMKID_INFO:
> -@@ -2277,7 +2277,7 @@ main (int argc, char **argv)
> - iwr.u.data.length = sizeof(*pi_cmd);
> - if (ioctl(s, IEEE80211_IOCTL_ADDPMKID, &iwr) < 0) {
> - printf("ADDPMKID IOCTL Error\n");
> -- err(1, ifr.ifr_name);
> -+ err(1, "%s", ifr.ifr_name);
> - }
> - break;
> - default:
> ---
> -2.13.2
> -
> diff --git a/meta-oe/recipes-support/wmiconfig/wmiconfig_git.bb b/meta-oe/recipes-support/wmiconfig/wmiconfig_git.bb
> deleted file mode 100644
> index 23273caf8e..0000000000
> --- a/meta-oe/recipes-support/wmiconfig/wmiconfig_git.bb
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -SUMMARY = "Atheros 6K Wifi configuration utility"
> -LICENSE = "GPLv2"
> -LIC_FILES_CHKSUM = "file://wmiconfig.c;endline=19;md5=4394a56bca1c5b2446c9f8e406c82911"
> -SECTION = "console/network"
> -PV = "1.0+git${SRCPV}"
> -
> -SRCREV = "0bde889e6fc09a330d0e0b9eb9808b20b2bf13d1"
> -SRC_URI = "git://github.com/openmoko/openmoko-svn.git;protocol=https;subpath=src/target/AR6kSDK.build_sw.18 \
> - file://0001-makefile-Pass-CFLAGS-to-compile.patch \
> - file://0002-fix-err-API-to-have-format-string.patch \
> -"
> -S = "${WORKDIR}/AR6kSDK.build_sw.18/host/tools/wmiconfig"
> -
> -CLEANBROKEN = "1"
> -
> -EXTRA_OEMAKE = "-e MAKEFLAGS="
> -
> -TARGET_CC_ARCH += "${LDFLAGS}"
> -
> -do_install() {
> - install -d ${D}${bindir}
> - install -m 0755 wmiconfig ${D}${bindir}
> -}
> -
>
^ permalink raw reply
* Re: [REGRESSION] gpio hogging fails with pinctrl gpio drivers
From: Russell King - ARM Linux admin @ 2020-02-20 18:19 UTC (permalink / raw)
To: Andrey Smirnov
Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Peter Rosin, Linux ARM
In-Reply-To: <CAHQ1cqFeMKrb-MxnifVJXfGciQH8wsjS1dSSeTTc0R06jLT+Cw@mail.gmail.com>
On Thu, Feb 20, 2020 at 09:28:14AM -0800, Andrey Smirnov wrote:
> On Thu, Feb 20, 2020 at 12:18 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> >
> > On Thu, Feb 6, 2020 at 6:33 PM Russell King - ARM Linux admin
> > <linux@armlinux.org.uk> wrote:
> >
> > > It seems that sometime between 4.20 and 5.5, something has broken the
> > > ability to specify gpio-hogs in DT for GPIOs that are written around
> > > pinctrl drivers.
> > (explanation that makes perfect sense)
> > > Consequently, adding a gpio-hog to DT for this driver results in the
> > > driver endlessly returning -EPROBE_DEFER.
> >
> > I suspect this is sx150x-specific and suspect these two commits:
> >
> > 1a1d39e1b8dd pinctrl: sx150x: Register pinctrl before adding the gpiochip
> > b930151e5b55 pinctrl: sx150x: Add a static gpio/pinctrl pin range mapping
> >
> > I suppose people weren't using hogs very much with the sx150x and
> > it didn't turn up in testing so far.
> >
> > I don't think for example pinctrl-stmfx.c has this problem, as it registers
> > the pin ranges from the device tree as part of the core code.
> > But other drivers calling gpiochip_add_pin_range() may be experiencing
> > this.
> >
> > Peter/Andrey, do you have some idea? Have you tested this usecase (hogs)
> > with the sx150x?
> >
>
> Haven't done any GPIO hogging on sx150x, unfortunately. My use-cases were:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
>
> and
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/vf610-zii-scu4-aib.dts
>
> which didn't have any hogs so far (there's a chance Russell is using
> the former for his experiments, so maybe that'll change). I don't any
> useful input on this regression, sorry. I do have Rev C. board readily
> available, so I can provide Tested-by's if I am CC'd on fixes.
The ZII dev rev C is where I had the hog as a means of kicking the
88x3310 PHY out of reset.
I've now converted it to a proper MDIO bus-level reset, so I no
longer have the hog, and I no longer care about the regression - but
that's not to say it shouldn't be fixed, as the code is wrong.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH kernel 5/5] vfio/spapr_tce: Advertise and allow a huge DMA windows at 4GB
From: Alex Williamson @ 2020-02-20 18:19 UTC (permalink / raw)
To: Alexey Kardashevskiy; +Cc: Alistair Popple, linuxppc-dev, kvm-ppc, David Gibson
In-Reply-To: <20200218073650.16149-6-aik@ozlabs.ru>
On Tue, 18 Feb 2020 18:36:50 +1100
Alexey Kardashevskiy <aik@ozlabs.ru> wrote:
> So far the only option for a big 64big DMA window was a window located
> at 0x800.0000.0000.0000 (1<<59) which creates problems for devices
> supporting smaller DMA masks.
>
> This exploits a POWER9 PHB option to allow the second DMA window to map
> at 0 and advertises it with a 4GB offset to avoid overlap with
> the default 32bit window.
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> include/uapi/linux/vfio.h | 2 ++
> drivers/vfio/vfio_iommu_spapr_tce.c | 10 ++++++++--
> 2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 9e843a147ead..c7f89d47335a 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -831,9 +831,11 @@ struct vfio_iommu_spapr_tce_info {
> __u32 argsz;
> __u32 flags;
> #define VFIO_IOMMU_SPAPR_INFO_DDW (1 << 0) /* DDW supported */
> +#define VFIO_IOMMU_SPAPR_INFO_DDW_START (1 << 1) /* DDW offset */
> __u32 dma32_window_start; /* 32 bit window start (bytes) */
> __u32 dma32_window_size; /* 32 bit window size (bytes) */
> struct vfio_iommu_spapr_tce_ddw_info ddw;
> + __u64 dma64_window_start;
> };
>
> #define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
> diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
> index 16b3adc508db..4f22be3c4aa2 100644
> --- a/drivers/vfio/vfio_iommu_spapr_tce.c
> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c
> @@ -691,7 +691,7 @@ static long tce_iommu_create_window(struct tce_container *container,
> container->tables[num] = tbl;
>
> /* Return start address assigned by platform in create_table() */
> - *start_addr = tbl->it_offset << tbl->it_page_shift;
> + *start_addr = tbl->it_dmaoff << tbl->it_page_shift;
>
> return 0;
>
> @@ -842,7 +842,13 @@ static long tce_iommu_ioctl(void *iommu_data,
> info.ddw.levels = table_group->max_levels;
> }
>
> - ddwsz = offsetofend(struct vfio_iommu_spapr_tce_info, ddw);
> + ddwsz = offsetofend(struct vfio_iommu_spapr_tce_info,
> + dma64_window_start);
This breaks existing users, now they no longer get the ddw struct
unless their argsz also includes the new dma64 window field.
> +
> + if (info.argsz >= ddwsz) {
> + info.flags |= VFIO_IOMMU_SPAPR_INFO_DDW_START;
> + info.dma64_window_start = table_group->tce64_start;
> + }
This is inconsistent with ddw where we set the flag regardless of
argsz, but obviously only provide the field to the user if they've
provided room for it. Thanks,
Alex
>
> if (info.argsz >= ddwsz)
> minsz = ddwsz;
^ permalink raw reply
* [PATCH v2 11/21] arm: socfpga: Secure register access for clock manager (SoC 64bits)
From: Ang, Chee Hong @ 2020-02-20 18:20 UTC (permalink / raw)
To: u-boot
In-Reply-To: <a9b802ea-bc93-49f8-ea7f-a940e1c4c808@denx.de>
> -----Original Message-----
> From: Marek Vasut <marex@denx.de>
> Sent: Friday, February 21, 2020 12:48 AM
> To: Ang, Chee Hong <chee.hong.ang@intel.com>; u-boot at lists.denx.de
> Cc: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>; See, Chin Liang
> <chin.liang.see@intel.com>; Tan, Ley Foon <ley.foon.tan@intel.com>;
> Westergreen, Dalon <dalon.westergreen@intel.com>; Gong, Richard
> <richard.gong@intel.com>; Tom Rini <trini@konsulko.com>; Michal Simek
> <michal.simek@xilinx.com>
> Subject: Re: [PATCH v2 11/21] arm: socfpga: Secure register access for clock
> manager (SoC 64bits)
>
> On 2/20/20 3:32 AM, Ang, Chee Hong wrote:
> >> On 2/19/20 1:25 PM, chee.hong.ang at intel.com wrote:
> >>> From: Chee Hong Ang <chee.hong.ang@intel.com>
> >>>
> >>> Allow clock manager driver to access the System Manager's Boot
> >>> Scratch Register 0 in non-secure mode (EL2) on SoC 64bits platform.
> >>>
> >>> Signed-off-by: Chee Hong Ang <chee.hong.ang@intel.com>
> >>> ---
> >>> arch/arm/mach-socfpga/clock_manager_agilex.c | 5 +++--
> >>> arch/arm/mach-socfpga/clock_manager_s10.c | 5 +++--
> >>> 2 files changed, 6 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/arch/arm/mach-socfpga/clock_manager_agilex.c
> >>> b/arch/arm/mach-socfpga/clock_manager_agilex.c
> >>> index 4ee2b7b..e5a0998 100644
> >>> --- a/arch/arm/mach-socfpga/clock_manager_agilex.c
> >>> +++ b/arch/arm/mach-socfpga/clock_manager_agilex.c
> >>> @@ -12,6 +12,7 @@
> >>> #include <asm/arch/system_manager.h> #include <asm/io.h> #include
> >>> <dt-bindings/clock/agilex-clock.h>
> >>> +#include <asm/arch/secure_reg_helper.h>
> >>>
> >>> DECLARE_GLOBAL_DATA_PTR;
> >>>
> >>> @@ -65,8 +66,8 @@ unsigned int cm_get_l4_sys_free_clk_hz(void)
> >>>
> >>> u32 cm_get_qspi_controller_clk_hz(void)
> >>> {
> >>> - return readl(socfpga_get_sysmgr_addr() +
> >>> - SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
> >>> + return socfpga_secure_reg_read32(socfpga_get_sysmgr_addr() +
> >>> +
> >> SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
> >>> }
> >>>
> >>> void cm_print_clock_quick_summary(void)
> >>> diff --git a/arch/arm/mach-socfpga/clock_manager_s10.c
> >>> b/arch/arm/mach-socfpga/clock_manager_s10.c
> >>> index 05e4212..02578cc 100644
> >>> --- a/arch/arm/mach-socfpga/clock_manager_s10.c
> >>> +++ b/arch/arm/mach-socfpga/clock_manager_s10.c
> >>> @@ -9,6 +9,7 @@
> >>> #include <asm/arch/clock_manager.h> #include
> >>> <asm/arch/handoff_s10.h> #include <asm/arch/system_manager.h>
> >>> +#include <asm/arch/secure_reg_helper.h>
> >>>
> >>> DECLARE_GLOBAL_DATA_PTR;
> >>>
> >>> @@ -385,8 +386,8 @@ unsigned int cm_get_l4_sp_clk_hz(void)
> >>>
> >>> unsigned int cm_get_qspi_controller_clk_hz(void)
> >>> {
> >>> - return readl(socfpga_get_sysmgr_addr() +
> >>> - SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
> >>> + return socfpga_secure_reg_read32(socfpga_get_sysmgr_addr() +
> >>> +
> >> SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
> >>> }
> >>>
> >>> unsigned int cm_get_spi_controller_clk_hz(void)
> >>
> >> Shouldn't the IO accessors already provide the necessary abstraction ?
> > This function accesses the system manager registers, therefore it is
> > required to call the secure register read function to make sure it
> > still can access the system manager register if it's running EL2 (non-secure).
>
> But shouldn't the standard IO accessors handle that transparently ?
Regarding this standard IO accessors, please refer to my reply in another email thread.
> What does Linux do ?
Currently, Linux run in EL1 (non-secure), it will crash if it's accessing
the secure zones directly with standard memory I/O functions provided
by kernel.
It goes through the ATF by making SMC/PSCI calls to ATF to access the
secure zones. Just Like what we did in this patchset.
The only difference is kernel code always access those secure zones by making SMC/PSCI
calls but U-Boot code get to choose the SMC/PSCI calls or standard I/O accessors in compile
time because same code base in U-Boot may run in EL2 or EL3 depending on whether the
code is built for SPL (EL3) or U-Boot proper without ATF (EL2).
^ permalink raw reply
* Re: [PATCH] MAINTAINERS: Update myself email address
From: Daniel Vetter @ 2020-02-20 18:21 UTC (permalink / raw)
To: Xinliang Liu; +Cc: airlied, dri-devel
In-Reply-To: <20200220090328.25932-1-xinliang.liu@linaro.org>
On Thu, Feb 20, 2020 at 09:03:28AM +0000, Xinliang Liu wrote:
> Update myself email address.
> Add John Stultz as a reviewer. Thanks John.
> Update git tree to drm-misc
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
I guess you're going to push this to drm-misc?
-Daniel
>
> Signed-off-by: Xinliang Liu <xinliang.liu@linaro.org>
> ---
> MAINTAINERS | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 978766c6715e..befc3c0afc75 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5600,12 +5600,13 @@ S: Maintained
> F: drivers/gpu/drm/gma500/
>
> DRM DRIVERS FOR HISILICON
> -M: Xinliang Liu <z.liuxinliang@hisilicon.com>
> +M: Xinliang Liu <xinliang.liu@linaro.org>
> M: Rongrong Zou <zourongrong@gmail.com>
> +R: John Stultz <john.stultz@linaro.org>
> R: Xinwei Kong <kong.kongxinwei@hisilicon.com>
> R: Chen Feng <puck.chen@hisilicon.com>
> L: dri-devel@lists.freedesktop.org
> -T: git git://github.com/xin3liang/linux.git
> +T: git git://anongit.freedesktop.org/drm/drm-misc
> S: Maintained
> F: drivers/gpu/drm/hisilicon/
> F: Documentation/devicetree/bindings/display/hisilicon/
> --
> 2.20.1
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: omap-secure.c:undefined reference to `__arm_smccc_smc'
From: Andrew F. Davis @ 2020-02-20 18:22 UTC (permalink / raw)
To: kbuild-all
In-Reply-To: <20200220181141.GR37466@atomide.com>
[-- Attachment #1: Type: text/plain, Size: 4350 bytes --]
On 2/20/20 1:11 PM, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [200220 17:58]:
>> * Andrew F. Davis <afd@ti.com> [200220 17:39]:
>>> On 2/20/20 12:13 PM, Tony Lindgren wrote:
>>>> * Tony Lindgren <tony@atomide.com> [200220 16:37]:
>>>>> * Andrew F. Davis <afd@ti.com> [200220 16:24]:
>>>>>> On 2/20/20 11:20 AM, Tony Lindgren wrote:
>>>>>>> * Andrew F. Davis <afd@ti.com> [200220 16:04]:
>>>>>>>> On 2/20/20 10:54 AM, Tony Lindgren wrote:
>>>>>>>>> Andrew,
>>>>>>>>>
>>>>>>>>> * kbuild test robot <lkp@intel.com> [200213 10:27]:
>>>>>>>>>> tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
>>>>>>>>>> head: 0bf999f9c5e74c7ecf9dafb527146601e5c848b9
>>>>>>>>>> commit: c37baa06f8a970e4a533d41f7d33e5e57de5ad25 ARM: OMAP2+: Fix undefined reference to omap_secure_init
>>>>>>>>>> date: 3 weeks ago
>>>>>>>>>> config: arm-randconfig-a001-20200213 (attached as .config)
>>>>>>>>>> compiler: arm-linux-gnueabi-gcc (GCC) 7.5.0
>>>>>>>>>> reproduce:
>>>>>>>>>> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>>>>>>>>>> chmod +x ~/bin/make.cross
>>>>>>>>>> git checkout c37baa06f8a970e4a533d41f7d33e5e57de5ad25
>>>>>>>>>> # save the attached .config to linux build tree
>>>>>>>>>> GCC_VERSION=7.5.0 make.cross ARCH=arm
>>>>>>>>>>
>>>>>>>>>> If you fix the issue, kindly add following tag
>>>>>>>>>> Reported-by: kbuild test robot <lkp@intel.com>
>>>>>>>>>>
>>>>>>>>>> All errors (new ones prefixed by >>):
>>>>>>>>>>
>>>>>>>>>> arch/arm/mach-omap2/omap-secure.o: In function `omap_smccc_smc':
>>>>>>>>>>>> omap-secure.c:(.text+0x94): undefined reference to `__arm_smccc_smc'
>>>>>>>>>
>>>>>>>>> Have you looked at this one? Looks like there's still an unhandled
>>>>>>>>> randconfig build case.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> I've had a quick look, all the ARM config does:
>>>>>>>>
>>>>>>>> select HAVE_ARM_SMCCC if CPU_V7
>>>>>>>>
>>>>>>>> so I don't think this will happen in any real config, but if we want to
>>>>>>>> prevent randconfig issue this we could force ARCH_OMAP2PLUS to "depend"
>>>>>>>> on it.
>>>>>>>
>>>>>>> Seems to happen at least with omap2 only config where we don't have
>>>>>>> CPU_V7. Something like below seems to fix it.
>>>>>>>
>>>>>>> If that looks OK to you, I'll send out a proper fix.
>>>>>>>
>>>>>>
>>>>>>
>>>>>> This looks fine to me.
>>>>>>
>>>>>> A better later fix might be to later stub out the actual __arm_smccc_smc
>>>>>> in common code if CONFIG_HAVE_ARM_SMCCC is not set, so any platform will
>>>>>> get the fix.
>>>>>
>>>>> Yeah seems that might be better. Adding Aaro and Marc to Cc.
>>>>
>>>> But if we can in theory have some arm11 machine with smccc, then this
>>>> local ifdef below is probably the way to go.
>>>>
>>>
>>> If the machine has SMCCC then it will also have the
>>> CONFIG_HAVE_ARM_SMCCC set and so nothing would change.
>>
>> Hmm yeah good point.
>
> So the patch below seems like the way to go then. Anybody have issues
> with the patch below?
>
> Regards,
>
> Tony
>
> 8< -------------------------
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -121,6 +121,7 @@ struct arm_smccc_quirk {
> } state;
> };
>
> +#ifdef CONFIG_HAVE_ARM_SMCCC
> /**
> * __arm_smccc_smc() - make SMC calls
> * @a0-a7: arguments passed in registers 0 to 7
> @@ -137,6 +138,14 @@ asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
> unsigned long a2, unsigned long a3, unsigned long a4,
> unsigned long a5, unsigned long a6, unsigned long a7,
> struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
> +#else
> +static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
> + unsigned long a2, unsigned long a3, unsigned long a4,
> + unsigned long a5, unsigned long a6, unsigned long a7,
> + struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
> +{
Maybe a warning? If you do not have SMC on your platform but are still
making SMC calls then something is broken and it looks like it would
fail silently here.
Andrew
> +}
> +#endif
>
> /**
> * __arm_smccc_hvc() - make HVC calls
>
^ permalink raw reply
* Re: [PATCH] ext4: fix handling mount -o remount,nolazytime
From: Theodore Y. Ts'o @ 2020-02-20 18:22 UTC (permalink / raw)
To: Konstantin Khlebnikov
Cc: Andreas Dilger, linux-ext4, Karel Zak, Dmitry Monakhov
In-Reply-To: <2326451b-faf2-72a5-cb55-89cb6d8ce9ed@yandex-team.ru>
On Thu, Feb 20, 2020 at 06:11:04PM +0300, Konstantin Khlebnikov wrote:
> Usually all these options are saved in /etc/fstab and
> mount -o remount,... includes them into line passed into syscall.
> In this case remounting any other option will not disable lazytime.
This assumes that there *is* an /etc/fstab entry. Sometimes system
administrators will perform ad hoc mounts of devices that aren't
mentioned in /etc/fstab.
For example, consider how xfstests works; it will run mounts commands
mentioning the test and scratch devices which are not mentioned on
/etc/fstab.
- Ted
^ permalink raw reply
* Re: [PATCH] MAINTAINERS: Update myself email address
From: Daniel Vetter @ 2020-02-20 18:22 UTC (permalink / raw)
To: Xinliang Liu; +Cc: airlied, dri-devel
In-Reply-To: <20200220182141.GY2363188@phenom.ffwll.local>
On Thu, Feb 20, 2020 at 07:21:41PM +0100, Daniel Vetter wrote:
> On Thu, Feb 20, 2020 at 09:03:28AM +0000, Xinliang Liu wrote:
> > Update myself email address.
> > Add John Stultz as a reviewer. Thanks John.
> > Update git tree to drm-misc
>
> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> I guess you're going to push this to drm-misc?
Oh and I guess time for John Stultz to apply for drm-misc commit rights,
seems to be lacking.
-Daniel
>
> >
> > Signed-off-by: Xinliang Liu <xinliang.liu@linaro.org>
> > ---
> > MAINTAINERS | 5 +++--
> > 1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 978766c6715e..befc3c0afc75 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -5600,12 +5600,13 @@ S: Maintained
> > F: drivers/gpu/drm/gma500/
> >
> > DRM DRIVERS FOR HISILICON
> > -M: Xinliang Liu <z.liuxinliang@hisilicon.com>
> > +M: Xinliang Liu <xinliang.liu@linaro.org>
> > M: Rongrong Zou <zourongrong@gmail.com>
> > +R: John Stultz <john.stultz@linaro.org>
> > R: Xinwei Kong <kong.kongxinwei@hisilicon.com>
> > R: Chen Feng <puck.chen@hisilicon.com>
> > L: dri-devel@lists.freedesktop.org
> > -T: git git://github.com/xin3liang/linux.git
> > +T: git git://anongit.freedesktop.org/drm/drm-misc
> > S: Maintained
> > F: drivers/gpu/drm/hisilicon/
> > F: Documentation/devicetree/bindings/display/hisilicon/
> > --
> > 2.20.1
> >
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH] drm/virtio: fix virtio-gpu resource id creation race
From: Chia-I Wu @ 2020-02-20 18:22 UTC (permalink / raw)
To: Emil Velikov
Cc: David Airlie, ML dri-devel, Gerd Hoffmann, John Bates,
Gurchetan Singh
In-Reply-To: <CACvgo52oabauyoz81Q1rpp46kf4F_mYZeBb5oSOvW3tsfQT7nQ@mail.gmail.com>
On Thu, Feb 20, 2020 at 5:30 AM Emil Velikov <emil.l.velikov@gmail.com> wrote:
>
> Hi John,
>
> On Thu, 20 Feb 2020 at 08:45, John Bates <jbates@chromium.org> wrote:
> >
> > The previous code was not thread safe and caused
> > undefined behavior from spurious duplicate resource IDs.
> > In this patch, an atomic_t is used instead. We no longer
> > see any duplicate IDs in tests with this change.
> >
> > Signed-off-by: John Bates <jbates@chromium.org>
> Adding a fixes tag like below makes it easier to track. Especially for
> Greg and team who are working on stable kernels.
>
> Fixes: 3e93bc2a58aa ("drm/virtio: make resource id workaround runtime
> switchable.")
FWIW, the fixes tag should refer to this commit instead
commit 16065fcdd19ddb9e093192914ac863884f308766
Author: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri Feb 8 15:04:09 2019 +0100
drm/virtio: do NOT reuse resource ids
>
> HTH
> Emil
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: omap-secure.c:undefined reference to `__arm_smccc_smc'
From: Andrew F. Davis @ 2020-02-20 18:22 UTC (permalink / raw)
To: Tony Lindgren
Cc: kbuild-all, linux-kernel, kbuild test robot, linux-omap,
Aaro Koskinen, Marc Zyngier, linux-arm-kernel, Arnd Bergmann,
Rob Herring
In-Reply-To: <20200220181141.GR37466@atomide.com>
On 2/20/20 1:11 PM, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [200220 17:58]:
>> * Andrew F. Davis <afd@ti.com> [200220 17:39]:
>>> On 2/20/20 12:13 PM, Tony Lindgren wrote:
>>>> * Tony Lindgren <tony@atomide.com> [200220 16:37]:
>>>>> * Andrew F. Davis <afd@ti.com> [200220 16:24]:
>>>>>> On 2/20/20 11:20 AM, Tony Lindgren wrote:
>>>>>>> * Andrew F. Davis <afd@ti.com> [200220 16:04]:
>>>>>>>> On 2/20/20 10:54 AM, Tony Lindgren wrote:
>>>>>>>>> Andrew,
>>>>>>>>>
>>>>>>>>> * kbuild test robot <lkp@intel.com> [200213 10:27]:
>>>>>>>>>> tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
>>>>>>>>>> head: 0bf999f9c5e74c7ecf9dafb527146601e5c848b9
>>>>>>>>>> commit: c37baa06f8a970e4a533d41f7d33e5e57de5ad25 ARM: OMAP2+: Fix undefined reference to omap_secure_init
>>>>>>>>>> date: 3 weeks ago
>>>>>>>>>> config: arm-randconfig-a001-20200213 (attached as .config)
>>>>>>>>>> compiler: arm-linux-gnueabi-gcc (GCC) 7.5.0
>>>>>>>>>> reproduce:
>>>>>>>>>> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>>>>>>>>>> chmod +x ~/bin/make.cross
>>>>>>>>>> git checkout c37baa06f8a970e4a533d41f7d33e5e57de5ad25
>>>>>>>>>> # save the attached .config to linux build tree
>>>>>>>>>> GCC_VERSION=7.5.0 make.cross ARCH=arm
>>>>>>>>>>
>>>>>>>>>> If you fix the issue, kindly add following tag
>>>>>>>>>> Reported-by: kbuild test robot <lkp@intel.com>
>>>>>>>>>>
>>>>>>>>>> All errors (new ones prefixed by >>):
>>>>>>>>>>
>>>>>>>>>> arch/arm/mach-omap2/omap-secure.o: In function `omap_smccc_smc':
>>>>>>>>>>>> omap-secure.c:(.text+0x94): undefined reference to `__arm_smccc_smc'
>>>>>>>>>
>>>>>>>>> Have you looked at this one? Looks like there's still an unhandled
>>>>>>>>> randconfig build case.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> I've had a quick look, all the ARM config does:
>>>>>>>>
>>>>>>>> select HAVE_ARM_SMCCC if CPU_V7
>>>>>>>>
>>>>>>>> so I don't think this will happen in any real config, but if we want to
>>>>>>>> prevent randconfig issue this we could force ARCH_OMAP2PLUS to "depend"
>>>>>>>> on it.
>>>>>>>
>>>>>>> Seems to happen at least with omap2 only config where we don't have
>>>>>>> CPU_V7. Something like below seems to fix it.
>>>>>>>
>>>>>>> If that looks OK to you, I'll send out a proper fix.
>>>>>>>
>>>>>>
>>>>>>
>>>>>> This looks fine to me.
>>>>>>
>>>>>> A better later fix might be to later stub out the actual __arm_smccc_smc
>>>>>> in common code if CONFIG_HAVE_ARM_SMCCC is not set, so any platform will
>>>>>> get the fix.
>>>>>
>>>>> Yeah seems that might be better. Adding Aaro and Marc to Cc.
>>>>
>>>> But if we can in theory have some arm11 machine with smccc, then this
>>>> local ifdef below is probably the way to go.
>>>>
>>>
>>> If the machine has SMCCC then it will also have the
>>> CONFIG_HAVE_ARM_SMCCC set and so nothing would change.
>>
>> Hmm yeah good point.
>
> So the patch below seems like the way to go then. Anybody have issues
> with the patch below?
>
> Regards,
>
> Tony
>
> 8< -------------------------
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -121,6 +121,7 @@ struct arm_smccc_quirk {
> } state;
> };
>
> +#ifdef CONFIG_HAVE_ARM_SMCCC
> /**
> * __arm_smccc_smc() - make SMC calls
> * @a0-a7: arguments passed in registers 0 to 7
> @@ -137,6 +138,14 @@ asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
> unsigned long a2, unsigned long a3, unsigned long a4,
> unsigned long a5, unsigned long a6, unsigned long a7,
> struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
> +#else
> +static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
> + unsigned long a2, unsigned long a3, unsigned long a4,
> + unsigned long a5, unsigned long a6, unsigned long a7,
> + struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
> +{
Maybe a warning? If you do not have SMC on your platform but are still
making SMC calls then something is broken and it looks like it would
fail silently here.
Andrew
> +}
> +#endif
>
> /**
> * __arm_smccc_hvc() - make HVC calls
>
^ permalink raw reply
* Re: omap-secure.c:undefined reference to `__arm_smccc_smc'
From: Andrew F. Davis @ 2020-02-20 18:22 UTC (permalink / raw)
To: Tony Lindgren
Cc: Rob Herring, kbuild-all, kbuild test robot, Arnd Bergmann,
Aaro Koskinen, Marc Zyngier, linux-kernel, linux-omap,
linux-arm-kernel
In-Reply-To: <20200220181141.GR37466@atomide.com>
On 2/20/20 1:11 PM, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [200220 17:58]:
>> * Andrew F. Davis <afd@ti.com> [200220 17:39]:
>>> On 2/20/20 12:13 PM, Tony Lindgren wrote:
>>>> * Tony Lindgren <tony@atomide.com> [200220 16:37]:
>>>>> * Andrew F. Davis <afd@ti.com> [200220 16:24]:
>>>>>> On 2/20/20 11:20 AM, Tony Lindgren wrote:
>>>>>>> * Andrew F. Davis <afd@ti.com> [200220 16:04]:
>>>>>>>> On 2/20/20 10:54 AM, Tony Lindgren wrote:
>>>>>>>>> Andrew,
>>>>>>>>>
>>>>>>>>> * kbuild test robot <lkp@intel.com> [200213 10:27]:
>>>>>>>>>> tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
>>>>>>>>>> head: 0bf999f9c5e74c7ecf9dafb527146601e5c848b9
>>>>>>>>>> commit: c37baa06f8a970e4a533d41f7d33e5e57de5ad25 ARM: OMAP2+: Fix undefined reference to omap_secure_init
>>>>>>>>>> date: 3 weeks ago
>>>>>>>>>> config: arm-randconfig-a001-20200213 (attached as .config)
>>>>>>>>>> compiler: arm-linux-gnueabi-gcc (GCC) 7.5.0
>>>>>>>>>> reproduce:
>>>>>>>>>> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>>>>>>>>>> chmod +x ~/bin/make.cross
>>>>>>>>>> git checkout c37baa06f8a970e4a533d41f7d33e5e57de5ad25
>>>>>>>>>> # save the attached .config to linux build tree
>>>>>>>>>> GCC_VERSION=7.5.0 make.cross ARCH=arm
>>>>>>>>>>
>>>>>>>>>> If you fix the issue, kindly add following tag
>>>>>>>>>> Reported-by: kbuild test robot <lkp@intel.com>
>>>>>>>>>>
>>>>>>>>>> All errors (new ones prefixed by >>):
>>>>>>>>>>
>>>>>>>>>> arch/arm/mach-omap2/omap-secure.o: In function `omap_smccc_smc':
>>>>>>>>>>>> omap-secure.c:(.text+0x94): undefined reference to `__arm_smccc_smc'
>>>>>>>>>
>>>>>>>>> Have you looked at this one? Looks like there's still an unhandled
>>>>>>>>> randconfig build case.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> I've had a quick look, all the ARM config does:
>>>>>>>>
>>>>>>>> select HAVE_ARM_SMCCC if CPU_V7
>>>>>>>>
>>>>>>>> so I don't think this will happen in any real config, but if we want to
>>>>>>>> prevent randconfig issue this we could force ARCH_OMAP2PLUS to "depend"
>>>>>>>> on it.
>>>>>>>
>>>>>>> Seems to happen at least with omap2 only config where we don't have
>>>>>>> CPU_V7. Something like below seems to fix it.
>>>>>>>
>>>>>>> If that looks OK to you, I'll send out a proper fix.
>>>>>>>
>>>>>>
>>>>>>
>>>>>> This looks fine to me.
>>>>>>
>>>>>> A better later fix might be to later stub out the actual __arm_smccc_smc
>>>>>> in common code if CONFIG_HAVE_ARM_SMCCC is not set, so any platform will
>>>>>> get the fix.
>>>>>
>>>>> Yeah seems that might be better. Adding Aaro and Marc to Cc.
>>>>
>>>> But if we can in theory have some arm11 machine with smccc, then this
>>>> local ifdef below is probably the way to go.
>>>>
>>>
>>> If the machine has SMCCC then it will also have the
>>> CONFIG_HAVE_ARM_SMCCC set and so nothing would change.
>>
>> Hmm yeah good point.
>
> So the patch below seems like the way to go then. Anybody have issues
> with the patch below?
>
> Regards,
>
> Tony
>
> 8< -------------------------
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -121,6 +121,7 @@ struct arm_smccc_quirk {
> } state;
> };
>
> +#ifdef CONFIG_HAVE_ARM_SMCCC
> /**
> * __arm_smccc_smc() - make SMC calls
> * @a0-a7: arguments passed in registers 0 to 7
> @@ -137,6 +138,14 @@ asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
> unsigned long a2, unsigned long a3, unsigned long a4,
> unsigned long a5, unsigned long a6, unsigned long a7,
> struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
> +#else
> +static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
> + unsigned long a2, unsigned long a3, unsigned long a4,
> + unsigned long a5, unsigned long a6, unsigned long a7,
> + struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
> +{
Maybe a warning? If you do not have SMC on your platform but are still
making SMC calls then something is broken and it looks like it would
fail silently here.
Andrew
> +}
> +#endif
>
> /**
> * __arm_smccc_hvc() - make HVC calls
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] mm: memcontrol: asynchronous reclaim for memory.high
From: Daniel Jordan @ 2020-02-20 18:23 UTC (permalink / raw)
To: Tejun Heo
Cc: Daniel Jordan, Johannes Weiner, Michal Hocko, Andrew Morton,
Roman Gushchin, linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
cgroups-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kernel-team-b10kYP2dOMg,
Peter Zijlstra
In-Reply-To: <20200220155651.GG698990-146+VewaZzwNjtGbbfXrCEEOCMrvLtNR@public.gmane.org>
On Thu, Feb 20, 2020 at 10:56:51AM -0500, Tejun Heo wrote:
> On Thu, Feb 20, 2020 at 10:45:24AM -0500, Daniel Jordan wrote:
> > Ok, consistency with io and memory is one advantage to doing it that way.
> > Creating kthreads in cgroups also seems viable so far, and it's unclear whether
> > either approach is significantly simpler or more maintainable than the other,
> > at least to me.
>
> The problem with separate kthread approach is that many of these work
> units are tiny, and cgroup membership might not be known or doesn't
> agree with the processing context from the beginning
The amount of work wouldn't seem to matter as long as the kernel thread stays
in the cgroup and lives long enough. There's only the one-time cost of
attaching it when it's forked. That seems doable for unbound workqueues (the
async reclaim), but may not be for the network packets.
The membership and context issues are pretty compelling though. Good to know,
I'll keep it in mind as I think this through.
> For example, the ownership of network packets can't be determined till
> processing has progressed quite a bit in shared contexts and each item
> too small to bounce around. The only viable way I can think of
> splitting aggregate overhead according to the number of packets (or
> some other trivially measureable quntity) processed.
>
> Anything sitting in reclaim layer is the same. Reclaim should be
> charged to the cgroup whose memory is reclaimed *but* shouldn't block
> other cgroups which are waiting for that memory. It has to happen in
> the context of the highest priority entity waiting for memory but the
> costs incurred must be charged to the memory owners.
>
> So, one way or the other, I think we'll need back charging and once
> back charging is needed for big ticket items like network and reclaim,
> it's kinda silly to use separate mechanisms for other stuff.
Yes, having both would appear to be redundant.
> > Is someone on your side working on remote charging right now? I was planning
> > to post an RFD comparing these soon and it would make sense to include them.
>
> It's been on the to do list but nobody is working on it yet.
Ok, thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.