* [PATCH 4/5] powerpc/mm: Simplify update_mmu_cache() on BOOK3S32
From: Christophe Leroy @ 2019-08-16 5:41 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <668aba4db6b9af6d8a151174e11a4289f1a6bbcd.1565933217.git.christophe.leroy@c-s.fr>
On BOOK3S32, hash_preload() neither use is_exec nor trap,
so drop those parameters and simplify update_mmu_cached().
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/mm/book3s32/mmu.c | 29 +++++++----------------------
arch/powerpc/mm/mmu_decl.h | 3 +--
arch/powerpc/mm/pgtable_32.c | 2 +-
3 files changed, 9 insertions(+), 25 deletions(-)
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 3e3c4077cdb7..3a62bf99f93f 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -297,8 +297,7 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
/*
* Preload a translation in the hash table
*/
-void hash_preload(struct mm_struct *mm, unsigned long ea,
- bool is_exec, unsigned long trap)
+void hash_preload(struct mm_struct *mm, unsigned long ea)
{
pmd_t *pmd;
@@ -324,34 +323,20 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
* We don't need to worry about _PAGE_PRESENT here because we are
* called with either mm->page_table_lock held or ptl lock held
*/
- unsigned long trap;
- bool is_exec;
/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
if (!pte_young(*ptep) || address >= TASK_SIZE)
return;
- /* We try to figure out if we are coming from an instruction
- * access fault and pass that down to __hash_page so we avoid
- * double-faulting on execution of fresh text. We have to test
- * for regs NULL since init will get here first thing at boot
- *
- * We also avoid filling the hash if not coming from a fault
- */
+ /* We have to test for regs NULL since init will get here first thing at boot */
+ if (!current->thread.regs)
+ return;
- trap = current->thread.regs ? TRAP(current->thread.regs) : 0UL;
- switch (trap) {
- case 0x300:
- is_exec = false;
- break;
- case 0x400:
- is_exec = true;
- break;
- default:
+ /* We also avoid filling the hash if not coming from a fault */
+ if (TRAP(current->thread.regs) != 0x300 && TRAP(current->thread.regs) != 0x400)
return;
- }
- hash_preload(vma->vm_mm, address, is_exec, trap);
+ hash_preload(vma->vm_mm, address);
}
/*
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 9f325a7a09cb..adbaf2167214 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -91,8 +91,7 @@ void print_system_hash_info(void);
#ifdef CONFIG_PPC32
-void hash_preload(struct mm_struct *mm, unsigned long ea,
- bool is_exec, unsigned long trap);
+void hash_preload(struct mm_struct *mm, unsigned long ea);
extern void mapin_ram(void);
extern void setbat(int index, unsigned long virt, phys_addr_t phys,
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 35cb96cfc258..97f401a06fcc 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -252,7 +252,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
#ifdef CONFIG_PPC_BOOK3S_32
if (ktext)
- hash_preload(&init_mm, v, false, 0x300);
+ hash_preload(&init_mm, v);
#endif
v += PAGE_SIZE;
p += PAGE_SIZE;
--
2.13.3
^ permalink raw reply related
* [PATCH 5/5] powerpc/mm: ppc 603 doesn't need update_mmu_cache()
From: Christophe Leroy @ 2019-08-16 5:41 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <668aba4db6b9af6d8a151174e11a4289f1a6bbcd.1565933217.git.christophe.leroy@c-s.fr>
On powerpc 603, there is no hash table so get out of
update_mmu_cache() early.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/mm/book3s32/mmu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 3a62bf99f93f..c20269be79ec 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -319,6 +319,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea)
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
pte_t *ptep)
{
+ if (!mmu_has_feature(MMU_FTR_HPTE_TABLE))
+ return;
/*
* We don't need to worry about _PAGE_PRESENT here because we are
* called with either mm->page_table_lock held or ptl lock held
--
2.13.3
^ permalink raw reply related
* Re: [PATCH v4 22/25] powernv/fadump: Warn before processing partial crashdump
From: Mahesh J Salgaonkar @ 2019-08-16 5:59 UTC (permalink / raw)
To: Hari Bathini
Cc: Ananth N Mavinakayanahalli, Mahesh J Salgaonkar, Nicholas Piggin,
linuxppc-dev, Oliver, Vasant Hegde, Stewart Smith, Daniel Axtens
In-Reply-To: <156327687873.27462.9042420686385726788.stgit@hbathini.in.ibm.com>
On 2019-07-16 17:04:38 Tue, Hari Bathini wrote:
> If not all kernel boot memory regions are registered for MPIPL before
> system crashes, try processing the partial crashdump but warn the user
> before proceeding.
>
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> ---
> arch/powerpc/platforms/powernv/opal-fadump.c | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c
> index b55f25c..3ef212d 100644
> --- a/arch/powerpc/platforms/powernv/opal-fadump.c
> +++ b/arch/powerpc/platforms/powernv/opal-fadump.c
> @@ -136,6 +136,27 @@ static void opal_fadump_get_config(struct fw_dump *fadump_conf,
> last_end = base + size;
> }
>
> + /*
> + * Rarely, but it can so happen that system crashes before all
> + * boot memory regions are registered for MPIPL. In such
> + * cases, warn that the vmcore may not be accurate and proceed
> + * anyway as that is the best bet considering free pages, cache
> + * pages, user pages, etc are usually filtered out.
> + *
> + * Hope the memory that could not be preserved only has pages
> + * that are usually filtered out while saving the vmcore.
> + */
> + if (fdm->region_cnt < fdm->registered_regions) {
> + pr_warn("The crashdump may not be accurate as the below boot memory regions could not be preserved:\n");
This would be opal crashing while kernel is middle of gearing itself for
fadump. If you decide to still go ahead with partial dump then you will need to
have nice warning message about dump capture (makedmpfile capture) may
fail, but we will still have full opal core that can help in analysis.
Thanks,
-Mahesh.
^ permalink raw reply
* next take at setting up a dma mask by default for platform devices v2
From: Christoph Hellwig @ 2019-08-16 6:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Maxime Chevallier
Cc: linux-arch, Gavin Li, linuxppc-dev, Mathias Nyman, Geoff Levand,
Fabio Estevam, Sascha Hauer, linux-usb, Michal Simek, iommu,
linux-kernel, linux-m68k, Alan Stern, NXP Linux Team,
Pengutronix Kernel Team, Minas Harutyunyan, Shawn Guo, Bin Liu,
linux-arm-kernel, Laurentiu Tudor
Hi all,
this is another attempt to make sure the dma_mask pointer is always
initialized for platform devices. Not doing so lead to lots of
boilerplate code, and makes platform devices different from all our
major busses like PCI where we always set up a dma_mask. In the long
run this should also help to eventually make dma_mask a scalar value
instead of a pointer and remove even more cruft.
The bigger blocker for this last time was the fact that the usb
subsystem uses the presence or lack of a dma_mask to check if the core
should do dma mapping for the driver, which is highly unusual. So we
fix this first. Note that this has some overlap with the pending
desire to use the proper dma_mmap_coherent helper for mapping usb
buffers. The first two patches have already been queued up by Greg
and are only included for completeness.
Changes since v1:
- fix a compile error in the ppc of ohci driver
- revamp the last patch to get rid of the archdata callout entirely.
^ permalink raw reply
* Re: 5.2.7 kernel doesn't boot on G5
From: Christian Marillat @ 2019-08-16 6:24 UTC (permalink / raw)
To: christophe leroy; +Cc: Mathieu Malaterre, Christian Marillat, linuxppc-dev
In-Reply-To: <e582fcf0-a311-07f7-5445-c3471ec5c783@c-s.fr>
On 15 août 2019 19:50, christophe leroy <christophe.leroy@c-s.fr> wrote:
> Le 15/08/2019 à 19:48, Christian Marillat a écrit :
>> On 15 août 2019 19:29, christophe leroy <christophe.leroy@c-s.fr> wrote:
>>
>>> Le 15/08/2019 à 19:05, Mathieu Malaterre a écrit :
>>>> Does that ring a bell to anyone here ? Thanks
>>>
>>> Apparently that's 5.2.0, not 5.2.7
>>
>> Yes, 5.2.7 is the Debian package version. Sorry for the mistake.
>>
>
> Can you test with latest stable version, ie 5.2.8 ?
I need to build a kernel.
Is there some documentation to cross-compile a kernel ?
Christian
^ permalink raw reply
* [PATCH 1/6] usb: don't create dma pools for HCDs with a localmem_pool
From: Christoph Hellwig @ 2019-08-16 6:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Maxime Chevallier
Cc: linux-arch, Gavin Li, linuxppc-dev, Mathias Nyman, Geoff Levand,
Fabio Estevam, Sascha Hauer, linux-usb, Michal Simek, iommu,
linux-kernel, linux-m68k, Alan Stern, NXP Linux Team,
Pengutronix Kernel Team, Minas Harutyunyan, Shawn Guo, Bin Liu,
linux-arm-kernel, Laurentiu Tudor
In-Reply-To: <20190816062435.881-1-hch@lst.de>
If the HCD provides a localmem pool we will never use the DMA pools, so
don't create them.
Fixes: b0310c2f09bb ("USB: use genalloc for USB HCs with local memory")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/usb/core/buffer.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 1359b78a624e..1a5b3dcae930 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -66,9 +66,9 @@ int hcd_buffer_create(struct usb_hcd *hcd)
char name[16];
int i, size;
- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
- (!is_device_dma_capable(hcd->self.sysdev) &&
- !hcd->localmem_pool))
+ if (hcd->localmem_pool ||
+ !IS_ENABLED(CONFIG_HAS_DMA) ||
+ !is_device_dma_capable(hcd->self.sysdev))
return 0;
for (i = 0; i < HCD_BUFFER_POOLS; i++) {
--
2.20.1
^ permalink raw reply related
* [PATCH 2/6] usb: add a hcd_uses_dma helper
From: Christoph Hellwig @ 2019-08-16 6:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Maxime Chevallier
Cc: linux-arch, Gavin Li, linuxppc-dev, Mathias Nyman, Geoff Levand,
Fabio Estevam, Sascha Hauer, linux-usb, Michal Simek, iommu,
linux-kernel, linux-m68k, Alan Stern, NXP Linux Team,
Pengutronix Kernel Team, Minas Harutyunyan, Shawn Guo, Bin Liu,
linux-arm-kernel, Laurentiu Tudor
In-Reply-To: <20190816062435.881-1-hch@lst.de>
The USB buffer allocation code is the only place in the usb core (and in
fact the whole kernel) that uses is_device_dma_capable, while the URB
mapping code uses the uses_dma flag in struct usb_bus. Switch the buffer
allocation to use the uses_dma flag used by the rest of the USB code,
and create a helper in hcd.h that checks this flag as well as the
CONFIG_HAS_DMA to simplify the caller a bit.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/usb/core/buffer.c | 10 +++-------
drivers/usb/core/hcd.c | 4 ++--
drivers/usb/dwc2/hcd.c | 2 +-
include/linux/usb.h | 2 +-
include/linux/usb/hcd.h | 3 +++
5 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 1a5b3dcae930..6cf22c27f2d2 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -66,9 +66,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
char name[16];
int i, size;
- if (hcd->localmem_pool ||
- !IS_ENABLED(CONFIG_HAS_DMA) ||
- !is_device_dma_capable(hcd->self.sysdev))
+ if (hcd->localmem_pool || !hcd_uses_dma(hcd))
return 0;
for (i = 0; i < HCD_BUFFER_POOLS; i++) {
@@ -129,8 +127,7 @@ void *hcd_buffer_alloc(
return gen_pool_dma_alloc(hcd->localmem_pool, size, dma);
/* some USB hosts just use PIO */
- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
- !is_device_dma_capable(bus->sysdev)) {
+ if (!hcd_uses_dma(hcd)) {
*dma = ~(dma_addr_t) 0;
return kmalloc(size, mem_flags);
}
@@ -160,8 +157,7 @@ void hcd_buffer_free(
return;
}
- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
- !is_device_dma_capable(bus->sysdev)) {
+ if (!hcd_uses_dma(hcd)) {
kfree(addr);
return;
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 2ccbc2f83570..8592c0344fe8 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1412,7 +1412,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
if (usb_endpoint_xfer_control(&urb->ep->desc)) {
if (hcd->self.uses_pio_for_control)
return ret;
- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
+ if (hcd_uses_dma(hcd)) {
if (is_vmalloc_addr(urb->setup_packet)) {
WARN_ONCE(1, "setup packet is not dma capable\n");
return -EAGAIN;
@@ -1446,7 +1446,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
if (urb->transfer_buffer_length != 0
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
+ if (hcd_uses_dma(hcd)) {
if (urb->num_sgs) {
int n;
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index ee144ff8af5b..111787a137ee 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4608,7 +4608,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
buf = urb->transfer_buffer;
- if (hcd->self.uses_dma) {
+ if (hcd_uses_dma(hcd)) {
if (!buf && (urb->transfer_dma & 3)) {
dev_err(hsotg->dev,
"%s: unaligned transfer with no transfer_buffer",
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 83d35d993e8c..e87826e23d59 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1457,7 +1457,7 @@ typedef void (*usb_complete_t)(struct urb *);
* field rather than determining a dma address themselves.
*
* Note that transfer_buffer must still be set if the controller
- * does not support DMA (as indicated by bus.uses_dma) and when talking
+ * does not support DMA (as indicated by hcd_uses_dma()) and when talking
* to root hub. If you have to trasfer between highmem zone and the device
* on such controller, create a bounce buffer or bail out with an error.
* If transfer_buffer cannot be set (is in highmem) and the controller is DMA
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index bab27ccc8ff5..a20e7815d814 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -422,6 +422,9 @@ static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd,
return hcd->high_prio_bh.completing_ep == ep;
}
+#define hcd_uses_dma(hcd) \
+ (IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma)
+
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
int status);
--
2.20.1
^ permalink raw reply related
* [PATCH 4/6] usb/max3421: remove the dummy {un, }map_urb_for_dma methods
From: Christoph Hellwig @ 2019-08-16 6:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Maxime Chevallier
Cc: linux-arch, Gavin Li, linuxppc-dev, Mathias Nyman, Geoff Levand,
Fabio Estevam, Sascha Hauer, linux-usb, Michal Simek, iommu,
linux-kernel, linux-m68k, Alan Stern, NXP Linux Team,
Pengutronix Kernel Team, Minas Harutyunyan, Shawn Guo, Bin Liu,
linux-arm-kernel, Laurentiu Tudor
In-Reply-To: <20190816062435.881-1-hch@lst.de>
Now that we have an explicit HCD_DMA flag, there is not need to override
these methods.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/usb/host/max3421-hcd.c | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index afa321ab55fc..8819f502b6a6 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1800,21 +1800,6 @@ max3421_bus_resume(struct usb_hcd *hcd)
return -1;
}
-/*
- * The SPI driver already takes care of DMA-mapping/unmapping, so no
- * reason to do it twice.
- */
-static int
-max3421_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
-{
- return 0;
-}
-
-static void
-max3421_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
-{
-}
-
static const struct hc_driver max3421_hcd_desc = {
.description = "max3421",
.product_desc = DRIVER_DESC,
@@ -1826,8 +1811,6 @@ static const struct hc_driver max3421_hcd_desc = {
.get_frame_number = max3421_get_frame_number,
.urb_enqueue = max3421_urb_enqueue,
.urb_dequeue = max3421_urb_dequeue,
- .map_urb_for_dma = max3421_map_urb_for_dma,
- .unmap_urb_for_dma = max3421_unmap_urb_for_dma,
.endpoint_disable = max3421_endpoint_disable,
.hub_status_data = max3421_hub_status_data,
.hub_control = max3421_hub_control,
--
2.20.1
^ permalink raw reply related
* [PATCH 3/6] usb: add a HCD_DMA flag instead of guestimating DMA capabilities
From: Christoph Hellwig @ 2019-08-16 6:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Maxime Chevallier
Cc: linux-arch, Gavin Li, linuxppc-dev, Mathias Nyman, Geoff Levand,
Fabio Estevam, Sascha Hauer, linux-usb, Michal Simek, iommu,
linux-kernel, linux-m68k, Alan Stern, NXP Linux Team,
Pengutronix Kernel Team, Minas Harutyunyan, Shawn Guo, Bin Liu,
linux-arm-kernel, Laurentiu Tudor
In-Reply-To: <20190816062435.881-1-hch@lst.de>
The usb core is the only major place in the kernel that checks for
a non-NULL device dma_mask to see if a device is DMA capable. This
is generally a bad idea, as all major busses always set up a DMA mask,
even if the device is not DMA capable - in fact bus layers like PCI
can't even know if a device is DMA capable at enumeration time. This
leads to lots of workaround in HCD drivers, and also prevented us from
setting up a DMA mask for platform devices by default last time we
tried.
Replace this guess with an explicit HCD_DMA that is set by drivers that
appear to have DMA support.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/staging/octeon-usb/octeon-hcd.c | 2 +-
drivers/usb/core/hcd.c | 1 -
drivers/usb/dwc2/hcd.c | 6 +++---
drivers/usb/host/ehci-grlib.c | 2 +-
drivers/usb/host/ehci-hcd.c | 2 +-
drivers/usb/host/ehci-pmcmsp.c | 2 +-
drivers/usb/host/ehci-ppc-of.c | 2 +-
drivers/usb/host/ehci-ps3.c | 2 +-
drivers/usb/host/ehci-sh.c | 2 +-
drivers/usb/host/ehci-xilinx-of.c | 2 +-
drivers/usb/host/fhci-hcd.c | 2 +-
drivers/usb/host/fotg210-hcd.c | 2 +-
drivers/usb/host/imx21-hcd.c | 2 +-
drivers/usb/host/isp116x-hcd.c | 6 ------
drivers/usb/host/isp1362-hcd.c | 5 -----
drivers/usb/host/ohci-hcd.c | 2 +-
drivers/usb/host/ohci-ppc-of.c | 2 +-
drivers/usb/host/ohci-ps3.c | 2 +-
drivers/usb/host/ohci-sa1111.c | 2 +-
drivers/usb/host/ohci-sm501.c | 2 +-
drivers/usb/host/ohci-tmio.c | 2 +-
drivers/usb/host/oxu210hp-hcd.c | 3 ---
drivers/usb/host/r8a66597-hcd.c | 6 ------
drivers/usb/host/sl811-hcd.c | 6 ------
drivers/usb/host/u132-hcd.c | 2 --
drivers/usb/host/uhci-grlib.c | 2 +-
drivers/usb/host/uhci-pci.c | 2 +-
drivers/usb/host/uhci-platform.c | 2 +-
drivers/usb/host/xhci.c | 2 +-
drivers/usb/isp1760/isp1760-core.c | 3 ---
drivers/usb/isp1760/isp1760-if.c | 1 -
drivers/usb/musb/musb_host.c | 2 +-
drivers/usb/renesas_usbhs/mod_host.c | 2 +-
include/linux/usb.h | 1 -
include/linux/usb/hcd.h | 7 +++++--
35 files changed, 31 insertions(+), 62 deletions(-)
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index cd2b777073c4..a5321cc692c5 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -3512,7 +3512,7 @@ static const struct hc_driver octeon_hc_driver = {
.product_desc = "Octeon Host Controller",
.hcd_priv_size = sizeof(struct octeon_hcd),
.irq = octeon_usb_irq,
- .flags = HCD_MEMORY | HCD_USB2,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2,
.start = octeon_usb_start,
.stop = octeon_usb_stop,
.urb_enqueue = octeon_usb_urb_enqueue,
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 8592c0344fe8..add2af4af766 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2454,7 +2454,6 @@ struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
hcd->self.controller = dev;
hcd->self.sysdev = sysdev;
hcd->self.bus_name = bus_name;
- hcd->self.uses_dma = (sysdev->dma_mask != NULL);
timer_setup(&hcd->rh_timer, rh_timer_func, 0);
#ifdef CONFIG_PM
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 111787a137ee..81afe553aa66 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5062,13 +5062,13 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
dwc2_hc_driver.reset_device = dwc2_reset_device;
}
+ if (hsotg->params.host_dma)
+ dwc2_hc_driver.flags |= HCD_DMA;
+
hcd = usb_create_hcd(&dwc2_hc_driver, hsotg->dev, dev_name(hsotg->dev));
if (!hcd)
goto error1;
- if (!hsotg->params.host_dma)
- hcd->self.uses_dma = 0;
-
hcd->has_tt = 1;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c
index 656b8c08efc8..a2c3b4ec8a8b 100644
--- a/drivers/usb/host/ehci-grlib.c
+++ b/drivers/usb/host/ehci-grlib.c
@@ -30,7 +30,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 9da7e22848c9..cf2b7ae93b7e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1193,7 +1193,7 @@ static const struct hc_driver ehci_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c
index 46e160370d6e..a2b610dbedfc 100644
--- a/drivers/usb/host/ehci-pmcmsp.c
+++ b/drivers/usb/host/ehci-pmcmsp.c
@@ -250,7 +250,7 @@ static const struct hc_driver ehci_msp_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index 576f7d79ad4e..6bbaee74f7e7 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -31,7 +31,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 454d8c624a3f..fb52133c3557 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -59,7 +59,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
.product_desc = "PS3 EHCI Host Controller",
.hcd_priv_size = sizeof(struct ehci_hcd),
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
.reset = ps3_ehci_hc_reset,
.start = ehci_run,
.stop = ehci_stop,
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c
index a9ee767952c1..6a28fb93b9f1 100644
--- a/drivers/usb/host/ehci-sh.c
+++ b/drivers/usb/host/ehci-sh.c
@@ -33,7 +33,7 @@ static const struct hc_driver ehci_sh_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_USB2 | HCD_MEMORY | HCD_BH,
+ .flags = HCD_USB2 | HCD_DMA | HCD_MEMORY | HCD_BH,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
index d2a27578e440..67a6ee8cb5d8 100644
--- a/drivers/usb/host/ehci-xilinx-of.c
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -66,7 +66,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index 48fe9e6c2465..04733876c9c6 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -538,7 +538,7 @@ static const struct hc_driver fhci_driver = {
/* generic hardware linkage */
.irq = fhci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
+ .flags = HCD_DMA | HCD_USB11 | HCD_MEMORY,
/* basic lifecycle operation */
.start = fhci_start,
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 77cc36efae95..8d7ccd032d47 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -5504,7 +5504,7 @@ static const struct hc_driver fotg210_fotg210_hc_driver = {
* generic hardware linkage
*/
.irq = fotg210_irq,
- .flags = HCD_MEMORY | HCD_USB2,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index 6e3dad19d369..bd5fcc935e09 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -1771,7 +1771,7 @@ static const struct hc_driver imx21_hc_driver = {
.product_desc = "IMX21 USB Host Controller",
.hcd_priv_size = sizeof(struct imx21),
- .flags = HCD_USB11,
+ .flags = HCD_DMA | HCD_USB11,
.irq = imx21_irq,
.reset = imx21_hc_reset,
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 74da136d322a..a87c0b26279e 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1581,12 +1581,6 @@ static int isp116x_probe(struct platform_device *pdev)
irq = ires->start;
irqflags = ires->flags & IRQF_TRIGGER_MASK;
- if (pdev->dev.dma_mask) {
- DBG("DMA not supported\n");
- ret = -EINVAL;
- goto err1;
- }
-
if (!request_mem_region(addr->start, 2, hcd_name)) {
ret = -EBUSY;
goto err1;
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 28bf8bfb091e..96f8daa11f25 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2645,11 +2645,6 @@ static int isp1362_probe(struct platform_device *pdev)
if (pdev->num_resources < 3)
return -ENODEV;
- if (pdev->dev.dma_mask) {
- DBG(1, "won't do DMA");
- return -ENODEV;
- }
-
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq_res)
return -ENODEV;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b457fdaff297..1eb8d17e19db 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1178,7 +1178,7 @@ static const struct hc_driver ohci_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index 76a9b40b08f1..45f7cceb6df3 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -50,7 +50,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
+ .flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 395f9d3bc849..f77cd6af0ccf 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -46,7 +46,7 @@ static const struct hc_driver ps3_ohci_hc_driver = {
.product_desc = "PS3 OHCI Host Controller",
.hcd_priv_size = sizeof(struct ohci_hcd),
.irq = ohci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
.reset = ps3_ohci_hc_reset,
.start = ps3_ohci_hc_start,
.stop = ohci_stop,
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index ebec9a7699e3..8e19a5eb5b62 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -84,7 +84,7 @@ static const struct hc_driver ohci_sa1111_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
+ .flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index c158cda9e4b9..0b2aea6e28d4 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -49,7 +49,7 @@ static const struct hc_driver ohci_sm501_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
+ .flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index d5a293a707b6..8edbacd3eb17 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -153,7 +153,7 @@ static const struct hc_driver ohci_tmio_hc_driver = {
/* generic hardware linkage */
.irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
+ .flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,
/* basic lifecycle operations */
.start = ohci_tmio_start,
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 47c5515a9ce4..29a49cc8a1ed 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -2649,9 +2649,6 @@ static int oxu_reset(struct usb_hcd *hcd)
INIT_LIST_HEAD(&oxu->urb_list);
oxu->urb_len = 0;
- /* FIMXE */
- hcd->self.controller->dma_mask = NULL;
-
if (oxu->is_otg) {
oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET;
oxu->regs = hcd->regs + OXU_OTG_CAP_OFFSET + \
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 42668aeca57c..0c03ac6b0213 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2411,12 +2411,6 @@ static int r8a66597_probe(struct platform_device *pdev)
if (usb_disabled())
return -ENODEV;
- if (pdev->dev.dma_mask) {
- ret = -EINVAL;
- dev_err(&pdev->dev, "dma not supported\n");
- goto clean_up;
- }
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 5b061e599948..72a34a1eb618 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1632,12 +1632,6 @@ sl811h_probe(struct platform_device *dev)
irq = ires->start;
irqflags = ires->flags & IRQF_TRIGGER_MASK;
- /* refuse to confuse usbcore */
- if (dev->dev.dma_mask) {
- dev_dbg(&dev->dev, "no we won't dma\n");
- return -EINVAL;
- }
-
/* the chip may be wired for either kind of addressing */
addr = platform_get_resource(dev, IORESOURCE_MEM, 0);
data = platform_get_resource(dev, IORESOURCE_MEM, 1);
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index 400c40bc43a6..4efee34f154f 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -3077,8 +3077,6 @@ static int u132_probe(struct platform_device *pdev)
retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a);
if (retval)
return retval;
- if (pdev->dev.dma_mask)
- return -EINVAL;
hcd = usb_create_hcd(&u132_hc_driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c
index 2103b1ed0f8f..0a201a73b196 100644
--- a/drivers/usb/host/uhci-grlib.c
+++ b/drivers/usb/host/uhci-grlib.c
@@ -63,7 +63,7 @@ static const struct hc_driver uhci_grlib_hc_driver = {
/* Generic hardware linkage */
.irq = uhci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
/* Basic lifecycle operations */
.reset = uhci_grlib_init,
diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c
index 0dd944277c99..0fa3d72bae26 100644
--- a/drivers/usb/host/uhci-pci.c
+++ b/drivers/usb/host/uhci-pci.c
@@ -261,7 +261,7 @@ static const struct hc_driver uhci_driver = {
/* Generic hardware linkage */
.irq = uhci_irq,
- .flags = HCD_USB11,
+ .flags = HCD_DMA | HCD_USB11,
/* Basic lifecycle operations */
.reset = uhci_pci_init,
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 89700e26fb29..70dbd95c3f06 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -41,7 +41,7 @@ static const struct hc_driver uhci_platform_hc_driver = {
/* Generic hardware linkage */
.irq = uhci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
/* Basic lifecycle operations */
.reset = uhci_platform_init,
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 03d1e552769b..e315c0158e90 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5217,7 +5217,7 @@ static const struct hc_driver xhci_hc_driver = {
* generic hardware linkage
*/
.irq = xhci_irq,
- .flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED,
+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB3 | HCD_SHARED,
/*
* basic lifecycle operations
diff --git a/drivers/usb/isp1760/isp1760-core.c b/drivers/usb/isp1760/isp1760-core.c
index 55b94fd10331..fdeb4cf97cc5 100644
--- a/drivers/usb/isp1760/isp1760-core.c
+++ b/drivers/usb/isp1760/isp1760-core.c
@@ -120,9 +120,6 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
(!IS_ENABLED(CONFIG_USB_ISP1761_UDC) || udc_disabled))
return -ENODEV;
- /* prevent usb-core allocating DMA pages */
- dev->dma_mask = NULL;
-
isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
if (!isp)
return -ENOMEM;
diff --git a/drivers/usb/isp1760/isp1760-if.c b/drivers/usb/isp1760/isp1760-if.c
index 241a00d75027..07cc82ff327c 100644
--- a/drivers/usb/isp1760/isp1760-if.c
+++ b/drivers/usb/isp1760/isp1760-if.c
@@ -139,7 +139,6 @@ static int isp1761_pci_probe(struct pci_dev *dev,
pci_set_master(dev);
- dev->dev.dma_mask = NULL;
ret = isp1760_register(&dev->resource[3], dev->irq, 0, &dev->dev,
devflags);
if (ret < 0)
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index eb308ec35c66..5a44b70372d9 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2689,7 +2689,7 @@ static const struct hc_driver musb_hc_driver = {
.description = "musb-hcd",
.product_desc = "MUSB HDRC host driver",
.hcd_priv_size = sizeof(struct musb *),
- .flags = HCD_USB2 | HCD_MEMORY,
+ .flags = HCD_USB2 | HCD_DMA | HCD_MEMORY,
/* not using irq handler or reset hooks from usbcore, since
* those must be shared with peripheral code for OTG configs
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index ddd3be48f948..ae54221011c3 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -1283,7 +1283,7 @@ static const struct hc_driver usbhsh_driver = {
/*
* generic hardware linkage
*/
- .flags = HCD_USB2,
+ .flags = HCD_DMA | HCD_USB2,
.start = usbhsh_host_start,
.stop = usbhsh_host_stop,
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e87826e23d59..85a8865f9e83 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -426,7 +426,6 @@ struct usb_bus {
struct device *sysdev; /* as seen from firmware or bus */
int busnum; /* Bus number (in order of reg) */
const char *bus_name; /* stable id (PCI slot_name etc) */
- u8 uses_dma; /* Does the host controller use DMA? */
u8 uses_pio_for_control; /*
* Does the host controller use PIO
* for control transfers?
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index a20e7815d814..8d3869c7de85 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -256,6 +256,7 @@ struct hc_driver {
int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
+#define HCD_DMA 0x0002 /* HC uses DMA */
#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
@@ -422,8 +423,10 @@ static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd,
return hcd->high_prio_bh.completing_ep == ep;
}
-#define hcd_uses_dma(hcd) \
- (IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma)
+static inline bool hcd_uses_dma(struct usb_hcd *hcd)
+{
+ return IS_ENABLED(CONFIG_HAS_DMA) && (hcd->driver->flags & HCD_DMA);
+}
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
--
2.20.1
^ permalink raw reply related
* [PATCH 5/6] dma-mapping: remove is_device_dma_capable
From: Christoph Hellwig @ 2019-08-16 6:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Maxime Chevallier
Cc: linux-arch, Gavin Li, linuxppc-dev, Mathias Nyman, Geoff Levand,
Fabio Estevam, Sascha Hauer, linux-usb, Michal Simek, iommu,
linux-kernel, linux-m68k, Alan Stern, NXP Linux Team,
Pengutronix Kernel Team, Minas Harutyunyan, Shawn Guo, Bin Liu,
linux-arm-kernel, Laurentiu Tudor
In-Reply-To: <20190816062435.881-1-hch@lst.de>
No users left.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/dma-mapping.h | 5 -----
1 file changed, 5 deletions(-)
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f7d1eea32c78..14702e2d6fa8 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -149,11 +149,6 @@ static inline int valid_dma_direction(int dma_direction)
(dma_direction == DMA_FROM_DEVICE));
}
-static inline int is_device_dma_capable(struct device *dev)
-{
- return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
-}
-
#ifdef CONFIG_DMA_DECLARE_COHERENT
/*
* These three functions are only for dma allocator.
--
2.20.1
^ permalink raw reply related
* [PATCH 6/6] driver core: initialize a default DMA mask for platform device
From: Christoph Hellwig @ 2019-08-16 6:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Maxime Chevallier
Cc: linux-arch, Gavin Li, linuxppc-dev, Mathias Nyman, Geoff Levand,
Fabio Estevam, Sascha Hauer, linux-usb, Michal Simek, iommu,
linux-kernel, linux-m68k, Alan Stern, NXP Linux Team,
Pengutronix Kernel Team, Minas Harutyunyan, Shawn Guo, Bin Liu,
linux-arm-kernel, Laurentiu Tudor
In-Reply-To: <20190816062435.881-1-hch@lst.de>
We still treat devices without a DMA mask as defaulting to 32-bits for
both mask, but a few releases ago we've started warning about such
cases, as they require special cases to work around this sloppyness.
Add a dma_mask field to struct platform_device so that we can initialize
the dma_mask pointer in struct device and initialize both masks to
32-bits by default, replacing similar functionality in m68k and
powerpc. The arch_setup_pdev_archdata hooks is now unused and removed.
Note that the code looks a little odd with the various conditionals
because we have to support platform_device structures that are
statically allocated.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/m68k/kernel/dma.c | 9 -------
arch/powerpc/kernel/setup-common.c | 6 -----
arch/sh/boards/mach-ap325rxa/setup.c | 1 -
arch/sh/boards/mach-ecovec24/setup.c | 2 --
arch/sh/boards/mach-kfr2r09/setup.c | 1 -
arch/sh/boards/mach-migor/setup.c | 1 -
arch/sh/boards/mach-se/7724/setup.c | 2 --
drivers/base/platform.c | 37 ++++++++++++----------------
include/linux/platform_device.h | 2 +-
9 files changed, 17 insertions(+), 44 deletions(-)
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 30cd59caf037..447849d1d645 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -79,12 +79,3 @@ void arch_sync_dma_for_device(struct device *dev, phys_addr_t handle,
break;
}
}
-
-void arch_setup_pdev_archdata(struct platform_device *pdev)
-{
- if (pdev->dev.coherent_dma_mask == DMA_MASK_NONE &&
- pdev->dev.dma_mask == NULL) {
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- }
-}
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1f8db666468d..5e6543aba1b3 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -778,12 +778,6 @@ void ppc_printk_progress(char *s, unsigned short hex)
pr_info("%s\n", s);
}
-void arch_setup_pdev_archdata(struct platform_device *pdev)
-{
- pdev->archdata.dma_mask = DMA_BIT_MASK(32);
- pdev->dev.dma_mask = &pdev->archdata.dma_mask;
-}
-
static __init void print_system_info(void)
{
pr_info("-----------------------------------------------------\n");
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 8301a4378f50..665cad452798 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -527,7 +527,6 @@ static int __init ap325rxa_devices_setup(void)
/* Initialize CEU platform device separately to map memory first */
device_initialize(&ap325rxa_ceu_device.dev);
- arch_setup_pdev_archdata(&ap325rxa_ceu_device);
dma_declare_coherent_memory(&ap325rxa_ceu_device.dev,
ceu_dma_membase, ceu_dma_membase,
ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index f402aa741bf3..acaa97459531 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -1440,7 +1440,6 @@ static int __init arch_setup(void)
/* Initialize CEU platform devices separately to map memory first */
device_initialize(&ecovec_ceu_devices[0]->dev);
- arch_setup_pdev_archdata(ecovec_ceu_devices[0]);
dma_declare_coherent_memory(&ecovec_ceu_devices[0]->dev,
ceu0_dma_membase, ceu0_dma_membase,
ceu0_dma_membase +
@@ -1448,7 +1447,6 @@ static int __init arch_setup(void)
platform_device_add(ecovec_ceu_devices[0]);
device_initialize(&ecovec_ceu_devices[1]->dev);
- arch_setup_pdev_archdata(ecovec_ceu_devices[1]);
dma_declare_coherent_memory(&ecovec_ceu_devices[1]->dev,
ceu1_dma_membase, ceu1_dma_membase,
ceu1_dma_membase +
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 1cf9a47ac90e..96538ba3aa32 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -601,7 +601,6 @@ static int __init kfr2r09_devices_setup(void)
/* Initialize CEU platform device separately to map memory first */
device_initialize(&kfr2r09_ceu_device.dev);
- arch_setup_pdev_archdata(&kfr2r09_ceu_device);
dma_declare_coherent_memory(&kfr2r09_ceu_device.dev,
ceu_dma_membase, ceu_dma_membase,
ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 90702740f207..9ed369dad62d 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -602,7 +602,6 @@ static int __init migor_devices_setup(void)
/* Initialize CEU platform device separately to map memory first */
device_initialize(&migor_ceu_device.dev);
- arch_setup_pdev_archdata(&migor_ceu_device);
dma_declare_coherent_memory(&migor_ceu_device.dev,
ceu_dma_membase, ceu_dma_membase,
ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 3674064816c7..32f5dd944889 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -937,7 +937,6 @@ static int __init devices_setup(void)
/* Initialize CEU platform devices separately to map memory first */
device_initialize(&ms7724se_ceu_devices[0]->dev);
- arch_setup_pdev_archdata(ms7724se_ceu_devices[0]);
dma_declare_coherent_memory(&ms7724se_ceu_devices[0]->dev,
ceu0_dma_membase, ceu0_dma_membase,
ceu0_dma_membase +
@@ -945,7 +944,6 @@ static int __init devices_setup(void)
platform_device_add(ms7724se_ceu_devices[0]);
device_initialize(&ms7724se_ceu_devices[1]->dev);
- arch_setup_pdev_archdata(ms7724se_ceu_devices[1]);
dma_declare_coherent_memory(&ms7724se_ceu_devices[1]->dev,
ceu1_dma_membase, ceu1_dma_membase,
ceu1_dma_membase +
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ec974ba9c0c4..600913aea73b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -39,25 +39,6 @@ struct device platform_bus = {
};
EXPORT_SYMBOL_GPL(platform_bus);
-/**
- * arch_setup_pdev_archdata - Allow manipulation of archdata before its used
- * @pdev: platform device
- *
- * This is called before platform_device_add() such that any pdev_archdata may
- * be setup before the platform_notifier is called. So if a user needs to
- * manipulate any relevant information in the pdev_archdata they can do:
- *
- * platform_device_alloc()
- * ... manipulate ...
- * platform_device_add()
- *
- * And if they don't care they can just call platform_device_register() and
- * everything will just work out.
- */
-void __weak arch_setup_pdev_archdata(struct platform_device *pdev)
-{
-}
-
/**
* platform_get_resource - get a resource for a device
* @dev: platform device
@@ -264,6 +245,20 @@ struct platform_object {
char name[];
};
+/*
+ * Set up default DMA mask for platform devices if the they weren't
+ * previously set by the architecture / DT.
+ */
+static void setup_pdev_dma_masks(struct platform_device *pdev)
+{
+ if (!pdev->dev.coherent_dma_mask)
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ if (!pdev->dma_mask)
+ pdev->dma_mask = DMA_BIT_MASK(32);
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &pdev->dma_mask;
+};
+
/**
* platform_device_put - destroy a platform device
* @pdev: platform device to free
@@ -310,7 +305,7 @@ struct platform_device *platform_device_alloc(const char *name, int id)
pa->pdev.id = id;
device_initialize(&pa->pdev.dev);
pa->pdev.dev.release = platform_device_release;
- arch_setup_pdev_archdata(&pa->pdev);
+ setup_pdev_dma_masks(&pa->pdev);
}
return pa ? &pa->pdev : NULL;
@@ -512,7 +507,7 @@ EXPORT_SYMBOL_GPL(platform_device_del);
int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
- arch_setup_pdev_archdata(pdev);
+ setup_pdev_dma_masks(pdev);
return platform_device_add(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_register);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 9bc36b589827..34a3d8ed8ba7 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -24,6 +24,7 @@ struct platform_device {
int id;
bool id_auto;
struct device dev;
+ u64 dma_mask;
u32 num_resources;
struct resource *resource;
@@ -48,7 +49,6 @@ extern void platform_device_unregister(struct platform_device *);
extern struct bus_type platform_bus_type;
extern struct device platform_bus;
-extern void arch_setup_pdev_archdata(struct platform_device *);
extern struct resource *platform_get_resource(struct platform_device *,
unsigned int, unsigned int);
extern void __iomem *
--
2.20.1
^ permalink raw reply related
* cleanup the dma_pgprot handling
From: Christoph Hellwig @ 2019-08-16 7:07 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
Hi all,
this series replaced the arch_dma_mmap_pgprot hooks with the
simpler pgprot_dmacoherent as used by the arm code already and
cleans up various bits around that area.
I'd still like to hear a confirmation from the mips folks how
the write combibe attribute can or can't work with the KSEG1
uncached segment.
^ permalink raw reply
* [PATCH 1/6] MIPS: remove support for DMA_ATTR_WRITE_COMBINE
From: Christoph Hellwig @ 2019-08-16 7:07 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190816070754.15653-1-hch@lst.de>
Mips uses the KSEG1 kernel memory segment do map dma coherent
allocations for non-coherent devices as uncachable, and does not have
any kind of special support for DMA_ATTR_WRITE_COMBINE in the allocation
path. Thus supporting DMA_ATTR_WRITE_COMBINE in dma_mmap_attrs will
lead to multiple mappings with different caching attributes.
Fixes: 8c172467be36 ("MIPS: Add implementation of dma_map_ops.mmap()")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/mips/Kconfig | 1 -
arch/mips/mm/dma-noncoherent.c | 8 --------
2 files changed, 9 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d50fafd7bf3a..86e6760ef0d0 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1119,7 +1119,6 @@ config DMA_PERDEV_COHERENT
config DMA_NONCOHERENT
bool
- select ARCH_HAS_DMA_MMAP_PGPROT
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_UNCACHED_SEGMENT
select NEED_DMA_MAP_STATE
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index ed56c6fa7be2..1d4d57dd9acf 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -65,14 +65,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
return page_to_pfn(virt_to_page(cached_kernel_address(cpu_addr)));
}
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- if (attrs & DMA_ATTR_WRITE_COMBINE)
- return pgprot_writecombine(prot);
- return pgprot_noncached(prot);
-}
-
static inline void dma_sync_virt(void *addr, size_t size,
enum dma_data_direction dir)
{
--
2.20.1
^ permalink raw reply related
* Re: [PATCH] powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB
From: Greg Kroah-Hartman @ 2019-08-16 7:14 UTC (permalink / raw)
To: Michael Ellerman
Cc: Alastair D'Silva, linux-kernel, stable, Paul Mackerras,
alastair, Thomas Gleixner, linuxppc-dev, Allison Randal
In-Reply-To: <87mug97uo1.fsf@concordia.ellerman.id.au>
On Fri, Aug 16, 2019 at 11:42:22AM +1000, Michael Ellerman wrote:
> Greg Kroah-Hartman <gregkh@linuxfoundation.org> writes:
> > On Thu, Aug 15, 2019 at 02:55:42PM +1000, Alastair D'Silva wrote:
> >> From: Alastair D'Silva <alastair@d-silva.org>
> >>
> >> Heads Up: This patch cannot be submitted to Linus's tree, as the affected
> >> assembler functions have already been converted to C.
>
> That was done in upstream commit:
>
> 22e9c88d486a ("powerpc/64: reuse PPC32 static inline flush_dcache_range()")
>
> Which is a larger change that we don't want to backport. This patch is a
> minimal fix for stable trees.
>
>
> >> When calling flush_(inval_)dcache_range with a size >4GB, we were masking
> >> off the upper 32 bits, so we would incorrectly flush a range smaller
> >> than intended.
> >>
> >> This patch replaces the 32 bit shifts with 64 bit ones, so that
> >> the full size is accounted for.
> >>
> >> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> >> ---
> >> arch/powerpc/kernel/misc_64.S | 4 ++--
> >> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> Acked-by: Michael Ellerman <mpe@ellerman.id.au>
>
> > <formletter>
> >
> > This is not the correct way to submit patches for inclusion in the
> > stable kernel tree. Please read:
> > https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
> > for how to do this properly.
> >
> > </formletter>
>
> Hi Greg,
>
> This is "option 3", submit the patch directly, and the patch "deviates
> from the original upstream patch" because the upstream patch was a
> wholesale conversion from asm to C.
>
> This patch applies cleanly to v4.14 and v4.19.
>
> The change log should have mentioned which upstream patch it is not a
> backport of, is there anything else we should have done differently to
> avoid the formletter bot :)
That is exactly what you should have done. It needs to be VERY explicit
as to why this is being submitted different from what upstream did, and
to what trees it needs to go to and who is going to be responsible for
when it breaks. And it will break :)
thanks,
greg k-h
^ permalink raw reply
* [PATCH 2/6] unicore32: remove the unused pgprot_dmacoherent define
From: Christoph Hellwig @ 2019-08-16 7:07 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190816070754.15653-1-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/unicore32/include/asm/pgtable.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/unicore32/include/asm/pgtable.h b/arch/unicore32/include/asm/pgtable.h
index 9492aa304f03..126e961a8cb0 100644
--- a/arch/unicore32/include/asm/pgtable.h
+++ b/arch/unicore32/include/asm/pgtable.h
@@ -198,8 +198,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
#define pgprot_writecombine(prot) \
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
-#define pgprot_dmacoherent(prot) \
- __pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_present(pmd) (pmd_val(pmd) & PMD_PRESENT)
--
2.20.1
^ permalink raw reply related
* [PATCH 3/6] arm-nommu: remove the unused pgprot_dmacoherent define
From: Christoph Hellwig @ 2019-08-16 7:07 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190816070754.15653-1-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/include/asm/pgtable-nommu.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
index 0b1f6799a32e..d0de24f06724 100644
--- a/arch/arm/include/asm/pgtable-nommu.h
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -62,7 +62,6 @@ typedef pte_t *pte_addr_t;
*/
#define pgprot_noncached(prot) (prot)
#define pgprot_writecombine(prot) (prot)
-#define pgprot_dmacoherent(prot) (prot)
#define pgprot_device(prot) (prot)
--
2.20.1
^ permalink raw reply related
* [PATCH 4/6] dma-mapping: remove arch_dma_mmap_pgprot
From: Christoph Hellwig @ 2019-08-16 7:07 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190816070754.15653-1-hch@lst.de>
arch_dma_mmap_pgprot is used for two things:
1) to override the "normal" uncached page attributes for mapping
memory coherent to devices that can't snoop the CPU caches
2) to provide the special DMA_ATTR_WRITE_COMBINE semantics on older
arm systems
Replace one with the pgprot_dmacoherent macro that is already provided
by arm and much simpler to use, and lift the DMA_ATTR_WRITE_COMBINE
handling to common code with an explicit arch opt-in.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/Kconfig | 1 +
arch/arm/mm/Kconfig | 1 -
arch/arm/mm/dma-mapping.c | 6 ------
arch/arm64/Kconfig | 1 -
arch/arm64/include/asm/pgtable.h | 4 ++++
arch/arm64/mm/dma-mapping.c | 6 ------
arch/m68k/Kconfig | 1 -
arch/m68k/include/asm/pgtable_mm.h | 3 +++
arch/m68k/kernel/dma.c | 3 +--
include/linux/dma-noncoherent.h | 13 +++++++++++--
kernel/dma/Kconfig | 14 +++++++++++---
kernel/dma/mapping.c | 8 +++++---
12 files changed, 36 insertions(+), 25 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 33b00579beff..e172fba1e8fd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -7,6 +7,7 @@ config ARM
select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEVMEM_IS_ALLOWED
+ select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KEEPINITRD
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c54cd7ed90ba..0609c9e2191b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -665,7 +665,6 @@ config ARM_LPAE
select PHYS_ADDR_T_64BIT
select SWIOTLB
select ARCH_HAS_DMA_COHERENT_TO_PFN
- select ARCH_HAS_DMA_MMAP_PGPROT
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_SYNC_DMA_FOR_CPU
help
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..d27b12f61737 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2402,12 +2402,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
return dma_to_pfn(dev, dma_addr);
}
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- return __get_dma_pgprot(attrs, prot);
-}
-
void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t gfp, unsigned long attrs)
{
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..dab9dda34206 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -13,7 +13,6 @@ config ARM64
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_COHERENT_TO_PFN
- select ARCH_HAS_DMA_MMAP_PGPROT
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index e09760ece844..6700371227d1 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,10 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+#define pgprot_dmacoherent(prot) \
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, \
+ PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index bd2b039f43a6..676efcda51e6 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -11,12 +11,6 @@
#include <asm/cacheflush.h>
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- return pgprot_writecombine(prot);
-}
-
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
size_t size, enum dma_data_direction dir)
{
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index c518d695c376..a9e564306d3e 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -4,7 +4,6 @@ config M68K
default y
select ARCH_32BIT_OFF_T
select ARCH_HAS_BINFMT_FLAT
- select ARCH_HAS_DMA_MMAP_PGPROT if MMU && !COLDFIRE
select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h
index fe3ddd73a0cc..fde4534b974f 100644
--- a/arch/m68k/include/asm/pgtable_mm.h
+++ b/arch/m68k/include/asm/pgtable_mm.h
@@ -169,6 +169,9 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
: (prot)))
+pgprot_t pgprot_dmacoherent(pgprot_t prot);
+#define pgprot_dmacoherent(prot) pgprot_dmacoherent(prot)
+
#endif /* CONFIG_COLDFIRE */
#include <asm-generic/pgtable.h>
#endif /* !__ASSEMBLY__ */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 30cd59caf037..35064150e348 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -23,8 +23,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
cache_push(page_to_phys(page), size);
}
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
+pgprot_t pgprot_dmacoherent(pgprot_t prot)
{
if (CPU_IS_040_OR_060) {
pgprot_val(prot) &= ~_PAGE_CACHE040;
diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
index 0bff3d7fac92..dd3de6d88fc0 100644
--- a/include/linux/dma-noncoherent.h
+++ b/include/linux/dma-noncoherent.h
@@ -3,6 +3,7 @@
#define _LINUX_DMA_NONCOHERENT_H 1
#include <linux/dma-mapping.h>
+#include <asm/pgtable.h>
#ifdef CONFIG_ARCH_HAS_DMA_COHERENCE_H
#include <asm/dma-coherence.h>
@@ -42,10 +43,18 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr, unsigned long attrs);
long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
dma_addr_t dma_addr);
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs);
#ifdef CONFIG_MMU
+/*
+ * Page protection so that devices that can't snoop CPU caches can use the
+ * memory coherently. We default to pgprot_noncached which is usually used
+ * for ioremap as a safe bet, but architectures can override this with less
+ * strict semantics if possible.
+ */
+#ifndef pgprot_dmacoherent
+#define pgprot_dmacoherent(prot) pgprot_noncached(prot)
+#endif
+
pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs);
#else
static inline pgprot_t dma_pgprot(struct device *dev, pgprot_t prot,
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 9decbba255fc..49148c207563 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -20,6 +20,17 @@ config ARCH_HAS_DMA_COHERENCE_H
config ARCH_HAS_DMA_SET_MASK
bool
+#
+# Select this option if the architecture needs special handling for
+# DMA_ATTR_WRITE_COMBINE. Normally the "uncached" mapping should be
+# what people thing of when saying write combine, but on old arm
+# platforms the write combine semantics are not well defined and thus
+# not enabled by default. You probably do not want to enable this for
+# any new port.
+#
+config ARCH_HAS_DMA_WRITE_COMBINE
+ bool
+
config DMA_DECLARE_COHERENT
bool
@@ -45,9 +56,6 @@ config ARCH_HAS_DMA_PREP_COHERENT
config ARCH_HAS_DMA_COHERENT_TO_PFN
bool
-config ARCH_HAS_DMA_MMAP_PGPROT
- bool
-
config ARCH_HAS_FORCE_DMA_UNENCRYPTED
bool
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index b0038ca3aa92..1b96616c9f20 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -161,9 +161,11 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
(IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) &&
(attrs & DMA_ATTR_NON_CONSISTENT)))
return prot;
- if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_MMAP_PGPROT))
- return arch_dma_mmap_pgprot(dev, prot, attrs);
- return pgprot_noncached(prot);
+#ifdef CONFIG_ARCH_HAS_DMA_WRITE_COMBINE
+ if (attrs & DMA_ATTR_WRITE_COMBINE)
+ return pgprot_writecombine(prot);
+#endif
+ return pgprot_dmacoherent(prot);
}
#endif /* CONFIG_MMU */
--
2.20.1
^ permalink raw reply related
* [PATCH 5/6] dma-mapping: make dma_atomic_pool_init self-contained
From: Christoph Hellwig @ 2019-08-16 7:07 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190816070754.15653-1-hch@lst.de>
The memory allocated for the atomic pool needs to have the same
mapping attributes that we use for remapping, so use
pgprot_dmacoherent instead of open coding it. Also deduct a
suitable zone to allocate the memory from based on the presence
of the DMA zones.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arc/mm/dma.c | 6 ------
arch/arm64/mm/dma-mapping.c | 6 ------
arch/csky/mm/dma-mapping.c | 6 ------
arch/nds32/kernel/dma.c | 6 ------
include/linux/dma-mapping.h | 1 -
kernel/dma/remap.c | 17 ++++++++++++++---
6 files changed, 14 insertions(+), 28 deletions(-)
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 62c210e7ee4c..ff4a5752f8cc 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -104,9 +104,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
dev_info(dev, "use %sncoherent DMA ops\n",
dev->dma_coherent ? "" : "non");
}
-
-static int __init atomic_pool_init(void)
-{
- return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 676efcda51e6..a1d05f669f67 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -28,12 +28,6 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
__dma_flush_area(page_address(page), size);
}
-static int __init arm64_dma_init(void)
-{
- return dma_atomic_pool_init(GFP_DMA32, __pgprot(PROT_NORMAL_NC));
-}
-arch_initcall(arm64_dma_init);
-
#ifdef CONFIG_IOMMU_DMA
void arch_teardown_dma_ops(struct device *dev)
{
diff --git a/arch/csky/mm/dma-mapping.c b/arch/csky/mm/dma-mapping.c
index 80783bb71c5c..602a60d47a94 100644
--- a/arch/csky/mm/dma-mapping.c
+++ b/arch/csky/mm/dma-mapping.c
@@ -14,12 +14,6 @@
#include <linux/version.h>
#include <asm/cache.h>
-static int __init atomic_pool_init(void)
-{
- return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
-
void arch_dma_prep_coherent(struct page *page, size_t size)
{
if (PageHighMem(page)) {
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index 490e3720d694..4206d4b6c8ce 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -80,9 +80,3 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
{
cache_op(page_to_phys(page), size, cpu_dma_wbinval_range);
}
-
-static int __init atomic_pool_init(void)
-{
- return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f7d1eea32c78..48ebe8295987 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -624,7 +624,6 @@ void *dma_common_pages_remap(struct page **pages, size_t size,
const void *caller);
void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot);
bool dma_in_atomic_pool(void *start, size_t size);
void *dma_alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags);
bool dma_free_from_pool(void *start, size_t size);
diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c
index ffe78f0b2fe4..838123f79639 100644
--- a/kernel/dma/remap.c
+++ b/kernel/dma/remap.c
@@ -105,7 +105,16 @@ static int __init early_coherent_pool(char *p)
}
early_param("coherent_pool", early_coherent_pool);
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
+static gfp_t dma_atomic_pool_gfp(void)
+{
+ if (IS_ENABLED(CONFIG_ZONE_DMA))
+ return GFP_DMA;
+ if (IS_ENABLED(CONFIG_ZONE_DMA32))
+ return GFP_DMA32;
+ return GFP_KERNEL;
+}
+
+static int __init dma_atomic_pool_init(void)
{
unsigned int pool_size_order = get_order(atomic_pool_size);
unsigned long nr_pages = atomic_pool_size >> PAGE_SHIFT;
@@ -117,7 +126,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
page = dma_alloc_from_contiguous(NULL, nr_pages,
pool_size_order, false);
else
- page = alloc_pages(gfp, pool_size_order);
+ page = alloc_pages(dma_atomic_pool_gfp(), pool_size_order);
if (!page)
goto out;
@@ -128,7 +137,8 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
goto free_page;
addr = dma_common_contiguous_remap(page, atomic_pool_size, VM_USERMAP,
- prot, __builtin_return_address(0));
+ pgprot_dmacoherent(PAGE_KERNEL),
+ __builtin_return_address(0));
if (!addr)
goto destroy_genpool;
@@ -155,6 +165,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
atomic_pool_size / 1024);
return -ENOMEM;
}
+postcore_initcall(dma_atomic_pool_init);
bool dma_in_atomic_pool(void *start, size_t size)
{
--
2.20.1
^ permalink raw reply related
* [PATCH 6/6] arm64: document the choice of page attributes for pgprot_dmacoherent
From: Christoph Hellwig @ 2019-08-16 7:07 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190816070754.15653-1-hch@lst.de>
Based on an email from Will Deacon.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/include/asm/pgtable.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6700371227d1..6ff221d9a631 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,14 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+/*
+ * DMA allocations for non-coherent devices use what the Arm architecture calls
+ * "Normal non-cacheable" memory, which permits speculation, unaligned accesses
+ * and merging of writes. This is different from "Strongly Ordered" memory
+ * which is intended for MMIO and thus forbids speculation, preserves access
+ * size, requires strict alignment and also forces write responses to come from
+ * the endpoint.
+ */
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 6/6] driver core: initialize a default DMA mask for platform device
From: Geert Uytterhoeven @ 2019-08-16 7:39 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Gavin Li, Shawn Guo, Fabio Estevam, Linux-Arch, Michal Simek,
Maxime Chevallier, Alan Stern, NXP Linux Team, Mathias Nyman,
Sascha Hauer, linux-m68k, Minas Harutyunyan, Bin Liu, Linux ARM,
Laurentiu Tudor, Geoff Levand, Greg Kroah-Hartman, USB list,
Linux Kernel Mailing List, Linux IOMMU, Pengutronix Kernel Team,
linuxppc-dev
In-Reply-To: <20190816062435.881-7-hch@lst.de>
Hi Christoph,
On Fri, Aug 16, 2019 at 8:30 AM Christoph Hellwig <hch@lst.de> wrote:
> We still treat devices without a DMA mask as defaulting to 32-bits for
> both mask, but a few releases ago we've started warning about such
> cases, as they require special cases to work around this sloppyness.
> Add a dma_mask field to struct platform_device so that we can initialize
> the dma_mask pointer in struct device and initialize both masks to
> 32-bits by default, replacing similar functionality in m68k and
> powerpc. The arch_setup_pdev_archdata hooks is now unused and removed.
>
> Note that the code looks a little odd with the various conditionals
> because we have to support platform_device structures that are
> statically allocated.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> arch/m68k/kernel/dma.c | 9 -------
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
> arch/sh/boards/mach-ecovec24/setup.c | 2 --
> arch/sh/boards/mach-migor/setup.c | 1 -
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
given "[PATCH 0/2] Remove calls to empty arch_setup_pdev_archdata()"
https://lore.kernel.org/linux-renesas-soc/1526641611-2769-1-git-send-email-geert+renesas@glider.be/
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 4/6] dma-mapping: remove arch_dma_mmap_pgprot
From: Geert Uytterhoeven @ 2019-08-16 7:43 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Shawn Anastasio, linux-m68k, Will Deacon, linuxppc-dev,
Linux Kernel Mailing List, Linux IOMMU, Paul Burton,
Catalin Marinas, James Hogan, Russell King, linux-mips,
Guan Xuetao, Linux ARM, Robin Murphy
In-Reply-To: <20190816070754.15653-5-hch@lst.de>
On Fri, Aug 16, 2019 at 9:19 AM Christoph Hellwig <hch@lst.de> wrote:
> arch_dma_mmap_pgprot is used for two things:
>
> 1) to override the "normal" uncached page attributes for mapping
> memory coherent to devices that can't snoop the CPU caches
> 2) to provide the special DMA_ATTR_WRITE_COMBINE semantics on older
> arm systems
>
> Replace one with the pgprot_dmacoherent macro that is already provided
> by arm and much simpler to use, and lift the DMA_ATTR_WRITE_COMBINE
> handling to common code with an explicit arch opt-in.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> arch/m68k/Kconfig | 1 -
> arch/m68k/include/asm/pgtable_mm.h | 3 +++
> arch/m68k/kernel/dma.c | 3 +--
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v4 1/3] kasan: support backing vmalloc space with real shadow memory
From: Christophe Leroy @ 2019-08-16 7:47 UTC (permalink / raw)
To: Daniel Axtens, kasan-dev, linux-mm, x86, aryabinin, glider, luto,
linux-kernel, mark.rutland, dvyukov
Cc: linuxppc-dev, gor
In-Reply-To: <20190815001636.12235-2-dja@axtens.net>
Le 15/08/2019 à 02:16, Daniel Axtens a écrit :
> Hook into vmalloc and vmap, and dynamically allocate real shadow
> memory to back the mappings.
>
> Most mappings in vmalloc space are small, requiring less than a full
> page of shadow space. Allocating a full shadow page per mapping would
> therefore be wasteful. Furthermore, to ensure that different mappings
> use different shadow pages, mappings would have to be aligned to
> KASAN_SHADOW_SCALE_SIZE * PAGE_SIZE.
>
> Instead, share backing space across multiple mappings. Allocate
> a backing page the first time a mapping in vmalloc space uses a
> particular page of the shadow region. Keep this page around
> regardless of whether the mapping is later freed - in the mean time
> the page could have become shared by another vmalloc mapping.
>
> This can in theory lead to unbounded memory growth, but the vmalloc
> allocator is pretty good at reusing addresses, so the practical memory
> usage grows at first but then stays fairly stable.
I guess people having gigabytes of memory don't mind, but I'm concerned
about tiny targets with very little amount of memory. I have boards with
as little as 32Mbytes of RAM. The shadow region for the linear space
already takes one eighth of the RAM. I'd rather avoid keeping unused
shadow pages busy.
Each page of shadow memory represent 8 pages of real memory. Could we
use page_ref to count how many pieces of a shadow page are used so that
we can free it when the ref count decreases to 0.
>
> This requires architecture support to actually use: arches must stop
> mapping the read-only zero page over portion of the shadow region that
> covers the vmalloc space and instead leave it unmapped.
Why 'must' ? Couldn't we switch back and forth from the zero page to
real page on demand ?
If the zero page is not mapped for unused vmalloc space, bad memory
accesses will Oops on the shadow memory access instead of Oopsing on the
real bad access, making it more difficult to locate and identify the issue.
>
> This allows KASAN with VMAP_STACK, and will be needed for architectures
> that do not have a separate module space (e.g. powerpc64, which I am
> currently working on). It also allows relaxing the module alignment
> back to PAGE_SIZE.
Why 'needed' ? powerpc32 doesn't have a separate module space and
doesn't need that.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=202009
> Acked-by: Vasily Gorbik <gor@linux.ibm.com>
> Signed-off-by: Daniel Axtens <dja@axtens.net>
> [Mark: rework shadow allocation]
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
>
> --
>
> v2: let kasan_unpoison_shadow deal with ranges that do not use a
> full shadow byte.
>
> v3: relax module alignment
> rename to kasan_populate_vmalloc which is a much better name
> deal with concurrency correctly
>
> v4: Integrate Mark's rework
> Poision pages on vfree
> Handle allocation failures. I've tested this by inserting artificial
> failures and using test_vmalloc to stress it. I haven't handled the
> per-cpu case: it looked like it would require a messy hacking-up of
> the function to deal with an OOM failure case in a debug feature.
>
> ---
> Documentation/dev-tools/kasan.rst | 60 +++++++++++++++++++++++++++
> include/linux/kasan.h | 24 +++++++++++
> include/linux/moduleloader.h | 2 +-
> include/linux/vmalloc.h | 12 ++++++
> lib/Kconfig.kasan | 16 ++++++++
> lib/test_kasan.c | 26 ++++++++++++
> mm/kasan/common.c | 67 +++++++++++++++++++++++++++++++
> mm/kasan/generic_report.c | 3 ++
> mm/kasan/kasan.h | 1 +
> mm/vmalloc.c | 28 ++++++++++++-
> 10 files changed, 237 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
> index b72d07d70239..35fda484a672 100644
> --- a/Documentation/dev-tools/kasan.rst
> +++ b/Documentation/dev-tools/kasan.rst
> @@ -215,3 +215,63 @@ brk handler is used to print bug reports.
> A potential expansion of this mode is a hardware tag-based mode, which would
> use hardware memory tagging support instead of compiler instrumentation and
> manual shadow memory manipulation.
> +
> +What memory accesses are sanitised by KASAN?
> +--------------------------------------------
> +
> +The kernel maps memory in a number of different parts of the address
> +space. This poses something of a problem for KASAN, which requires
> +that all addresses accessed by instrumented code have a valid shadow
> +region.
> +
> +The range of kernel virtual addresses is large: there is not enough
> +real memory to support a real shadow region for every address that
> +could be accessed by the kernel.
> +
> +By default
> +~~~~~~~~~~
> +
> +By default, architectures only map real memory over the shadow region
> +for the linear mapping (and potentially other small areas). For all
> +other areas - such as vmalloc and vmemmap space - a single read-only
> +page is mapped over the shadow area. This read-only shadow page
> +declares all memory accesses as permitted.
> +
> +This presents a problem for modules: they do not live in the linear
> +mapping, but in a dedicated module space. By hooking in to the module
> +allocator, KASAN can temporarily map real shadow memory to cover
> +them. This allows detection of invalid accesses to module globals, for
> +example.
> +
> +This also creates an incompatibility with ``VMAP_STACK``: if the stack
> +lives in vmalloc space, it will be shadowed by the read-only page, and
> +the kernel will fault when trying to set up the shadow data for stack
> +variables.
> +
> +CONFIG_KASAN_VMALLOC
> +~~~~~~~~~~~~~~~~~~~~
> +
> +With ``CONFIG_KASAN_VMALLOC``, KASAN can cover vmalloc space at the
> +cost of greater memory usage. Currently this is only supported on x86.
> +
> +This works by hooking into vmalloc and vmap, and dynamically
> +allocating real shadow memory to back the mappings.
> +
> +Most mappings in vmalloc space are small, requiring less than a full
> +page of shadow space. Allocating a full shadow page per mapping would
> +therefore be wasteful. Furthermore, to ensure that different mappings
> +use different shadow pages, mappings would have to be aligned to
> +``KASAN_SHADOW_SCALE_SIZE * PAGE_SIZE``.
> +
> +Instead, we share backing space across multiple mappings. We allocate
> +a backing page the first time a mapping in vmalloc space uses a
> +particular page of the shadow region. We keep this page around
> +regardless of whether the mapping is later freed - in the mean time
> +this page could have become shared by another vmalloc mapping.
> +
> +This can in theory lead to unbounded memory growth, but the vmalloc
> +allocator is pretty good at reusing addresses, so the practical memory
> +usage grows at first but then stays fairly stable.
> +
> +This allows ``VMAP_STACK`` support on x86, and enables support of
> +architectures that do not have a fixed module region.
That's wrong, powerpc32 doesn't have a fixed module region and is
already supported.
> diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> index cc8a03cc9674..d666748cd378 100644
> --- a/include/linux/kasan.h
> +++ b/include/linux/kasan.h
> @@ -70,8 +70,18 @@ struct kasan_cache {
> int free_meta_offset;
> };
>
> +/*
> + * These functions provide a special case to support backing module
> + * allocations with real shadow memory. With KASAN vmalloc, the special
> + * case is unnecessary, as the work is handled in the generic case.
> + */
> +#ifndef CONFIG_KASAN_VMALLOC
> int kasan_module_alloc(void *addr, size_t size);
> void kasan_free_shadow(const struct vm_struct *vm);
> +#else
> +static inline int kasan_module_alloc(void *addr, size_t size) { return 0; }
> +static inline void kasan_free_shadow(const struct vm_struct *vm) {}
> +#endif
>
> int kasan_add_zero_shadow(void *start, unsigned long size);
> void kasan_remove_zero_shadow(void *start, unsigned long size);
> @@ -194,4 +204,18 @@ static inline void *kasan_reset_tag(const void *addr)
>
> #endif /* CONFIG_KASAN_SW_TAGS */
>
> +#ifdef CONFIG_KASAN_VMALLOC
> +int kasan_populate_vmalloc(unsigned long requested_size,
> + struct vm_struct *area);
> +void kasan_free_vmalloc(void *start, unsigned long size);
> +#else
> +static inline int kasan_populate_vmalloc(unsigned long requested_size,
> + struct vm_struct *area)
> +{
> + return 0;
> +}
> +
> +static inline void kasan_free_vmalloc(void *start, unsigned long size) {}
> +#endif
> +
> #endif /* LINUX_KASAN_H */
> diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h
> index 5229c18025e9..ca92aea8a6bd 100644
> --- a/include/linux/moduleloader.h
> +++ b/include/linux/moduleloader.h
> @@ -91,7 +91,7 @@ void module_arch_cleanup(struct module *mod);
> /* Any cleanup before freeing mod->module_init */
> void module_arch_freeing_init(struct module *mod);
>
> -#ifdef CONFIG_KASAN
> +#if defined(CONFIG_KASAN) && !defined(CONFIG_KASAN_VMALLOC)
> #include <linux/kasan.h>
> #define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> #else
> diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
> index 9b21d0047710..cdc7a60f7d81 100644
> --- a/include/linux/vmalloc.h
> +++ b/include/linux/vmalloc.h
> @@ -21,6 +21,18 @@ struct notifier_block; /* in notifier.h */
> #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */
> #define VM_NO_GUARD 0x00000040 /* don't add guard page */
> #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */
> +
> +/*
> + * VM_KASAN is used slighly differently depending on CONFIG_KASAN_VMALLOC.
> + *
> + * If IS_ENABLED(CONFIG_KASAN_VMALLOC), VM_KASAN is set on a vm_struct after
> + * shadow memory has been mapped. It's used to handle allocation errors so that
> + * we don't try to poision shadow on free if it was never allocated.
> + *
> + * Otherwise, VM_KASAN is set for kasan_module_alloc() allocations and used to
> + * determine which allocations need the module shadow freed.
> + */
> +
> /*
> * Memory with VM_FLUSH_RESET_PERMS cannot be freed in an interrupt or with
> * vfree_atomic().
> diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
> index 4fafba1a923b..a320dc2e9317 100644
> --- a/lib/Kconfig.kasan
> +++ b/lib/Kconfig.kasan
> @@ -6,6 +6,9 @@ config HAVE_ARCH_KASAN
> config HAVE_ARCH_KASAN_SW_TAGS
> bool
>
> +config HAVE_ARCH_KASAN_VMALLOC
> + bool
> +
> config CC_HAS_KASAN_GENERIC
> def_bool $(cc-option, -fsanitize=kernel-address)
>
> @@ -135,6 +138,19 @@ config KASAN_S390_4_LEVEL_PAGING
> to 3TB of RAM with KASan enabled). This options allows to force
> 4-level paging instead.
>
> +config KASAN_VMALLOC
> + bool "Back mappings in vmalloc space with real shadow memory"
> + depends on KASAN && HAVE_ARCH_KASAN_VMALLOC
> + help
> + By default, the shadow region for vmalloc space is the read-only
> + zero page. This means that KASAN cannot detect errors involving
> + vmalloc space.
> +
> + Enabling this option will hook in to vmap/vmalloc and back those
> + mappings with real shadow memory allocated on demand. This allows
> + for KASAN to detect more sorts of errors (and to support vmapped
> + stacks), but at the cost of higher memory usage.
> +
> config TEST_KASAN
> tristate "Module for testing KASAN for bug detection"
> depends on m && KASAN
> diff --git a/lib/test_kasan.c b/lib/test_kasan.c
> index b63b367a94e8..d375246f5f96 100644
> --- a/lib/test_kasan.c
> +++ b/lib/test_kasan.c
Could we put the testing part in a separate patch ?
> @@ -18,6 +18,7 @@
> #include <linux/slab.h>
> #include <linux/string.h>
> #include <linux/uaccess.h>
> +#include <linux/vmalloc.h>
>
> /*
> * Note: test functions are marked noinline so that their names appear in
> @@ -709,6 +710,30 @@ static noinline void __init kmalloc_double_kzfree(void)
> kzfree(ptr);
> }
>
> +#ifdef CONFIG_KASAN_VMALLOC
> +static noinline void __init vmalloc_oob(void)
> +{
> + void *area;
> +
> + pr_info("vmalloc out-of-bounds\n");
> +
> + /*
> + * We have to be careful not to hit the guard page.
> + * The MMU will catch that and crash us.
> + */
> + area = vmalloc(3000);
> + if (!area) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + ((volatile char *)area)[3100];
> + vfree(area);
> +}
> +#else
> +static void __init vmalloc_oob(void) {}
> +#endif
> +
> static int __init kmalloc_tests_init(void)
> {
> /*
> @@ -752,6 +777,7 @@ static int __init kmalloc_tests_init(void)
> kasan_strings();
> kasan_bitops();
> kmalloc_double_kzfree();
> + vmalloc_oob();
>
> kasan_restore_multi_shot(multishot);
>
> diff --git a/mm/kasan/common.c b/mm/kasan/common.c
> index 2277b82902d8..b8374e3773cf 100644
> --- a/mm/kasan/common.c
> +++ b/mm/kasan/common.c
> @@ -568,6 +568,7 @@ void kasan_kfree_large(void *ptr, unsigned long ip)
> /* The object will be poisoned by page_alloc. */
> }
>
> +#ifndef CONFIG_KASAN_VMALLOC
> int kasan_module_alloc(void *addr, size_t size)
> {
> void *ret;
> @@ -603,6 +604,7 @@ void kasan_free_shadow(const struct vm_struct *vm)
> if (vm->flags & VM_KASAN)
> vfree(kasan_mem_to_shadow(vm->addr));
> }
> +#endif
>
> extern void __kasan_report(unsigned long addr, size_t size, bool is_write, unsigned long ip);
>
> @@ -722,3 +724,68 @@ static int __init kasan_memhotplug_init(void)
>
> core_initcall(kasan_memhotplug_init);
> #endif
> +
> +#ifdef CONFIG_KASAN_VMALLOC
> +static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
> + void *unused)
> +{
> + unsigned long page;
> + pte_t pte;
> +
> + if (likely(!pte_none(*ptep)))
> + return 0;
Prior to this, the zero shadow area should be mapped, and the test
should be:
if (likely(pte_pfn(*ptep) != PHYS_PFN(__pa(kasan_early_shadow_page))))
return 0;
> +
> + page = __get_free_page(GFP_KERNEL);
> + if (!page)
> + return -ENOMEM;
> +
> + memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE);
> + pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL);
> +
> + /*
> + * Ensure poisoning is visible before the shadow is made visible
> + * to other CPUs.
> + */
> + smp_wmb();
> +
> + spin_lock(&init_mm.page_table_lock);
> + if (likely(pte_none(*ptep))) {
> + set_pte_at(&init_mm, addr, ptep, pte);
> + page = 0;
> + }
> + spin_unlock(&init_mm.page_table_lock);
> + if (page)
> + free_page(page);
> + return 0;
> +}
> +
> +int kasan_populate_vmalloc(unsigned long requested_size, struct vm_struct *area)
> +{
> + unsigned long shadow_start, shadow_end;
> + int ret;
> +
> + shadow_start = (unsigned long)kasan_mem_to_shadow(area->addr);
> + shadow_start = ALIGN_DOWN(shadow_start, PAGE_SIZE);
> + shadow_end = (unsigned long)kasan_mem_to_shadow(
> + area->addr + area->size);
> + shadow_end = ALIGN(shadow_end, PAGE_SIZE);
> +
> + ret = apply_to_page_range(&init_mm, shadow_start,
> + shadow_end - shadow_start,
> + kasan_populate_vmalloc_pte, NULL);
> + if (ret)
> + return ret;
> +
> + kasan_unpoison_shadow(area->addr, requested_size);
> +
> + area->flags |= VM_KASAN;
> +
> + return 0;
> +}
> +
> +void kasan_free_vmalloc(void *start, unsigned long size)
> +{
> + size = round_up(size, KASAN_SHADOW_SCALE_SIZE);
> + kasan_poison_shadow(start, size, KASAN_VMALLOC_INVALID);
> +}
> +#endif
> diff --git a/mm/kasan/generic_report.c b/mm/kasan/generic_report.c
> index 36c645939bc9..2d97efd4954f 100644
> --- a/mm/kasan/generic_report.c
> +++ b/mm/kasan/generic_report.c
> @@ -86,6 +86,9 @@ static const char *get_shadow_bug_type(struct kasan_access_info *info)
> case KASAN_ALLOCA_RIGHT:
> bug_type = "alloca-out-of-bounds";
> break;
> + case KASAN_VMALLOC_INVALID:
> + bug_type = "vmalloc-out-of-bounds";
> + break;
> }
>
> return bug_type;
> diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
> index 014f19e76247..8b1f2fbc780b 100644
> --- a/mm/kasan/kasan.h
> +++ b/mm/kasan/kasan.h
> @@ -25,6 +25,7 @@
> #endif
>
> #define KASAN_GLOBAL_REDZONE 0xFA /* redzone for global variable */
> +#define KASAN_VMALLOC_INVALID 0xF9 /* unallocated space in vmapped page */
>
> /*
> * Stack redzone shadow values
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 4fa8d84599b0..c20a7e663004 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -2056,6 +2056,22 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
>
> setup_vmalloc_vm(area, va, flags, caller);
>
> + /*
> + * For KASAN, if we are in vmalloc space, we need to cover the shadow
> + * area with real memory. If we come here through VM_ALLOC, this is
> + * done by a higher level function that has access to the true size,
> + * which might not be a full page.
> + *
> + * We assume module space comes via VM_ALLOC path.
> + */
> + if (is_vmalloc_addr(area->addr) && !(area->flags & VM_ALLOC)) {
> + if (kasan_populate_vmalloc(area->size, area)) {
> + unmap_vmap_area(va);
> + kfree(area);
> + return NULL;
> + }
> + }
> +
> return area;
> }
>
> @@ -2233,6 +2249,9 @@ static void __vunmap(const void *addr, int deallocate_pages)
> debug_check_no_locks_freed(area->addr, get_vm_area_size(area));
> debug_check_no_obj_freed(area->addr, get_vm_area_size(area));
>
> + if (area->flags & VM_KASAN)
> + kasan_free_vmalloc(area->addr, area->size);
> +
> vm_remove_mappings(area, deallocate_pages);
>
> if (deallocate_pages) {
> @@ -2483,6 +2502,9 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
> if (!addr)
> return NULL;
>
> + if (kasan_populate_vmalloc(real_size, area))
> + return NULL;
> +
> /*
> * In this function, newly allocated vm_struct has VM_UNINITIALIZED
> * flag. It means that vm_struct is not fully initialized.
> @@ -3324,10 +3346,14 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
> spin_unlock(&vmap_area_lock);
>
> /* insert all vm's */
> - for (area = 0; area < nr_vms; area++)
> + for (area = 0; area < nr_vms; area++) {
> setup_vmalloc_vm(vms[area], vas[area], VM_ALLOC,
> pcpu_get_vm_areas);
>
> + /* assume success here */
> + kasan_populate_vmalloc(sizes[area], vms[area]);
> + }
> +
> kfree(vas);
> return vms;
>
>
Christophe
^ permalink raw reply
* [PATCH] powerpc/32: Add warning on misaligned copy_page() or clear_page()
From: Christophe Leroy @ 2019-08-16 7:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
copy_page() and clear_page() expect page aligned destination, and
use dcbz instruction to clear entire cache lines based on the
assumption that the destination is cache aligned.
As shown during analysis of a bug in BTRFS filesystem, a misaligned
copy_page() can create bugs that are difficult to locate (see Link).
Add an explicit WARNING when copy_page() or clear_page() are called
with misaligned destination.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Erhard F. <erhard_f@mailbox.org>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=204371
---
arch/powerpc/include/asm/page_32.h | 4 ++++
arch/powerpc/kernel/misc_32.S | 5 +++++
2 files changed, 9 insertions(+)
diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h
index 683dfbc67ca8..d64dfe3ac712 100644
--- a/arch/powerpc/include/asm/page_32.h
+++ b/arch/powerpc/include/asm/page_32.h
@@ -40,6 +40,8 @@ typedef unsigned long long pte_basic_t;
typedef unsigned long pte_basic_t;
#endif
+#include <asm/bug.h>
+
/*
* Clear page using the dcbz instruction, which doesn't cause any
* memory traffic (except to write out any cache lines which get
@@ -49,6 +51,8 @@ static inline void clear_page(void *addr)
{
unsigned int i;
+ WARN_ON((unsigned long)addr & (L1_CACHE_BYTES - 1));
+
for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES)
dcbz(addr);
}
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index fe4bd321730e..02d90e1ebf65 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -452,7 +452,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
stwu r9,16(r3)
_GLOBAL(copy_page)
+ rlwinm r5, r3, 0, L1_CACHE_BYTES - 1
addi r3,r3,-4
+
+0: twnei r5, 0 /* WARN if r3 is not cache aligned */
+ EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING
+
addi r4,r4,-4
li r5,4
--
2.13.3
^ permalink raw reply related
* Re: [PATCH v4 3/3] x86/kasan: support KASAN_VMALLOC
From: Christophe Leroy @ 2019-08-16 8:04 UTC (permalink / raw)
To: Daniel Axtens, kasan-dev, linux-mm, x86, aryabinin, glider, luto,
linux-kernel, mark.rutland, dvyukov
Cc: linuxppc-dev, gor
In-Reply-To: <20190815001636.12235-4-dja@axtens.net>
Le 15/08/2019 à 02:16, Daniel Axtens a écrit :
> In the case where KASAN directly allocates memory to back vmalloc
> space, don't map the early shadow page over it.
If early shadow page is not mapped, any bad memory access will Oops on
the shadow access instead of Oopsing on the real bad access.
You should still map early shadow page, and replace it with real page
when needed.
Christophe
>
> We prepopulate pgds/p4ds for the range that would otherwise be empty.
> This is required to get it synced to hardware on boot, allowing the
> lower levels of the page tables to be filled dynamically.
>
> Acked-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Daniel Axtens <dja@axtens.net>
>
> ---
>
> v2: move from faulting in shadow pgds to prepopulating
> ---
> arch/x86/Kconfig | 1 +
> arch/x86/mm/kasan_init_64.c | 61 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 62 insertions(+)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 222855cc0158..40562cc3771f 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -134,6 +134,7 @@ config X86
> select HAVE_ARCH_JUMP_LABEL
> select HAVE_ARCH_JUMP_LABEL_RELATIVE
> select HAVE_ARCH_KASAN if X86_64
> + select HAVE_ARCH_KASAN_VMALLOC if X86_64
> select HAVE_ARCH_KGDB
> select HAVE_ARCH_MMAP_RND_BITS if MMU
> select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT
> diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
> index 296da58f3013..2f57c4ddff61 100644
> --- a/arch/x86/mm/kasan_init_64.c
> +++ b/arch/x86/mm/kasan_init_64.c
> @@ -245,6 +245,52 @@ static void __init kasan_map_early_shadow(pgd_t *pgd)
> } while (pgd++, addr = next, addr != end);
> }
>
> +static void __init kasan_shallow_populate_p4ds(pgd_t *pgd,
> + unsigned long addr,
> + unsigned long end,
> + int nid)
> +{
> + p4d_t *p4d;
> + unsigned long next;
> + void *p;
> +
> + p4d = p4d_offset(pgd, addr);
> + do {
> + next = p4d_addr_end(addr, end);
> +
> + if (p4d_none(*p4d)) {
> + p = early_alloc(PAGE_SIZE, nid, true);
> + p4d_populate(&init_mm, p4d, p);
> + }
> + } while (p4d++, addr = next, addr != end);
> +}
> +
> +static void __init kasan_shallow_populate_pgds(void *start, void *end)
> +{
> + unsigned long addr, next;
> + pgd_t *pgd;
> + void *p;
> + int nid = early_pfn_to_nid((unsigned long)start);
> +
> + addr = (unsigned long)start;
> + pgd = pgd_offset_k(addr);
> + do {
> + next = pgd_addr_end(addr, (unsigned long)end);
> +
> + if (pgd_none(*pgd)) {
> + p = early_alloc(PAGE_SIZE, nid, true);
> + pgd_populate(&init_mm, pgd, p);
> + }
> +
> + /*
> + * we need to populate p4ds to be synced when running in
> + * four level mode - see sync_global_pgds_l4()
> + */
> + kasan_shallow_populate_p4ds(pgd, addr, next, nid);
> + } while (pgd++, addr = next, addr != (unsigned long)end);
> +}
> +
> +
> #ifdef CONFIG_KASAN_INLINE
> static int kasan_die_handler(struct notifier_block *self,
> unsigned long val,
> @@ -352,9 +398,24 @@ void __init kasan_init(void)
> shadow_cpu_entry_end = (void *)round_up(
> (unsigned long)shadow_cpu_entry_end, PAGE_SIZE);
>
> + /*
> + * If we're in full vmalloc mode, don't back vmalloc space with early
> + * shadow pages. Instead, prepopulate pgds/p4ds so they are synced to
> + * the global table and we can populate the lower levels on demand.
> + */
> +#ifdef CONFIG_KASAN_VMALLOC
> + kasan_shallow_populate_pgds(
> + kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
> + kasan_mem_to_shadow((void *)VMALLOC_END));
> +
> + kasan_populate_early_shadow(
> + kasan_mem_to_shadow((void *)VMALLOC_END + 1),
> + shadow_cpu_entry_begin);
> +#else
> kasan_populate_early_shadow(
> kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
> shadow_cpu_entry_begin);
> +#endif
>
> kasan_populate_shadow((unsigned long)shadow_cpu_entry_begin,
> (unsigned long)shadow_cpu_entry_end, 0);
>
^ permalink raw reply
* [Bug 204371] BUG kmalloc-4k (Tainted: G W ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-16 8:22 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204371
--- Comment #32 from Christophe Leroy (christophe.leroy@c-s.fr) ---
I think first thing is to fix test_add_free_space_entry() :
- replace the map = kzalloc(...) by map = (void *)get_zeroed_page(...) like in
other places.
- replace the kfree(map); by free_page((unsigned long)map);
Then see if the WARNING on kfree() in btrfs_free_dummy_fs_info() is still
there.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ 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