* Re: [PATCH v1 4/4] mmc: sdhci-of-esdhc: add erratum A011334 support in ls1028a 1.0 SoC
From: Ulf Hansson @ 2019-08-22 12:13 UTC (permalink / raw)
To: Yinbo Zhu
Cc: Mark Rutland, Catalin Marinas, Will Deacon, Adrian Hunter,
Catalin Horghidan, linux-mmc@vger.kernel.org, DTML, Rajesh Bhagat,
Alison Wang, Ashish Kumar, Claudiu Manoil, Rob Herring,
Vabhav Sharma, Linux ARM, Amit Jain, Alex Marginean,
Linux Kernel Mailing List, Li Yang, Rajat Srivastava, Yangbo Lu,
Jiafei Pan, linuxppc-dev, Xiaobo Xie
In-Reply-To: <20190814072649.8237-4-yinbo.zhu@nxp.com>
On Wed, 14 Aug 2019 at 09:24, Yinbo Zhu <yinbo.zhu@nxp.com> wrote:
>
> This patch is to add erratum A011334 support in ls1028a 1.0 SoC
>
> Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com>
Applied for next, thanks!
Kind regards
Uffe
> ---
> drivers/mmc/host/sdhci-of-esdhc.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index b16f7d440f78..eb2b290447fc 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -1006,6 +1006,7 @@ static struct soc_device_attribute soc_incorrect_hostver[] = {
> static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = {
> { .family = "QorIQ LX2160A", .revision = "1.0", },
> { .family = "QorIQ LX2160A", .revision = "2.0", },
> + { .family = "QorIQ LS1028A", .revision = "1.0", },
> { },
> };
>
> --
> 2.17.1
>
_______________________________________________
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 1/2] mmc: sdhci-of-at91: add quirk for broken HS200
From: Ulf Hansson @ 2019-08-22 12:12 UTC (permalink / raw)
To: Eugen.Hristev, Ludovic Desroches
Cc: Alexandre Belloni, linux-mmc@vger.kernel.org,
Linux Kernel Mailing List, Ulf Hansson, Adrian Hunter, Linux ARM
In-Reply-To: <20190809080842.zl4ytbjyt54bj6ta@M43218.corp.atmel.com>
On Fri, 9 Aug 2019 at 10:09, Ludovic Desroches
<ludovic.desroches@microchip.com> wrote:
>
> On Thu, Aug 08, 2019 at 05:23:00PM +0200, Ulf Hansson wrote:
> > On Thu, 8 Aug 2019 at 10:35, <Eugen.Hristev@microchip.com> wrote:
> > >
> > > From: Eugen Hristev <eugen.hristev@microchip.com>
> > >
> > > HS200 is not implemented in the driver, but the controller claims it
> > > through caps.
> > > Remove it via quirk.
> > > Without this quirk, the mmc core will try to enable hs200, which will fail,
> > > and the eMMC initialization will fail.
> > >
> > > Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> >
> > Should this be applied as a fix and possibly tagged for stable?
> >
> > In such case, do you have a specific commit that it fixes?
>
> I think so, I would say:
> Fixes: bb5f8ea4d514 ("mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC")
> Cc: stable@vger.kernel.org #v4.4 and later
>
> It doesn't apply on 4.4 but resolution is trivial.
>
> Regards
>
> Ludovic
>
[...]
Applied for fixes, by adding the above tags, thanks!
Kind regards
Uffe
_______________________________________________
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 v10 09/23] iommu/io-pgtable-arm-v7s: Extend to support PA[33:32] for MediaTek
From: Yong Wu @ 2019-08-22 12:05 UTC (permalink / raw)
To: Will Deacon, Robin Murphy
Cc: youlin.pei, devicetree, Nicolas Boichat, cui.zhang,
srv_heupstream, Tomasz Figa, Joerg Roedel, linux-kernel,
Evan Green, chao.hao, iommu, Rob Herring, linux-mediatek,
Matthias Brugger, ming-fan.chen, anan.sun, Matthias Kaehlcke,
linux-arm-kernel
In-Reply-To: <20190822112836.efodtwu3souq3uwa@willie-the-truck>
Thanks very much for viewing this so quickly.
On Thu, 2019-08-22 at 12:28 +0100, Will Deacon wrote:
> On Thu, Aug 22, 2019 at 11:57:11AM +0100, Robin Murphy wrote:
> > On 2019-08-22 11:17 am, Will Deacon wrote:
> > > On Thu, Aug 22, 2019 at 11:08:58AM +0100, Robin Murphy wrote:
> > > > On 2019-08-22 9:56 am, Yong Wu wrote:
> > > > > On Wed, 2019-08-21 at 16:24 +0100, Will Deacon wrote:
> > > > > > On Wed, Aug 21, 2019 at 09:53:12PM +0800, Yong Wu wrote:
> > > > > > > MediaTek extend the arm v7s descriptor to support up to 34 bits PA where
> > > > > > > the bit32 and bit33 are encoded in the bit9 and bit4 of the PTE
> > > > > > > respectively. Meanwhile the iova still is 32bits.
> > > > > > >
> > > > > > > Regarding whether the pagetable address could be over 4GB, the mt8183
> > > > > > > support it while the previous mt8173 don't, thus keep it as is.
> > > > > > >
> > > > > > > Signed-off-by: Yong Wu <yong.wu@mediatek.com>
> > > > > > > ---
> > > > > > > drivers/iommu/io-pgtable-arm-v7s.c | 32 +++++++++++++++++++++++++-------
> > > > > > > include/linux/io-pgtable.h | 7 +++----
> > > > > > > 2 files changed, 28 insertions(+), 11 deletions(-)
> > > > > >
> > > > > > [...]
> > > > > >
> > > > > > > @@ -731,7 +747,9 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
> > > > > > > {
> > > > > > > struct arm_v7s_io_pgtable *data;
> > > > > > > - if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS)
> > > > > > > + if (cfg->ias > ARM_V7S_ADDR_BITS ||
> > > > > > > + (cfg->oas > ARM_V7S_ADDR_BITS &&
> > > > > > > + !(cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)))
> > > > > >
> > > > > > Please can you instead change arm_v7s_alloc_pgtable() so that it allows an
> > > > > > ias of up to 34 when the IO_PGTABLE_QUIRK_ARM_MTK_EXT is set?
> > > > >
> > > > > Here I only simply skip the oas checking for our case. then which way do
> > > > > your prefer? something like you commented before:?
> > > > >
> > > > >
> > > > > if (cfg->ias > ARM_V7S_ADDR_BITS)
> > > > > return NULL;
> > > > >
> > > > > if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT) {
> > > > > if (!IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
> > > > > cfg->oas = min(cfg->oas, ARM_V7S_ADDR_BITS);
> > > > > else if (cfg->oas > 34)
> > > > > return NULL;
> > > > > } else if (cfg->oas > ARM_V7S_ADDR_BITS) {
> > > > > return NULL;
> > > > > }
> > > >
> > > > All it should take is something like:
> > > >
> > > > if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)
> > > > max_oas = 34;
> > > > else
> > > > max_oas = 32;
> > > > if (cfg->oas > max_oas)
> > > > return NULL;
> > > >
> > > > or even just:
> > > >
> > > > if (cfg->oas > 32 ||
> > > > (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT && cfg->oas > 34))
> > > > return NULL;
> > > >
> > > > (and if we prefer the latter style, perhaps we could introduce some kind of
> > > > "is_mtk_4gb()" helper to save on verbosity)
> > >
> > > I wondered the same thing, but another place we'd want the check is in
> > > iopte_to_paddr() which probably needs the PHYS_ADDR_T check to avoid GCC
> > > warnings, although I didn't try it.
> >
> > I'm pretty sure I confirmed that "paddr |= BIT_ULL(32)" doesn't warn when
> > phys_addt_t is 32-bit - it's well-defined unsigned integer truncation after
> > all, and if GCC starts warning about all the valid no-op code it optimises
> > away then it's going to run up against IS_ENABLED() first and foremost ;)
>
> You're quite right, although we live in a world where GCC shouts at us about
> missing comments in switch statements so I think my worry was justified!
>
> > > So if we did:
> > >
> > > static bool cfg_mtk_ext_enabled(struct io_pgtable_cfg *cfg)
> > > {
> > > return IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) &&
> > > cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT;
> > > }
> > >
> > > Then I suppose we could do this in _alloc():
> > >
> > > if (cfg->oas > cfg_mtk_ext_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS)
> > > return NULL;
>
> ^^ Apparantly, I left the bracketting here as an exercise to the reader.
>
> > >
> > > and then this in iopte_to_paddr():
> > >
> > > [...]
> > >
> > > paddr = pte & mask;
> > > if (!cfg_mtk_ext_enabled(cfg))
> > > return paddr;
> > >
> > > if (pte & ARM_V7S_ATTR_MTK_PA_BIT32)
> > > paddr |= ...
> > >
> > > [...]
> > >
> > > What do you reckon?
> >
> > Yeah, that's the general shape of things I was picturing - I'm not that
> > fussed about the PHYS_ADDR_T_64BIT thing, especially if it's wrapped up in
> > just one place, so if you do want to keep it as belt-and-braces I'll just
> > consider it a slight code size optimisation for 32-bit builds.
>
> Ok, great. Yong Wu -- are you ok respinning with the above + missing
> brackets?
Of course I can.
NearlyAll the interface in this file is prefixed with "arm_v7s_", so
does the new interface also need it?, like arm_v7s_is_mtk_enabled. And
keep the iopte_to_paddr and paddr_to_iopte symmetrical.
Then the final patch would looks like below, is it ok?
+static bool arm_v7s_is_mtk_enabled(struct io_pgtable_cfg *cfg)
+{
+ return IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) &&
+ (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT);
+}
+
static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl,
struct io_pgtable_cfg *cfg)
{
- return paddr & ARM_V7S_LVL_MASK(lvl);
+ arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl);
+
+ if (!arm_v7s_is_mtk_enabled(cfg))
+ return pte;
+
+ if (paddr & BIT_ULL(32))
+ pte |= ARM_V7S_ATTR_MTK_PA_BIT32;
+ if (paddr & BIT_ULL(33))
+ pte |= ARM_V7S_ATTR_MTK_PA_BIT33;
+ return pte;
}
static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl,
struct io_pgtable_cfg *cfg)
{
arm_v7s_iopte mask;
+ phys_addr_t paddr;
if (ARM_V7S_PTE_IS_TABLE(pte, lvl))
mask = ARM_V7S_TABLE_MASK;
@@ -194,7 +212,15 @@ static phys_addr_t iopte_to_paddr(arm_v7s_iopte
pte, int lvl,
else
mask = ARM_V7S_LVL_MASK(lvl);
- return pte & mask;
+ paddr = pte & mask;
+ if (!arm_v7s_is_mtk_enabled(cfg))
+ return paddr;
+
+ if (pte & ARM_V7S_ATTR_MTK_PA_BIT32)
+ paddr |= BIT_ULL(32);
+ if (pte & ARM_V7S_ATTR_MTK_PA_BIT33)
+ paddr |= BIT_ULL(33);
+ return paddr;
}
static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl,
@@ -315,9 +341,6 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot,
int lvl,
if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
pte |= ARM_V7S_ATTR_NS_SECTION;
- if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)
- pte |= ARM_V7S_ATTR_MTK_4GB;
-
return pte;
}
@@ -731,7 +754,10 @@ static struct io_pgtable
*arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
{
struct arm_v7s_io_pgtable *data;
- if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS)
+ if (cfg->ias > ARM_V7S_ADDR_BITS)
+ return NULL;
+
+ if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS))
return NULL;
>
> Will
_______________________________________________
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 00/59] KVM: arm64: ARMv8.3 Nested Virtualization support
From: Alexandru Elisei @ 2019-08-22 11:57 UTC (permalink / raw)
To: Marc Zyngier, linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org
Cc: Andre Przywara, Dave P Martin
In-Reply-To: <0d9aa552-fa01-c482-41d7-587acf308259@arm.com>
On 8/9/19 11:01 AM, Alexandru Elisei wrote:
> On 8/2/19 11:11 AM, Alexandru Elisei wrote:
>> Hi,
>>
>> On 6/21/19 10:37 AM, Marc Zyngier wrote:
>> When working on adding support for EL2 to kvm-unit-tests I was able to trigger
>> the following warning:
>>
>> # ./lkvm run -f psci.flat -m 128 -c 8 --console serial --irqchip gicv3 --nested
>> # lkvm run --firmware psci.flat -m 128 -c 8 --name guest-151
>> Info: Placing fdt at 0x80200000 - 0x80210000
>> # Warning: The maximum recommended amount of VCPUs is 4
>> chr_testdev_init: chr-testdev: can't find a virtio-console
>> INFO: PSCI version 1.0
>> PASS: invalid-function
>> PASS: affinity-info-on
>> PASS: affinity-info-off
>> [ 24.381266] WARNING: CPU: 3 PID: 160 at
>> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
>> kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.381366] Modules linked in:
>> [ 24.381466] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Not tainted
>> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
>> [ 24.381566] Hardware name: Foundation-v8A (DT)
>> [ 24.381566] pstate: 40400009 (nZcv daif +PAN -UAO)
>> [ 24.381666] pc : kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.381766] lr : timer_emulate+0x24/0x98
>> [ 24.381766] sp : ffff000013d8b780
>> [ 24.381866] x29: ffff000013d8b780 x28: ffff80087a639b80
>> [ 24.381966] x27: ffff000010ba8648 x26: ffff000010b71b40
>> [ 24.382066] x25: ffff80087a63a100 x24: 0000000000000000
>> [ 24.382111] x23: 000080086ca54000 x22: ffff0000100ce260
>> [ 24.382166] x21: ffff800875e7c918 x20: ffff800875e7a800
>> [ 24.382275] x19: ffff800875e7ca08 x18: 0000000000000000
>> [ 24.382366] x17: 0000000000000000 x16: 0000000000000000
>> [ 24.382466] x15: 0000000000000000 x14: 0000000000002118
>> [ 24.382566] x13: 0000000000002190 x12: 0000000000002280
>> [ 24.382566] x11: 0000000000002208 x10: 0000000000000040
>> [ 24.382666] x9 : ffff000012dc3b38 x8 : 0000000000000000
>> [ 24.382766] x7 : 0000000000000000 x6 : ffff80087ac00248
>> [ 24.382866] x5 : 000080086ca54000 x4 : 0000000000002118
>> [ 24.382966] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
>> [ 24.383066] x1 : 0000000000000001 x0 : ffff800875e7ca08
>> [ 24.383066] Call trace:
>> [ 24.383166] kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.383266] kvm_timer_vcpu_load+0x9c/0x1a0
>> [ 24.383366] kvm_arch_vcpu_load+0xb0/0x1f0
>> [ 24.383366] kvm_sched_in+0x1c/0x28
>> [ 24.383466] finish_task_switch+0xd8/0x1d8
>> [ 24.383566] __schedule+0x248/0x4a0
>> [ 24.383666] preempt_schedule_irq+0x60/0x90
>> [ 24.383666] el1_irq+0xd0/0x180
>> [ 24.383766] kvm_handle_guest_abort+0x0/0x3a0
>> [ 24.383866] kvm_arch_vcpu_ioctl_run+0x41c/0x688
>> [ 24.383866] kvm_vcpu_ioctl+0x4c0/0x838
>> [ 24.383966] do_vfs_ioctl+0xb8/0x878
>> [ 24.384077] ksys_ioctl+0x84/0x90
>> [ 24.384166] __arm64_sys_ioctl+0x18/0x28
>> [ 24.384166] el0_svc_common.constprop.0+0xb0/0x168
>> [ 24.384266] el0_svc_handler+0x28/0x78
>> [ 24.384366] el0_svc+0x8/0xc
>> [ 24.384366] ---[ end trace 37a32293e43ac12c ]---
>> [ 24.384666] WARNING: CPU: 3 PID: 160 at
>> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
>> kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.384766] Modules linked in:
>> [ 24.384866] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Tainted: G W
>> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
>> [ 24.384966] Hardware name: Foundation-v8A (DT)
>> [ 24.384966] pstate: 40400009 (nZcv daif +PAN -UAO)
>> [ 24.385066] pc : kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.385166] lr : timer_emulate+0x24/0x98
>> [ 24.385166] sp : ffff000013d8b780
>> [ 24.385266] x29: ffff000013d8b780 x28: ffff80087a639b80
>> [ 24.385366] x27: ffff000010ba8648 x26: ffff000010b71b40
>> [ 24.385466] x25: ffff80087a63a100 x24: 0000000000000000
>> [ 24.385466] x23: 000080086ca54000 x22: ffff0000100ce260
>> [ 24.385566] x21: ffff800875e7c918 x20: ffff800875e7a800
>> [ 24.385666] x19: ffff800875e7ca80 x18: 0000000000000000
>> [ 24.385766] x17: 0000000000000000 x16: 0000000000000000
>> [ 24.385866] x15: 0000000000000000 x14: 0000000000002118
>> [ 24.385966] x13: 0000000000002190 x12: 0000000000002280
>> [ 24.385966] x11: 0000000000002208 x10: 0000000000000040
>> [ 24.386066] x9 : ffff000012dc3b38 x8 : 0000000000000000
>> [ 24.386166] x7 : 0000000000000000 x6 : ffff80087ac00248
>> [ 24.386266] x5 : 000080086ca54000 x4 : 0000000000002118
>> [ 24.386366] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
>> [ 24.386466] x1 : 0000000000000001 x0 : ffff800875e7ca80
>> [ 24.386466] Call trace:
>> [ 24.386566] kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.386666] kvm_timer_vcpu_load+0xa8/0x1a0
>> [ 24.386666] kvm_arch_vcpu_load+0xb0/0x1f0
>> [ 24.386898] kvm_sched_in+0x1c/0x28
>> [ 24.386966] finish_task_switch+0xd8/0x1d8
>> [ 24.387166] __schedule+0x248/0x4a0
>> [ 24.387354] preempt_schedule_irq+0x60/0x90
>> [ 24.387366] el1_irq+0xd0/0x180
>> [ 24.387466] kvm_handle_guest_abort+0x0/0x3a0
>> [ 24.387566] kvm_arch_vcpu_ioctl_run+0x41c/0x688
>> [ 24.387566] kvm_vcpu_ioctl+0x4c0/0x838
>> [ 24.387666] do_vfs_ioctl+0xb8/0x878
>> [ 24.387766] ksys_ioctl+0x84/0x90
>> [ 24.387866] __arm64_sys_ioctl+0x18/0x28
>> [ 24.387866] el0_svc_common.constprop.0+0xb0/0x168
>> [ 24.387966] el0_svc_handler+0x28/0x78
>> [ 24.388066] el0_svc+0x8/0xc
>> [ 24.388066] ---[ end trace 37a32293e43ac12d ]---
>> PASS: cpu-on
>> SUMMARY: 4 te[ 24.390266] WARNING: CPU: 3 PID: 160 at
>> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
>> kvm_timer_irq_can_fire+0xc/0x30
>> s[ 24.390366] Modules linked in:
>> ts[ 24.390366] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Tainted: G W
>> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
>> [ 24.390566] Hardware name: Foundation-v8A (DT)
>>
>> [ 24.390795] pstate: 40400009 (nZcv daif +PAN -UAO)
>> [ 24.390866] pc : kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.390966] lr : timer_emulate+0x24/0x98
>> [ 24.391066] sp : ffff000013d8b780
>> [ 24.391066] x29: ffff000013d8b780 x28: ffff80087a639b80
>> [ 24.391166] x27: ffff000010ba8648 x26: ffff000010b71b40
>> [ 24.391266] x25: ffff80087a63a100 x24: 0000000000000000
>> [ 24.391366] x23: 000080086ca54000 x22: 0000000000000003
>> [ 24.391466] x21: ffff800875e7c918 x20: ffff800875e7a800
>> [ 24.391466] x19: ffff800875e7ca08 x18: 0000000000000000
>> [ 24.391566] x17: 0000000000000000 x16: 0000000000000000
>> [ 24.391666] x15: 0000000000000000 x14: 0000000000002118
>> [ 24.391766] x13: 0000000000002190 x12: 0000000000002280
>> [ 24.391866] x11: 0000000000002208 x10: 0000000000000040
>> [ 24.391942] x9 : ffff000012dc3b38 x8 : 0000000000000000
>> [ 24.391966] x7 : 0000000000000000 x6 : ffff80087ac00248
>> [ 24.392066] x5 : 000080086ca54000 x4 : 0000000000002118
>> [ 24.392166] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
>> [ 24.392269] x1 : 0000000000000001 x0 : ffff800875e7ca08
>> [ 24.392366] Call trace:
>> [ 24.392433] kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.392466] kvm_timer_vcpu_load+0x9c/0x1a0
>> [ 24.392597] kvm_arch_vcpu_load+0xb0/0x1f0
>> [ 24.392666] kvm_sched_in+0x1c/0x28
>> [ 24.392766] finish_task_switch+0xd8/0x1d8
>> [ 24.392766] __schedule+0x248/0x4a0
>> [ 24.392866] preempt_schedule_irq+0x60/0x90
>> [ 24.392966] el1_irq+0xd0/0x180
>> [ 24.392966] kvm_handle_guest_abort+0x0/0x3a0
>> [ 24.393066] kvm_arch_vcpu_ioctl_run+0x41c/0x688
>> [ 24.393166] kvm_vcpu_ioctl+0x4c0/0x838
>> [ 24.393266] do_vfs_ioctl+0xb8/0x878
>> [ 24.393266] ksys_ioctl+0x84/0x90
>> [ 24.393366] __arm64_sys_ioctl+0x18/0x28
>> [ 24.393466] el0_svc_common.constprop.0+0xb0/0x168
>> [ 24.393566] el0_svc_handler+0x28/0x78
>> [ 24.393566] el0_svc+0x8/0xc
>> [ 24.393666] ---[ end trace 37a32293e43ac12e ]---
>> [ 24.393866] WARNING: CPU: 3 PID: 160 at
>> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
>> kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.394066] Modules linked in:
>> [ 24.394266] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Tainted: G W
>> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
>> [ 24.394366] Hardware name: Foundation-v8A (DT)
>> [ 24.394466] pstate: 40400009 (nZcv daif +PAN -UAO)
>> [ 24.394466] pc : kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.394566] lr : timer_emulate+0x24/0x98
>> [ 24.394666] sp : ffff000013d8b780
>> [ 24.394727] x29: ffff000013d8b780 x28: ffff80087a639b80
>> [ 24.394766] x27: ffff000010ba8648 x26: ffff000010b71b40
>> [ 24.394866] x25: ffff80087a63a100 x24: 0000000000000000
>> [ 24.394966] x23: 000080086ca54000 x22: 0000000000000003
>> [ 24.394966] x21: ffff800875e7c918 x20: ffff800875e7a800
>> [ 24.395066] x19: ffff800875e7ca80 x18: 0000000000000000
>> [ 24.395166] x17: 0000000000000000 x16: 0000000000000000
>> [ 24.395266] x15: 0000000000000000 x14: 0000000000002118
>> [ 24.395383] x13: 0000000000002190 x12: 0000000000002280
>> [ 24.395466] x11: 0000000000002208 x10: 0000000000000040
>> [ 24.395547] x9 : ffff000012dc3b38 x8 : 0000000000000000
>> [ 24.395666] x7 : 0000000000000000 x6 : ffff80087ac00248
>> [ 24.395866] x5 : 000080086ca54000 x4 : 0000000000002118
>> [ 24.395966] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
>> [ 24.396066] x1 : 0000000000000001 x0 : ffff800875e7ca80
>> [ 24.396066] Call trace:
>> [ 24.396166] kvm_timer_irq_can_fire+0xc/0x30
>> [ 24.396266] kvm_timer_vcpu_load+0xa8/0x1a0
>> [ 24.396366] kvm_arch_vcpu_load+0xb0/0x1f0
>> [ 24.396366] kvm_sched_in+0x1c/0x28
>> [ 24.396466] finish_task_switch+0xd8/0x1d8
>> [ 24.396566] __schedule+0x248/0x4a0
>> [ 24.396666] preempt_schedule_irq+0x60/0x90
>> [ 24.396666] el1_irq+0xd0/0x180
>> [ 24.396766] kvm_handle_guest_abort+0x0/0x3a0
>> [ 24.396866] kvm_arch_vcpu_ioctl_run+0x41c/0x688
>> [ 24.396866] kvm_vcpu_ioctl+0x4c0/0x838
>> [ 24.397021] do_vfs_ioctl+0xb8/0x878
>> [ 24.397066] ksys_ioctl+0x84/0x90
>> [ 24.397166] __arm64_sys_ioctl+0x18/0x28
>> [ 24.397348] el0_svc_common.constprop.0+0xb0/0x168
>> [ 24.397366] el0_svc_handler+0x28/0x78
>> [ 24.397566] el0_svc+0x8/0xc
>> [ 24.397676] ---[ end trace 37a32293e43ac12f ]---
>>
>> # KVM compatibility warning.
>> virtio-9p device was not detected.
>> While you have requested a virtio-9p device, the guest kernel did not
>> initialize it.
>> Please make sure that the guest kernel was compiled with
>> CONFIG_NET_9P_VIRTIO=y enabled in .config.
>>
>> # KVM compatibility warning.
>> virtio-net device was not detected.
>> While you have requested a virtio-net device, the guest kernel did not
>> initialize it.
>> Please make sure that the guest kernel was compiled with CONFIG_VIRTIO_NET=y
>> enabled in .config.
>>
>> [..]
> Did some investigating and this was caused by a bug in kvm-unit-tests (the fix
> for it will be part of the EL2 patches for kvm-unit-tests). The guest was trying
> to fetch an instruction from address 0x200, which KVM interprets as a prefetch
> abort on an I/O address and ends up calling kvm_inject_pabt. The code from
> arch/arm64/kvm/inject_fault.c doesn't know anything about nested virtualization,
> and it sets the VCPU mode directly to PSR_MODE_EL1h. This makes_hyp_ctxt return
> false, and get_timer_map will return an incorrect mapping.
>
> On next kvm_timer_vcpu_put, the direct timers will be {p,v}timer, and
> h{p,v}timer->loaded will not be set to false. In the corresponding call to
> kvm_timer_vcpu_load, KVM will try to emulate the hptimer and hvtimer, which
> still have loaded = true. And this causes the warning I saw.
I tried to fix it with the following patch, inject_undef64 was similarly broken:
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index fac962b467bd..aee8a9ef36d5 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -53,15 +53,7 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt,
unsigned long addr
{
unsigned long cpsr = *vcpu_cpsr(vcpu);
bool is_aarch32 = vcpu_mode_is_32bit(vcpu);
- u32 esr = 0;
-
- vcpu_write_elr_el1(vcpu, *vcpu_pc(vcpu));
- *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
-
- *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
- vcpu_write_spsr(vcpu, cpsr);
-
- vcpu_write_sys_reg(vcpu, addr, FAR_EL1);
+ u32 esr = ESR_ELx_FSC_EXTABT;
/*
* Build an {i,d}abort, depending on the level and the
@@ -82,13 +74,12 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool
is_iabt, unsigned long addr
if (!is_iabt)
esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
- vcpu_write_sys_reg(vcpu, esr | ESR_ELx_FSC_EXTABT, ESR_EL1);
-}
+ if (nested_virt_in_use(vcpu)) {
+ kvm_inject_nested_sync(vcpu, esr);
+ return;
+ }
-static void inject_undef64(struct kvm_vcpu *vcpu)
-{
- unsigned long cpsr = *vcpu_cpsr(vcpu);
- u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+ vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
vcpu_write_elr_el1(vcpu, *vcpu_pc(vcpu));
*vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
@@ -96,6 +87,14 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
*vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
vcpu_write_spsr(vcpu, cpsr);
+ vcpu_write_sys_reg(vcpu, addr, FAR_EL1);
+}
+
+static void inject_undef64(struct kvm_vcpu *vcpu)
+{
+ unsigned long cpsr = *vcpu_cpsr(vcpu);
+ u32 esr = ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT;
+
/*
* Build an unknown exception, depending on the instruction
* set.
@@ -103,7 +102,18 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
if (kvm_vcpu_trap_il_is32bit(vcpu))
esr |= ESR_ELx_IL;
+ if (nested_virt_in_use(vcpu)) {
+ kvm_inject_nested_sync(vcpu, esr);
+ return;
+ }
+
vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
+
+ vcpu_write_elr_el1(vcpu, *vcpu_pc(vcpu));
+ *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
+
+ *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
+ vcpu_write_spsr(vcpu, cpsr);
}
/**
_______________________________________________
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: [PATCH v5 1/2] dt-bindings: mmc: Document Aspeed SD controller
From: Andrew Jeffery @ 2019-08-22 11:55 UTC (permalink / raw)
To: Ulf Hansson
Cc: Mark Rutland, devicetree, linux-aspeed, Ryan Chen, linux-mmc,
Adrian Hunter, Linux Kernel Mailing List, Rob Herring,
Joel Stanley, Linux ARM
In-Reply-To: <CAPDyKFrDPxFMm710Z25i-euOT2rrgCNXVa4na-fye0xamMXq_A@mail.gmail.com>
On Thu, 22 Aug 2019, at 21:15, Ulf Hansson wrote:
> On Thu, 15 Aug 2019 at 07:37, Andrew Jeffery <andrew@aj.id.au> wrote:
> >
> >
> >
> > On Thu, 15 Aug 2019, at 15:06, Joel Stanley wrote:
> > > On Wed, 7 Aug 2019 at 00:38, Andrew Jeffery <andrew@aj.id.au> wrote:
> > > >
> > > > The ASPEED SD/SDIO/MMC controller exposes two slots implementing the
> > > > SDIO Host Specification v2.00, with 1 or 4 bit data buses, or an 8 bit
> > > > data bus if only a single slot is enabled.
> > > >
> > > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > >
> > > Reviewed-by: Joel Stanley <joel@jms.id.au>
> > >
> > > Two minor comments below.
> > >
> > > > +++ b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml
> > > > @@ -0,0 +1,105 @@
> > > > +# SPDX-License-Identifier: GPL-2.0-or-later
> > >
> > > No "Copyright IBM" ?
> >
> > I'm going rogue.
> >
> > That reminds me I should chase up where we got to with the binding
> > licensing.
> >
> > >
> > > > +%YAML 1.2
> > > > +---
> > >
> > > > +
> > > > +examples:
> > > > + - |
> > > > + #include <dt-bindings/clock/aspeed-clock.h>
> > > > + sdc@1e740000 {
> > > > + compatible = "aspeed,ast2500-sd-controller";
> > > > + reg = <0x1e740000 0x100>;
> > > > + #address-cells = <1>;
> > > > + #size-cells = <1>;
> > > > + ranges = <0 0x1e740000 0x10000>;
> > >
> > > According to the datasheet this could be 0x20000. It does not matter
> > > though, as there's nothing in it past 0x300.
> >
> > Good catch.
> >
>
> Are you planning on sending a v6 or you want me to apply this and you
> can post a patch on top?
Yeah, sorry, I wasn't very clear there. I was hoping just to do a follow-up
patch with the cleanups if you're okay with that?
Andrew
_______________________________________________
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 v5] arm64: implement KPROBES_ON_FTRACE
From: Naveen N. Rao @ 2019-08-22 11:52 UTC (permalink / raw)
To: Catalin Marinas, Jonathan Corbet, Jisheng Zhang, Masami Hiramatsu
Cc: Mark Rutland, linux-doc@vger.kernel.org, Peter Zijlstra,
linux-kernel@vger.kernel.org, Steven Rostedt, Thomas Gleixner,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190822191351.3796aca8@xhacker.debian>
Jisheng Zhang wrote:
> KPROBES_ON_FTRACE avoids much of the overhead with regular kprobes as it
> eliminates the need for a trap, as well as the need to emulate or
> single-step instructions.
>
> Tested on berlin arm64 platform.
>
> ~ # mount -t debugfs debugfs /sys/kernel/debug/
> ~ # cd /sys/kernel/debug/
> /sys/kernel/debug # echo 'p _do_fork' > tracing/kprobe_events
>
> before the patch:
>
> /sys/kernel/debug # cat kprobes/list
> ffffff801009fe28 k _do_fork+0x0 [DISABLED]
>
> after the patch:
>
> /sys/kernel/debug # cat kprobes/list
> ffffff801009ff54 k _do_fork+0x4 [DISABLED][FTRACE]
>
> Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
Reviewed-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
- Naveen
_______________________________________________
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 v2 2/4] rtc: Add support for the MediaTek MT2712 RTC
From: Ran Bi @ 2019-08-22 11:50 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Mark Rutland, Alessandro Zummo, YT Shen, Flora Fu, srv_heupstream,
devicetree, Greg Kroah-Hartman, Linus Walleij, Sean Wang,
linux-kernel, Mauro Carvalho Chehab, Rob Herring, linux-mediatek,
Jonathan Cameron, Matthias Brugger, Yingjoe Chen, Eddie Huang,
David S . Miller, linux-arm-kernel, linux-rtc
In-Reply-To: <20190822092008.GR27031@piout.net>
On Thu, 2019-08-22 at 11:20 +0200, Alexandre Belloni wrote:
> On 22/08/2019 11:12:29+0200, Matthias Brugger wrote:
> >
> >
> > On 01/08/2019 13:01, Ran Bi wrote:
> > > This add support for the MediaTek MT2712 RTC. It was SoC based RTC, but
> > > had different architecture compared with MT7622 RTC.
> > >
> > > Signed-off-by: Ran Bi <ran.bi@mediatek.com>
> > > ---
> > > drivers/rtc/Kconfig | 10 +
> > > drivers/rtc/Makefile | 1 +
> > > drivers/rtc/rtc-mt2712.c | 444 +++++++++++++++++++++++++++++++++++++++
> >
> > Can't we just adjust rtc-mt7622.c (and rename it) to unify the source for both
> > devices. What is the difference that we need to write a driver of our own?
> >
>
> If they are compatible, this is the way to go but the file can't be
> renamed (and that is fine).
>
>
They are not compatible. Both registers and operating methods are
different.
Best Regards,
Ran
_______________________________________________
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 v3 07/10] KVM: arm64: Provide a PV_TIME device to user space
From: Jonathan Cameron @ 2019-08-22 11:48 UTC (permalink / raw)
To: Steven Price
Cc: Mark Rutland, Radim Krčmář, kvm, Suzuki K Pouloze,
Marc Zyngier, linux-doc, linux-kernel, Russell King, James Morse,
linux-arm-kernel, Catalin Marinas, Paolo Bonzini, Will Deacon,
kvmarm, Julien Thierry
In-Reply-To: <87bc2a01-8cf5-5161-45f8-00384775cf3a@arm.com>
On Thu, 22 Aug 2019 12:11:55 +0100
Steven Price <steven.price@arm.com> wrote:
> On 22/08/2019 11:57, Jonathan Cameron wrote:
> > On Wed, 21 Aug 2019 16:36:53 +0100
> > Steven Price <steven.price@arm.com> wrote:
> >
> >> Allow user space to inform the KVM host where in the physical memory
> >> map the paravirtualized time structures should be located.
> >>
> >> A device is created which provides the base address of an array of
> >> Stolen Time (ST) structures, one for each VCPU. There must be (64 *
> >> total number of VCPUs) bytes of memory available at this location.
> >>
> >> The address is given in terms of the physical address visible to
> >> the guest and must be page aligned. The guest will discover the address
> >> via a hypercall.
> >>
> >> Signed-off-by: Steven Price <steven.price@arm.com>
> >
> > Hi Steven,
> >
> > One general question inline. I'm not particularly familiar with this area
> > of the kernel, so maybe I'm missing something obvious, but having
> > .destroy free the kvm_device which wasn't created in .create seems
> > 'unusual'.
> >
> > Otherwise, FWIW looks good to me.
> >
> > Jonathan
> >
> [...]
> >> +static void kvm_arm_pvtime_destroy(struct kvm_device *dev)
> >> +{
> >> + struct kvm_arch_pvtime *pvtime = &dev->kvm->arch.pvtime;
> >> +
> >> + pvtime->st_base = GPA_INVALID;
> >> + kfree(dev);
> >
> > Nothing to do with your patch as such... All users do the same.
> >
> > This seems miss balanced. Why do we need to free the device by hand
> > when we didn't create it in the create function? I appreciate
> > the comments say this is needed, but as far as I can see every
> > single callback does kfree(dev) at the end which seems an
> > odd thing to do.
>
> Yes I think this is odd too - indeed when I initially wrote this I
> missed off the kfree() call and had to track down the memory leak.
>
> When I looked into potentially tiding this up I found some other
> oddities, e.g. "kvm-xive" (arch/powerpc/kvm/book3s_xive.c) doesn't have
> a destroy callback. But I can't see anything in the common code which
> deals with that case. So I decided to just "go with the flow" at the
> moment, since I don't understand how some of these existing devices work
> (perhaps they are already broken?).
It has a release however and kvm_device_release also removes the
device from the list that would then be cleared by kvm_destroy_devices.
kvm_device_release is a release callback for the file operations so it
'might' be called in all paths.
Fun though, in kvm_ioctl_create_device the error handling for
the anon_inode_getfd calls ops->destroy without checking it exists.
Boom.
Possibly never happens in reality but looks like a bug to me.
Jonathan
>
> Steve
>
> >> +}
> >> +
> >> +static int kvm_arm_pvtime_set_attr(struct kvm_device *dev,
> >> + struct kvm_device_attr *attr)
> >> +{
> >> + struct kvm *kvm = dev->kvm;
> >> + struct kvm_arch_pvtime *pvtime = &kvm->arch.pvtime;
> >> + u64 __user *user = (u64 __user *)attr->addr;
> >> + struct kvm_dev_arm_st_region region;
> >> +
> >> + switch (attr->group) {
> >> + case KVM_DEV_ARM_PV_TIME_REGION:
> >> + if (copy_from_user(®ion, user, sizeof(region)))
> >> + return -EFAULT;
> >> + if (region.gpa & ~PAGE_MASK)
> >> + return -EINVAL;
> >> + if (region.size & ~PAGE_MASK)
> >> + return -EINVAL;
> >> + switch (attr->attr) {
> >> + case KVM_DEV_ARM_PV_TIME_ST:
> >> + if (pvtime->st_base != GPA_INVALID)
> >> + return -EEXIST;
> >> + pvtime->st_base = region.gpa;
> >> + pvtime->st_size = region.size;
> >> + return 0;
> >> + }
> >> + break;
> >> + }
> >> + return -ENXIO;
> >> +}
> >> +
> >> +static int kvm_arm_pvtime_get_attr(struct kvm_device *dev,
> >> + struct kvm_device_attr *attr)
> >> +{
> >> + struct kvm_arch_pvtime *pvtime = &dev->kvm->arch.pvtime;
> >> + u64 __user *user = (u64 __user *)attr->addr;
> >> + struct kvm_dev_arm_st_region region;
> >> +
> >> + switch (attr->group) {
> >> + case KVM_DEV_ARM_PV_TIME_REGION:
> >> + switch (attr->attr) {
> >> + case KVM_DEV_ARM_PV_TIME_ST:
> >> + region.gpa = pvtime->st_base;
> >> + region.size = pvtime->st_size;
> >> + if (copy_to_user(user, ®ion, sizeof(region)))
> >> + return -EFAULT;
> >> + return 0;
> >> + }
> >> + break;
> >> + }
> >> + return -ENXIO;
> >> +}
> >> +
> >> +static int kvm_arm_pvtime_has_attr(struct kvm_device *dev,
> >> + struct kvm_device_attr *attr)
> >> +{
> >> + switch (attr->group) {
> >> + case KVM_DEV_ARM_PV_TIME_REGION:
> >> + switch (attr->attr) {
> >> + case KVM_DEV_ARM_PV_TIME_ST:
> >> + return 0;
> >> + }
> >> + break;
> >> + }
> >> + return -ENXIO;
> >> +}
> >> +
> >> +static const struct kvm_device_ops pvtime_ops = {
> >> + "Arm PV time",
> >> + .create = kvm_arm_pvtime_create,
> >> + .destroy = kvm_arm_pvtime_destroy,
> >> + .set_attr = kvm_arm_pvtime_set_attr,
> >> + .get_attr = kvm_arm_pvtime_get_attr,
> >> + .has_attr = kvm_arm_pvtime_has_attr
> >> +};
> >> +
> >> +void kvm_pvtime_init(void)
> >> +{
> >> + kvm_register_device_ops(&pvtime_ops, KVM_DEV_TYPE_ARM_PV_TIME);
> >> +}
> >
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> >
>
_______________________________________________
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 v2 2/4] rtc: Add support for the MediaTek MT2712 RTC
From: Ran Bi @ 2019-08-22 11:47 UTC (permalink / raw)
To: Matthias Brugger
Cc: Mark Rutland, Alessandro Zummo, Alexandre Belloni, Flora Fu,
srv_heupstream, devicetree, Greg Kroah-Hartman, Linus Walleij,
Sean Wang, linux-kernel, YT Shen, Rob Herring, linux-mediatek,
Jonathan Cameron, Mauro Carvalho Chehab, Yingjoe Chen,
Eddie Huang, David S . Miller, linux-arm-kernel, linux-rtc
In-Reply-To: <c4e8b041-4a35-578e-07a3-2ebc99848ee2@gmail.com>
On Thu, 2019-08-22 at 11:12 +0200, Matthias Brugger wrote:
>
> On 01/08/2019 13:01, Ran Bi wrote:
> > This add support for the MediaTek MT2712 RTC. It was SoC based RTC, but
> > had different architecture compared with MT7622 RTC.
> >
> > Signed-off-by: Ran Bi <ran.bi@mediatek.com>
> > ---
> > drivers/rtc/Kconfig | 10 +
> > drivers/rtc/Makefile | 1 +
> > drivers/rtc/rtc-mt2712.c | 444 +++++++++++++++++++++++++++++++++++++++
>
> Can't we just adjust rtc-mt7622.c (and rename it) to unify the source for both
> devices. What is the difference that we need to write a driver of our own?
>
> Regards,
> Matthias
We cannot merge rtc-mt7622.c and rtc-mt2712.c together. These two rtc
hardwares have totally different design. Registers naming, registers
offset and operating method are different.
_______________________________________________
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 v5 1/2] dt-bindings: mmc: Document Aspeed SD controller
From: Ulf Hansson @ 2019-08-22 11:45 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Mark Rutland, devicetree, linux-aspeed, Ryan Chen, linux-mmc,
Adrian Hunter, Linux Kernel Mailing List, Rob Herring,
Joel Stanley, Linux ARM
In-Reply-To: <6c94aada-9c4a-4f55-9a43-349282ad12af@www.fastmail.com>
On Thu, 15 Aug 2019 at 07:37, Andrew Jeffery <andrew@aj.id.au> wrote:
>
>
>
> On Thu, 15 Aug 2019, at 15:06, Joel Stanley wrote:
> > On Wed, 7 Aug 2019 at 00:38, Andrew Jeffery <andrew@aj.id.au> wrote:
> > >
> > > The ASPEED SD/SDIO/MMC controller exposes two slots implementing the
> > > SDIO Host Specification v2.00, with 1 or 4 bit data buses, or an 8 bit
> > > data bus if only a single slot is enabled.
> > >
> > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> >
> > Reviewed-by: Joel Stanley <joel@jms.id.au>
> >
> > Two minor comments below.
> >
> > > +++ b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml
> > > @@ -0,0 +1,105 @@
> > > +# SPDX-License-Identifier: GPL-2.0-or-later
> >
> > No "Copyright IBM" ?
>
> I'm going rogue.
>
> That reminds me I should chase up where we got to with the binding
> licensing.
>
> >
> > > +%YAML 1.2
> > > +---
> >
> > > +
> > > +examples:
> > > + - |
> > > + #include <dt-bindings/clock/aspeed-clock.h>
> > > + sdc@1e740000 {
> > > + compatible = "aspeed,ast2500-sd-controller";
> > > + reg = <0x1e740000 0x100>;
> > > + #address-cells = <1>;
> > > + #size-cells = <1>;
> > > + ranges = <0 0x1e740000 0x10000>;
> >
> > According to the datasheet this could be 0x20000. It does not matter
> > though, as there's nothing in it past 0x300.
>
> Good catch.
>
Are you planning on sending a v6 or you want me to apply this and you
can post a patch on top?
Kind regards
Uffe
_______________________________________________
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 v2 06/10] PCI: layerscape: Modify the way of getting capability with different PEX
From: Kishon Vijay Abraham I @ 2019-08-22 11:43 UTC (permalink / raw)
To: Xiaowei Bao, bhelgaas, robh+dt, mark.rutland, shawnguo,
leoyang.li, lorenzo.pieralisi, arnd, gregkh, minghuan.Lian,
mingkai.hu, roy.zang, jingoohan1, gustavo.pimentel, linux-pci,
devicetree, linux-kernel, linux-arm-kernel, linuxppc-dev,
andrew.murray
In-Reply-To: <20190822112242.16309-6-xiaowei.bao@nxp.com>
Hi,
On 22/08/19 4:52 PM, Xiaowei Bao wrote:
> The different PCIe controller in one board may be have different
> capability of MSI or MSIX, so change the way of getting the MSI
> capability, make it more flexible.
please use different pci_epc_features table for different boards.
Thanks
Kishon
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> v2:
> - Remove the repeated assignment code.
>
> drivers/pci/controller/dwc/pci-layerscape-ep.c | 26 +++++++++++++++++++-------
> 1 file changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index 4e92a95..8461f62 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -22,6 +22,7 @@
>
> struct ls_pcie_ep {
> struct dw_pcie *pci;
> + struct pci_epc_features *ls_epc;
> };
>
> #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
> @@ -40,25 +41,26 @@ static const struct of_device_id ls_pcie_ep_of_match[] = {
> { },
> };
>
> -static const struct pci_epc_features ls_pcie_epc_features = {
> - .linkup_notifier = false,
> - .msi_capable = true,
> - .msix_capable = false,
> -};
> -
> static const struct pci_epc_features*
> ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
> {
> - return &ls_pcie_epc_features;
> + struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> + struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
> +
> + return pcie->ls_epc;
> }
>
> static void ls_pcie_ep_init(struct dw_pcie_ep *ep)
> {
> struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> + struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
> enum pci_barno bar;
>
> for (bar = BAR_0; bar <= BAR_5; bar++)
> dw_pcie_ep_reset_bar(pci, bar);
> +
> + pcie->ls_epc->msi_capable = ep->msi_cap ? true : false;
> + pcie->ls_epc->msix_capable = ep->msix_cap ? true : false;
> }
>
> static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
> @@ -118,6 +120,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> struct device *dev = &pdev->dev;
> struct dw_pcie *pci;
> struct ls_pcie_ep *pcie;
> + struct pci_epc_features *ls_epc;
> struct resource *dbi_base;
> int ret;
>
> @@ -129,6 +132,10 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> if (!pci)
> return -ENOMEM;
>
> + ls_epc = devm_kzalloc(dev, sizeof(*ls_epc), GFP_KERNEL);
> + if (!ls_epc)
> + return -ENOMEM;
> +
> dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
> pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
> if (IS_ERR(pci->dbi_base))
> @@ -139,6 +146,11 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> pci->ops = &ls_pcie_ep_ops;
> pcie->pci = pci;
>
> + ls_epc->linkup_notifier = false,
> + ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> +
> + pcie->ls_epc = ls_epc;
> +
> platform_set_drvdata(pdev, pcie);
>
> ret = ls_add_pcie_ep(pcie, pdev);
>
_______________________________________________
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 1/1] arm64: dts: imx8mq: Add mux controller to iomuxc_gpr
From: Philipp Zabel @ 2019-08-22 11:38 UTC (permalink / raw)
To: Guido Günther, Rob Herring, Mark Rutland, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Lucas Stach, Abel Vesa, Anson Huang, Carlo Caione,
Angus Ainslie (Purism), Andrey Smirnov, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <fa3b1df7fc5e74f375df5de53061d1a93d154b51.1566471985.git.agx@sigxcpu.org>
On Thu, 2019-08-22 at 13:10 +0200, Guido Günther wrote:
> The only mux controls the MIPI DSI input selection.
>
> Signed-off-by: Guido Günther <agx@sigxcpu.org>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
> ---
> arch/arm64/boot/dts/freescale/imx8mq.dtsi | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> index 4fdd60f2c51e..3f3594d9485c 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> @@ -440,8 +440,15 @@
> };
>
> iomuxc_gpr: syscon@30340000 {
> - compatible = "fsl,imx8mq-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr", "syscon";
> + compatible = "fsl,imx8mq-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr",
> + "syscon", "simple-mfd";
> reg = <0x30340000 0x10000>;
> +
> + mux: mux-controller {
> + compatible = "mmio-mux";
> + #mux-control-cells = <1>;
> + mux-reg-masks = <0x34 0x00000004>; /* MIPI_MUX_SEL */
> + };
> };
>
> ocotp: ocotp-ctrl@30350000 {
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 09/10] arm64: dts: layerscape: Add PCIe EP node for ls1088a
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
Add PCIe EP node for ls1088a to support EP mode.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- Remove the pf-offset proparty.
arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 31 ++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index dfbead4..79109ad 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -471,6 +471,17 @@
status = "disabled";
};
+ pcie_ep@3400000 {
+ compatible = "fsl,ls1088a-pcie-ep","fsl,ls-pcie-ep";
+ reg = <0x00 0x03400000 0x0 0x00100000
+ 0x20 0x00000000 0x8 0x00000000>;
+ reg-names = "regs", "addr_space";
+ num-ib-windows = <24>;
+ num-ob-windows = <128>;
+ max-functions = /bits/ 8 <2>;
+ status = "disabled";
+ };
+
pcie@3500000 {
compatible = "fsl,ls1088a-pcie";
reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */
@@ -497,6 +508,16 @@
status = "disabled";
};
+ pcie_ep@3500000 {
+ compatible = "fsl,ls1088a-pcie-ep","fsl,ls-pcie-ep";
+ reg = <0x00 0x03500000 0x0 0x00100000
+ 0x28 0x00000000 0x8 0x00000000>;
+ reg-names = "regs", "addr_space";
+ num-ib-windows = <6>;
+ num-ob-windows = <8>;
+ status = "disabled";
+ };
+
pcie@3600000 {
compatible = "fsl,ls1088a-pcie";
reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */
@@ -523,6 +544,16 @@
status = "disabled";
};
+ pcie_ep@3600000 {
+ compatible = "fsl,ls1088a-pcie-ep","fsl,ls-pcie-ep";
+ reg = <0x00 0x03600000 0x0 0x00100000
+ 0x30 0x00000000 0x8 0x00000000>;
+ reg-names = "regs", "addr_space";
+ num-ib-windows = <6>;
+ num-ob-windows = <8>;
+ status = "disabled";
+ };
+
smmu: iommu@5000000 {
compatible = "arm,mmu-500";
reg = <0 0x5000000 0 0x800000>;
--
2.9.5
_______________________________________________
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 10/10] misc: pci_endpoint_test: Add LS1088a in pci_device_id table
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
Add LS1088a in pci_device_id table so that pci-epf-test can be used
for testing PCIe EP in LS1088a.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- No change.
drivers/misc/pci_endpoint_test.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 6e208a0..d531951 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -793,6 +793,7 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x80c0) },
{ PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
.driver_data = (kernel_ulong_t)&am654_data
--
2.9.5
_______________________________________________
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 08/10] PCI: layerscape: Add EP mode support for ls1088a and ls2088a
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
Add PCIe EP mode support for ls1088a and ls2088a, there are some
difference between LS1 and LS2 platform, so refactor the code of
the EP driver.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- New mechanism for layerscape EP driver.
drivers/pci/controller/dwc/pci-layerscape-ep.c | 76 ++++++++++++++++++++------
1 file changed, 58 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 7ca5fe8..2a66f07 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -20,27 +20,29 @@
#define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/
-struct ls_pcie_ep {
- struct dw_pcie *pci;
- struct pci_epc_features *ls_epc;
+#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
+
+struct ls_pcie_ep_drvdata {
+ u32 func_offset;
+ const struct dw_pcie_ep_ops *ops;
+ const struct dw_pcie_ops *dw_pcie_ops;
};
-#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
+struct ls_pcie_ep {
+ struct dw_pcie *pci;
+ struct pci_epc_features *ls_epc;
+ const struct ls_pcie_ep_drvdata *drvdata;
+};
static int ls_pcie_establish_link(struct dw_pcie *pci)
{
return 0;
}
-static const struct dw_pcie_ops ls_pcie_ep_ops = {
+static const struct dw_pcie_ops dw_ls_pcie_ep_ops = {
.start_link = ls_pcie_establish_link,
};
-static const struct of_device_id ls_pcie_ep_of_match[] = {
- { .compatible = "fsl,ls-pcie-ep",},
- { },
-};
-
static const struct pci_epc_features*
ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
@@ -82,10 +84,44 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
}
}
-static const struct dw_pcie_ep_ops pcie_ep_ops = {
+static unsigned int ls_pcie_ep_func_conf_select(struct dw_pcie_ep *ep,
+ u8 func_no)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
+ u8 header_type;
+
+ header_type = ioread8(pci->dbi_base + PCI_HEADER_TYPE);
+
+ if (header_type & (1 << 7))
+ return pcie->drvdata->func_offset * func_no;
+ else
+ return 0;
+}
+
+static const struct dw_pcie_ep_ops ls_pcie_ep_ops = {
.ep_init = ls_pcie_ep_init,
.raise_irq = ls_pcie_ep_raise_irq,
.get_features = ls_pcie_ep_get_features,
+ .func_conf_select = ls_pcie_ep_func_conf_select,
+};
+
+static const struct ls_pcie_ep_drvdata ls1_ep_drvdata = {
+ .ops = &ls_pcie_ep_ops,
+ .dw_pcie_ops = &dw_ls_pcie_ep_ops,
+};
+
+static const struct ls_pcie_ep_drvdata ls2_ep_drvdata = {
+ .func_offset = 0x20000,
+ .ops = &ls_pcie_ep_ops,
+ .dw_pcie_ops = &dw_ls_pcie_ep_ops,
+};
+
+static const struct of_device_id ls_pcie_ep_of_match[] = {
+ { .compatible = "fsl,ls1046a-pcie-ep", .data = &ls1_ep_drvdata },
+ { .compatible = "fsl,ls1088a-pcie-ep", .data = &ls2_ep_drvdata },
+ { .compatible = "fsl,ls2088a-pcie-ep", .data = &ls2_ep_drvdata },
+ { },
};
static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
@@ -98,7 +134,7 @@ static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
int ret;
ep = &pci->ep;
- ep->ops = &pcie_ep_ops;
+ ep->ops = pcie->drvdata->ops;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
if (!res)
@@ -137,14 +173,11 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
if (!ls_epc)
return -ENOMEM;
- dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
- pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
+ pcie->drvdata = of_device_get_match_data(dev);
- pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
pci->dev = dev;
- pci->ops = &ls_pcie_ep_ops;
+ pci->ops = pcie->drvdata->dw_pcie_ops;
+
pcie->pci = pci;
ls_epc->linkup_notifier = false,
@@ -152,6 +185,13 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pcie->ls_epc = ls_epc;
+ dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+ pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
+ if (IS_ERR(pci->dbi_base))
+ return PTR_ERR(pci->dbi_base);
+
+ pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
+
platform_set_drvdata(pdev, pcie);
ret = ls_add_pcie_ep(pcie, pdev);
--
2.9.5
_______________________________________________
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 07/10] PCI: layerscape: Modify the MSIX to the doorbell way
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
The layerscape platform use the doorbell way to trigger MSIX
interrupt in EP mode.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- No change.
drivers/pci/controller/dwc/pci-layerscape-ep.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 8461f62..7ca5fe8 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -74,7 +74,8 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
case PCI_EPC_IRQ_MSI:
return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
case PCI_EPC_IRQ_MSIX:
- return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num);
+ return dw_pcie_ep_raise_msix_irq_doorbell(ep, func_no,
+ interrupt_num);
default:
dev_err(pci->dev, "UNKNOWN IRQ type\n");
return -EINVAL;
--
2.9.5
_______________________________________________
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 06/10] PCI: layerscape: Modify the way of getting capability with different PEX
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
The different PCIe controller in one board may be have different
capability of MSI or MSIX, so change the way of getting the MSI
capability, make it more flexible.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- Remove the repeated assignment code.
drivers/pci/controller/dwc/pci-layerscape-ep.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 4e92a95..8461f62 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -22,6 +22,7 @@
struct ls_pcie_ep {
struct dw_pcie *pci;
+ struct pci_epc_features *ls_epc;
};
#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
@@ -40,25 +41,26 @@ static const struct of_device_id ls_pcie_ep_of_match[] = {
{ },
};
-static const struct pci_epc_features ls_pcie_epc_features = {
- .linkup_notifier = false,
- .msi_capable = true,
- .msix_capable = false,
-};
-
static const struct pci_epc_features*
ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
- return &ls_pcie_epc_features;
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
+
+ return pcie->ls_epc;
}
static void ls_pcie_ep_init(struct dw_pcie_ep *ep)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
enum pci_barno bar;
for (bar = BAR_0; bar <= BAR_5; bar++)
dw_pcie_ep_reset_bar(pci, bar);
+
+ pcie->ls_epc->msi_capable = ep->msi_cap ? true : false;
+ pcie->ls_epc->msix_capable = ep->msix_cap ? true : false;
}
static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -118,6 +120,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
struct ls_pcie_ep *pcie;
+ struct pci_epc_features *ls_epc;
struct resource *dbi_base;
int ret;
@@ -129,6 +132,10 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
if (!pci)
return -ENOMEM;
+ ls_epc = devm_kzalloc(dev, sizeof(*ls_epc), GFP_KERNEL);
+ if (!ls_epc)
+ return -ENOMEM;
+
dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
if (IS_ERR(pci->dbi_base))
@@ -139,6 +146,11 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ops = &ls_pcie_ep_ops;
pcie->pci = pci;
+ ls_epc->linkup_notifier = false,
+ ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
+
+ pcie->ls_epc = ls_epc;
+
platform_set_drvdata(pdev, pcie);
ret = ls_add_pcie_ep(pcie, pdev);
--
2.9.5
_______________________________________________
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 05/10] PCI: layerscape: Fix some format issue of the code
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
Fix some format issue of the code in EP driver.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- No change.
drivers/pci/controller/dwc/pci-layerscape-ep.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index be61d96..4e92a95 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -62,7 +62,7 @@ static void ls_pcie_ep_init(struct dw_pcie_ep *ep)
}
static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
- enum pci_epc_irq_type type, u16 interrupt_num)
+ enum pci_epc_irq_type type, u16 interrupt_num)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -86,7 +86,7 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {
};
static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
- struct platform_device *pdev)
+ struct platform_device *pdev)
{
struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
--
2.9.5
_______________________________________________
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 04/10] dt-bindings: pci: layerscape-pci: add compatible strings for ls1088a and ls2088a
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
Add compatible strings for ls1088a and ls2088a.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- No change.
Documentation/devicetree/bindings/pci/layerscape-pci.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt
index e20ceaa..16f592e 100644
--- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt
+++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt
@@ -22,7 +22,10 @@ Required properties:
"fsl,ls1043a-pcie"
"fsl,ls1012a-pcie"
EP mode:
- "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep"
+ "fsl,ls-pcie-ep"
+ "fsl,ls1046a-pcie-ep"
+ "fsl,ls1088a-pcie-ep"
+ "fsl,ls2088a-pcie-ep"
- reg: base addresses and lengths of the PCIe controller register blocks.
- interrupts: A list of interrupt outputs of the controller. Must contain an
entry for each entry in the interrupt-names property.
--
2.9.5
_______________________________________________
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 03/10] PCI: designware-ep: Move the function of getting MSI capability forward
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
Move the function of getting MSI capability to the front of init
function, because the init function of the EP platform driver will use
the return value by the function of getting MSI capability.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- No change.
drivers/pci/controller/dwc/pcie-designware-ep.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index b8388f8..0a6c199 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -656,6 +656,10 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
if (ret < 0)
epc->max_functions = 1;
+ ep->msi_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSI);
+
+ ep->msix_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSIX);
+
if (ep->ops->ep_init)
ep->ops->ep_init(ep);
@@ -672,9 +676,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
return -ENOMEM;
}
- ep->msi_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSI);
-
- ep->msix_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSIX);
offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
if (offset) {
--
2.9.5
_______________________________________________
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 01/10] PCI: designware-ep: Add multiple PFs support for DWC
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
Add multiple PFs support for DWC, different PF have different config space
we use pf-offset property which get from the DTS to access the different pF
config space.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- Remove duplicate redundant code.
- Reimplement the PF config space access way.
drivers/pci/controller/dwc/pcie-designware-ep.c | 122 ++++++++++++++++--------
drivers/pci/controller/dwc/pcie-designware.c | 59 ++++++++----
drivers/pci/controller/dwc/pcie-designware.h | 11 ++-
3 files changed, 134 insertions(+), 58 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 2bf5a35..3e2b740 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -19,12 +19,17 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
pci_epc_linkup(epc);
}
-static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar,
- int flags)
+static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
+ enum pci_barno bar, int flags)
{
u32 reg;
+ unsigned int func_offset = 0;
+ struct dw_pcie_ep *ep = &pci->ep;
- reg = PCI_BASE_ADDRESS_0 + (4 * bar);
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
+
+ reg = func_offset + PCI_BASE_ADDRESS_0 + (4 * bar);
dw_pcie_dbi_ro_wr_en(pci);
dw_pcie_writel_dbi2(pci, reg, 0x0);
dw_pcie_writel_dbi(pci, reg, 0x0);
@@ -37,7 +42,12 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar,
void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
{
- __dw_pcie_ep_reset_bar(pci, bar, 0);
+ u8 func_no, funcs;
+
+ funcs = pci->ep.epc->max_functions;
+
+ for (func_no = 0; func_no < funcs; func_no++)
+ __dw_pcie_ep_reset_bar(pci, func_no, bar, 0);
}
static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
@@ -78,28 +88,32 @@ static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
{
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ unsigned int func_offset = 0;
+
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
dw_pcie_dbi_ro_wr_en(pci);
- dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid);
- dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid);
- dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid);
- dw_pcie_writeb_dbi(pci, PCI_CLASS_PROG, hdr->progif_code);
- dw_pcie_writew_dbi(pci, PCI_CLASS_DEVICE,
+ dw_pcie_writew_dbi(pci, func_offset + PCI_VENDOR_ID, hdr->vendorid);
+ dw_pcie_writew_dbi(pci, func_offset + PCI_DEVICE_ID, hdr->deviceid);
+ dw_pcie_writeb_dbi(pci, func_offset + PCI_REVISION_ID, hdr->revid);
+ dw_pcie_writeb_dbi(pci, func_offset + PCI_CLASS_PROG, hdr->progif_code);
+ dw_pcie_writew_dbi(pci, func_offset + PCI_CLASS_DEVICE,
hdr->subclass_code | hdr->baseclass_code << 8);
- dw_pcie_writeb_dbi(pci, PCI_CACHE_LINE_SIZE,
+ dw_pcie_writeb_dbi(pci, func_offset + PCI_CACHE_LINE_SIZE,
hdr->cache_line_size);
- dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_VENDOR_ID,
+ dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_VENDOR_ID,
hdr->subsys_vendor_id);
- dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id);
- dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN,
+ dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_ID, hdr->subsys_id);
+ dw_pcie_writeb_dbi(pci, func_offset + PCI_INTERRUPT_PIN,
hdr->interrupt_pin);
dw_pcie_dbi_ro_wr_dis(pci);
return 0;
}
-static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
- dma_addr_t cpu_addr,
+static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no,
+ enum pci_barno bar, dma_addr_t cpu_addr,
enum dw_pcie_as_type as_type)
{
int ret;
@@ -112,7 +126,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
return -EINVAL;
}
- ret = dw_pcie_prog_inbound_atu(pci, free_win, bar, cpu_addr,
+ ret = dw_pcie_prog_inbound_atu(pci, func_no, free_win, bar, cpu_addr,
as_type);
if (ret < 0) {
dev_err(pci->dev, "Failed to program IB window\n");
@@ -125,7 +139,8 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
return 0;
}
-static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
+static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
+ phys_addr_t phys_addr,
u64 pci_addr, size_t size)
{
u32 free_win;
@@ -137,8 +152,8 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
return -EINVAL;
}
- dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
- phys_addr, pci_addr, size);
+ dw_pcie_prog_ep_outbound_atu(pci, func_no, free_win, PCIE_ATU_TYPE_MEM,
+ phys_addr, pci_addr, size);
set_bit(free_win, ep->ob_window_map);
ep->outbound_addr[free_win] = phys_addr;
@@ -154,7 +169,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
enum pci_barno bar = epf_bar->barno;
u32 atu_index = ep->bar_to_atu[bar];
- __dw_pcie_ep_reset_bar(pci, bar, epf_bar->flags);
+ __dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags);
dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
clear_bit(atu_index, ep->ib_window_map);
@@ -170,14 +185,21 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
size_t size = epf_bar->size;
int flags = epf_bar->flags;
enum dw_pcie_as_type as_type;
- u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
+ u32 reg;
+ unsigned int func_offset = 0;
+
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
+
+ reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func_offset;
if (!(flags & PCI_BASE_ADDRESS_SPACE))
as_type = DW_PCIE_AS_MEM;
else
as_type = DW_PCIE_AS_IO;
- ret = dw_pcie_ep_inbound_atu(ep, bar, epf_bar->phys_addr, as_type);
+ ret = dw_pcie_ep_inbound_atu(ep, func_no, bar,
+ epf_bar->phys_addr, as_type);
if (ret)
return ret;
@@ -235,7 +257,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- ret = dw_pcie_ep_outbound_atu(ep, addr, pci_addr, size);
+ ret = dw_pcie_ep_outbound_atu(ep, func_no, addr, pci_addr, size);
if (ret) {
dev_err(pci->dev, "Failed to enable address\n");
return ret;
@@ -249,11 +271,15 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
u32 val, reg;
+ unsigned int func_offset = 0;
+
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
if (!ep->msi_cap)
return -EINVAL;
- reg = ep->msi_cap + PCI_MSI_FLAGS;
+ reg = ep->msi_cap + func_offset + PCI_MSI_FLAGS;
val = dw_pcie_readw_dbi(pci, reg);
if (!(val & PCI_MSI_FLAGS_ENABLE))
return -EINVAL;
@@ -268,11 +294,15 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
u32 val, reg;
+ unsigned int func_offset = 0;
+
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
if (!ep->msi_cap)
return -EINVAL;
- reg = ep->msi_cap + PCI_MSI_FLAGS;
+ reg = ep->msi_cap + func_offset + PCI_MSI_FLAGS;
val = dw_pcie_readw_dbi(pci, reg);
val &= ~PCI_MSI_FLAGS_QMASK;
val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
@@ -288,11 +318,15 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
u32 val, reg;
+ unsigned int func_offset = 0;
+
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
if (!ep->msix_cap)
return -EINVAL;
- reg = ep->msix_cap + PCI_MSIX_FLAGS;
+ reg = ep->msix_cap + func_offset + PCI_MSIX_FLAGS;
val = dw_pcie_readw_dbi(pci, reg);
if (!(val & PCI_MSIX_FLAGS_ENABLE))
return -EINVAL;
@@ -307,11 +341,15 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
u32 val, reg;
+ unsigned int func_offset = 0;
+
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
if (!ep->msix_cap)
return -EINVAL;
- reg = ep->msix_cap + PCI_MSIX_FLAGS;
+ reg = ep->msix_cap + func_offset + PCI_MSIX_FLAGS;
val = dw_pcie_readw_dbi(pci, reg);
val &= ~PCI_MSIX_FLAGS_QSIZE;
val |= interrupts;
@@ -398,29 +436,33 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct pci_epc *epc = ep->epc;
unsigned int aligned_offset;
+ unsigned int func_offset = 0;
u16 msg_ctrl, msg_data;
u32 msg_addr_lower, msg_addr_upper, reg;
u64 msg_addr;
bool has_upper;
int ret;
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
+
if (!ep->msi_cap)
return -EINVAL;
/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
- reg = ep->msi_cap + PCI_MSI_FLAGS;
+ reg = ep->msi_cap + func_offset + PCI_MSI_FLAGS;
msg_ctrl = dw_pcie_readw_dbi(pci, reg);
has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
- reg = ep->msi_cap + PCI_MSI_ADDRESS_LO;
+ reg = ep->msi_cap + func_offset + PCI_MSI_ADDRESS_LO;
msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
if (has_upper) {
- reg = ep->msi_cap + PCI_MSI_ADDRESS_HI;
+ reg = ep->msi_cap + func_offset + PCI_MSI_ADDRESS_HI;
msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
- reg = ep->msi_cap + PCI_MSI_DATA_64;
+ reg = ep->msi_cap + func_offset + PCI_MSI_DATA_64;
msg_data = dw_pcie_readw_dbi(pci, reg);
} else {
msg_addr_upper = 0;
- reg = ep->msi_cap + PCI_MSI_DATA_32;
+ reg = ep->msi_cap + func_offset + PCI_MSI_DATA_32;
msg_data = dw_pcie_readw_dbi(pci, reg);
}
aligned_offset = msg_addr_lower & (epc->mem->page_size - 1);
@@ -439,11 +481,12 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
}
int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
- u16 interrupt_num)
+ u16 interrupt_num)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct pci_epc *epc = ep->epc;
u16 tbl_offset, bir;
+ unsigned int func_offset = 0;
u32 bar_addr_upper, bar_addr_lower;
u32 msg_addr_upper, msg_addr_lower;
u32 reg, msg_data, vec_ctrl;
@@ -451,12 +494,15 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
void __iomem *msix_tbl;
int ret;
- reg = ep->msix_cap + PCI_MSIX_TABLE;
+ if (ep->ops->func_conf_select)
+ func_offset = ep->ops->func_conf_select(ep, func_no);
+
+ reg = ep->msix_cap + func_offset + PCI_MSIX_TABLE;
tbl_offset = dw_pcie_readl_dbi(pci, reg);
bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
tbl_offset &= PCI_MSIX_TABLE_OFFSET;
- reg = PCI_BASE_ADDRESS_0 + (4 * bir);
+ reg = PCI_BASE_ADDRESS_0 + func_offset + (4 * bir);
bar_addr_upper = 0;
bar_addr_lower = dw_pcie_readl_dbi(pci, reg);
reg_u64 = (bar_addr_lower & PCI_BASE_ADDRESS_MEM_TYPE_MASK);
@@ -592,13 +638,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
ep->epc = epc;
epc_set_drvdata(epc, ep);
- if (ep->ops->ep_init)
- ep->ops->ep_init(ep);
-
ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
if (ret < 0)
epc->max_functions = 1;
+ if (ep->ops->ep_init)
+ ep->ops->ep_init(ep);
+
ret = __pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
ep->page_size);
if (ret < 0) {
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 7d25102..305e73d 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -158,9 +158,10 @@ static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg,
dw_pcie_writel_atu(pci, offset + reg, val);
}
-static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
- int type, u64 cpu_addr,
- u64 pci_addr, u32 size)
+static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,
+ int index, int type,
+ u64 cpu_addr, u64 pci_addr,
+ u32 size)
{
u32 retries, val;
@@ -175,7 +176,7 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
upper_32_bits(pci_addr));
dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
- type);
+ type | PCIE_ATU_FUNC_NUM(func_no));
dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
PCIE_ATU_ENABLE);
@@ -194,8 +195,9 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
dev_err(pci->dev, "Outbound iATU is not being enabled\n");
}
-void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
- u64 cpu_addr, u64 pci_addr, u32 size)
+static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
+ int index, int type, u64 cpu_addr,
+ u64 pci_addr, u32 size)
{
u32 retries, val;
@@ -203,8 +205,8 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
if (pci->iatu_unroll_enabled) {
- dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
- pci_addr, size);
+ dw_pcie_prog_outbound_atu_unroll(pci, func_no, index, type,
+ cpu_addr, pci_addr, size);
return;
}
@@ -220,7 +222,8 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
lower_32_bits(pci_addr));
dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
upper_32_bits(pci_addr));
- dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type |
+ PCIE_ATU_FUNC_NUM(func_no));
dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
/*
@@ -237,6 +240,21 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
dev_err(pci->dev, "Outbound iATU is not being enabled\n");
}
+void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
+ u64 cpu_addr, u64 pci_addr, u32 size)
+{
+ __dw_pcie_prog_outbound_atu(pci, 0, index, type,
+ cpu_addr, pci_addr, size);
+}
+
+void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ int type, u64 cpu_addr, u64 pci_addr,
+ u32 size)
+{
+ __dw_pcie_prog_outbound_atu(pci, func_no, index, type,
+ cpu_addr, pci_addr, size);
+}
+
static u32 dw_pcie_readl_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg)
{
u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index);
@@ -252,8 +270,8 @@ static void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg,
dw_pcie_writel_atu(pci, offset + reg, val);
}
-static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
- int bar, u64 cpu_addr,
+static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, u8 func_no,
+ int index, int bar, u64 cpu_addr,
enum dw_pcie_as_type as_type)
{
int type;
@@ -275,8 +293,10 @@ static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
return -EINVAL;
}
- dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, type);
+ dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, type |
+ PCIE_ATU_FUNC_NUM(func_no));
dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
+ PCIE_ATU_FUNC_NUM_MATCH_EN |
PCIE_ATU_ENABLE |
PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
@@ -297,14 +317,15 @@ static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
return -EBUSY;
}
-int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
- u64 cpu_addr, enum dw_pcie_as_type as_type)
+int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ int bar, u64 cpu_addr,
+ enum dw_pcie_as_type as_type)
{
int type;
u32 retries, val;
if (pci->iatu_unroll_enabled)
- return dw_pcie_prog_inbound_atu_unroll(pci, index, bar,
+ return dw_pcie_prog_inbound_atu_unroll(pci, func_no, index, bar,
cpu_addr, as_type);
dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_INBOUND |
@@ -323,9 +344,11 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
return -EINVAL;
}
- dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
- dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE
- | PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type |
+ PCIE_ATU_FUNC_NUM(func_no));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE |
+ PCIE_ATU_FUNC_NUM_MATCH_EN |
+ PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
/*
* Make sure ATU enable takes effect before any subsequent config
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index ffed084..a0fdbf7 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -71,9 +71,11 @@
#define PCIE_ATU_TYPE_IO 0x2
#define PCIE_ATU_TYPE_CFG0 0x4
#define PCIE_ATU_TYPE_CFG1 0x5
+#define PCIE_ATU_FUNC_NUM(pf) (pf << 20)
#define PCIE_ATU_CR2 0x908
#define PCIE_ATU_ENABLE BIT(31)
#define PCIE_ATU_BAR_MODE_ENABLE BIT(30)
+#define PCIE_ATU_FUNC_NUM_MATCH_EN BIT(19)
#define PCIE_ATU_LOWER_BASE 0x90C
#define PCIE_ATU_UPPER_BASE 0x910
#define PCIE_ATU_LIMIT 0x914
@@ -197,6 +199,7 @@ struct dw_pcie_ep_ops {
int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
enum pci_epc_irq_type type, u16 interrupt_num);
const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep);
+ unsigned int (*func_conf_select)(struct dw_pcie_ep *ep, u8 func_no);
};
struct dw_pcie_ep {
@@ -265,8 +268,12 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci);
void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
int type, u64 cpu_addr, u64 pci_addr,
u32 size);
-int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
- u64 cpu_addr, enum dw_pcie_as_type as_type);
+void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ int type, u64 cpu_addr, u64 pci_addr,
+ u32 size);
+int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ int bar, u64 cpu_addr,
+ enum dw_pcie_as_type as_type);
void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
enum dw_pcie_region_type type);
void dw_pcie_setup(struct dw_pcie *pci);
--
2.9.5
_______________________________________________
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 02/10] PCI: designware-ep: Add the doorbell mode of MSI-X in EP mode
From: Xiaowei Bao @ 2019-08-22 11:22 UTC (permalink / raw)
To: bhelgaas, robh+dt, mark.rutland, shawnguo, leoyang.li, kishon,
lorenzo.pieralisi, arnd, gregkh, minghuan.Lian, mingkai.hu,
roy.zang, jingoohan1, gustavo.pimentel, linux-pci, devicetree,
linux-kernel, linux-arm-kernel, linuxppc-dev, andrew.murray
Cc: Xiaowei Bao
In-Reply-To: <20190822112242.16309-1-xiaowei.bao@nxp.com>
Add the doorbell mode of MSI-X in EP mode.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- Remove the macro of no used.
drivers/pci/controller/dwc/pcie-designware-ep.c | 14 ++++++++++++++
drivers/pci/controller/dwc/pcie-designware.h | 12 ++++++++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 3e2b740..b8388f8 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -480,6 +480,20 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
return 0;
}
+int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
+ u16 interrupt_num)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ u32 msg_data;
+
+ msg_data = (func_no << PCIE_MSIX_DOORBELL_PF_SHIFT) |
+ (interrupt_num - 1);
+
+ dw_pcie_writel_dbi(pci, PCIE_MSIX_DOORBELL, msg_data);
+
+ return 0;
+}
+
int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
u16 interrupt_num)
{
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index a0fdbf7..895a9ef 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -88,6 +88,9 @@
#define PCIE_MISC_CONTROL_1_OFF 0x8BC
#define PCIE_DBI_RO_WR_EN BIT(0)
+#define PCIE_MSIX_DOORBELL 0x948
+#define PCIE_MSIX_DOORBELL_PF_SHIFT 24
+
/*
* iATU Unroll-specific register definitions
* From 4.80 core version the address translation will be made by unroll
@@ -400,6 +403,8 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
u8 interrupt_num);
int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
u16 interrupt_num);
+int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
+ u16 interrupt_num);
void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar);
#else
static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
@@ -432,6 +437,13 @@ static inline int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
return 0;
}
+static inline int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep,
+ u8 func_no,
+ u16 interrupt_num)
+{
+ return 0;
+}
+
static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
{
}
--
2.9.5
_______________________________________________
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: [PATCH v10 09/23] iommu/io-pgtable-arm-v7s: Extend to support PA[33:32] for MediaTek
From: Will Deacon @ 2019-08-22 11:28 UTC (permalink / raw)
To: Robin Murphy
Cc: youlin.pei, devicetree, Nicolas Boichat, cui.zhang,
srv_heupstream, Tomasz Figa, Joerg Roedel, linux-kernel,
Evan Green, chao.hao, iommu, Rob Herring, linux-mediatek,
linux-arm-kernel, Matthias Brugger, ming-fan.chen, anan.sun,
Matthias Kaehlcke, Yong Wu
In-Reply-To: <e6652176-763d-5298-9e10-8c1fbe1b3c0d@arm.com>
On Thu, Aug 22, 2019 at 11:57:11AM +0100, Robin Murphy wrote:
> On 2019-08-22 11:17 am, Will Deacon wrote:
> > On Thu, Aug 22, 2019 at 11:08:58AM +0100, Robin Murphy wrote:
> > > On 2019-08-22 9:56 am, Yong Wu wrote:
> > > > On Wed, 2019-08-21 at 16:24 +0100, Will Deacon wrote:
> > > > > On Wed, Aug 21, 2019 at 09:53:12PM +0800, Yong Wu wrote:
> > > > > > MediaTek extend the arm v7s descriptor to support up to 34 bits PA where
> > > > > > the bit32 and bit33 are encoded in the bit9 and bit4 of the PTE
> > > > > > respectively. Meanwhile the iova still is 32bits.
> > > > > >
> > > > > > Regarding whether the pagetable address could be over 4GB, the mt8183
> > > > > > support it while the previous mt8173 don't, thus keep it as is.
> > > > > >
> > > > > > Signed-off-by: Yong Wu <yong.wu@mediatek.com>
> > > > > > ---
> > > > > > drivers/iommu/io-pgtable-arm-v7s.c | 32 +++++++++++++++++++++++++-------
> > > > > > include/linux/io-pgtable.h | 7 +++----
> > > > > > 2 files changed, 28 insertions(+), 11 deletions(-)
> > > > >
> > > > > [...]
> > > > >
> > > > > > @@ -731,7 +747,9 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
> > > > > > {
> > > > > > struct arm_v7s_io_pgtable *data;
> > > > > > - if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS)
> > > > > > + if (cfg->ias > ARM_V7S_ADDR_BITS ||
> > > > > > + (cfg->oas > ARM_V7S_ADDR_BITS &&
> > > > > > + !(cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)))
> > > > >
> > > > > Please can you instead change arm_v7s_alloc_pgtable() so that it allows an
> > > > > ias of up to 34 when the IO_PGTABLE_QUIRK_ARM_MTK_EXT is set?
> > > >
> > > > Here I only simply skip the oas checking for our case. then which way do
> > > > your prefer? something like you commented before:?
> > > >
> > > >
> > > > if (cfg->ias > ARM_V7S_ADDR_BITS)
> > > > return NULL;
> > > >
> > > > if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT) {
> > > > if (!IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
> > > > cfg->oas = min(cfg->oas, ARM_V7S_ADDR_BITS);
> > > > else if (cfg->oas > 34)
> > > > return NULL;
> > > > } else if (cfg->oas > ARM_V7S_ADDR_BITS) {
> > > > return NULL;
> > > > }
> > >
> > > All it should take is something like:
> > >
> > > if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)
> > > max_oas = 34;
> > > else
> > > max_oas = 32;
> > > if (cfg->oas > max_oas)
> > > return NULL;
> > >
> > > or even just:
> > >
> > > if (cfg->oas > 32 ||
> > > (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT && cfg->oas > 34))
> > > return NULL;
> > >
> > > (and if we prefer the latter style, perhaps we could introduce some kind of
> > > "is_mtk_4gb()" helper to save on verbosity)
> >
> > I wondered the same thing, but another place we'd want the check is in
> > iopte_to_paddr() which probably needs the PHYS_ADDR_T check to avoid GCC
> > warnings, although I didn't try it.
>
> I'm pretty sure I confirmed that "paddr |= BIT_ULL(32)" doesn't warn when
> phys_addt_t is 32-bit - it's well-defined unsigned integer truncation after
> all, and if GCC starts warning about all the valid no-op code it optimises
> away then it's going to run up against IS_ENABLED() first and foremost ;)
You're quite right, although we live in a world where GCC shouts at us about
missing comments in switch statements so I think my worry was justified!
> > So if we did:
> >
> > static bool cfg_mtk_ext_enabled(struct io_pgtable_cfg *cfg)
> > {
> > return IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) &&
> > cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT;
> > }
> >
> > Then I suppose we could do this in _alloc():
> >
> > if (cfg->oas > cfg_mtk_ext_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS)
> > return NULL;
^^ Apparantly, I left the bracketting here as an exercise to the reader.
> >
> > and then this in iopte_to_paddr():
> >
> > [...]
> >
> > paddr = pte & mask;
> > if (!cfg_mtk_ext_enabled(cfg))
> > return paddr;
> >
> > if (pte & ARM_V7S_ATTR_MTK_PA_BIT32)
> > paddr |= ...
> >
> > [...]
> >
> > What do you reckon?
>
> Yeah, that's the general shape of things I was picturing - I'm not that
> fussed about the PHYS_ADDR_T_64BIT thing, especially if it's wrapped up in
> just one place, so if you do want to keep it as belt-and-braces I'll just
> consider it a slight code size optimisation for 32-bit builds.
Ok, great. Yong Wu -- are you ok respinning with the above + missing
brackets?
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v5] arm64: implement KPROBES_ON_FTRACE
From: Jisheng Zhang @ 2019-08-22 11:25 UTC (permalink / raw)
To: Catalin Marinas, Jonathan Corbet, Masami Hiramatsu, Naveen N. Rao
Cc: Mark Rutland, linux-doc@vger.kernel.org, Peter Zijlstra,
linux-kernel@vger.kernel.org, Steven Rostedt, Thomas Gleixner,
linux-arm-kernel@lists.infradead.org
KPROBES_ON_FTRACE avoids much of the overhead with regular kprobes as it
eliminates the need for a trap, as well as the need to emulate or
single-step instructions.
Tested on berlin arm64 platform.
~ # mount -t debugfs debugfs /sys/kernel/debug/
~ # cd /sys/kernel/debug/
/sys/kernel/debug # echo 'p _do_fork' > tracing/kprobe_events
before the patch:
/sys/kernel/debug # cat kprobes/list
ffffff801009fe28 k _do_fork+0x0 [DISABLED]
after the patch:
/sys/kernel/debug # cat kprobes/list
ffffff801009ff54 k _do_fork+0x4 [DISABLED][FTRACE]
Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
KPROBES_ON_FTRACE avoids much of the overhead with regular kprobes as it
eliminates the need for a trap, as well as the need to emulate or
single-step instructions.
Applied after arm64 FTRACE_WITH_REGS:
http://lists.infradead.org/pipermail/linux-arm-kernel/2019-August/674404.html
Changes since v4:
- correct reg->pc: probed on foo, then pre_handler see foo+0x4, while
post_handler see foo+0x8
Changes since v3:
- move kprobe_lookup_name() and arch_kprobe_on_func_entry to ftrace.c since
we only want to choose the ftrace entry for KPROBES_ON_FTRACE.
- only choose ftrace entry if (addr && !offset)
Changes since v2:
- remove patch1, make it a single cleanup patch
- remove "This patch" in the change log
- implement arm64's kprobe_lookup_name() and arch_kprobe_on_func_entry instead
of patching the common kprobes code
Changes since v1:
- make the kprobes/x86: use instruction_pointer and instruction_pointer_set
as patch1
- add Masami's ACK to patch1
- add some description about KPROBES_ON_FTRACE and why we need it on
arm64
- correct the log before the patch
- remove the consolidation patch, make it as TODO
- only adjust kprobe's addr when KPROBE_FLAG_FTRACE is set
- if KPROBES_ON_FTRACE, ftrace_call_adjust() the kprobe's addr before
calling ftrace_location()
- update the kprobes-on-ftrace/arch-support.txt in doc
.../debug/kprobes-on-ftrace/arch-support.txt | 2 +-
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/probes/Makefile | 1 +
arch/arm64/kernel/probes/ftrace.c | 83 +++++++++++++++++++
4 files changed, 86 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/kernel/probes/ftrace.c
diff --git a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
index 68f266944d5f..e8358a38981c 100644
--- a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
+++ b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
@@ -9,7 +9,7 @@
| alpha: | TODO |
| arc: | TODO |
| arm: | TODO |
- | arm64: | TODO |
+ | arm64: | ok |
| c6x: | TODO |
| csky: | TODO |
| h8300: | TODO |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 663392d1eae2..928700f15e23 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -167,6 +167,7 @@ config ARM64
select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KPROBES
+ select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES
select HAVE_GENERIC_VDSO
select IOMMU_DMA if IOMMU_SUPPORT
diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
index 8e4be92e25b1..4020cfc66564 100644
--- a/arch/arm64/kernel/probes/Makefile
+++ b/arch/arm64/kernel/probes/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o \
simulate-insn.o
obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o \
simulate-insn.o
+obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
diff --git a/arch/arm64/kernel/probes/ftrace.c b/arch/arm64/kernel/probes/ftrace.c
new file mode 100644
index 000000000000..9f80905f02fa
--- /dev/null
+++ b/arch/arm64/kernel/probes/ftrace.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Dynamic Ftrace based Kprobes Optimization
+ *
+ * Copyright (C) Hitachi Ltd., 2012
+ * Copyright (C) 2019 Jisheng Zhang <jszhang@kernel.org>
+ * Synaptics Incorporated
+ */
+
+#include <linux/kprobes.h>
+
+/* Ftrace callback handler for kprobes -- called under preepmt disabed */
+void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+ struct ftrace_ops *ops, struct pt_regs *regs)
+{
+ struct kprobe *p;
+ struct kprobe_ctlblk *kcb;
+
+ /* Preempt is disabled by ftrace */
+ p = get_kprobe((kprobe_opcode_t *)ip);
+ if (unlikely(!p) || kprobe_disabled(p))
+ return;
+
+ kcb = get_kprobe_ctlblk();
+ if (kprobe_running()) {
+ kprobes_inc_nmissed_count(p);
+ } else {
+ unsigned long orig_ip = instruction_pointer(regs);
+
+ instruction_pointer_set(regs, ip);
+ __this_cpu_write(current_kprobe, p);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ if (!p->pre_handler || !p->pre_handler(p, regs)) {
+ /*
+ * Emulate singlestep (and also recover regs->pc)
+ * as if there is a nop
+ */
+ instruction_pointer_set(regs,
+ (unsigned long)p->addr + MCOUNT_INSN_SIZE);
+ if (unlikely(p->post_handler)) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ p->post_handler(p, regs, 0);
+ }
+ instruction_pointer_set(regs, orig_ip);
+ }
+ /*
+ * If pre_handler returns !0, it changes regs->pc. We have to
+ * skip emulating post_handler.
+ */
+ __this_cpu_write(current_kprobe, NULL);
+ }
+}
+NOKPROBE_SYMBOL(kprobe_ftrace_handler);
+
+kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
+{
+ unsigned long addr = kallsyms_lookup_name(name);
+
+ if (addr && !offset) {
+ unsigned long faddr;
+ /*
+ * with -fpatchable-function-entry=2, the first 4 bytes is the
+ * LR saver, then the actual call insn. So ftrace location is
+ * always on the first 4 bytes offset.
+ */
+ faddr = ftrace_location_range(addr,
+ addr + AARCH64_INSN_SIZE);
+ if (faddr)
+ return (kprobe_opcode_t *)faddr;
+ }
+ return (kprobe_opcode_t *)addr;
+}
+
+bool arch_kprobe_on_func_entry(unsigned long offset)
+{
+ return offset <= AARCH64_INSN_SIZE;
+}
+
+int arch_prepare_kprobe_ftrace(struct kprobe *p)
+{
+ p->ainsn.api.insn = NULL;
+ return 0;
+}
--
2.23.0.rc1
_______________________________________________
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: [PATCH v4] arm64: implement KPROBES_ON_FTRACE
From: Jisheng Zhang @ 2019-08-22 11:20 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Mark Rutland, linux-doc@vger.kernel.org, Peter Zijlstra,
Catalin Marinas, Jonathan Corbet, linux-kernel@vger.kernel.org,
Steven Rostedt, Ingo Molnar, Masami Hiramatsu, Thomas Gleixner,
Will Deacon, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190822183254.1bb5576d@xhacker.debian>
Hi,
On Thu, 22 Aug 2019 18:32:54 +0800
Jisheng Zhang <Jisheng.Zhang@synaptics.com> wrote:
> On Thu, 22 Aug 2019 15:52:05 +0530
> "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> >
> >
> > Jisheng Zhang wrote:
> > > Hi,
> > >
> > > On Thu, 22 Aug 2019 12:23:58 +0530
> > > "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> wrote:
> > >> Jisheng Zhang wrote:
> > ...
> > >> > +/* Ftrace callback handler for kprobes -- called under preepmt
> > >> > disabed */
> > >> > +void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
> > >> > + struct ftrace_ops *ops, struct pt_regs *regs)
> > >> > +{
> > >> > + struct kprobe *p;
> > >> > + struct kprobe_ctlblk *kcb;
> > >> > +
> > >> > + /* Preempt is disabled by ftrace */
> > >> > + p = get_kprobe((kprobe_opcode_t *)ip);
> > >> > + if (unlikely(!p) || kprobe_disabled(p))
> > >> > + return;
> > >> > +
> > >> > + kcb = get_kprobe_ctlblk();
> > >> > + if (kprobe_running()) {
> > >> > + kprobes_inc_nmissed_count(p);
> > >> > + } else {
> > >> > + unsigned long orig_ip = instruction_pointer(regs);
> > >> > + /* Kprobe handler expects regs->pc = pc + 4 as breakpoint hit */
> > >> > + instruction_pointer_set(regs, ip + sizeof(kprobe_opcode_t));
> > >>
> > >> Just want to make sure that you've confirmed that this is what happens
> > >> with a regular trap/brk based kprobe on ARM64. The reason for setting
> > >> the instruction pointer here is to ensure that it is set to the same
> > >> value as would be set if there was a trap/brk instruction at the ftrace
> > >> location. This ensures that the kprobe pre handler sees the same value
> > >> regardless.
> > >
> > > Due to the arm64's DYNAMIC_FTRACE_WITH_REGS implementation, the code itself
> > > is correct. But this doesn't look like "there was a trap instruction at
> > > the ftrace location".
> > >
> > > W/O KPROBE_ON_FTRACE:
> > >
> > > foo:
> > > 00 insA
> > > 04 insB
> > > 08 insC
> > >
> > > kprobe's pre_handler() will see pc points to 00.
> >
> > In this case, the probe will be placed at foo+0x00, so pre_handler()
> > seeing that address in pt_regs is correct behavior - as long as arm64
> > 'brk' instruction causes an exception with the instruction pointer set
>
> Yep, confirmed with regular trap/brk based kprobes, I do see PC set to
> the "brk" instruction.
>
> > *to* the 'brk' instruction. This is similar to how powerpc 'trap' works.
> > However, x86 'int3' causes an exception *after* execution of the
> > instruction.
>
> Got it. I understand where's the comment "expects regs->pc = pc + 1" from.
>
> >
> > >
> > > W/ KPROBE_ON_FTRACE:
> > >
> > > foo:
> > > 00 lr saver
> > > 04 nop // will be modified to ftrace call ins when KPROBE is armed
> > > 08 insA
> > > 0c insB
> >
> > In this case, if user asks for a probe to be placed at 'foo', we will
> > choose foo+0x04 and from that point on, the behavior should reflect that
> > a kprobe was placed at foo+0x04. In particular, the pre_handler() should
> > see foo+0x04 in pt_regs. The post_handler() would then see foo+0x08.
> >
> > >
> > > later, kprobe_ftrace_handler() will see pc points to 04, so pc + 4 will
> > > point to 08 the same as the one w/o KPROBE_ON_FTRACE.
> >
> > I didn't mean to compare regular trap/brk based kprobes with
> > KPROBES_ON_FTRACE. The only important aspect is that the handlers see
> > consistent pt_regs in both cases, depending on where the kprobe was
> > placed. Choosing a different address/offset to place a kprobe during its
> > registration is an orthogonal aspect.
>
> Indeed, previously, I want to let the PC point to the same instruction, it
> seems I misunderstood the "consistent" meaning.
>
> >
> > >
> > > It seems I need to fix the comment.
> >
> > Given your explanation above, I think you can simply drop the first
> > adjustment to the instruction pointer before the pre handler invocation.
Just send out v5. But the first adjustment is modified as
instruction_pointer_set(regs, ip);
Because in entry of kprobe_ftrace_handler() pc/ip(the first parameter) points
to foo+0x4, while regs->pc points to foo+0x8. Based on your previous
explanation, I think we should instruction_pointer_set(regs, ip) to let the
pre_handler see foo+0x4
Thanks a lot for your help
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox