* Re: image/wrapper script questions
From: Wolfgang Denk @ 2009-07-27 18:31 UTC (permalink / raw)
To: Eddie Dawydiuk; +Cc: linuxppc-dev
In-Reply-To: <4A6DDF80.209@embeddedarm.com>
Dear Eddie Dawydiuk,
In message <4A6DDF80.209@embeddedarm.com> you wrote:
>
> I'm working on a custom board using an AMCC 440EP that is using a proprietary
> bootloader(optimized for fast boot time). Currently our bootloader loads a
> simpleImage.initrd into RAM and jumps into it. I originally chose to use a
> simpleImage with an initial ramdisk embedded because it was the simplest
> solution to debug the hardware and get a kernel and initial ramdisk running for
> development. For production I would prefer to put the initial ramdisk on it's
Hm... isn't that an oxymoron? Trying to optimize for speed on one
hand, and using an initrd which is one of the slowest ways to boot on
the other hand?
> Thanks for any suggestions :)
Use another file system (and another fstype) and separate it from the
kernel image.
See also http://www.denx.de/wiki/view/DULG/RootFileSystemSelection
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Computers are not intelligent. They only think they are.
^ permalink raw reply
* anyone know of a patch to support mcpn905/cpci6115 on recent-ish kernels?
From: Chris Friesen @ 2009-07-27 18:43 UTC (permalink / raw)
To: linuxppc-dev
We've got some people that are currently running an older linux kernel
(from before the ppc/ppc64 merge and the conversion to device tree) on
an Emerson/Motorola cpci6115 (also known as mcpn905) compactPCI board.
They're wondering if it's possible to upgrade to a more recent kernel.
I don't see support for these boards in mainline, but is anyone aware of
patches adding support for more recent kernels?
Barring that, are there any tutorials out there on how to build a dts
file from scratch? I think we've got the hardware specs, and we've got
a running earlier kernel.
Thanks,
Chris
^ permalink raw reply
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
From: Linus Torvalds @ 2009-07-27 19:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Nick Piggin, Linux-Arch, linuxppc-dev, Hugh Dickins, linux-kernel,
Linux Memory Management
In-Reply-To: <1248310415.3367.22.camel@pasglop>
On Thu, 23 Jul 2009, Benjamin Herrenschmidt wrote:
>
> Hrm... my powerpc-next branch will contain stuff that depend on it, so
> I'll probably have to pull it in though, unless I tell all my
> sub-maintainers to also pull from that other branch first :-)
Ok, I'll just apply the patch. It does look obvious enough.
Linus
^ permalink raw reply
* Re: image/wrapper script questions
From: Eddie Dawydiuk @ 2009-07-27 20:15 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-dev
In-Reply-To: <20090727183155.7FA16832E416@gemini.denx.de>
Wolfgang,
> In message <4A6DDF80.209@embeddedarm.com> you wrote:
>> I'm working on a custom board using an AMCC 440EP that is using a proprietary
>> bootloader(optimized for fast boot time). Currently our bootloader loads a
>> simpleImage.initrd into RAM and jumps into it. I originally chose to use a
>> simpleImage with an initial ramdisk embedded because it was the simplest
>> solution to debug the hardware and get a kernel and initial ramdisk running for
>> development. For production I would prefer to put the initial ramdisk on it's
>
> Hm... isn't that an oxymoron? Trying to optimize for speed on one
> hand, and using an initrd which is one of the slowest ways to boot on
> the other hand?
We advertise the amount of time from a cold boot until one is sitting at a
command prompt(< 2 s). A Debian filesystem(from Nand or SD card) is then mounted
in the background. This gives one the power of Debian in a very short amount of
time. From a technical stand point we have to use an initial ramdisk as we are a
member of the SD association so we signed an NDA agreeing not to release any
details of the SD spec. As a result we have code we can't release under the GPL
so we have to load a proprietary SD card driver as a module.
I guess it depends upon how you define boot, that is we define it as how long it
takes to get to a Linux shell prompt :) Even without the licensing issue I'm not
sure we could boot faster(by the definition above) via some other method. All of
the products I've seen that advertise a fast Linux boot time, boot to an initial
ramdisk.
http://www.mvista.com/press_release_detail.php?fid=news/2009/Ultra-fast-boot.html
>> Thanks for any suggestions :)
>
> Use another file system (and another fstype) and separate it from the
> kernel image.
>
> See also http://www.denx.de/wiki/view/DULG/RootFileSystemSelection
Thanks for the link. Although, I'm not looking for info on optimizing boot time.
Rather I'm looking for information on what the path of least resistance is to
boot a kernel with an initrd being loaded from it's own partition. To clarify
currently I am using a simpleImage.initrd which is a single image with the
flattened device tree, kernel, and initial ramdisk in a single file. One can
simply load this image in RAM(assuming 1 to 1 MMU mapping) and jump into it. Now
what I would like to do is to load a kernel, device tree, and initial ramdisk
into RAM at different locations.
I'm in the process of coming back up to speed on the low-level boot details of
the powerpc kernel/architecture. It looks like one can accomplish this by
loading R3 with the phys address of the device tree block, R4 with the phys
address of the kernel, and R5 with Null. It also looks like the kernel, already
has several routines which know about these details(prom_init() and __start())
and I was hoping I could reuse this code to accomplish this rather than
rewriting the bootrom to handle this. That is I was hoping there is a boot
wrapper image that would allow me to accomplish my goal of creating a single
image containing a kernel and device tree block, and an interface to specify
where the bootrom loads the initial ramdisk in RAM. I'll continue reading
through the docs and code, but if anyone could provide any pointers on how to do
this I would really appreciate it.
--
Best Regards,
________________________________________________________________
Eddie Dawydiuk, Technologic Systems | voice: (480) 837-5200
16525 East Laser Drive | fax: (480) 837-5300
Fountain Hills, AZ 85268 | web: www.embeddedARM.com
^ permalink raw reply
* Re: [PATCH 1/5] powerpc: remove addr_needs_map in struct dma_mapping_ops
From: Becky Bruce @ 2009-07-27 21:02 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1248405855-15546-2-git-send-email-fujita.tomonori@lab.ntt.co.jp>
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote:
> This patch adds max_direct_dma_addr to struct dev_archdata to remove
> addr_needs_map in struct dma_mapping_ops. It also converts
> dma_capable() to use max_direct_dma_addr.
>
> max_direct_dma_addr is initialized in pci_dma_dev_setup_swiotlb(),
> called via ppc_md.pci_dma_dev_setup hook.
>
> For further information:
> http://marc.info/?t=124719060200001&r=1&w=2
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Becky Bruce <beckyb@kernel.crashing.org>
>
> ---
> arch/powerpc/include/asm/device.h | 3 ++
> arch/powerpc/include/asm/dma-mapping.h | 8 +++---
> arch/powerpc/include/asm/swiotlb.h | 5 +--
> arch/powerpc/kernel/dma-swiotlb.c | 36 ++++++++++
> +----------------
> arch/powerpc/platforms/85xx/mpc8536_ds.c | 1 +
> arch/powerpc/platforms/85xx/mpc85xx_ds.c | 1 +
> arch/powerpc/platforms/85xx/mpc85xx_mds.c | 1 +
> arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 1 +
> 8 files changed, 28 insertions(+), 28 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/
> include/asm/device.h
> index 7d2277c..0086f8d 100644
> --- a/arch/powerpc/include/asm/device.h
> +++ b/arch/powerpc/include/asm/device.h
> @@ -16,6 +16,9 @@ struct dev_archdata {
> /* DMA operations on that device */
> struct dma_mapping_ops *dma_ops;
> void *dma_data;
> +#ifdef CONFIG_SWIOTLB
> + dma_addr_t max_direct_dma_addr;
> +#endif
> };
>
> static inline void dev_archdata_set_node(struct dev_archdata *ad,
> diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/
> include/asm/dma-mapping.h
> index 0c34371..1765c37 100644
> --- a/arch/powerpc/include/asm/dma-mapping.h
> +++ b/arch/powerpc/include/asm/dma-mapping.h
> @@ -87,8 +87,6 @@ struct dma_mapping_ops {
> dma_addr_t dma_address, size_t size,
> enum dma_data_direction direction,
> struct dma_attrs *attrs);
> - int (*addr_needs_map)(struct device *dev, dma_addr_t addr,
> - size_t size);
> #ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
> void (*sync_single_range_for_cpu)(struct device *hwdev,
> dma_addr_t dma_handle, unsigned long offset,
> @@ -426,10 +424,12 @@ static inline int dma_mapping_error(struct
> device *dev, dma_addr_t dma_addr)
>
> static inline bool dma_capable(struct device *dev, dma_addr_t addr,
> size_t size)
> {
> - struct dma_mapping_ops *ops = get_dma_ops(dev);
> +#ifdef CONFIG_SWIOTLB
> + struct dev_archdata *sd = &dev->archdata;
>
> - if (ops->addr_needs_map && ops->addr_needs_map(dev, addr, size))
> + if (sd->max_direct_dma_addr && addr + size > sd-
> >max_direct_dma_addr)
> return 0;
> +#endif
>
> if (!dev->dma_mask)
> return 0;
> diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/
> include/asm/swiotlb.h
> index 30891d6..31e0e43 100644
> --- a/arch/powerpc/include/asm/swiotlb.h
> +++ b/arch/powerpc/include/asm/swiotlb.h
> @@ -16,12 +16,11 @@
> extern struct dma_mapping_ops swiotlb_dma_ops;
> extern struct dma_mapping_ops swiotlb_pci_dma_ops;
>
> -int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t,
> - size_t size);
> -
> static inline void dma_mark_clean(void *addr, size_t size) {}
>
> extern unsigned int ppc_swiotlb_enable;
> int __init swiotlb_setup_bus_notifier(void);
>
> +extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev);
> +
> #endif /* __ASM_SWIOTLB_H */
> diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/
> dma-swiotlb.c
> index e8a57de..c9f6a30 100644
> --- a/arch/powerpc/kernel/dma-swiotlb.c
> +++ b/arch/powerpc/kernel/dma-swiotlb.c
> @@ -25,26 +25,6 @@ int swiotlb __read_mostly;
> unsigned int ppc_swiotlb_enable;
>
> /*
> - * Determine if an address is reachable by a pci device, or if we
> must bounce.
> - */
> -static int
> -swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr,
> size_t size)
> -{
> - dma_addr_t max;
> - struct pci_controller *hose;
> - struct pci_dev *pdev = to_pci_dev(hwdev);
> -
> - hose = pci_bus_to_host(pdev->bus);
> - max = hose->dma_window_base_cur + hose->dma_window_size;
> -
> - /* check that we're within mapped pci window space */
> - if ((addr + size > max) | (addr < hose->dma_window_base_cur))
> - return 1;
> -
> - return 0;
> -}
> -
> -/*
> * At the moment, all platforms that use this code only require
> * swiotlb to be used if we're operating on HIGHMEM. Since
> * we don't ever call anything other than map_sg, unmap_sg,
> @@ -73,22 +53,36 @@ struct dma_mapping_ops swiotlb_pci_dma_ops = {
> .dma_supported = swiotlb_dma_supported,
> .map_page = swiotlb_map_page,
> .unmap_page = swiotlb_unmap_page,
> - .addr_needs_map = swiotlb_pci_addr_needs_map,
> .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
> .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
> .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
> .sync_sg_for_device = swiotlb_sync_sg_for_device
> };
>
> +void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
> +{
> + struct pci_controller *hose;
> + struct dev_archdata *sd;
> +
> + hose = pci_bus_to_host(pdev->bus);
> + sd = &pdev->dev.archdata;
> + sd->max_direct_dma_addr =
> + hose->dma_window_base_cur + hose->dma_window_size;
> +}
> +
> static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
> unsigned long action, void *data)
> {
> struct device *dev = data;
> + struct dev_archdata *sd;
>
> /* We are only intereted in device addition */
> if (action != BUS_NOTIFY_ADD_DEVICE)
> return 0;
>
> + sd = &dev->archdata;
> + sd->max_direct_dma_addr = 0;
> +
> /* May need to bounce if the device can't address all of DRAM */
> if (dma_get_mask(dev) < lmb_end_of_DRAM())
> set_dma_ops(dev, &swiotlb_dma_ops);
> diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/
> platforms/85xx/mpc8536_ds.c
> index 055ff41..bf052c0 100644
> --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
> @@ -97,6 +97,7 @@ static void __init mpc8536_ds_setup_arch(void)
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
>
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/
> platforms/85xx/mpc85xx_ds.c
> index 849c0ac..c6f92cc 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> @@ -193,6 +193,7 @@ static void __init mpc85xx_ds_setup_arch(void)
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
>
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/
> powerpc/platforms/85xx/mpc85xx_mds.c
> index 60ed9c0..8b8e5f9 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> @@ -242,6 +242,7 @@ static void __init mpc85xx_mds_setup_arch(void)
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
> }
> diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/
> powerpc/platforms/86xx/mpc86xx_hpcn.c
> index 6632702..8032301 100644
> --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
> +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
> @@ -106,6 +106,7 @@ mpc86xx_hpcn_setup_arch(void)
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
> }
> --
> 1.6.0.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 2/5] powerpc: remove swiotlb_pci_dma_ops
From: Becky Bruce @ 2009-07-27 21:02 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1248405855-15546-3-git-send-email-fujita.tomonori@lab.ntt.co.jp>
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote:
> Now swiotlb_pci_dma_ops is identical to swiotlb_dma_ops; we can use
> swiotlb_dma_ops with any devices. This removes swiotlb_pci_dma_ops.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Becky Bruce <beckyb@kernel.crashing.org>
>
> ---
> arch/powerpc/include/asm/swiotlb.h | 1 -
> arch/powerpc/kernel/dma-swiotlb.c | 14 --------------
> arch/powerpc/platforms/85xx/mpc8536_ds.c | 2 +-
> arch/powerpc/platforms/85xx/mpc85xx_ds.c | 2 +-
> arch/powerpc/platforms/85xx/mpc85xx_mds.c | 2 +-
> arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 2 +-
> 6 files changed, 4 insertions(+), 19 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/
> include/asm/swiotlb.h
> index 31e0e43..21ce0a3 100644
> --- a/arch/powerpc/include/asm/swiotlb.h
> +++ b/arch/powerpc/include/asm/swiotlb.h
> @@ -14,7 +14,6 @@
> #include <linux/swiotlb.h>
>
> extern struct dma_mapping_ops swiotlb_dma_ops;
> -extern struct dma_mapping_ops swiotlb_pci_dma_ops;
>
> static inline void dma_mark_clean(void *addr, size_t size) {}
>
> diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/
> dma-swiotlb.c
> index c9f6a30..ca141e1 100644
> --- a/arch/powerpc/kernel/dma-swiotlb.c
> +++ b/arch/powerpc/kernel/dma-swiotlb.c
> @@ -45,20 +45,6 @@ struct dma_mapping_ops swiotlb_dma_ops = {
> .sync_sg_for_device = swiotlb_sync_sg_for_device
> };
>
> -struct dma_mapping_ops swiotlb_pci_dma_ops = {
> - .alloc_coherent = dma_direct_alloc_coherent,
> - .free_coherent = dma_direct_free_coherent,
> - .map_sg = swiotlb_map_sg_attrs,
> - .unmap_sg = swiotlb_unmap_sg_attrs,
> - .dma_supported = swiotlb_dma_supported,
> - .map_page = swiotlb_map_page,
> - .unmap_page = swiotlb_unmap_page,
> - .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
> - .sync_single_range_for_device =
> swiotlb_sync_single_range_for_device,
> - .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
> - .sync_sg_for_device = swiotlb_sync_sg_for_device
> -};
> -
> void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
> {
> struct pci_controller *hose;
> diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/
> platforms/85xx/mpc8536_ds.c
> index bf052c0..004b7d3 100644
> --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
> @@ -96,7 +96,7 @@ static void __init mpc8536_ds_setup_arch(void)
> #ifdef CONFIG_SWIOTLB
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> - set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + set_pci_dma_ops(&swiotlb_dma_ops);
> ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/
> platforms/85xx/mpc85xx_ds.c
> index c6f92cc..544011a 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> @@ -192,7 +192,7 @@ static void __init mpc85xx_ds_setup_arch(void)
> #ifdef CONFIG_SWIOTLB
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> - set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + set_pci_dma_ops(&swiotlb_dma_ops);
> ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/
> powerpc/platforms/85xx/mpc85xx_mds.c
> index 8b8e5f9..c4961ed 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> @@ -241,7 +241,7 @@ static void __init mpc85xx_mds_setup_arch(void)
> #ifdef CONFIG_SWIOTLB
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> - set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + set_pci_dma_ops(&swiotlb_dma_ops);
> ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
> diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/
> powerpc/platforms/86xx/mpc86xx_hpcn.c
> index 8032301..2aa69a6 100644
> --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
> +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
> @@ -105,7 +105,7 @@ mpc86xx_hpcn_setup_arch(void)
> #ifdef CONFIG_SWIOTLB
> if (lmb_end_of_DRAM() > max) {
> ppc_swiotlb_enable = 1;
> - set_pci_dma_ops(&swiotlb_pci_dma_ops);
> + set_pci_dma_ops(&swiotlb_dma_ops);
> ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
> }
> #endif
> --
> 1.6.0.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 3/5] add set_dma_mask hook to struct dma_map_ops
From: Becky Bruce @ 2009-07-27 21:02 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1248405855-15546-4-git-send-email-fujita.tomonori@lab.ntt.co.jp>
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote:
> POWERPC needs this hook. SPARC could use it too.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Becky Bruce <beckyb@kernel.crashing.org>
>
> ---
> include/linux/dma-mapping.h | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index c0f6c3c..91b7618 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -58,6 +58,7 @@ struct dma_map_ops {
> enum dma_data_direction dir);
> int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
> int (*dma_supported)(struct device *dev, u64 mask);
> + int (*set_dma_mask)(struct device *dev, u64 mask);
> int is_phys;
> };
>
> --
> 1.6.0.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 4/5] powerpc: use dma_map_ops struct
From: Becky Bruce @ 2009-07-27 21:03 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1248405855-15546-5-git-send-email-fujita.tomonori@lab.ntt.co.jp>
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote:
> This converts uses dma_map_ops struct (in include/linux/dma-mapping.h)
> instead of POWERPC homegrown dma_mapping_ops.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Becky Bruce <beckyb@kernel.crashing.org>
>
> ---
> arch/powerpc/include/asm/device.h | 4 +-
> arch/powerpc/include/asm/dma-mapping.h | 84 +++++++
> +-----------------------
> arch/powerpc/include/asm/pci.h | 4 +-
> arch/powerpc/include/asm/swiotlb.h | 2 +-
> arch/powerpc/kernel/dma-iommu.c | 2 +-
> arch/powerpc/kernel/dma-swiotlb.c | 2 +-
> arch/powerpc/kernel/dma.c | 2 +-
> arch/powerpc/kernel/ibmebus.c | 2 +-
> arch/powerpc/kernel/pci-common.c | 6 +-
> arch/powerpc/kernel/vio.c | 2 +-
> arch/powerpc/platforms/cell/iommu.c | 2 +-
> arch/powerpc/platforms/ps3/system-bus.c | 4 +-
> 12 files changed, 37 insertions(+), 79 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/
> include/asm/device.h
> index 0086f8d..67fcd7f 100644
> --- a/arch/powerpc/include/asm/device.h
> +++ b/arch/powerpc/include/asm/device.h
> @@ -6,7 +6,7 @@
> #ifndef _ASM_POWERPC_DEVICE_H
> #define _ASM_POWERPC_DEVICE_H
>
> -struct dma_mapping_ops;
> +struct dma_map_ops;
> struct device_node;
>
> struct dev_archdata {
> @@ -14,7 +14,7 @@ struct dev_archdata {
> struct device_node *of_node;
>
> /* DMA operations on that device */
> - struct dma_mapping_ops *dma_ops;
> + struct dma_map_ops *dma_ops;
> void *dma_data;
> #ifdef CONFIG_SWIOTLB
> dma_addr_t max_direct_dma_addr;
> diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/
> include/asm/dma-mapping.h
> index 1765c37..8ca2b51 100644
> --- a/arch/powerpc/include/asm/dma-mapping.h
> +++ b/arch/powerpc/include/asm/dma-mapping.h
> @@ -64,56 +64,14 @@ static inline unsigned long
> device_to_mask(struct device *dev)
> }
>
> /*
> - * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
> - */
> -struct dma_mapping_ops {
> - void * (*alloc_coherent)(struct device *dev, size_t size,
> - dma_addr_t *dma_handle, gfp_t flag);
> - void (*free_coherent)(struct device *dev, size_t size,
> - void *vaddr, dma_addr_t dma_handle);
> - int (*map_sg)(struct device *dev, struct scatterlist *sg,
> - int nents, enum dma_data_direction direction,
> - struct dma_attrs *attrs);
> - void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
> - int nents, enum dma_data_direction direction,
> - struct dma_attrs *attrs);
> - int (*dma_supported)(struct device *dev, u64 mask);
> - int (*set_dma_mask)(struct device *dev, u64 dma_mask);
> - dma_addr_t (*map_page)(struct device *dev, struct page *page,
> - unsigned long offset, size_t size,
> - enum dma_data_direction direction,
> - struct dma_attrs *attrs);
> - void (*unmap_page)(struct device *dev,
> - dma_addr_t dma_address, size_t size,
> - enum dma_data_direction direction,
> - struct dma_attrs *attrs);
> -#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
> - void (*sync_single_range_for_cpu)(struct device *hwdev,
> - dma_addr_t dma_handle, unsigned long offset,
> - size_t size,
> - enum dma_data_direction direction);
> - void (*sync_single_range_for_device)(struct device
> *hwdev,
> - dma_addr_t dma_handle, unsigned long offset,
> - size_t size,
> - enum dma_data_direction direction);
> - void (*sync_sg_for_cpu)(struct device *hwdev,
> - struct scatterlist *sg, int nelems,
> - enum dma_data_direction direction);
> - void (*sync_sg_for_device)(struct device *hwdev,
> - struct scatterlist *sg, int nelems,
> - enum dma_data_direction direction);
> -#endif
> -};
> -
> -/*
> * Available generic sets of operations
> */
> #ifdef CONFIG_PPC64
> -extern struct dma_mapping_ops dma_iommu_ops;
> +extern struct dma_map_ops dma_iommu_ops;
> #endif
> -extern struct dma_mapping_ops dma_direct_ops;
> +extern struct dma_map_ops dma_direct_ops;
>
> -static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
> +static inline struct dma_map_ops *get_dma_ops(struct device *dev)
> {
> /* We don't handle the NULL dev case for ISA for now. We could
> * do it via an out of line call but it is not needed for now. The
> @@ -126,14 +84,14 @@ static inline struct dma_mapping_ops
> *get_dma_ops(struct device *dev)
> return dev->archdata.dma_ops;
> }
>
> -static inline void set_dma_ops(struct device *dev, struct
> dma_mapping_ops *ops)
> +static inline void set_dma_ops(struct device *dev, struct
> dma_map_ops *ops)
> {
> dev->archdata.dma_ops = ops;
> }
>
> static inline int dma_supported(struct device *dev, u64 mask)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> if (unlikely(dma_ops == NULL))
> return 0;
> @@ -147,7 +105,7 @@ static inline int dma_supported(struct device
> *dev, u64 mask)
>
> static inline int dma_set_mask(struct device *dev, u64 dma_mask)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> if (unlikely(dma_ops == NULL))
> return -EIO;
> @@ -161,7 +119,7 @@ static inline int dma_set_mask(struct device
> *dev, u64 dma_mask)
>
> /*
> * map_/unmap_single actually call through to map/unmap_page now
> that all the
> - * dma_mapping_ops have been converted over. We just have to get
> the page and
> + * dma_map_ops have been converted over. We just have to get the
> page and
> * offset to pass through to map_page
> */
> static inline dma_addr_t dma_map_single_attrs(struct device *dev,
> @@ -170,7 +128,7 @@ static inline dma_addr_t
> dma_map_single_attrs(struct device *dev,
> enum dma_data_direction direction,
> struct dma_attrs *attrs)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -185,7 +143,7 @@ static inline void dma_unmap_single_attrs(struct
> device *dev,
> enum dma_data_direction direction,
> struct dma_attrs *attrs)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -198,7 +156,7 @@ static inline dma_addr_t
> dma_map_page_attrs(struct device *dev,
> enum dma_data_direction direction,
> struct dma_attrs *attrs)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -211,7 +169,7 @@ static inline void dma_unmap_page_attrs(struct
> device *dev,
> enum dma_data_direction direction,
> struct dma_attrs *attrs)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -222,7 +180,7 @@ static inline int dma_map_sg_attrs(struct device
> *dev, struct scatterlist *sg,
> int nents, enum dma_data_direction direction,
> struct dma_attrs *attrs)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
> return dma_ops->map_sg(dev, sg, nents, direction, attrs);
> @@ -234,7 +192,7 @@ static inline void dma_unmap_sg_attrs(struct
> device *dev,
> enum dma_data_direction direction,
> struct dma_attrs *attrs)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
> dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs);
> @@ -243,7 +201,7 @@ static inline void dma_unmap_sg_attrs(struct
> device *dev,
> static inline void *dma_alloc_coherent(struct device *dev, size_t
> size,
> dma_addr_t *dma_handle, gfp_t flag)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
> return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
> @@ -252,7 +210,7 @@ static inline void *dma_alloc_coherent(struct
> device *dev, size_t size,
> static inline void dma_free_coherent(struct device *dev, size_t size,
> void *cpu_addr, dma_addr_t dma_handle)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
> dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
> @@ -304,7 +262,7 @@ static inline void
> dma_sync_single_for_cpu(struct device *dev,
> dma_addr_t dma_handle, size_t size,
> enum dma_data_direction direction)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -317,7 +275,7 @@ static inline void
> dma_sync_single_for_device(struct device *dev,
> dma_addr_t dma_handle, size_t size,
> enum dma_data_direction direction)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -330,7 +288,7 @@ static inline void dma_sync_sg_for_cpu(struct
> device *dev,
> struct scatterlist *sgl, int nents,
> enum dma_data_direction direction)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -342,7 +300,7 @@ static inline void dma_sync_sg_for_device(struct
> device *dev,
> struct scatterlist *sgl, int nents,
> enum dma_data_direction direction)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -354,7 +312,7 @@ static inline void
> dma_sync_single_range_for_cpu(struct device *dev,
> dma_addr_t dma_handle, unsigned long offset, size_t size,
> enum dma_data_direction direction)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> @@ -367,7 +325,7 @@ static inline void
> dma_sync_single_range_for_device(struct device *dev,
> dma_addr_t dma_handle, unsigned long offset, size_t size,
> enum dma_data_direction direction)
> {
> - struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> + struct dma_map_ops *dma_ops = get_dma_ops(dev);
>
> BUG_ON(!dma_ops);
>
> diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/
> asm/pci.h
> index d9483c5..7ae46d7 100644
> --- a/arch/powerpc/include/asm/pci.h
> +++ b/arch/powerpc/include/asm/pci.h
> @@ -61,8 +61,8 @@ static inline int pci_get_legacy_ide_irq(struct
> pci_dev *dev, int channel)
> }
>
> #ifdef CONFIG_PCI
> -extern void set_pci_dma_ops(struct dma_mapping_ops *dma_ops);
> -extern struct dma_mapping_ops *get_pci_dma_ops(void);
> +extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
> +extern struct dma_map_ops *get_pci_dma_ops(void);
> #else /* CONFIG_PCI */
> #define set_pci_dma_ops(d)
> #define get_pci_dma_ops() NULL
> diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/
> include/asm/swiotlb.h
> index 21ce0a3..8979d4c 100644
> --- a/arch/powerpc/include/asm/swiotlb.h
> +++ b/arch/powerpc/include/asm/swiotlb.h
> @@ -13,7 +13,7 @@
>
> #include <linux/swiotlb.h>
>
> -extern struct dma_mapping_ops swiotlb_dma_ops;
> +extern struct dma_map_ops swiotlb_dma_ops;
>
> static inline void dma_mark_clean(void *addr, size_t size) {}
>
> diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/
> dma-iommu.c
> index 2983ada..87ddb3f 100644
> --- a/arch/powerpc/kernel/dma-iommu.c
> +++ b/arch/powerpc/kernel/dma-iommu.c
> @@ -89,7 +89,7 @@ static int dma_iommu_dma_supported(struct device
> *dev, u64 mask)
> return 1;
> }
>
> -struct dma_mapping_ops dma_iommu_ops = {
> +struct dma_map_ops dma_iommu_ops = {
> .alloc_coherent = dma_iommu_alloc_coherent,
> .free_coherent = dma_iommu_free_coherent,
> .map_sg = dma_iommu_map_sg,
> diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/
> dma-swiotlb.c
> index ca141e1..d1143a6 100644
> --- a/arch/powerpc/kernel/dma-swiotlb.c
> +++ b/arch/powerpc/kernel/dma-swiotlb.c
> @@ -31,7 +31,7 @@ unsigned int ppc_swiotlb_enable;
> * map_page, and unmap_page on highmem, use normal dma_ops
> * for everything else.
> */
> -struct dma_mapping_ops swiotlb_dma_ops = {
> +struct dma_map_ops swiotlb_dma_ops = {
> .alloc_coherent = dma_direct_alloc_coherent,
> .free_coherent = dma_direct_free_coherent,
> .map_sg = swiotlb_map_sg_attrs,
> diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
> index 20a60d6..3e8bb9a 100644
> --- a/arch/powerpc/kernel/dma.c
> +++ b/arch/powerpc/kernel/dma.c
> @@ -140,7 +140,7 @@ static inline void
> dma_direct_sync_single_range(struct device *dev,
> }
> #endif
>
> -struct dma_mapping_ops dma_direct_ops = {
> +struct dma_map_ops dma_direct_ops = {
> .alloc_coherent = dma_direct_alloc_coherent,
> .free_coherent = dma_direct_free_coherent,
> .map_sg = dma_direct_map_sg,
> diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/
> ibmebus.c
> index 6e3f624..a4c8b38 100644
> --- a/arch/powerpc/kernel/ibmebus.c
> +++ b/arch/powerpc/kernel/ibmebus.c
> @@ -127,7 +127,7 @@ static int ibmebus_dma_supported(struct device
> *dev, u64 mask)
> return 1;
> }
>
> -static struct dma_mapping_ops ibmebus_dma_ops = {
> +static struct dma_map_ops ibmebus_dma_ops = {
> .alloc_coherent = ibmebus_alloc_coherent,
> .free_coherent = ibmebus_free_coherent,
> .map_sg = ibmebus_map_sg,
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/
> pci-common.c
> index 5a56e97..7585f1f 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -50,14 +50,14 @@ resource_size_t isa_mem_base;
> unsigned int ppc_pci_flags = 0;
>
>
> -static struct dma_mapping_ops *pci_dma_ops = &dma_direct_ops;
> +static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
>
> -void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
> +void set_pci_dma_ops(struct dma_map_ops *dma_ops)
> {
> pci_dma_ops = dma_ops;
> }
>
> -struct dma_mapping_ops *get_pci_dma_ops(void)
> +struct dma_map_ops *get_pci_dma_ops(void)
> {
> return pci_dma_ops;
> }
> diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
> index 819e59f..bc7b41e 100644
> --- a/arch/powerpc/kernel/vio.c
> +++ b/arch/powerpc/kernel/vio.c
> @@ -601,7 +601,7 @@ static void vio_dma_iommu_unmap_sg(struct device
> *dev,
> vio_cmo_dealloc(viodev, alloc_size);
> }
>
> -struct dma_mapping_ops vio_dma_mapping_ops = {
> +struct dma_map_ops vio_dma_mapping_ops = {
> .alloc_coherent = vio_dma_iommu_alloc_coherent,
> .free_coherent = vio_dma_iommu_free_coherent,
> .map_sg = vio_dma_iommu_map_sg,
> diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/
> platforms/cell/iommu.c
> index 5b34fc2..416db17 100644
> --- a/arch/powerpc/platforms/cell/iommu.c
> +++ b/arch/powerpc/platforms/cell/iommu.c
> @@ -642,7 +642,7 @@ static int dma_fixed_dma_supported(struct device
> *dev, u64 mask)
>
> static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
>
> -struct dma_mapping_ops dma_iommu_fixed_ops = {
> +struct dma_map_ops dma_iommu_fixed_ops = {
> .alloc_coherent = dma_fixed_alloc_coherent,
> .free_coherent = dma_fixed_free_coherent,
> .map_sg = dma_fixed_map_sg,
> diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/
> platforms/ps3/system-bus.c
> index 3f763c5..02ddcc2 100644
> --- a/arch/powerpc/platforms/ps3/system-bus.c
> +++ b/arch/powerpc/platforms/ps3/system-bus.c
> @@ -694,7 +694,7 @@ static int ps3_dma_supported(struct device
> *_dev, u64 mask)
> return mask >= DMA_BIT_MASK(32);
> }
>
> -static struct dma_mapping_ops ps3_sb_dma_ops = {
> +static struct dma_map_ops ps3_sb_dma_ops = {
> .alloc_coherent = ps3_alloc_coherent,
> .free_coherent = ps3_free_coherent,
> .map_sg = ps3_sb_map_sg,
> @@ -704,7 +704,7 @@ static struct dma_mapping_ops ps3_sb_dma_ops = {
> .unmap_page = ps3_unmap_page,
> };
>
> -static struct dma_mapping_ops ps3_ioc0_dma_ops = {
> +static struct dma_map_ops ps3_ioc0_dma_ops = {
> .alloc_coherent = ps3_alloc_coherent,
> .free_coherent = ps3_free_coherent,
> .map_sg = ps3_ioc0_map_sg,
> --
> 1.6.0.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 5/5] powerpc: use asm-generic/dma-mapping-common.h
From: Becky Bruce @ 2009-07-27 21:08 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1248405855-15546-6-git-send-email-fujita.tomonori@lab.ntt.co.jp>
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote:
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Fujita,
Since you're removing all the uses of it, you should probably remove
PPC_NEED_DMA_SYNC_OPS from arch/powerpc/Kconfig:
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 0603b6c..fb3f4ff 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -307,10 +307,6 @@ config SWIOTLB
platforms where the size of a physical address is larger
than the bus address. Not all platforms support this.
-config PPC_NEED_DMA_SYNC_OPS
- def_bool y
- depends on (NOT_COHERENT_CACHE || SWIOTLB)
-
config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES ||
PPC_PMAC)
Otherwise, this looks good to me.
I also think you want an ACK from Ben - making this switch does add
slight overhead to platforms that don't need sync ops, but I think
it's worth it. IIRC, it was Ben who asked for the optimization of
NEED_DMA_SYNC_OPS, so I'd like him to weigh in here.
Cheers,
Becky
>
> ---
> arch/powerpc/Kconfig | 2 +-
> arch/powerpc/include/asm/dma-mapping.h | 242
> +-------------------------------
> 2 files changed, 7 insertions(+), 237 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index d00131c..0603b6c 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -120,7 +120,7 @@ config PPC
> select HAVE_KRETPROBES
> select HAVE_ARCH_TRACEHOOK
> select HAVE_LMB
> - select HAVE_DMA_ATTRS if PPC64
> + select HAVE_DMA_ATTRS
> select USE_GENERIC_SMP_HELPERS if SMP
> select HAVE_OPROFILE
> select HAVE_SYSCALL_WRAPPERS if PPC64
> diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/
> include/asm/dma-mapping.h
> index 8ca2b51..91217e4 100644
> --- a/arch/powerpc/include/asm/dma-mapping.h
> +++ b/arch/powerpc/include/asm/dma-mapping.h
> @@ -14,6 +14,7 @@
> #include <linux/mm.h>
> #include <linux/scatterlist.h>
> #include <linux/dma-attrs.h>
> +#include <linux/dma-debug.h>
> #include <asm/io.h>
> #include <asm/swiotlb.h>
>
> @@ -89,6 +90,11 @@ static inline void set_dma_ops(struct device
> *dev, struct dma_map_ops *ops)
> dev->archdata.dma_ops = ops;
> }
>
> +/* this will be removed soon */
> +#define flush_write_buffers()
> +
> +#include <asm-generic/dma-mapping-common.h>
> +
> static inline int dma_supported(struct device *dev, u64 mask)
> {
> struct dma_map_ops *dma_ops = get_dma_ops(dev);
> @@ -117,87 +123,6 @@ static inline int dma_set_mask(struct device
> *dev, u64 dma_mask)
> return 0;
> }
>
> -/*
> - * map_/unmap_single actually call through to map/unmap_page now
> that all the
> - * dma_map_ops have been converted over. We just have to get the
> page and
> - * offset to pass through to map_page
> - */
> -static inline dma_addr_t dma_map_single_attrs(struct device *dev,
> - void *cpu_addr,
> - size_t size,
> - enum dma_data_direction direction,
> - struct dma_attrs *attrs)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - return dma_ops->map_page(dev, virt_to_page(cpu_addr),
> - (unsigned long)cpu_addr % PAGE_SIZE, size,
> - direction, attrs);
> -}
> -
> -static inline void dma_unmap_single_attrs(struct device *dev,
> - dma_addr_t dma_addr,
> - size_t size,
> - enum dma_data_direction direction,
> - struct dma_attrs *attrs)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - dma_ops->unmap_page(dev, dma_addr, size, direction, attrs);
> -}
> -
> -static inline dma_addr_t dma_map_page_attrs(struct device *dev,
> - struct page *page,
> - unsigned long offset, size_t size,
> - enum dma_data_direction direction,
> - struct dma_attrs *attrs)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - return dma_ops->map_page(dev, page, offset, size, direction, attrs);
> -}
> -
> -static inline void dma_unmap_page_attrs(struct device *dev,
> - dma_addr_t dma_address,
> - size_t size,
> - enum dma_data_direction direction,
> - struct dma_attrs *attrs)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - dma_ops->unmap_page(dev, dma_address, size, direction, attrs);
> -}
> -
> -static inline int dma_map_sg_attrs(struct device *dev, struct
> scatterlist *sg,
> - int nents, enum dma_data_direction direction,
> - struct dma_attrs *attrs)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> - return dma_ops->map_sg(dev, sg, nents, direction, attrs);
> -}
> -
> -static inline void dma_unmap_sg_attrs(struct device *dev,
> - struct scatterlist *sg,
> - int nhwentries,
> - enum dma_data_direction direction,
> - struct dma_attrs *attrs)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> - dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs);
> -}
> -
> static inline void *dma_alloc_coherent(struct device *dev, size_t
> size,
> dma_addr_t *dma_handle, gfp_t flag)
> {
> @@ -216,161 +141,6 @@ static inline void dma_free_coherent(struct
> device *dev, size_t size,
> dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
> }
>
> -static inline dma_addr_t dma_map_single(struct device *dev, void
> *cpu_addr,
> - size_t size,
> - enum dma_data_direction direction)
> -{
> - return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL);
> -}
> -
> -static inline void dma_unmap_single(struct device *dev, dma_addr_t
> dma_addr,
> - size_t size,
> - enum dma_data_direction direction)
> -{
> - dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL);
> -}
> -
> -static inline dma_addr_t dma_map_page(struct device *dev, struct
> page *page,
> - unsigned long offset, size_t size,
> - enum dma_data_direction direction)
> -{
> - return dma_map_page_attrs(dev, page, offset, size, direction, NULL);
> -}
> -
> -static inline void dma_unmap_page(struct device *dev, dma_addr_t
> dma_address,
> - size_t size,
> - enum dma_data_direction direction)
> -{
> - dma_unmap_page_attrs(dev, dma_address, size, direction, NULL);
> -}
> -
> -static inline int dma_map_sg(struct device *dev, struct scatterlist
> *sg,
> - int nents, enum dma_data_direction direction)
> -{
> - return dma_map_sg_attrs(dev, sg, nents, direction, NULL);
> -}
> -
> -static inline void dma_unmap_sg(struct device *dev, struct
> scatterlist *sg,
> - int nhwentries,
> - enum dma_data_direction direction)
> -{
> - dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
> -}
> -
> -#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
> -static inline void dma_sync_single_for_cpu(struct device *dev,
> - dma_addr_t dma_handle, size_t size,
> - enum dma_data_direction direction)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - if (dma_ops->sync_single_range_for_cpu)
> - dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0,
> - size, direction);
> -}
> -
> -static inline void dma_sync_single_for_device(struct device *dev,
> - dma_addr_t dma_handle, size_t size,
> - enum dma_data_direction direction)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - if (dma_ops->sync_single_range_for_device)
> - dma_ops->sync_single_range_for_device(dev, dma_handle,
> - 0, size, direction);
> -}
> -
> -static inline void dma_sync_sg_for_cpu(struct device *dev,
> - struct scatterlist *sgl, int nents,
> - enum dma_data_direction direction)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - if (dma_ops->sync_sg_for_cpu)
> - dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction);
> -}
> -
> -static inline void dma_sync_sg_for_device(struct device *dev,
> - struct scatterlist *sgl, int nents,
> - enum dma_data_direction direction)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - if (dma_ops->sync_sg_for_device)
> - dma_ops->sync_sg_for_device(dev, sgl, nents, direction);
> -}
> -
> -static inline void dma_sync_single_range_for_cpu(struct device *dev,
> - dma_addr_t dma_handle, unsigned long offset, size_t size,
> - enum dma_data_direction direction)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - if (dma_ops->sync_single_range_for_cpu)
> - dma_ops->sync_single_range_for_cpu(dev, dma_handle,
> - offset, size, direction);
> -}
> -
> -static inline void dma_sync_single_range_for_device(struct device
> *dev,
> - dma_addr_t dma_handle, unsigned long offset, size_t size,
> - enum dma_data_direction direction)
> -{
> - struct dma_map_ops *dma_ops = get_dma_ops(dev);
> -
> - BUG_ON(!dma_ops);
> -
> - if (dma_ops->sync_single_range_for_device)
> - dma_ops->sync_single_range_for_device(dev, dma_handle, offset,
> - size, direction);
> -}
> -#else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */
> -static inline void dma_sync_single_for_cpu(struct device *dev,
> - dma_addr_t dma_handle, size_t size,
> - enum dma_data_direction direction)
> -{
> -}
> -
> -static inline void dma_sync_single_for_device(struct device *dev,
> - dma_addr_t dma_handle, size_t size,
> - enum dma_data_direction direction)
> -{
> -}
> -
> -static inline void dma_sync_sg_for_cpu(struct device *dev,
> - struct scatterlist *sgl, int nents,
> - enum dma_data_direction direction)
> -{
> -}
> -
> -static inline void dma_sync_sg_for_device(struct device *dev,
> - struct scatterlist *sgl, int nents,
> - enum dma_data_direction direction)
> -{
> -}
> -
> -static inline void dma_sync_single_range_for_cpu(struct device *dev,
> - dma_addr_t dma_handle, unsigned long offset, size_t size,
> - enum dma_data_direction direction)
> -{
> -}
> -
> -static inline void dma_sync_single_range_for_device(struct device
> *dev,
> - dma_addr_t dma_handle, unsigned long offset, size_t size,
> - enum dma_data_direction direction)
> -{
> -}
> -#endif
> -
> static inline int dma_mapping_error(struct device *dev, dma_addr_t
> dma_addr)
> {
> #ifdef CONFIG_PPC64
> --
> 1.6.0.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply related
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
From: Benjamin Herrenschmidt @ 2009-07-27 21:35 UTC (permalink / raw)
To: Linus Torvalds
Cc: Nick Piggin, Linux-Arch, linuxppc-dev, Hugh Dickins, linux-kernel,
Linux Memory Management
In-Reply-To: <alpine.LFD.2.01.0907271210210.25224@localhost.localdomain>
On Mon, 2009-07-27 at 12:11 -0700, Linus Torvalds wrote:
>
> On Thu, 23 Jul 2009, Benjamin Herrenschmidt wrote:
> >
> > Hrm... my powerpc-next branch will contain stuff that depend on it, so
> > I'll probably have to pull it in though, unless I tell all my
> > sub-maintainers to also pull from that other branch first :-)
>
> Ok, I'll just apply the patch. It does look obvious enough.
Thanks. It's been in -next for a day now btw, and afaik, there have been
no issue reported.
Cheers,
Ben.
^ permalink raw reply
* Re: PPCboot and latest kernel
From: Scott Wood @ 2009-07-27 21:59 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-dev, vijay sharma
In-Reply-To: <20090720174041.1873A832E416@gemini.denx.de>
On Mon, Jul 20, 2009 at 07:40:41PM +0200, Wolfgang Denk wrote:
> > zImage starting: loaded at 0x01900000 (sp: 0x0fdc3a08)
> > Allocating 0x165ca04 bytes for kernel ...
> > gunzipping (0x00000000 <- 0x0190c000:0x02f58efc)...done 0x1637b54 bytes
>
> You loaded the image at 01900000, but the uncompr4essed image extends
> until 02f58efc, i. e. there is a good chance that you will overwrite
> parts of the still uncompressed image.
I think the above output says that the compressed image extends to
0x02f58efc, and that the uncompressed image goes from zero to 0x165ca04.
So no conflict (you should get an error message in case of conflict) with
0x01900000.
> > Linux/PowerPC load:
> > Finalizing device tree... flat tree at 0x2f65300 <== Beyond this point no
> > output is available.
>
> Your device tree might be wrong, too.
Either that or something is wrong with the kernel itself. This is the
point at which it transfers control to the main kernel.
-Scott
^ permalink raw reply
* Re: image/wrapper script questions
From: Grant Likely @ 2009-07-27 21:53 UTC (permalink / raw)
To: Eddie Dawydiuk; +Cc: linuxppc-dev, devicetree-discuss, Wolfgang Denk
In-Reply-To: <4A6E0AE2.3090600@embeddedarm.com>
(Adding cc:devicetree-discuss)
On Mon, Jul 27, 2009 at 2:15 PM, Eddie Dawydiuk <eddie@embeddedarm.com> wro=
te:
> Thanks for the link. Although, I'm not looking for info on optimizing
> boot time. Rather I'm looking for information on what the path of least
> resistance is to boot a kernel with an initrd being loaded from it's
> own partition. To clarify currently I am using a simpleImage.initrd which
> is a single image with the flattened device tree, kernel, and initial
> ramdisk in a single file. One can simply load this image in RAM(assuming
> 1 to 1 MMU mapping) and jump into it. Now what I would like to do is to
> load a kernel, device tree, and initial ramdisk into RAM at different
> locations.
Quick word of warning, if you do split the kernel and .dtb images (which
is a good thing to do for several reasons, and I strongly recommend it),
make sure you do *not* hard code the .dtb image into firmware.=A0 If the
end user isn't able to update the .dtb image as easily as updating the
kernel image, then you are asking for a world of hurt for yourself and
your users.
> I'm in the process of coming back up to speed on the low-level boot
> details of the powerpc kernel/architecture. It looks like one can
> accomplish this by loading R3 with the phys address of the device
> tree block, R4 with the phys address of the kernel, and R5 with Null.
> It also looks like the kernel, already has several routines which know
> about these details(prom_init() and __start()) and I was hoping I could
> reuse this code to accomplish this rather than rewriting the bootrom to
> handle this. That is I was hoping there is a boot wrapper image that
> would allow me to accomplish my goal of creating a single image
> containing a kernel and device tree block, and an interface to specify
> where the bootrom loads the initial ramdisk in RAM. I'll continue
> reading through the docs and code, but if anyone could provide any
> pointers on how to do this I would really appreciate it.
It really sounds like you're asking for a new board-specific dtbImage
(which is what dtbImages are designed for). simpleImage is really just
a dtbImage with the assumption that firmware provides no boot information.
*HOWEVER* dtbImages were really designed for older firmware that cannot
handle the kernel and .dtb images separately. If you've got control of
the firmware then I strongly recommend *not* relying on the dtbImage
approach of binding the device tree into the kernel image. You ignore
a lot of the advantages of the device tree model if you do. In particular
you take on maintenance of a new dtbImage variant in the kernel tree and
loose the ability to build and boot a more or less 'standard' 440 kernel
image.
Honestly, I think you'd be better off adapting your firmware to parse and
boot either a raw vmlinux elf image or a u-boot uImage wrapped image and
pass in the .dtb and initrd pointers. I predict it will result in far
less confusion for your users (they don't need to know about a particular
'dtbImage.<board>', less maintenance pain for you, and less cursing from
the rest of the powerpc community about an oddball firmware that behaves
differently from everything else (from a boot perspective).
In other words, don't try to adapt the kernel boot to your firmware;
adapt the firmware to an established boot mechanism.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: PPCboot and latest kernel
From: Scott Wood @ 2009-07-27 22:07 UTC (permalink / raw)
To: vijay sharma; +Cc: linuxppc-dev
In-Reply-To: <e571380d0907191136j37d341d7k514f46396a38abc3@mail.gmail.com>
On Mon, Jul 20, 2009 at 12:06:42AM +0530, vijay sharma wrote:
> 2)Built cuImage and loaded it into memory. I am not seeing any output once
> control passes from wrapper to kernel. As you can see from logs mentioned
> above.
Try enabling early udbg console output. Also, make sure that Linux is
using the correct baud rate (either with console= or by putting a
current-speed property in the serial node), and that your board file
matches the device tree's root compatible (i.e. the probe function will
succeed).
> While going through mail achieves I found two possible reasons for this
> 1) Wrong entries inside dts file
> I am sure serial attributes are correctly defined inside the file. Also it
> works for wrapper. It should work for linux also.
That does not follow. There are many things that Linux depends on in the
tree that the wrapper does not care about.
> 2) PPCboot not providing information.
> I have built cuImage . Shouldn't kernel be getting its attributes from dtb
> file rather then depending on bd_info structure.
> I cannot upgrade to uboot. Is there some way I can make my board come up?
If you cannot upgrade to u-boot, then no, it should not be passing a
device tree since it is too old. Dealing with old firmware that only
passes bd_t is what cuImage is for.
How about:
3) Something is wrong with the kernel port to this platform? :-)
-Scott
^ permalink raw reply
* Re: [RFC/PATCH] powerpc: Don't use alloc_bootmem in cpm_uart_cpm2.c
From: Scott Wood @ 2009-07-27 22:16 UTC (permalink / raw)
To: Mark Ware; +Cc: Linuxppc-dev Development
In-Reply-To: <4A645A27.7040002@elphinstone.net>
On Mon, Jul 20, 2009 at 09:51:03PM +1000, Mark Ware wrote:
> This is another alloc_bootmem() -> kzalloc() change, this time to
> fix the non-fatal badness caused when booting with a cpm2_uart console.
>
> Signed-Off-By: Mark Ware <mware@elphinstone.net>
>
> ---
> drivers/serial/cpm_uart/cpm_uart_cpm2.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
> b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
> index 141c0a3..a9802e7 100644
> --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
> +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
> @@ -132,7 +132,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo,
> unsigned int is_con)
> memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
> L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
> if (is_con) {
> - mem_addr = alloc_bootmem(memsz);
> + mem_addr = kzalloc(memsz, GFP_NOWAIT);
> dma_addr = virt_to_bus(mem_addr);
> }
Hmm, is dma_alloc_coherent() now available this early as well? If so, we
could get rid of the separate "is_con" handling altogether.
-Scott
^ permalink raw reply
* Subject: Re: PPCboot and latest kernel
From: Mike Ditto @ 2009-07-27 23:06 UTC (permalink / raw)
To: linuxppc-dev, vijay sharma
In-Reply-To: <mailman.23.1248732967.30868.linuxppc-dev@lists.ozlabs.org>
vijay sharma wrote:
> Linux/PowerPC load:
> Finalizing device tree... flat tree at 0x2f65300 <== Beyond this point no
> output is available.
I have found that on my MPC8272 system running 2.6.28 & cuImage, the
/chosen/linux,stdout-path node is respected by the boot wrapper, but the
main kernel always uses the first serial port mentioned in the device
tree as the console. If you have multiple serial ports in your .dts,
try re-ordering them.
-=] Mike [=-
^ permalink raw reply
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
From: Benjamin Herrenschmidt @ 2009-07-28 0:17 UTC (permalink / raw)
To: Linus Torvalds
Cc: Nick Piggin, Linux-Arch, linuxppc-dev, Hugh Dickins, linux-kernel,
ralf, Linux Memory Management, Paul Mundt
In-Reply-To: <alpine.LFD.2.01.0907271210210.25224@localhost.localdomain>
On Mon, 2009-07-27 at 12:11 -0700, Linus Torvalds wrote:
>
> On Thu, 23 Jul 2009, Benjamin Herrenschmidt wrote:
> >
> > Hrm... my powerpc-next branch will contain stuff that depend on it, so
> > I'll probably have to pull it in though, unless I tell all my
> > sub-maintainers to also pull from that other branch first :-)
>
> Ok, I'll just apply the patch. It does look obvious enough.
There seem to be a MIPS and SH breakage as a result but I can't see
how my patch would have broken it, ie, it looks like the bug was
already in those two archs. The error is that it complains about a
duplicate definition of __pmd_free_tlb() between those arch pgalloc.h
and pgtable-nopmd.h
For MIPS, when CONFIG_32BIT is set, asm/pgalloc.h redefines
__pmd_free_tlb despite the fact that it's already defined by
asm-generic/pgtable-nopmd.h (via via pgtable.h via linux/mm.h).
I -suspect- what happens is that the compiler, before, would ignore the
double definition (or maybe just warn) due to the definition being
strictly identical. With the new argument added, it's no longer the case
as it's called "a" in asm-generic and "addr" in mips... oops.
In any case, can Ralf and Paul check if the following patch is correct ?
>From 41928c7945d855ae0eb053eadad590ab6876847e Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Tue, 28 Jul 2009 10:16:48 +1000
Subject: [PATCH] mm: Remove duplicate definitions in MIPS and SH
Those definitions are already provided by asm-generic
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/mips/include/asm/pgalloc.h | 11 -----------
arch/sh/include/asm/pgalloc.h | 8 --------
2 files changed, 0 insertions(+), 19 deletions(-)
diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
index f705735..3738f4b 100644
--- a/arch/mips/include/asm/pgalloc.h
+++ b/arch/mips/include/asm/pgalloc.h
@@ -104,17 +104,6 @@ do { \
tlb_remove_page((tlb), pte); \
} while (0)
-#ifdef CONFIG_32BIT
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb, x, addr) do { } while (0)
-
-#endif
-
#ifdef CONFIG_64BIT
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h
index 89a4827..63ca37b 100644
--- a/arch/sh/include/asm/pgalloc.h
+++ b/arch/sh/include/asm/pgalloc.h
@@ -79,14 +79,6 @@ do { \
tlb_remove_page((tlb), (pte)); \
} while (0)
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-
-#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb,x,addr) do { } while (0)
-
static inline void check_pgt_cache(void)
{
quicklist_trim(QUICK_PGD, NULL, 25, 16);
--
1.6.1.2.14.gf26b5
^ permalink raw reply related
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
From: Linus Torvalds @ 2009-07-28 0:41 UTC (permalink / raw)
To: Paul Mundt
Cc: Nick Piggin, Linux-Arch, Linux Memory Management, linux-kernel,
ralf, linuxppc-dev, Hugh Dickins
In-Reply-To: <20090728002529.GB22668@linux-sh.org>
On Tue, 28 Jul 2009, Paul Mundt wrote:
>
> Yup, that seems to be what happened. I've never seen a warning about this
> with any compiler version, otherwise we would have caught this much
> earlier. As soon as the addr -> a rename took place it blew up
> immediately as a redefinition. Is there a magical gcc flag we can turn on
> to warn on identical definitions, even if just for testing?
No, this is actually defined C behavior - identical macro redefinitions
are ok. That's very much on purpose, and allows different header files to
use an identical #define to define some common macro.
Strictly speaking, this is a "safety feature", in that you obviously
_could_ just always do a #undef+#define, but such a case would be able to
redefine a macro even if the new definition didn't match the old one. So
the C pre-processor rules is that you can safely re-define something if
you re-define it identically.
Of course, we could make the rules for the kernel be stricter, but I don't
know if there are any flags to warn about it, since it's such a standard C
feature: the lack of warning is _not_ an accident.
It would be trivial to teach sparse to warn about it, of course. Look at
sparse/pre-process.c, function do_handle_define(). Notice how it literally
checks that any previous #define is identical in both expansion and
argument list, with:
if (token_list_different(sym->expansion, expansion) ||
token_list_different(sym->arglist, arglist)) {
and just make token_list_different() always return true (this is the only
use of that function).
I haven't checked if such a change would actually result in a lot of
warnings.
Linus
^ permalink raw reply
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te, ud, md}_free_tlb()
From: Paul Mundt @ 2009-07-28 0:25 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Nick Piggin, Linux-Arch, linuxppc-dev, Hugh Dickins, linux-kernel,
ralf, Linux Memory Management, Linus Torvalds
In-Reply-To: <1248740260.30993.26.camel@pasglop>
On Tue, Jul 28, 2009 at 10:17:40AM +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2009-07-27 at 12:11 -0700, Linus Torvalds wrote:
> > On Thu, 23 Jul 2009, Benjamin Herrenschmidt wrote:
> > >
> > > Hrm... my powerpc-next branch will contain stuff that depend on it, so
> > > I'll probably have to pull it in though, unless I tell all my
> > > sub-maintainers to also pull from that other branch first :-)
> >
> > Ok, I'll just apply the patch. It does look obvious enough.
>
> There seem to be a MIPS and SH breakage as a result but I can't see
> how my patch would have broken it, ie, it looks like the bug was
> already in those two archs. The error is that it complains about a
> duplicate definition of __pmd_free_tlb() between those arch pgalloc.h
> and pgtable-nopmd.h
>
> For MIPS, when CONFIG_32BIT is set, asm/pgalloc.h redefines
> __pmd_free_tlb despite the fact that it's already defined by
> asm-generic/pgtable-nopmd.h (via via pgtable.h via linux/mm.h).
>
> I -suspect- what happens is that the compiler, before, would ignore the
> double definition (or maybe just warn) due to the definition being
> strictly identical. With the new argument added, it's no longer the case
> as it's called "a" in asm-generic and "addr" in mips... oops.
>
> In any case, can Ralf and Paul check if the following patch is correct ?
>
Yup, that seems to be what happened. I've never seen a warning about this
with any compiler version, otherwise we would have caught this much
earlier. As soon as the addr -> a rename took place it blew up
immediately as a redefinition. Is there a magical gcc flag we can turn on
to warn on identical definitions, even if just for testing?
> >From 41928c7945d855ae0eb053eadad590ab6876847e Mon Sep 17 00:00:00 2001
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Date: Tue, 28 Jul 2009 10:16:48 +1000
> Subject: [PATCH] mm: Remove duplicate definitions in MIPS and SH
>
> Those definitions are already provided by asm-generic
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Builds and boots fine, thanks.
Acked-by: Paul Mundt <lethal@linux-sh.org>
^ permalink raw reply
* "next" branch update
From: Benjamin Herrenschmidt @ 2009-07-28 4:14 UTC (permalink / raw)
To: linuxppc-dev list
So I opened powerpc-next, and pushed the pile that was in "test" (with
an additional bug fix to one of my patches that was causing the crash
at boot that mpe reported with hugetlbfs enabled).
The pre-req patch for adding an argument to __pte_free_tlb() has already
been merged upstream by Linus.
Now is time for people who want things into 2.6.32 to be noisy about it.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 5/5] powerpc: use asm-generic/dma-mapping-common.h
From: FUJITA Tomonori @ 2009-07-28 5:54 UTC (permalink / raw)
To: beckyb, benh; +Cc: fujita.tomonori, linuxppc-dev, linux-kernel
In-Reply-To: <B388F2F2-C68F-4464-A63A-4D541DF5E9C9@kernel.crashing.org>
On Mon, 27 Jul 2009 16:08:46 -0500
Becky Bruce <beckyb@kernel.crashing.org> wrote:
>
> On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote:
>
> > Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
>
> Fujita,
>
> Since you're removing all the uses of it, you should probably remove
> PPC_NEED_DMA_SYNC_OPS from arch/powerpc/Kconfig:
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 0603b6c..fb3f4ff 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -307,10 +307,6 @@ config SWIOTLB
> platforms where the size of a physical address is larger
> than the bus address. Not all platforms support this.
>
> -config PPC_NEED_DMA_SYNC_OPS
> - def_bool y
> - depends on (NOT_COHERENT_CACHE || SWIOTLB)
> -
> config HOTPLUG_CPU
> bool "Support for enabling/disabling CPUs"
> depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES ||
> PPC_PMAC)
>
> Otherwise, this looks good to me.
Ah, thanks. I fold the above change. The updated patchset is available
at:
git://git.kernel.org/pub/scm/linux/kernel/git/tomo/linux-2.6-misc.git powerpc
> I also think you want an ACK from Ben - making this switch does add
> slight overhead to platforms that don't need sync ops, but I think
> it's worth it. IIRC, it was Ben who asked for the optimization of
> NEED_DMA_SYNC_OPS, so I'd like him to weigh in here.
Yeah, of course. Ben?
^ permalink raw reply
* Question about tracking freescale patches for Linux
From: B.J. Buchalter @ 2009-07-28 6:08 UTC (permalink / raw)
To: linuxppc-dev
Hi Folks,
Sorry if this question is out of place for this list -- if it is,
please point me to the proper place for this sort of question. It just
seems like this might be the best place to ask.
I am looking at bunch of patches to the 2.6.25 kernel (primarily in
the drivers) that are provided by freescale as part of the BSP that
they provide for the MPC837x parts.
Most of these patches are in the 2.6.30 kernel, but a number of them
are not; these primarily relate to changes to drivers for DMA, the
Security peripheral and the TSEC controllers.
I have contacted Freescale, but they basically say that they provide
the BSP, and make no commitments to supporting any other version of
the linux kernel.
My questions are:
1) is there any way to determine if any these patches are currently
being worked into the mainline kernel, or if they have been abandoned
for some reason?
2) Is it worth trying to move these patches up to the head of
development and trying to get them merged into the mainline kernel, or
is that really just up to freescale to do?
Again, if there is a better place to be addressing this, please point
me in that direction.
Thanks in advance!
B.J. Buchalter
Metric Halo
http://www.mhlabs.com
^ permalink raw reply
* [PATCH/RFC] powerpc/mm: Cleanup handling of execute permission
From: Benjamin Herrenschmidt @ 2009-07-28 7:32 UTC (permalink / raw)
To: linuxppc-dev list; +Cc: Kumar Gala
This is an attempt at cleaning up a bit the way we handle execute
permission on powerpc (again !).
_PAGE_HWEXEC is gone, _PAGE_EXEC is now only defined by CPUs that
can do something with it, and the myriad of #ifdef's in the I$/D$
coherency code is reduced to 2 cases that hopefully should cover
everything.
The logic on BookE is a little bit different than what it was though
not by much. Since now, _PAGE_EXEC will be set by the generic code
for executable pages, we need to filter out if they are unclean and
recover it. However, I don't expect the code to be more bloated than
it already was in that area due to that change.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
I could boast that this brings proper enforcing of per-page execute
permissions to all BookE and 40x but in fact, we've had that now for
some time as a side effect of my previous rework in that area (and
I didn't even know it :-) We would only enable execute permission if
the page was cache clean and we would only cache clean it if we took
and exec fault. Since we now enforce that the later only work if
VM_EXEC is part of the VMA flags, we de-fact already enforce per-page
execute permissions... Unless I missed something
Kumar, Becky, I could really use some review here :-) I tested on
440 and that's about it, I'll do more testing tomorrow. Basically, I
_think_ we already enforce execute permission fully on all BookE today
(test case welcome) but at least after that patch it becomes more
obvious what is happening in the code.
arch/powerpc/include/asm/pgtable-ppc32.h | 7 +-
arch/powerpc/include/asm/pgtable-ppc64.h | 3 +-
arch/powerpc/include/asm/pte-40x.h | 2 +-
arch/powerpc/include/asm/pte-44x.h | 2 +-
arch/powerpc/include/asm/pte-8xx.h | 1 -
arch/powerpc/include/asm/pte-book3e.h | 13 ++-
arch/powerpc/include/asm/pte-common.h | 22 ++--
arch/powerpc/include/asm/pte-fsl-booke.h | 2 +-
arch/powerpc/include/asm/pte-hash32.h | 1 -
arch/powerpc/kernel/head_44x.S | 2 +-
arch/powerpc/kernel/head_fsl_booke.S | 4 +-
arch/powerpc/mm/40x_mmu.c | 4 +-
arch/powerpc/mm/pgtable.c | 148 ++++++++++++++++++++----------
arch/powerpc/mm/pgtable_32.c | 2 +-
arch/powerpc/mm/tlb_low_64e.S | 4 +-
15 files changed, 132 insertions(+), 85 deletions(-)
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index c9ff9d7..f2c52e2 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -186,7 +186,7 @@ static inline unsigned long pte_update(pte_t *p,
#endif /* !PTE_ATOMIC_UPDATES */
#ifdef CONFIG_44x
- if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+ if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
icache_44x_need_flush = 1;
#endif
return old;
@@ -217,7 +217,7 @@ static inline unsigned long long pte_update(pte_t *p,
#endif /* !PTE_ATOMIC_UPDATES */
#ifdef CONFIG_44x
- if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+ if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
icache_44x_need_flush = 1;
#endif
return old;
@@ -267,8 +267,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
- _PAGE_HWEXEC | _PAGE_EXEC);
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
pte_update(ptep, 0, bits);
}
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 200ec2d..806abe7 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -313,8 +313,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
- _PAGE_EXEC | _PAGE_HWEXEC);
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
#ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/pte-40x.h
index 07630fa..6c3e1f4 100644
--- a/arch/powerpc/include/asm/pte-40x.h
+++ b/arch/powerpc/include/asm/pte-40x.h
@@ -46,7 +46,7 @@
#define _PAGE_RW 0x040 /* software: Writes permitted */
#define _PAGE_DIRTY 0x080 /* software: dirty page */
#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
-#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
+#define _PAGE_EXEC 0x200 /* hardware: EX permission */
#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
diff --git a/arch/powerpc/include/asm/pte-44x.h b/arch/powerpc/include/asm/pte-44x.h
index 37e98bc..4192b9b 100644
--- a/arch/powerpc/include/asm/pte-44x.h
+++ b/arch/powerpc/include/asm/pte-44x.h
@@ -78,7 +78,7 @@
#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
#define _PAGE_RW 0x00000002 /* S: Write permission */
#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */
-#define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */
+#define _PAGE_EXEC 0x00000004 /* H: Execute permission */
#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */
#define _PAGE_SPECIAL 0x00000020 /* S: Special page */
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h
index 8c6e312..94e9797 100644
--- a/arch/powerpc/include/asm/pte-8xx.h
+++ b/arch/powerpc/include/asm/pte-8xx.h
@@ -36,7 +36,6 @@
/* These five software bits must be masked out when the entry is loaded
* into the TLB.
*/
-#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */
#define _PAGE_GUARDED 0x0010 /* software: guarded access */
#define _PAGE_DIRTY 0x0020 /* software: page changed */
#define _PAGE_RW 0x0040 /* software: user write access allowed */
diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h
index 1d27c77..9800565 100644
--- a/arch/powerpc/include/asm/pte-book3e.h
+++ b/arch/powerpc/include/asm/pte-book3e.h
@@ -37,12 +37,13 @@
#define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */
/* "Higher level" linux bit combinations */
-#define _PAGE_EXEC _PAGE_BAP_SX /* Can be executed from potentially */
-#define _PAGE_HWEXEC _PAGE_BAP_UX /* .. and was cache cleaned */
-#define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
-#define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
-#define _PAGE_KERNEL_RO (_PAGE_BAP_SR)
-#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
+#define _PAGE_EXEC _PAGE_BAP_UX /* .. and was cache cleaned */
+#define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
+#define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
+#define _PAGE_KERNEL_RO (_PAGE_BAP_SR)
+#define _PAGE_KERNEL_RWX (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
+#define _PAGE_KERNEL_ROX (_PAGE_BAP_SR | _PAGE_BAP_SX)
+#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
#define _PAGE_HASHPTE 0
#define _PAGE_BUSY 0
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index 8bb6464..c3b6507 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -13,9 +13,6 @@
#ifndef _PAGE_HWWRITE
#define _PAGE_HWWRITE 0
#endif
-#ifndef _PAGE_HWEXEC
-#define _PAGE_HWEXEC 0
-#endif
#ifndef _PAGE_EXEC
#define _PAGE_EXEC 0
#endif
@@ -48,10 +45,16 @@
#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
#endif
#ifndef _PAGE_KERNEL_RO
-#define _PAGE_KERNEL_RO 0
+#define _PAGE_KERNEL_RO 0
+#endif
+#ifndef _PAGE_KERNEL_ROX
+#define _PAGE_KERNEL_ROX (_PAGE_EXEC)
#endif
#ifndef _PAGE_KERNEL_RW
-#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#endif
+#ifndef _PAGE_KERNEL_RWX
+#define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_EXEC)
#endif
#ifndef _PAGE_HPTEFLAGS
#define _PAGE_HPTEFLAGS _PAGE_HASHPTE
@@ -96,8 +99,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
_PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
_PAGE_USER | _PAGE_ACCESSED | \
- _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
- _PAGE_EXEC | _PAGE_HWEXEC)
+ _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
/*
* We define 2 sets of base prot bits, one for basic pages (ie,
@@ -154,11 +156,9 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
_PAGE_NO_CACHE)
#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
_PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC | \
- _PAGE_HWEXEC)
+#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
-#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC | \
- _PAGE_HWEXEC)
+#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
/* Protection used for kernel text. We want the debuggers to be able to
* set breakpoints anywhere, so don't write protect the kernel text
diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
index 10820f5..ce8a9e9 100644
--- a/arch/powerpc/include/asm/pte-fsl-booke.h
+++ b/arch/powerpc/include/asm/pte-fsl-booke.h
@@ -23,7 +23,7 @@
#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
-#define _PAGE_HWEXEC 0x00010 /* H: SX permission */
+#define _PAGE_EXEC 0x00010 /* H: SX permission */
#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
#define _PAGE_ENDIAN 0x00040 /* H: E bit */
diff --git a/arch/powerpc/include/asm/pte-hash32.h b/arch/powerpc/include/asm/pte-hash32.h
index 16e571c..4aad413 100644
--- a/arch/powerpc/include/asm/pte-hash32.h
+++ b/arch/powerpc/include/asm/pte-hash32.h
@@ -26,7 +26,6 @@
#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
#define _PAGE_DIRTY 0x080 /* C: page changed */
#define _PAGE_ACCESSED 0x100 /* R: page referenced */
-#define _PAGE_EXEC 0x200 /* software: i-cache coherency required */
#define _PAGE_RW 0x400 /* software: user write access allowed */
#define _PAGE_SPECIAL 0x800 /* software: Special page */
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 656cfb2..711368b 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -497,7 +497,7 @@ tlb_44x_patch_hwater_D:
mtspr SPRN_MMUCR,r12
/* Make up the required permissions */
- li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
/* Compute pgdir/pmd offset */
rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index eca8048..2c5af52 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -643,7 +643,7 @@ interrupt_base:
4:
/* Make up the required permissions */
- li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
FIND_PTE
andc. r13,r13,r11 /* Check permission */
@@ -742,7 +742,7 @@ finish_tlb_load:
#endif
mtspr SPRN_MAS2, r12
- li r10, (_PAGE_HWEXEC | _PAGE_PRESENT)
+ li r10, (_PAGE_EXEC | _PAGE_PRESENT)
rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */
and r12, r11, r10
andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 29954dc..f5e7b9c 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -105,7 +105,7 @@ unsigned long __init mmu_mapin_ram(void)
while (s >= LARGE_PAGE_SIZE_16M) {
pmd_t *pmdp;
- unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+ unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_HWWRITE;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
pmd_val(*pmdp++) = val;
@@ -120,7 +120,7 @@ unsigned long __init mmu_mapin_ram(void)
while (s >= LARGE_PAGE_SIZE_4M) {
pmd_t *pmdp;
- unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+ unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_HWWRITE;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
pmd_val(*pmdp) = val;
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index cafb2a2..d568d2c 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -128,73 +128,126 @@ void pte_free_finish(void)
#endif /* CONFIG_SMP */
+static inline int is_exec_fault(void)
+{
+ return current->thread.regs && TRAP(current->thread.regs) == 0x400;
+}
+
+/* We only try to do i/d cache coherency on stuff that looks like
+ * reasonably "normal" PTEs. We currently require a PTE to be present
+ * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE. We also only do that
+ * on userspace PTEs
+ */
+static inline int pte_looks_normal(pte_t pte)
+{
+ return (pte_val(pte) &
+ (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER)) ==
+ (_PAGE_PRESENT | _PAGE_USER);
+}
+
+
/*
* Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
*/
-static pte_t do_dcache_icache_coherency(pte_t pte)
+struct page * maybe_pte_to_page(pte_t pte)
{
unsigned long pfn = pte_pfn(pte);
struct page *page;
if (unlikely(!pfn_valid(pfn)))
- return pte;
+ return NULL;
page = pfn_to_page(pfn);
-
- if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
- pr_devel("do_dcache_icache_coherency... flushing\n");
- flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
- }
- else
- pr_devel("do_dcache_icache_coherency... already clean\n");
- return __pte(pte_val(pte) | _PAGE_HWEXEC);
+ if (PageReserved(page))
+ return NULL;
+ return page;
}
-static inline int is_exec_fault(void)
-{
- return current->thread.regs && TRAP(current->thread.regs) == 0x400;
-}
+#if defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0
-/* We only try to do i/d cache coherency on stuff that looks like
- * reasonably "normal" PTEs. We currently require a PTE to be present
- * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE
+/* Server-style MMU handles coherency when hashing if HW exec permission
+ * is supposed per page (currently 64-bit only). If not, then, we always
+ * flush the cache for valid PTEs in set_pte. Embedded CPU without HW exec
+ * support falls into the same category.
*/
-static inline int pte_looks_normal(pte_t pte)
+
+static pte_t set_pte_filter(pte_t pte)
{
- return (pte_val(pte) &
- (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) ==
- (_PAGE_PRESENT);
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
+ cpu_has_feature(CPU_FTR_NOEXECUTE))) {
+ struct page *pg = maybe_pte_to_page(pte);
+ if (!pg)
+ return pte;
+ if (!test_bit(PG_arch_1, &pg->flags)) {
+ flush_dcache_icache_page(pg);
+ set_bit(PG_arch_1, &pg->flags);
+ }
+ }
+ return pte;
}
-#if defined(CONFIG_PPC_STD_MMU)
-/* Server-style MMU handles coherency when hashing if HW exec permission
- * is supposed per page (currently 64-bit only). Else, we always flush
- * valid PTEs in set_pte.
- */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma, int dirty)
{
- return set_pte && pte_looks_normal(pte) &&
- !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
- cpu_has_feature(CPU_FTR_NOEXECUTE));
+ return pte;
}
-#elif _PAGE_HWEXEC == 0
-/* Embedded type MMU without HW exec support (8xx only so far), we flush
- * the cache for any present PTE
+
+#else /* defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0 */
+
+/* Embedded type MMU with HW exec support. This is a bit more complicated
+ * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
+ * instead we "filter out" the exec permission for non clean pages.
*/
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+static pte_t set_pte_filter(pte_t pte)
{
- return set_pte && pte_looks_normal(pte);
+ struct page *pg;
+
+ /* No exec permission in the first place, move on */
+ if (!(pte_val(pte) & _PAGE_EXEC) || !pte_looks_normal(pte))
+ return pte;
+
+ /* If you set _PAGE_EXEC on weird pages you're on your own */
+ pg = maybe_pte_to_page(pte);
+ if (!pg)
+ return pte;
+
+ /* If the page clean, we move on */
+ if (test_bit(PG_arch_1, &pg->flags))
+ return pte;
+
+ /* If it's an exec fault, we flush the cache and make it clean */
+ if (is_exec_fault()) {
+ flush_dcache_icache_page(pg);
+ set_bit(PG_arch_1, &pg->flags);
+ return pte;
+ }
+
+ /* Else, we filter out _PAGE_EXEC */
+ return __pte(pte_val(pte) & ~_PAGE_EXEC);
}
-#else
-/* Other embedded CPUs with HW exec support per-page, we flush on exec
- * fault if HWEXEC is not set
- */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma, int dirty)
{
- return pte_looks_normal(pte) && is_exec_fault() &&
- !(pte_val(pte) & _PAGE_HWEXEC);
+ /* So here, we only care about exec faults, as we use them
+ * to recover lost _PAGE_EXEC and perform I$/D$ coherency
+ * if necessary. Also if _PAGE_EXEC is already set, same deal,
+ * we just bail out
+ */
+ if (dirty || (pte_val(pte) & _PAGE_EXEC) || !is_exec_fault())
+ return pte;
+
+#ifdef CONFIG_DEBUG_VM
+ /* So this is an exec fault, _PAGE_EXEC is not set. If it was
+ * an error we would have bailed out earlier in do_page_fault()
+ * but let's make sure of it
+ */
+ if (WARN_ON(!(vma->vm_flags & VM_EXEC)))
+ return pte;
+#endif /* CONFIG_DEBUG_VM */
+
+ return __pte(pte_val(pte) | _PAGE_EXEC);
}
-#endif
+
+#endif /* !(defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0) */
/*
* set_pte stores a linux PTE into the linux page table.
@@ -208,9 +261,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte
* this context might not have been activated yet when this
* is called.
*/
- pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
- if (pte_need_exec_flush(pte, 1))
- pte = do_dcache_icache_coherency(pte);
+ pte = set_pte_filter(pte);
/* Perform the setting of the PTE */
__set_pte_at(mm, addr, ptep, pte, 0);
@@ -227,8 +278,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
pte_t *ptep, pte_t entry, int dirty)
{
int changed;
- if (!dirty && pte_need_exec_flush(entry, 0))
- entry = do_dcache_icache_coherency(entry);
+ entry = set_access_flags_filter(entry, vma, dirty);
changed = !pte_same(*(ptep), entry);
if (changed) {
if (!(vma->vm_flags & VM_HUGETLB))
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 5422169..cb96cb2 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -142,7 +142,7 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
flags |= _PAGE_DIRTY | _PAGE_HWWRITE;
/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
- flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC);
+ flags &= ~(_PAGE_USER | _PAGE_EXEC);
return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
}
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 10d524d..cd92f62 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -133,7 +133,7 @@
/* We do the user/kernel test for the PID here along with the RW test
*/
- li r11,_PAGE_PRESENT|_PAGE_HWEXEC /* Base perm */
+ li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */
oris r11,r11,_PAGE_ACCESSED@h
cmpldi cr0,r15,0 /* Check for user region */
@@ -256,7 +256,7 @@ normal_tlb_miss_done:
normal_tlb_miss_access_fault:
/* We need to check if it was an instruction miss */
- andi. r10,r11,_PAGE_HWEXEC
+ andi. r10,r11,_PAGE_EXEC
bne 1f
ld r14,EX_TLB_DEAR(r12)
ld r15,EX_TLB_ESR(r12)
--
1.6.1.2.14.gf26b5
^ permalink raw reply related
* Re: "next" branch update
From: Martyn Welch @ 2009-07-28 7:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1248754493.30993.47.camel@pasglop>
Benjamin Herrenschmidt wrote:
> So I opened powerpc-next, and pushed the pile that was in "test" (with
> an additional bug fix to one of my patches that was causing the crash
> at boot that mpe reported with hugetlbfs enabled).
>
> The pre-req patch for adding an argument to __pte_free_tlb() has already
> been merged upstream by Linus.
>
> Now is time for people who want things into 2.6.32 to be noisy about it.
>
Hi Ben,
I'd like to get the NVRAM patches into 2.6.32, I know you said to pester
you in a week but your asking now :-) :
http://patchwork.ozlabs.org/patch/29420/
http://patchwork.ozlabs.org/patch/29422/
http://patchwork.ozlabs.org/patch/29421/
http://patchwork.ozlabs.org/patch/29419/
http://patchwork.ozlabs.org/patch/29418/
There's also some updates to the boards I work on:
http://patchwork.ozlabs.org/patch/29404/
http://patchwork.ozlabs.org/patch/29403/
http://patchwork.ozlabs.org/patch/29402/
http://patchwork.ozlabs.org/patch/29335/
http://patchwork.ozlabs.org/patch/29332/
Kumar: have you had a chance to look at these / are you happy with them?
Martyn
--
Martyn Welch MEng MPhil MIET (Principal Software Engineer) T:+44(0)1327322748
GE Fanuc Intelligent Platforms Ltd, |Registered in England and Wales
Tove Valley Business Park, Towcester, |(3828642) at 100 Barbirolli Square,
Northants, NN12 6PF, UK T:+44(0)1327359444 |Manchester,M2 3AB VAT:GB 927559189
^ permalink raw reply
* [PATCH] [v2] prom_init: evaluate mem kernel parameter for early allocation
From: Benjamin Krill @ 2009-07-28 8:02 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev, Benjamin Herrenschmidt
Evaluate mem kernel parameter for early memory allocations. If mem is set
no allocation in the region above the given boundary is allowed. The current
code doesn't take care about this and allocate memory above the given mem
boundary.
Signed-off-by: Benjamin Krill <ben@codiert.org>
---
arch/powerpc/kernel/prom_init.c | 103 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 101 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index a538824..069f24e 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -190,6 +190,8 @@ static int __initdata of_platform;
static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
+static unsigned long __initdata prom_memory_limit;
+
static unsigned long __initdata alloc_top;
static unsigned long __initdata alloc_top_high;
static unsigned long __initdata alloc_bottom;
@@ -484,6 +486,67 @@ static int __init prom_setprop(phandle node, const char *nodename,
return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
}
+/* We can't use the standard versions because of RELOC headaches. */
+#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'f') \
+ || ('A' <= (c) && (c) <= 'F'))
+
+#define isdigit(c) ('0' <= (c) && (c) <= '9')
+#define islower(c) ('a' <= (c) && (c) <= 'z')
+#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
+
+unsigned long prom_strtoul(const char *cp, const char **endp)
+{
+ unsigned long result = 0, base = 10, value;
+
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if (toupper(*cp) == 'X') {
+ cp++;
+ base = 16;
+ }
+ }
+
+ while (isxdigit(*cp) &&
+ (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
+ result = result * base + value;
+ cp++;
+ }
+
+ if (endp)
+ *endp = cp;
+
+ return result;
+}
+
+unsigned long prom_memparse(const char *ptr, const char **retptr)
+{
+ unsigned long ret = prom_strtoul(ptr, retptr);
+ int shift = 0;
+
+ /*
+ * We can't use a switch here because GCC *may* generate a
+ * jump table which won't work, because we're not running at
+ * the address we're linked at.
+ */
+ if ('G' == **retptr || 'g' == **retptr)
+ shift = 30;
+
+ if ('M' == **retptr || 'm' == **retptr)
+ shift = 20;
+
+ if ('K' == **retptr || 'k' == **retptr)
+ shift = 10;
+
+ if (shift) {
+ ret <<= shift;
+ (*retptr)++;
+ }
+
+ return ret;
+}
+
/*
* Early parsing of the command line passed to the kernel, used for
* "mem=x" and the options that affect the iommu
@@ -491,9 +554,8 @@ static int __init prom_setprop(phandle node, const char *nodename,
static void __init early_cmdline_parse(void)
{
struct prom_t *_prom = &RELOC(prom);
-#ifdef CONFIG_PPC64
const char *opt;
-#endif
+
char *p;
int l = 0;
@@ -521,6 +583,15 @@ static void __init early_cmdline_parse(void)
RELOC(prom_iommu_force_on) = 1;
}
#endif
+ opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
+ if (opt) {
+ opt += 4;
+ RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
+#ifdef CONFIG_PPC64
+ /* Align to 16 MB == size of ppc64 large page */
+ RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
+#endif
+ }
}
#ifdef CONFIG_PPC_PSERIES
@@ -1027,6 +1098,29 @@ static void __init prom_init_mem(void)
}
/*
+ * If prom_memory_limit is set we reduce the upper limits *except* for
+ * alloc_top_high. This must be the real top of RAM so we can put
+ * TCE's up there.
+ */
+
+ RELOC(alloc_top_high) = RELOC(ram_top);
+
+ if (RELOC(prom_memory_limit)) {
+ if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
+ prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
+ prom_printf("Ignoring mem=%x >= ram_top.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else {
+ RELOC(ram_top) = RELOC(prom_memory_limit);
+ RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
+ }
+ }
+
+ /*
* Setup our top alloc point, that is top of RMO or top of
* segment 0 when running non-LPAR.
* Some RS64 machines have buggy firmware where claims up at
@@ -1041,6 +1135,7 @@ static void __init prom_init_mem(void)
RELOC(alloc_top_high) = RELOC(ram_top);
prom_printf("memory layout at init:\n");
+ prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
@@ -2399,6 +2494,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
/*
* Fill in some infos for use by the kernel later on
*/
+ if (RELOC(prom_memory_limit))
+ prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
+ &RELOC(prom_memory_limit),
+ sizeof(prom_memory_limit));
#ifdef CONFIG_PPC64
if (RELOC(prom_iommu_off))
prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
--
1.5.4.5
^ permalink raw reply related
* Re: Question about tracking freescale patches for Linux
From: Wolfram Sang @ 2009-07-28 8:31 UTC (permalink / raw)
To: B.J. Buchalter; +Cc: linuxppc-dev
In-Reply-To: <06A91D45-B506-44F8-A234-D9E55301349D@mhlabs.com>
[-- Attachment #1: Type: text/plain, Size: 997 bytes --]
> I have contacted Freescale, but they basically say that they provide the
> BSP, and make no commitments to supporting any other version of the linux
> kernel.
So true :(
> 1) is there any way to determine if any these patches are currently
> being worked into the mainline kernel, or if they have been abandoned
> for some reason?
I usually use search engines (which often lead to linux-ppc threads) and
patchwork.ozlabs.org.
>
> 2) Is it worth trying to move these patches up to the head of
> development and trying to get them merged into the mainline kernel, or
> is that really just up to freescale to do?
It surely is worth (and is often done by people not involved with fsl). But be
warned, some patches are in a terrible state, meaning half a rewrite is
necessary.
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ 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