* Re: [PATCH 2/6] powerpc: Define CPU_FTR_HAS_PPR
From: Haren Myneni @ 2012-11-27 0:52 UTC (permalink / raw)
To: Michael Neuling; +Cc: anton, paulus, linuxppc-dev
In-Reply-To: <28905.1353643302@neuling.org>
On 11/22/2012 08:01 PM, Michael Neuling wrote:
> Heaven Myneni <haren@linux.vnet.ibm.com> wrote:
>
>> [PATCH 2/6] powerpc: Define CPU_FTR_HAS_PPR
>>
>> CPU_FTR_HAS_PPR is defined for POWER7.
>>
>> Signed-off-by: Haren Myneni <haren@us.ibm.com>
>> ---
>> arch/powerpc/include/asm/cputable.h | 6 ++++--
>> 1 files changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
>> index 21a0687..12e3a1d 100644
>> --- a/arch/powerpc/include/asm/cputable.h
>> +++ b/arch/powerpc/include/asm/cputable.h
>> @@ -171,6 +171,7 @@ extern const char *powerpc_base_platform;
>> #define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0800000000000000)
>> #define CPU_FTR_ICSWX LONG_ASM_CONST(0x1000000000000000)
>> #define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x2000000000000000)
>> +#define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x4000000000000000)
>>
>> #ifndef __ASSEMBLY__
>>
>> @@ -400,7 +401,8 @@ extern const char *powerpc_base_platform;
>> CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
>> CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
>> CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
>> - CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
>> + CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \
>> + CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR)
>> #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
>> CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
>> CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
>> @@ -422,7 +424,7 @@ extern const char *powerpc_base_platform;
>> (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
>> CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
>> CPU_FTRS_POWER7 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
>> - CPU_FTR_VSX)
>> + CPU_FTR_VSX | CPU_FTR_HAS_PPR)
>
> FYI, there is no need to add this to POSSIBLE, since you are adding it
> to POWER7 anyway.
Will remove CPU_FTR_HAS_PPR for POSSIBLE macro. Added this in second
version for enabling this feature with command parameter, but forgot to
remove it.
Thanks
Haren
>
> Mikey
>
^ permalink raw reply
* Re: [PATCH] vfio powerpc: enabled and supported on powernv platform
From: Benjamin Herrenschmidt @ 2012-11-27 0:21 UTC (permalink / raw)
To: Alex Williamson
Cc: kvm@vger.kernel.org, Alexey Kardashevskiy,
linux-kernel@vger.kernel.org, Paul Mackerras, Sethi Varun-B16395,
linuxppc-dev@lists.ozlabs.org, David Gibson
In-Reply-To: <1353953070.1809.103.camel@bling.home>
On Mon, 2012-11-26 at 11:04 -0700, Alex Williamson wrote:
> Ok, I see tces are put on shutdown via tce_iommu_detach_group, so you're
> more concerned about the guest simply mapping over top of it's own
> mappings. Is that common? Is it common enough for every multi-page
> mapping to assume it will happen? I know this is a performance
> sensitive path for you and it seems like a map-only w/ fallback to
> unmap, remap would be better in the general case.
>
> On x86 we do exactly that, but we do the unmap, remap from userspace
> when we get an EBUSY. Thanks,
Right, Linux as guest at least will never map "over" an existing
mapping. It will always unmap first. IE. The only transition we do on
H_PUT_TCE are 0 -> valid and valid -> 0.
So it would be fine to simplify the code and keep the "map over map" as
a slow fallback. I can't tell for other operating systems but we don't
care about those at this point :-)
Cheers,
Ben.
^ permalink raw reply
* Re: Build regressions/improvements in v3.7-rc7
From: Geert Uytterhoeven @ 2012-11-26 20:56 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev, Linux-sh list
In-Reply-To: <1353963243-21887-1-git-send-email-geert@linux-m68k.org>
On Mon, Nov 26, 2012 at 9:54 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> JFYI, when comparing v3.7-rc7 to v3.7-rc6[3], the summaries are:
> - build errors: +4/-8
+ error: "__sync_fetch_and_and_4"
[drivers/staging/line6/line6usb.ko] undefined!: => N/A
+ error: "__sync_fetch_and_or_4" [drivers/staging/line6/line6usb.ko]
undefined!: => N/A
sh4/sh-randconfig
+ error: "smp_send_reschedule" [arch/powerpc/kvm/kvm.ko] undefined!: => N/A
powerpc/powerpc-randconfig
> [1] http://kisskb.ellerman.id.au/kisskb/head/5646/ (all 117 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/head/5628/ (all 117 configs)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 437/493] char: remove use of __devexit
From: Kent Yoder @ 2012-11-26 20:36 UTC (permalink / raw)
To: Bill Pemberton
Cc: David Airlie, gregkh, Marcel Selhorst, platform-driver-x86,
Rajiv Andrade, Mattia Dongili, tpmdd-devel, Olof Johansson,
openipmi-developer, linuxppc-dev, Sirrix AG, linux-arm-kernel
In-Reply-To: <1353349642-3677-437-git-send-email-wfp5p@virginia.edu>
On Mon, Nov 19, 2012 at 01:26:26PM -0500, Bill Pemberton wrote:
> CONFIG_HOTPLUG is going away as an option so __devexit is no
> longer needed.
>
> Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
> Cc: David Airlie <airlied@linux.ie>
> Cc: Olof Johansson <olof@lixom.net>
> Cc: Mattia Dongili <malattia@linux.it>
> Cc: Kent Yoder <key@linux.vnet.ibm.com>
> Cc: Rajiv Andrade <mail@srajiv.net>
> Cc: Marcel Selhorst <tpmdd@selhorst.net>
> Cc: Sirrix AG <tpmdd@sirrix.com>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: openipmi-developer@lists.sourceforge.net
> Cc: platform-driver-x86@vger.kernel.org
> Cc: tpmdd-devel@lists.sourceforge.net
Acked-by: Kent Yoder <key@linux.vnet.ibm.com>
> ---
> drivers/char/agp/ali-agp.c | 2 +-
> drivers/char/agp/amd-k7-agp.c | 2 +-
> drivers/char/agp/amd64-agp.c | 2 +-
> drivers/char/agp/ati-agp.c | 2 +-
> drivers/char/agp/efficeon-agp.c | 2 +-
> drivers/char/agp/i460-agp.c | 2 +-
> drivers/char/agp/intel-agp.c | 2 +-
> drivers/char/agp/nvidia-agp.c | 2 +-
> drivers/char/agp/sgi-agp.c | 2 +-
> drivers/char/agp/sis-agp.c | 2 +-
> drivers/char/agp/sworks-agp.c | 2 +-
> drivers/char/agp/uninorth-agp.c | 2 +-
> drivers/char/agp/via-agp.c | 2 +-
> drivers/char/hw_random/atmel-rng.c | 2 +-
> drivers/char/hw_random/bcm63xx-rng.c | 2 +-
> drivers/char/hw_random/exynos-rng.c | 2 +-
> drivers/char/hw_random/n2-drv.c | 2 +-
> drivers/char/hw_random/pasemi-rng.c | 2 +-
> drivers/char/hw_random/picoxcell-rng.c | 2 +-
> drivers/char/hw_random/ppc4xx-rng.c | 2 +-
> drivers/char/hw_random/timeriomem-rng.c | 2 +-
> drivers/char/hw_random/virtio-rng.c | 2 +-
> drivers/char/ipmi/ipmi_si_intf.c | 6 +++---
> drivers/char/sonypi.c | 2 +-
> drivers/char/tb0219.c | 2 +-
> drivers/char/tpm/tpm_i2c_infineon.c | 2 +-
> drivers/char/tpm/tpm_ibmvtpm.c | 2 +-
> drivers/char/tpm/tpm_infineon.c | 2 +-
> drivers/char/tpm/tpm_tis.c | 2 +-
> drivers/char/xilinx_hwicap/xilinx_hwicap.c | 4 ++--
> 30 files changed, 33 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
> index 9eb629b..0e69e60 100644
> --- a/drivers/char/agp/ali-agp.c
> +++ b/drivers/char/agp/ali-agp.c
> @@ -374,7 +374,7 @@ found:
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_ali_remove(struct pci_dev *pdev)
> +static void agp_ali_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
> index 2e1efa9..cb9c9f9 100644
> --- a/drivers/char/agp/amd-k7-agp.c
> +++ b/drivers/char/agp/amd-k7-agp.c
> @@ -480,7 +480,7 @@ static int agp_amdk7_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_amdk7_remove(struct pci_dev *pdev)
> +static void agp_amdk7_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
> index f4086c5..280c0d5 100644
> --- a/drivers/char/agp/amd64-agp.c
> +++ b/drivers/char/agp/amd64-agp.c
> @@ -579,7 +579,7 @@ static int agp_amd64_probe(struct pci_dev *pdev,
> return 0;
> }
>
> -static void __devexit agp_amd64_remove(struct pci_dev *pdev)
> +static void agp_amd64_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
> index 6aeb624..485b15c 100644
> --- a/drivers/char/agp/ati-agp.c
> +++ b/drivers/char/agp/ati-agp.c
> @@ -533,7 +533,7 @@ found:
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_ati_remove(struct pci_dev *pdev)
> +static void agp_ati_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
> index bf80cf1..08a465e 100644
> --- a/drivers/char/agp/efficeon-agp.c
> +++ b/drivers/char/agp/efficeon-agp.c
> @@ -407,7 +407,7 @@ static int agp_efficeon_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_efficeon_remove(struct pci_dev *pdev)
> +static void agp_efficeon_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
> index bda2215..0436bf1 100644
> --- a/drivers/char/agp/i460-agp.c
> +++ b/drivers/char/agp/i460-agp.c
> @@ -611,7 +611,7 @@ static int agp_intel_i460_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_intel_i460_remove(struct pci_dev *pdev)
> +static void agp_intel_i460_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
> index ad6739e..362e744 100644
> --- a/drivers/char/agp/intel-agp.c
> +++ b/drivers/char/agp/intel-agp.c
> @@ -819,7 +819,7 @@ found_gmch:
> return err;
> }
>
> -static void __devexit agp_intel_remove(struct pci_dev *pdev)
> +static void agp_intel_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
> index 1f7fddf..adaa47b 100644
> --- a/drivers/char/agp/nvidia-agp.c
> +++ b/drivers/char/agp/nvidia-agp.c
> @@ -388,7 +388,7 @@ static int agp_nvidia_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_nvidia_remove(struct pci_dev *pdev)
> +static void agp_nvidia_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
> index 8356e89..05b8d02 100644
> --- a/drivers/char/agp/sgi-agp.c
> +++ b/drivers/char/agp/sgi-agp.c
> @@ -327,7 +327,7 @@ static int agp_sgi_init(void)
> return 0;
> }
>
> -static void __devexit agp_sgi_cleanup(void)
> +static void agp_sgi_cleanup(void)
> {
> kfree(sgi_tioca_agp_bridges);
> sgi_tioca_agp_bridges = NULL;
> diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
> index 7d6f3c6..37ee0eb 100644
> --- a/drivers/char/agp/sis-agp.c
> +++ b/drivers/char/agp/sis-agp.c
> @@ -211,7 +211,7 @@ static int agp_sis_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_sis_remove(struct pci_dev *pdev)
> +static void agp_sis_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
> index d1b063b..d046de9 100644
> --- a/drivers/char/agp/sworks-agp.c
> +++ b/drivers/char/agp/sworks-agp.c
> @@ -518,7 +518,7 @@ static int agp_serverworks_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_serverworks_remove(struct pci_dev *pdev)
> +static void agp_serverworks_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
> index d7168ca..2d29f04 100644
> --- a/drivers/char/agp/uninorth-agp.c
> +++ b/drivers/char/agp/uninorth-agp.c
> @@ -663,7 +663,7 @@ static int agp_uninorth_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_uninorth_remove(struct pci_dev *pdev)
> +static void agp_uninorth_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
> index 774fe1e..8b2c285 100644
> --- a/drivers/char/agp/via-agp.c
> +++ b/drivers/char/agp/via-agp.c
> @@ -485,7 +485,7 @@ static int agp_via_probe(struct pci_dev *pdev,
> return agp_add_bridge(bridge);
> }
>
> -static void __devexit agp_via_remove(struct pci_dev *pdev)
> +static void agp_via_remove(struct pci_dev *pdev)
> {
> struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
>
> diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
> index 0f6ca8f..7c73d4a 100644
> --- a/drivers/char/hw_random/atmel-rng.c
> +++ b/drivers/char/hw_random/atmel-rng.c
> @@ -98,7 +98,7 @@ err_enable:
> return ret;
> }
>
> -static int __devexit atmel_trng_remove(struct platform_device *pdev)
> +static int atmel_trng_remove(struct platform_device *pdev)
> {
> struct atmel_trng *trng = platform_get_drvdata(pdev);
>
> diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c
> index c46fc74..f343b7d 100644
> --- a/drivers/char/hw_random/bcm63xx-rng.c
> +++ b/drivers/char/hw_random/bcm63xx-rng.c
> @@ -145,7 +145,7 @@ out:
> return ret;
> }
>
> -static int __devexit bcm63xx_rng_remove(struct platform_device *pdev)
> +static int bcm63xx_rng_remove(struct platform_device *pdev)
> {
> struct hwrng *rng = platform_get_drvdata(pdev);
> struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
> diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c
> index 92d302a..48bbfec 100644
> --- a/drivers/char/hw_random/exynos-rng.c
> +++ b/drivers/char/hw_random/exynos-rng.c
> @@ -134,7 +134,7 @@ static int exynos_rng_probe(struct platform_device *pdev)
> return hwrng_register(&exynos_rng->rng);
> }
>
> -static int __devexit exynos_rng_remove(struct platform_device *pdev)
> +static int exynos_rng_remove(struct platform_device *pdev)
> {
> struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
>
> diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
> index 5819c7b..20b962e 100644
> --- a/drivers/char/hw_random/n2-drv.c
> +++ b/drivers/char/hw_random/n2-drv.c
> @@ -719,7 +719,7 @@ out:
> return err;
> }
>
> -static int __devexit n2rng_remove(struct platform_device *op)
> +static int n2rng_remove(struct platform_device *op)
> {
> struct n2rng *np = dev_get_drvdata(&op->dev);
>
> diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c
> index da5dfb5..c6df5b2 100644
> --- a/drivers/char/hw_random/pasemi-rng.c
> +++ b/drivers/char/hw_random/pasemi-rng.c
> @@ -122,7 +122,7 @@ static int rng_probe(struct platform_device *ofdev)
> return err;
> }
>
> -static int __devexit rng_remove(struct platform_device *dev)
> +static int rng_remove(struct platform_device *dev)
> {
> void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv;
>
> diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c
> index b4f7f06..973b951 100644
> --- a/drivers/char/hw_random/picoxcell-rng.c
> +++ b/drivers/char/hw_random/picoxcell-rng.c
> @@ -151,7 +151,7 @@ err_enable:
> return ret;
> }
>
> -static int __devexit picoxcell_trng_remove(struct platform_device *pdev)
> +static int picoxcell_trng_remove(struct platform_device *pdev)
> {
> hwrng_unregister(&picoxcell_trng);
> clk_disable(rng_clk);
> diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c
> index c4b89c2..732c330 100644
> --- a/drivers/char/hw_random/ppc4xx-rng.c
> +++ b/drivers/char/hw_random/ppc4xx-rng.c
> @@ -111,7 +111,7 @@ static int ppc4xx_rng_probe(struct platform_device *dev)
> return err;
> }
>
> -static int __devexit ppc4xx_rng_remove(struct platform_device *dev)
> +static int ppc4xx_rng_remove(struct platform_device *dev)
> {
> void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv;
>
> diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
> index 0153d0c..849db19 100644
> --- a/drivers/char/hw_random/timeriomem-rng.c
> +++ b/drivers/char/hw_random/timeriomem-rng.c
> @@ -130,7 +130,7 @@ failed:
> return ret;
> }
>
> -static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
> +static int timeriomem_rng_remove(struct platform_device *pdev)
> {
> del_timer_sync(&timeriomem_rng_timer);
> hwrng_unregister(&timeriomem_rng_ops);
> diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
> index bb78033..b65c103 100644
> --- a/drivers/char/hw_random/virtio-rng.c
> +++ b/drivers/char/hw_random/virtio-rng.c
> @@ -119,7 +119,7 @@ static int virtrng_probe(struct virtio_device *vdev)
> return probe_common(vdev);
> }
>
> -static void __devexit virtrng_remove(struct virtio_device *vdev)
> +static void virtrng_remove(struct virtio_device *vdev)
> {
> remove_common(vdev);
> }
> diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
> index 94c5b88..14ab4c4 100644
> --- a/drivers/char/ipmi/ipmi_si_intf.c
> +++ b/drivers/char/ipmi/ipmi_si_intf.c
> @@ -2228,7 +2228,7 @@ err_free:
> return -EINVAL;
> }
>
> -static void __devexit ipmi_pnp_remove(struct pnp_dev *dev)
> +static void ipmi_pnp_remove(struct pnp_dev *dev)
> {
> struct smi_info *info = pnp_get_drvdata(dev);
>
> @@ -2529,7 +2529,7 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
> return 0;
> }
>
> -static void __devexit ipmi_pci_remove(struct pci_dev *pdev)
> +static void ipmi_pci_remove(struct pci_dev *pdev)
> {
> struct smi_info *info = pci_get_drvdata(pdev);
> cleanup_one_si(info);
> @@ -2635,7 +2635,7 @@ static int ipmi_probe(struct platform_device *dev)
> return 0;
> }
>
> -static int __devexit ipmi_remove(struct platform_device *dev)
> +static int ipmi_remove(struct platform_device *dev)
> {
> #ifdef CONFIG_OF
> cleanup_one_si(dev_get_drvdata(&dev->dev));
> diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
> index 861efa4..d780295 100644
> --- a/drivers/char/sonypi.c
> +++ b/drivers/char/sonypi.c
> @@ -1428,7 +1428,7 @@ static int sonypi_probe(struct platform_device *dev)
> return error;
> }
>
> -static int __devexit sonypi_remove(struct platform_device *dev)
> +static int sonypi_remove(struct platform_device *dev)
> {
> sonypi_disable();
>
> diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
> index 76e3aea..34c63f8 100644
> --- a/drivers/char/tb0219.c
> +++ b/drivers/char/tb0219.c
> @@ -318,7 +318,7 @@ static int tb0219_probe(struct platform_device *dev)
> return 0;
> }
>
> -static int __devexit tb0219_remove(struct platform_device *dev)
> +static int tb0219_remove(struct platform_device *dev)
> {
> _machine_restart = old_machine_restart;
>
> diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
> index bcdb078..fb447bd 100644
> --- a/drivers/char/tpm/tpm_i2c_infineon.c
> +++ b/drivers/char/tpm/tpm_i2c_infineon.c
> @@ -656,7 +656,7 @@ static int tpm_tis_i2c_probe(struct i2c_client *client,
> return rc;
> }
>
> -static int __devexit tpm_tis_i2c_remove(struct i2c_client *client)
> +static int tpm_tis_i2c_remove(struct i2c_client *client)
> {
> struct tpm_chip *chip = tpm_dev.chip;
> release_locality(chip, chip->vendor.locality, 1);
> diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
> index a027bd8..9978609 100644
> --- a/drivers/char/tpm/tpm_ibmvtpm.c
> +++ b/drivers/char/tpm/tpm_ibmvtpm.c
> @@ -267,7 +267,7 @@ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
> * Return value:
> * 0
> */
> -static int __devexit tpm_ibmvtpm_remove(struct vio_dev *vdev)
> +static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
> {
> struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev);
> int rc = 0;
> diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
> index 0126e80..2b480c2 100644
> --- a/drivers/char/tpm/tpm_infineon.c
> +++ b/drivers/char/tpm/tpm_infineon.c
> @@ -594,7 +594,7 @@ err_last:
> return rc;
> }
>
> -static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
> +static void tpm_inf_pnp_remove(struct pnp_dev *dev)
> {
> struct tpm_chip *chip = pnp_get_drvdata(dev);
>
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index 419a7e0..ea31daf 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -783,7 +783,7 @@ static struct pnp_device_id tpm_pnp_tbl[] = {
> };
> MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
>
> -static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
> +static void tpm_tis_pnp_remove(struct pnp_dev *dev)
> {
> struct tpm_chip *chip = pnp_get_drvdata(dev);
>
> diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
> index d10085f..5224da52 100644
> --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
> +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
> @@ -717,7 +717,7 @@ static struct hwicap_driver_config fifo_icap_config = {
> .reset = fifo_icap_reset,
> };
>
> -static int __devexit hwicap_remove(struct device *dev)
> +static int hwicap_remove(struct device *dev)
> {
> struct hwicap_drvdata *drvdata;
>
> @@ -822,7 +822,7 @@ static int hwicap_drv_probe(struct platform_device *pdev)
> &buffer_icap_config, regs);
> }
>
> -static int __devexit hwicap_drv_remove(struct platform_device *pdev)
> +static int hwicap_drv_remove(struct platform_device *pdev)
> {
> return hwicap_remove(&pdev->dev);
> }
> --
> 1.8.0
>
^ permalink raw reply
* Re: [PATCH 1/2] vfio powerpc: implemented IOMMU driver for VFIO
From: Alex Williamson @ 2012-11-26 18:20 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: kvm, linux-kernel, Paul Mackerras, linuxppc-dev, David Gibson
In-Reply-To: <1353661396-14374-2-git-send-email-aik@ozlabs.ru>
On Fri, 2012-11-23 at 20:03 +1100, Alexey Kardashevskiy wrote:
> VFIO implements platform independent stuff such as
> a PCI driver, BAR access (via read/write on a file descriptor
> or direct mapping when possible) and IRQ signaling.
>
> The platform dependent part includes IOMMU initialization
> and handling. This patch implements an IOMMU driver for VFIO
> which does mapping/unmapping pages for the guest IO and
> provides information about DMA window (required by a POWERPC
> guest).
>
> The counterpart in QEMU is required to support this functionality.
>
> Cc: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> drivers/vfio/Kconfig | 6 +
> drivers/vfio/Makefile | 1 +
> drivers/vfio/vfio_iommu_spapr_tce.c | 247 +++++++++++++++++++++++++++++++++++
> include/linux/vfio.h | 20 +++
> 4 files changed, 274 insertions(+)
> create mode 100644 drivers/vfio/vfio_iommu_spapr_tce.c
>
> diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
> index 7cd5dec..b464687 100644
> --- a/drivers/vfio/Kconfig
> +++ b/drivers/vfio/Kconfig
> @@ -3,10 +3,16 @@ config VFIO_IOMMU_TYPE1
> depends on VFIO
> default n
>
> +config VFIO_IOMMU_SPAPR_TCE
> + tristate
> + depends on VFIO && SPAPR_TCE_IOMMU
> + default n
> +
> menuconfig VFIO
> tristate "VFIO Non-Privileged userspace driver framework"
> depends on IOMMU_API
> select VFIO_IOMMU_TYPE1 if X86
> + select VFIO_IOMMU_SPAPR_TCE if PPC_POWERNV
> help
> VFIO provides a framework for secure userspace device drivers.
> See Documentation/vfio.txt for more details.
> diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile
> index 2398d4a..72bfabc 100644
> --- a/drivers/vfio/Makefile
> +++ b/drivers/vfio/Makefile
> @@ -1,3 +1,4 @@
> obj-$(CONFIG_VFIO) += vfio.o
> obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
> +obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
> obj-$(CONFIG_VFIO_PCI) += pci/
> diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
> new file mode 100644
> index 0000000..46a6298
> --- /dev/null
> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c
> @@ -0,0 +1,247 @@
> +/*
> + * VFIO: IOMMU DMA mapping support for TCE on POWER
> + *
> + * Copyright (C) 2012 IBM Corp. All rights reserved.
> + * Author: Alexey Kardashevskiy <aik@ozlabs.ru>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Derived from original vfio_iommu_type1.c:
> + * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
> + * Author: Alex Williamson <alex.williamson@redhat.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/pci.h>
> +#include <linux/slab.h>
> +#include <linux/uaccess.h>
> +#include <linux/err.h>
> +#include <linux/vfio.h>
> +#include <asm/iommu.h>
> +
> +#define DRIVER_VERSION "0.1"
> +#define DRIVER_AUTHOR "aik@ozlabs.ru"
> +#define DRIVER_DESC "VFIO IOMMU SPAPR TCE"
> +
> +static void tce_iommu_detach_group(void *iommu_data,
> + struct iommu_group *iommu_group);
> +
> +/*
> + * VFIO IOMMU fd for SPAPR_TCE IOMMU implementation
> + */
> +
> +/*
> + * The container descriptor supports only a single group per container.
> + * Required by the API as the container is not supplied with the IOMMU group
> + * at the moment of initialization.
> + */
> +struct tce_container {
> + struct mutex lock;
> + struct iommu_table *tbl;
> +};
> +
> +static void *tce_iommu_open(unsigned long arg)
> +{
> + struct tce_container *container;
> +
> + if (arg != VFIO_SPAPR_TCE_IOMMU) {
> + printk(KERN_ERR "tce_vfio: Wrong IOMMU type\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + container = kzalloc(sizeof(*container), GFP_KERNEL);
> + if (!container)
> + return ERR_PTR(-ENOMEM);
> +
> + mutex_init(&container->lock);
> +
> + return container;
> +}
> +
> +static void tce_iommu_release(void *iommu_data)
> +{
> + struct tce_container *container = iommu_data;
> +
> + WARN_ON(container->tbl && !container->tbl->it_group);
I think your patch ordering is backwards here. it_group isn't added
until 2/2. I'd really like to see the arch/powerpc code approved and
merged by the powerpc maintainer before we add the code that makes use
of it into vfio. Otherwise we just get lots of churn if interfaces
change or they disapprove of it altogether.
> + if (container->tbl && container->tbl->it_group)
> + tce_iommu_detach_group(iommu_data, container->tbl->it_group);
> +
> + mutex_destroy(&container->lock);
> +
> + kfree(container);
> +}
> +
> +static long tce_iommu_ioctl(void *iommu_data,
> + unsigned int cmd, unsigned long arg)
> +{
> + struct tce_container *container = iommu_data;
> + unsigned long minsz;
> +
> + switch (cmd) {
> + case VFIO_CHECK_EXTENSION: {
> + return (arg == VFIO_SPAPR_TCE_IOMMU) ? 1 : 0;
> + }
> + case VFIO_IOMMU_SPAPR_TCE_GET_INFO: {
> + struct vfio_iommu_spapr_tce_info info;
> + struct iommu_table *tbl = container->tbl;
> +
> + if (WARN_ON(!tbl))
> + return -ENXIO;
> +
> + minsz = offsetofend(struct vfio_iommu_spapr_tce_info,
> + dma64_window_size);
> +
> + if (copy_from_user(&info, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (info.argsz < minsz)
> + return -EINVAL;
> +
> + info.dma32_window_start = tbl->it_offset << IOMMU_PAGE_SHIFT;
> + info.dma32_window_size = tbl->it_size << IOMMU_PAGE_SHIFT;
> + info.dma64_window_start = 0;
> + info.dma64_window_size = 0;
> + info.flags = 0;
> +
> + if (copy_to_user((void __user *)arg, &info, minsz))
> + return -EFAULT;
> +
> + return 0;
> + }
> + case VFIO_IOMMU_MAP_DMA: {
> + vfio_iommu_spapr_tce_dma_map param;
> + struct iommu_table *tbl = container->tbl;
> + enum dma_data_direction direction = DMA_NONE;
> +
> + if (WARN_ON(!tbl))
> + return -ENXIO;
> +
> + minsz = offsetofend(vfio_iommu_spapr_tce_dma_map, size);
> +
> + if (copy_from_user(¶m, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (param.argsz < minsz)
> + return -EINVAL;
> +
> + if ((param.flags & VFIO_DMA_MAP_FLAG_READ) &&
> + (param.flags & VFIO_DMA_MAP_FLAG_WRITE)) {
> + direction = DMA_BIDIRECTIONAL;
> + } else if (param.flags & VFIO_DMA_MAP_FLAG_READ) {
> + direction = DMA_TO_DEVICE;
> + } else if (param.flags & VFIO_DMA_MAP_FLAG_WRITE) {
> + direction = DMA_FROM_DEVICE;
> + }
> +
> + param.size += param.iova & ~IOMMU_PAGE_MASK;
> + param.size = _ALIGN_UP(param.size, IOMMU_PAGE_SIZE);
On x86 we force iova, vaddr, and size to all be aligned to the smallest
page granularity of the iommu and return -EINVAL if it doesn't fit.
What does it imply to the user if they're always aligned to work here?
Won't this interface happily map overlapping entries with no indication
to the user that the previous mapping is no longer valid?
Maybe another reason why a combined unmap/map makes me nervous, we have
to assume the user knows what they're doing.
> +
> + return iommu_put_tces(tbl, param.iova >> IOMMU_PAGE_SHIFT,
> + param.vaddr & IOMMU_PAGE_MASK, direction,
> + param.size >> IOMMU_PAGE_SHIFT);
> + }
> + case VFIO_IOMMU_UNMAP_DMA: {
> + vfio_iommu_spapr_tce_dma_unmap param;
> + struct iommu_table *tbl = container->tbl;
> +
> + if (WARN_ON(!tbl))
> + return -ENXIO;
> +
> + minsz = offsetofend(vfio_iommu_spapr_tce_dma_unmap, size);
> +
> + if (copy_from_user(¶m, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (param.argsz < minsz)
> + return -EINVAL;
> +
> + param.size += param.iova & ~IOMMU_PAGE_MASK;
> + param.size = _ALIGN_UP(param.size, IOMMU_PAGE_SIZE);
> +
> + return iommu_put_tces(tbl, param.iova >> IOMMU_PAGE_SHIFT,
> + 0, DMA_NONE, param.size >> IOMMU_PAGE_SHIFT);
> + }
> + default:
> + printk(KERN_WARNING "tce_vfio: unexpected cmd %x\n", cmd);
pr_warn
> + }
> +
> + return -ENOTTY;
> +}
> +
> +static int tce_iommu_attach_group(void *iommu_data,
> + struct iommu_group *iommu_group)
> +{
> + struct tce_container *container = iommu_data;
> + struct iommu_table *tbl = iommu_group_get_iommudata(iommu_group);
> +
> + BUG_ON(!tbl);
> + mutex_lock(&container->lock);
> + pr_debug("tce_vfio: Attaching group #%u to iommu %p\n",
> + iommu_group_id(iommu_group), iommu_group);
> + if (container->tbl) {
> + printk(KERN_WARNING "tce_vfio: Only one group per IOMMU container is allowed, existing id=%d, attaching id=%d\n",
pr_warn
> + iommu_group_id(container->tbl->it_group),
> + iommu_group_id(iommu_group));
> + mutex_unlock(&container->lock);
> + return -EBUSY;
> + }
> +
> + container->tbl = tbl;
Would it be too much paranoia to clear all the tce here as you do below
on detach? ie. is there any risk that there's leftover programming?
x86 allocates a new domain on open of the iommu, so we always start out
clean.
> + mutex_unlock(&container->lock);
> +
> + return 0;
> +}
> +
> +static void tce_iommu_detach_group(void *iommu_data,
> + struct iommu_group *iommu_group)
> +{
> + struct tce_container *container = iommu_data;
> + struct iommu_table *tbl = iommu_group_get_iommudata(iommu_group);
> +
> + BUG_ON(!tbl);
> + mutex_lock(&container->lock);
> + if (tbl != container->tbl) {
> + printk(KERN_WARNING "tce_vfio: detaching group #%u, expected group is #%u\n",
pr_warn
> + iommu_group_id(iommu_group),
> + iommu_group_id(tbl->it_group));
> + } else {
> +
> + pr_debug("tce_vfio: detaching group #%u from iommu %p\n",
> + iommu_group_id(iommu_group), iommu_group);
> +
> + iommu_put_tces(tbl, tbl->it_offset, 0, DMA_NONE, tbl->it_size);
So this cleans out any mappings when vfio is closed, good.
> + container->tbl = NULL;
> + }
> + mutex_unlock(&container->lock);
> +}
> +
> +const struct vfio_iommu_driver_ops tce_iommu_driver_ops = {
> + .name = "iommu-vfio-powerpc",
> + .owner = THIS_MODULE,
> + .open = tce_iommu_open,
> + .release = tce_iommu_release,
> + .ioctl = tce_iommu_ioctl,
> + .attach_group = tce_iommu_attach_group,
> + .detach_group = tce_iommu_detach_group,
> +};
> +
> +static int __init tce_iommu_init(void)
> +{
> + return vfio_register_iommu_driver(&tce_iommu_driver_ops);
> +}
> +
> +static void __exit tce_iommu_cleanup(void)
> +{
> + vfio_unregister_iommu_driver(&tce_iommu_driver_ops);
> +}
> +
> +module_init(tce_iommu_init);
> +module_exit(tce_iommu_cleanup);
> +
> +MODULE_VERSION(DRIVER_VERSION);
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR(DRIVER_AUTHOR);
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +
> diff --git a/include/linux/vfio.h b/include/linux/vfio.h
> index 0a4f180..3ecd65c 100644
> --- a/include/linux/vfio.h
> +++ b/include/linux/vfio.h
> @@ -99,6 +99,7 @@ extern void vfio_unregister_iommu_driver(
> /* Extensions */
>
> #define VFIO_TYPE1_IOMMU 1
> +#define VFIO_SPAPR_TCE_IOMMU 2
>
> /*
> * The IOCTL interface is designed for extensibility by embedding the
> @@ -442,4 +443,23 @@ struct vfio_iommu_type1_dma_unmap {
>
> #define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14)
>
> +/* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */
> +
> +struct vfio_iommu_spapr_tce_info {
> + __u32 argsz;
> + __u32 flags;
> + __u32 dma32_window_start;
> + __u32 dma32_window_size;
> + __u64 dma64_window_start;
> + __u64 dma64_window_size;
> +};
Is there anything we can document about this? It should probably list
that size is in bytes. Is there any need to communicate the IOMMU page
size here?
> +
> +#define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
> +
> +/* Reuse type1 map/unmap structs as they are the same at the moment */
> +typedef struct vfio_iommu_type1_dma_map vfio_iommu_spapr_tce_dma_map;
> +typedef struct vfio_iommu_type1_dma_unmap vfio_iommu_spapr_tce_dma_unmap;
> +
> +/* ***************************************************************** */
> +
> #endif /* VFIO_H */
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH] vfio powerpc: enabled and supported on powernv platform
From: Alex Williamson @ 2012-11-26 18:04 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Mackerras,
Sethi Varun-B16395, linuxppc-dev@lists.ozlabs.org, David Gibson
In-Reply-To: <1353943130.1809.29.camel@bling.home>
On Mon, 2012-11-26 at 08:18 -0700, Alex Williamson wrote:
> On Fri, 2012-11-23 at 13:02 +1100, Alexey Kardashevskiy wrote:
> > On 22/11/12 22:56, Sethi Varun-B16395 wrote:
> > >
> > >
> > >> -----Original Message-----
> > >> From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
> > >> owner@vger.kernel.org] On Behalf Of Alex Williamson
> > >> Sent: Tuesday, November 20, 2012 11:50 PM
> > >> To: Alexey Kardashevskiy
> > >> Cc: Benjamin Herrenschmidt; Paul Mackerras; linuxppc-
> > >> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; kvm@vger.kernel.org;
> > >> David Gibson
> > >> Subject: Re: [PATCH] vfio powerpc: enabled and supported on powernv
> > >> platform
> > >>
> > >> On Tue, 2012-11-20 at 11:48 +1100, Alexey Kardashevskiy wrote:
> > >>> VFIO implements platform independent stuff such as a PCI driver, BAR
> > >>> access (via read/write on a file descriptor or direct mapping when
> > >>> possible) and IRQ signaling.
> > >>> The platform dependent part includes IOMMU initialization and
> > >>> handling.
> > >>>
> > >>> This patch initializes IOMMU groups based on the IOMMU configuration
> > >>> discovered during the PCI scan, only POWERNV platform is supported at
> > >>> the moment.
> > >>>
> > >>> Also the patch implements an VFIO-IOMMU driver which manages DMA
> > >>> mapping/unmapping requests coming from the client (now QEMU). It also
> > >>> returns a DMA window information to let the guest initialize the
> > >>> device tree for a guest OS properly. Although this driver has been
> > >>> tested only on POWERNV, it should work on any platform supporting TCE
> > >>> tables.
> > >>>
> > >>> To enable VFIO on POWER, enable SPAPR_TCE_IOMMU config option.
> > >>>
> > >>> Cc: David Gibson <david@gibson.dropbear.id.au>
> > >>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> > >>> ---
> > >>> arch/powerpc/include/asm/iommu.h | 6 +
> > >>> arch/powerpc/kernel/iommu.c | 140 +++++++++++++++++++
> > >>> arch/powerpc/platforms/powernv/pci.c | 135 +++++++++++++++++++
> > >>> drivers/iommu/Kconfig | 8 ++
> > >>> drivers/vfio/Kconfig | 6 +
> > >>> drivers/vfio/Makefile | 1 +
> > >>> drivers/vfio/vfio_iommu_spapr_tce.c | 247
> > >> ++++++++++++++++++++++++++++++++++
> > >>> include/linux/vfio.h | 20 +++
> > >>> 8 files changed, 563 insertions(+)
> > >>> create mode 100644 drivers/vfio/vfio_iommu_spapr_tce.c
> > >>>
> > >>> diff --git a/arch/powerpc/include/asm/iommu.h
> > >>> b/arch/powerpc/include/asm/iommu.h
> > >>> index cbfe678..5ba66cb 100644
> > >>> --- a/arch/powerpc/include/asm/iommu.h
> > >>> +++ b/arch/powerpc/include/asm/iommu.h
> > >>> @@ -64,30 +64,33 @@ struct iommu_pool { }
> > >>> ____cacheline_aligned_in_smp;
> > >>>
> > >>> struct iommu_table {
> > >>> unsigned long it_busno; /* Bus number this table belongs to */
> > >>> unsigned long it_size; /* Size of iommu table in entries */
> > >>> unsigned long it_offset; /* Offset into global table */
> > >>> unsigned long it_base; /* mapped address of tce table */
> > >>> unsigned long it_index; /* which iommu table this is */
> > >>> unsigned long it_type; /* type: PCI or Virtual Bus */
> > >>> unsigned long it_blocksize; /* Entries in each block (cacheline)
> > >> */
> > >>> unsigned long poolsize;
> > >>> unsigned long nr_pools;
> > >>> struct iommu_pool large_pool;
> > >>> struct iommu_pool pools[IOMMU_NR_POOLS];
> > >>> unsigned long *it_map; /* A simple allocation bitmap for now
> > >> */
> > >>> +#ifdef CONFIG_IOMMU_API
> > >>> + struct iommu_group *it_group;
> > >>> +#endif
> > >>> };
> > >>>
> > >>> struct scatterlist;
> > >>>
> > >>> static inline void set_iommu_table_base(struct device *dev, void
> > >>> *base) {
> > >>> dev->archdata.dma_data.iommu_table_base = base; }
> > >>>
> > >>> static inline void *get_iommu_table_base(struct device *dev) {
> > >>> return dev->archdata.dma_data.iommu_table_base;
> > >>> }
> > >>>
> > >>> /* Frees table for an individual device node */ @@ -135,17 +138,20 @@
> > >>> static inline void pci_iommu_init(void) { } extern void
> > >>> alloc_dart_table(void); #if defined(CONFIG_PPC64) &&
> > >>> defined(CONFIG_PM) static inline void iommu_save(void) {
> > >>> if (ppc_md.iommu_save)
> > >>> ppc_md.iommu_save();
> > >>> }
> > >>>
> > >>> static inline void iommu_restore(void) {
> > >>> if (ppc_md.iommu_restore)
> > >>> ppc_md.iommu_restore();
> > >>> }
> > >>> #endif
> > >>>
> > >>> +extern long iommu_put_tces(struct iommu_table *tbl, unsigned long
> > >> entry, uint64_t tce,
> > >>> + enum dma_data_direction direction, unsigned long pages);
> > >>> +
> > >>> #endif /* __KERNEL__ */
> > >>> #endif /* _ASM_IOMMU_H */
> > >>> diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
> > >>> index ff5a6ce..94f614b 100644
> > >>> --- a/arch/powerpc/kernel/iommu.c
> > >>> +++ b/arch/powerpc/kernel/iommu.c
> > >>> @@ -32,30 +32,31 @@
> > >>> #include <linux/dma-mapping.h>
> > >>> #include <linux/bitmap.h>
> > >>> #include <linux/iommu-helper.h>
> > >>> #include <linux/crash_dump.h>
> > >>> #include <linux/hash.h>
> > >>> #include <linux/fault-inject.h>
> > >>> #include <linux/pci.h>
> > >>> #include <asm/io.h>
> > >>> #include <asm/prom.h>
> > >>> #include <asm/iommu.h>
> > >>> #include <asm/pci-bridge.h>
> > >>> #include <asm/machdep.h>
> > >>> #include <asm/kdump.h>
> > >>> #include <asm/fadump.h>
> > >>> #include <asm/vio.h>
> > >>> +#include <asm/tce.h>
> > >>>
> > >>> #define DBG(...)
> > >>>
> > >>> static int novmerge;
> > >>>
> > >>> static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned
> > >>> int);
> > >>>
> > >>> static int __init setup_iommu(char *str) {
> > >>> if (!strcmp(str, "novmerge"))
> > >>> novmerge = 1;
> > >>> else if (!strcmp(str, "vmerge"))
> > >>> novmerge = 0;
> > >>> return 1;
> > >>> }
> > >>> @@ -844,15 +845,154 @@ void *iommu_alloc_coherent(struct device *dev,
> > >>> struct iommu_table *tbl, }
> > >>>
> > >>> void iommu_free_coherent(struct iommu_table *tbl, size_t size,
> > >>> void *vaddr, dma_addr_t dma_handle) {
> > >>> if (tbl) {
> > >>> unsigned int nio_pages;
> > >>>
> > >>> size = PAGE_ALIGN(size);
> > >>> nio_pages = size >> IOMMU_PAGE_SHIFT;
> > >>> iommu_free(tbl, dma_handle, nio_pages);
> > >>> size = PAGE_ALIGN(size);
> > >>> free_pages((unsigned long)vaddr, get_order(size));
> > >>> }
> > >>> }
> > >>> +
> > >>> +#ifdef CONFIG_IOMMU_API
> > >>> +/*
> > >>> + * SPAPR TCE API
> > >>> + */
> > >>> +static struct page *free_tce(struct iommu_table *tbl, unsigned long
> > >>> +entry) {
> > >>> + struct page *page = NULL;
> > >>
> > >> NULL initialization doesn't appear to be necessary
> > >>
> > >>> + unsigned long oldtce;
> > >>> +
> > >>> + oldtce = ppc_md.tce_get(tbl, entry);
> > >>> +
> > >>> + if (!(oldtce & (TCE_PCI_WRITE | TCE_PCI_READ)))
> > >>> + return NULL;
> > >>> +
> > >>> + page = pfn_to_page(oldtce >> PAGE_SHIFT);
> > >>> +
> > >>> + WARN_ON(!page);
> > >>> + if (page && (oldtce & TCE_PCI_WRITE))
> > >>> + SetPageDirty(page);
> > >>> + ppc_md.tce_free(tbl, entry, 1);
> > >>> +
> > >>> + return page;
> > >>> +}
> > >>> +
> > >>> +static int put_tce(struct iommu_table *tbl, unsigned long entry,
> > >>> + uint64_t tce, enum dma_data_direction direction) {
> > >>> + int ret;
> > >>> + struct page *page = NULL;
> > >>> + unsigned long kva, offset;
> > >>> +
> > >>> + /* Map new TCE */
> > >>> + offset = (tce & IOMMU_PAGE_MASK) - (tce & PAGE_MASK);
> > >>> + ret = get_user_pages_fast(tce & PAGE_MASK, 1,
> > >>> + direction != DMA_TO_DEVICE, &page);
> > >>> + if (ret < 1) {
> > >>> + printk(KERN_ERR "tce_vfio: get_user_pages_fast failed
> > >> tce=%llx ioba=%lx ret=%d\n",
> > >>> + tce, entry << IOMMU_PAGE_SHIFT, ret);
> > >>> + if (!ret)
> > >>> + ret = -EFAULT;
> > >>
> > >> Missing return ret? Otherwise we've got some bogus uses of page below
> > >> and we're setting ret for no reason here.
> > >>
> > >>> + }
> > >>> +
> > >>> + kva = (unsigned long) page_address(page);
> > >>> + kva += offset;
> > >>> +
> > >>> + /* tce_build receives a virtual address */
> > >>> + entry += tbl->it_offset; /* Offset into real TCE table */
> > >>> + ret = ppc_md.tce_build(tbl, entry, 1, kva, direction, NULL);
> > >>> +
> > >>> + /* tce_build() only returns non-zero for transient errors */
> > >>> + if (unlikely(ret)) {
> > >>> + printk(KERN_ERR "tce_vfio: tce_put failed on tce=%llx
> > >> ioba=%lx kva=%lx ret=%d\n",
> > >>> + tce, entry << IOMMU_PAGE_SHIFT, kva, ret);
> > >>> + put_page(page);
> > >>> + return -EIO;
> > >>> + }
> > >>> +
> > >>> + return 0;
> > >>> +}
> > >>> +
> > >>> +static void tce_flush(struct iommu_table *tbl) {
> > >>> + /* Flush/invalidate TLB caches if necessary */
> > >>> + if (ppc_md.tce_flush)
> > >>> + ppc_md.tce_flush(tbl);
> > >>> +
> > >>> + /* Make sure updates are seen by hardware */
> > >>> + mb();
> > >>> +}
> > >>> +
> > >>> +long iommu_put_tces(struct iommu_table *tbl, unsigned long entry,
> > >> uint64_t tce,
> > >>> + enum dma_data_direction direction, unsigned long pages) {
> > >>> + int i, ret = 0, pages_to_put = 0;
> > >>> + struct page *page;
> > >>> + struct iommu_pool *pool = get_pool(tbl, entry);
> > >>> + struct page **oldpages;
> > >>> + const int oldpagesnum = PAGE_SIZE/sizeof(*oldpages);
> > >>> +
> > >>> + BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE);
> > >>> +
> > >>> + /* Handle a single page request without allocation
> > >>> + of pages-to-release array */
> > >>> + if (pages == 1) {
> > >>> + spin_lock(&(pool->lock));
> > >>> + page = free_tce(tbl, entry);
> > >>> +
> > >>> + if (direction != DMA_NONE)
> > >>> + ret = put_tce(tbl, entry, tce, direction);
> > >>> +
> > >>> + tce_flush(tbl);
> > >>> +
> > >>> + if (page)
> > >>> + put_page(page);
> > >>> +
> > >>> + spin_unlock(&(pool->lock));
> > >>> + return ret;
> > >>> + }
> > >>> +
> > >>> + /* Releasing multiple pages */
> > >>> + /* Allocate an array for pages to be released after TCE table
> > >>> + is updated */
> > >>> + oldpages = kmalloc(PAGE_SIZE, GFP_KERNEL);
> > >>> + if (!oldpages)
> > >>> + return -ENOMEM;
> > >>> +
> > >>> + spin_lock(&(pool->lock));
> > >>> +
> > >>> + for (i = 0; (i < pages) && !ret; ++i, ++entry, tce +=
> > >> IOMMU_PAGE_SIZE) {
> > >>> + page = free_tce(tbl, entry);
> > >>> + if (page) {
> > >>> + oldpages[pages_to_put] = page;
> > >>> + ++pages_to_put;
> > >>> + }
> > >>> +
> > >>> + if (direction != DMA_NONE)
> > >>> + ret = put_tce(tbl, entry, tce, direction);
> > >>> +
> > >>> + /* Release old pages if we reached the end of oldpages[] or
> > >>> + it is the last page or we are about to exit the loop */
> > >>> + if ((pages_to_put == oldpagesnum) || (i == pages - 1) || ret)
> > >> {
> > >>> + tce_flush(tbl);
> > >>
> > >> Avoiding tce_flush() is the reason for all this extra overhead, right?
> > >> I wonder if it'd be cleaner separating map vs unmap, where the map case
> > >> can avoid the oldpages array... but that means inserting new mappings on
> > >> top of old ones wouldn't put the pages.
> >
> >
> > Yes, we do not want to loose pages if the guest forgot to unmap them.
>
> Hmm, does that mean we're not actively clearing tce entries or somehow
> disabling the iommu window when the iommu is released through vfio?
Ok, I see tces are put on shutdown via tce_iommu_detach_group, so you're
more concerned about the guest simply mapping over top of it's own
mappings. Is that common? Is it common enough for every multi-page
mapping to assume it will happen? I know this is a performance
sensitive path for you and it seems like a map-only w/ fallback to
unmap, remap would be better in the general case.
On x86 we do exactly that, but we do the unmap, remap from userspace
when we get an EBUSY. Thanks,
Alex
^ permalink raw reply
* Re: [Pv-drivers] [PATCH 192/493] scsi: remove use of __devinit
From: Dmitry Torokhov @ 2012-11-26 17:37 UTC (permalink / raw)
To: Bill Pemberton
Cc: VMware PV-Drivers, Kurt Garloff, Kai Mäkisara, GOTO Masanori,
Russell King, linux-scsi, Jamie Lenehan, osst-users, Michael Reed,
cbe-oss-dev, iss_storagedev, Matthew Wilcox, Ali Akcaagac, dc395x,
linux-arm-kernel, Neela Syam Kolli, Geoff Levand, gregkh,
Oliver Neukum, James E.J. Bottomley, Willem Riede, YOKOTA Hiroshi,
linuxppc-dev, Guennadi Liakhovetski
In-Reply-To: <1353349642-3677-192-git-send-email-wfp5p@virginia.edu>
On Mon, Nov 19, 2012 at 01:22:21PM -0500, Bill Pemberton wrote:
> CONFIG_HOTPLUG is going away as an option so __devinit is no longer
> needed.
>
...
> drivers/scsi/vmw_pvscsi.c | 6 +-
For vmw_pvscsi:
Acked-by: Dmitry Torokhov <dtor@vmware.com>
Thanks,
Dmitry
^ permalink raw reply
* Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEBUG_API
From: Shuah Khan @ 2012-11-26 16:09 UTC (permalink / raw)
To: Joerg Roedel
Cc: linux-mips, linux-ia64, a-jacquiot, catalin.marinas, Ming Lei,
shuahkhan, sparclinux, m.szyprowski, linux-c6x-dev, linux-sh,
msalter, fenghua.yu, microblaze-uclinux, linux-arm-kernel, monstr,
tony.luck, LKML, ralf, lethal, linuxppc-dev, davem
In-Reply-To: <20121126112217.GG25742@8bytes.org>
On Mon, 2012-11-26 at 12:22 +0100, Joerg Roedel wrote:
> Hi Shuah,
>
> On Fri, Nov 23, 2012 at 02:29:02PM -0700, Shuah Khan wrote:
> > x86 - done in the first patch that added the feature.
> >
> > ARM64: dma_debug: add debug_dma_mapping_error support
> > c6x: dma_debug: add debug_dma_mapping_error support
> > ia64: dma_debug: add debug_dma_mapping_error support
> > microblaze: dma-mapping: support debug_dma_mapping_error
> > mips: dma_debug: add debug_dma_mapping_error support
> > powerpc: dma_debug: add debug_dma_mapping_error support
> > sh: dma_debug: add debug_dma_mapping_error support
> > sparc: dma_debug: add debug_dma_mapping_error support
> > tile: dma_debug: add debug_dma_mapping_error support
>
> Have you compile-tested the invididual archs you are changing here?
>
Joerg,
Yes I compile tested all of them (except microblaze) on Nov 20th
linux_next git. The patch for microblaze is already in linux_next when I
tried to apply the patch to Nov 20th linux-next and figured that is
already covered and skipped that one.
-- Shuah
^ permalink raw reply
* Re: [PATCH] vfio powerpc: enabled and supported on powernv platform
From: Alex Williamson @ 2012-11-26 15:18 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Mackerras,
Sethi Varun-B16395, linuxppc-dev@lists.ozlabs.org, David Gibson
In-Reply-To: <50AED94E.4000006@ozlabs.ru>
On Fri, 2012-11-23 at 13:02 +1100, Alexey Kardashevskiy wrote:
> On 22/11/12 22:56, Sethi Varun-B16395 wrote:
> >
> >
> >> -----Original Message-----
> >> From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
> >> owner@vger.kernel.org] On Behalf Of Alex Williamson
> >> Sent: Tuesday, November 20, 2012 11:50 PM
> >> To: Alexey Kardashevskiy
> >> Cc: Benjamin Herrenschmidt; Paul Mackerras; linuxppc-
> >> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; kvm@vger.kernel.org;
> >> David Gibson
> >> Subject: Re: [PATCH] vfio powerpc: enabled and supported on powernv
> >> platform
> >>
> >> On Tue, 2012-11-20 at 11:48 +1100, Alexey Kardashevskiy wrote:
> >>> VFIO implements platform independent stuff such as a PCI driver, BAR
> >>> access (via read/write on a file descriptor or direct mapping when
> >>> possible) and IRQ signaling.
> >>> The platform dependent part includes IOMMU initialization and
> >>> handling.
> >>>
> >>> This patch initializes IOMMU groups based on the IOMMU configuration
> >>> discovered during the PCI scan, only POWERNV platform is supported at
> >>> the moment.
> >>>
> >>> Also the patch implements an VFIO-IOMMU driver which manages DMA
> >>> mapping/unmapping requests coming from the client (now QEMU). It also
> >>> returns a DMA window information to let the guest initialize the
> >>> device tree for a guest OS properly. Although this driver has been
> >>> tested only on POWERNV, it should work on any platform supporting TCE
> >>> tables.
> >>>
> >>> To enable VFIO on POWER, enable SPAPR_TCE_IOMMU config option.
> >>>
> >>> Cc: David Gibson <david@gibson.dropbear.id.au>
> >>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> >>> ---
> >>> arch/powerpc/include/asm/iommu.h | 6 +
> >>> arch/powerpc/kernel/iommu.c | 140 +++++++++++++++++++
> >>> arch/powerpc/platforms/powernv/pci.c | 135 +++++++++++++++++++
> >>> drivers/iommu/Kconfig | 8 ++
> >>> drivers/vfio/Kconfig | 6 +
> >>> drivers/vfio/Makefile | 1 +
> >>> drivers/vfio/vfio_iommu_spapr_tce.c | 247
> >> ++++++++++++++++++++++++++++++++++
> >>> include/linux/vfio.h | 20 +++
> >>> 8 files changed, 563 insertions(+)
> >>> create mode 100644 drivers/vfio/vfio_iommu_spapr_tce.c
> >>>
> >>> diff --git a/arch/powerpc/include/asm/iommu.h
> >>> b/arch/powerpc/include/asm/iommu.h
> >>> index cbfe678..5ba66cb 100644
> >>> --- a/arch/powerpc/include/asm/iommu.h
> >>> +++ b/arch/powerpc/include/asm/iommu.h
> >>> @@ -64,30 +64,33 @@ struct iommu_pool { }
> >>> ____cacheline_aligned_in_smp;
> >>>
> >>> struct iommu_table {
> >>> unsigned long it_busno; /* Bus number this table belongs to */
> >>> unsigned long it_size; /* Size of iommu table in entries */
> >>> unsigned long it_offset; /* Offset into global table */
> >>> unsigned long it_base; /* mapped address of tce table */
> >>> unsigned long it_index; /* which iommu table this is */
> >>> unsigned long it_type; /* type: PCI or Virtual Bus */
> >>> unsigned long it_blocksize; /* Entries in each block (cacheline)
> >> */
> >>> unsigned long poolsize;
> >>> unsigned long nr_pools;
> >>> struct iommu_pool large_pool;
> >>> struct iommu_pool pools[IOMMU_NR_POOLS];
> >>> unsigned long *it_map; /* A simple allocation bitmap for now
> >> */
> >>> +#ifdef CONFIG_IOMMU_API
> >>> + struct iommu_group *it_group;
> >>> +#endif
> >>> };
> >>>
> >>> struct scatterlist;
> >>>
> >>> static inline void set_iommu_table_base(struct device *dev, void
> >>> *base) {
> >>> dev->archdata.dma_data.iommu_table_base = base; }
> >>>
> >>> static inline void *get_iommu_table_base(struct device *dev) {
> >>> return dev->archdata.dma_data.iommu_table_base;
> >>> }
> >>>
> >>> /* Frees table for an individual device node */ @@ -135,17 +138,20 @@
> >>> static inline void pci_iommu_init(void) { } extern void
> >>> alloc_dart_table(void); #if defined(CONFIG_PPC64) &&
> >>> defined(CONFIG_PM) static inline void iommu_save(void) {
> >>> if (ppc_md.iommu_save)
> >>> ppc_md.iommu_save();
> >>> }
> >>>
> >>> static inline void iommu_restore(void) {
> >>> if (ppc_md.iommu_restore)
> >>> ppc_md.iommu_restore();
> >>> }
> >>> #endif
> >>>
> >>> +extern long iommu_put_tces(struct iommu_table *tbl, unsigned long
> >> entry, uint64_t tce,
> >>> + enum dma_data_direction direction, unsigned long pages);
> >>> +
> >>> #endif /* __KERNEL__ */
> >>> #endif /* _ASM_IOMMU_H */
> >>> diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
> >>> index ff5a6ce..94f614b 100644
> >>> --- a/arch/powerpc/kernel/iommu.c
> >>> +++ b/arch/powerpc/kernel/iommu.c
> >>> @@ -32,30 +32,31 @@
> >>> #include <linux/dma-mapping.h>
> >>> #include <linux/bitmap.h>
> >>> #include <linux/iommu-helper.h>
> >>> #include <linux/crash_dump.h>
> >>> #include <linux/hash.h>
> >>> #include <linux/fault-inject.h>
> >>> #include <linux/pci.h>
> >>> #include <asm/io.h>
> >>> #include <asm/prom.h>
> >>> #include <asm/iommu.h>
> >>> #include <asm/pci-bridge.h>
> >>> #include <asm/machdep.h>
> >>> #include <asm/kdump.h>
> >>> #include <asm/fadump.h>
> >>> #include <asm/vio.h>
> >>> +#include <asm/tce.h>
> >>>
> >>> #define DBG(...)
> >>>
> >>> static int novmerge;
> >>>
> >>> static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned
> >>> int);
> >>>
> >>> static int __init setup_iommu(char *str) {
> >>> if (!strcmp(str, "novmerge"))
> >>> novmerge = 1;
> >>> else if (!strcmp(str, "vmerge"))
> >>> novmerge = 0;
> >>> return 1;
> >>> }
> >>> @@ -844,15 +845,154 @@ void *iommu_alloc_coherent(struct device *dev,
> >>> struct iommu_table *tbl, }
> >>>
> >>> void iommu_free_coherent(struct iommu_table *tbl, size_t size,
> >>> void *vaddr, dma_addr_t dma_handle) {
> >>> if (tbl) {
> >>> unsigned int nio_pages;
> >>>
> >>> size = PAGE_ALIGN(size);
> >>> nio_pages = size >> IOMMU_PAGE_SHIFT;
> >>> iommu_free(tbl, dma_handle, nio_pages);
> >>> size = PAGE_ALIGN(size);
> >>> free_pages((unsigned long)vaddr, get_order(size));
> >>> }
> >>> }
> >>> +
> >>> +#ifdef CONFIG_IOMMU_API
> >>> +/*
> >>> + * SPAPR TCE API
> >>> + */
> >>> +static struct page *free_tce(struct iommu_table *tbl, unsigned long
> >>> +entry) {
> >>> + struct page *page = NULL;
> >>
> >> NULL initialization doesn't appear to be necessary
> >>
> >>> + unsigned long oldtce;
> >>> +
> >>> + oldtce = ppc_md.tce_get(tbl, entry);
> >>> +
> >>> + if (!(oldtce & (TCE_PCI_WRITE | TCE_PCI_READ)))
> >>> + return NULL;
> >>> +
> >>> + page = pfn_to_page(oldtce >> PAGE_SHIFT);
> >>> +
> >>> + WARN_ON(!page);
> >>> + if (page && (oldtce & TCE_PCI_WRITE))
> >>> + SetPageDirty(page);
> >>> + ppc_md.tce_free(tbl, entry, 1);
> >>> +
> >>> + return page;
> >>> +}
> >>> +
> >>> +static int put_tce(struct iommu_table *tbl, unsigned long entry,
> >>> + uint64_t tce, enum dma_data_direction direction) {
> >>> + int ret;
> >>> + struct page *page = NULL;
> >>> + unsigned long kva, offset;
> >>> +
> >>> + /* Map new TCE */
> >>> + offset = (tce & IOMMU_PAGE_MASK) - (tce & PAGE_MASK);
> >>> + ret = get_user_pages_fast(tce & PAGE_MASK, 1,
> >>> + direction != DMA_TO_DEVICE, &page);
> >>> + if (ret < 1) {
> >>> + printk(KERN_ERR "tce_vfio: get_user_pages_fast failed
> >> tce=%llx ioba=%lx ret=%d\n",
> >>> + tce, entry << IOMMU_PAGE_SHIFT, ret);
> >>> + if (!ret)
> >>> + ret = -EFAULT;
> >>
> >> Missing return ret? Otherwise we've got some bogus uses of page below
> >> and we're setting ret for no reason here.
> >>
> >>> + }
> >>> +
> >>> + kva = (unsigned long) page_address(page);
> >>> + kva += offset;
> >>> +
> >>> + /* tce_build receives a virtual address */
> >>> + entry += tbl->it_offset; /* Offset into real TCE table */
> >>> + ret = ppc_md.tce_build(tbl, entry, 1, kva, direction, NULL);
> >>> +
> >>> + /* tce_build() only returns non-zero for transient errors */
> >>> + if (unlikely(ret)) {
> >>> + printk(KERN_ERR "tce_vfio: tce_put failed on tce=%llx
> >> ioba=%lx kva=%lx ret=%d\n",
> >>> + tce, entry << IOMMU_PAGE_SHIFT, kva, ret);
> >>> + put_page(page);
> >>> + return -EIO;
> >>> + }
> >>> +
> >>> + return 0;
> >>> +}
> >>> +
> >>> +static void tce_flush(struct iommu_table *tbl) {
> >>> + /* Flush/invalidate TLB caches if necessary */
> >>> + if (ppc_md.tce_flush)
> >>> + ppc_md.tce_flush(tbl);
> >>> +
> >>> + /* Make sure updates are seen by hardware */
> >>> + mb();
> >>> +}
> >>> +
> >>> +long iommu_put_tces(struct iommu_table *tbl, unsigned long entry,
> >> uint64_t tce,
> >>> + enum dma_data_direction direction, unsigned long pages) {
> >>> + int i, ret = 0, pages_to_put = 0;
> >>> + struct page *page;
> >>> + struct iommu_pool *pool = get_pool(tbl, entry);
> >>> + struct page **oldpages;
> >>> + const int oldpagesnum = PAGE_SIZE/sizeof(*oldpages);
> >>> +
> >>> + BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE);
> >>> +
> >>> + /* Handle a single page request without allocation
> >>> + of pages-to-release array */
> >>> + if (pages == 1) {
> >>> + spin_lock(&(pool->lock));
> >>> + page = free_tce(tbl, entry);
> >>> +
> >>> + if (direction != DMA_NONE)
> >>> + ret = put_tce(tbl, entry, tce, direction);
> >>> +
> >>> + tce_flush(tbl);
> >>> +
> >>> + if (page)
> >>> + put_page(page);
> >>> +
> >>> + spin_unlock(&(pool->lock));
> >>> + return ret;
> >>> + }
> >>> +
> >>> + /* Releasing multiple pages */
> >>> + /* Allocate an array for pages to be released after TCE table
> >>> + is updated */
> >>> + oldpages = kmalloc(PAGE_SIZE, GFP_KERNEL);
> >>> + if (!oldpages)
> >>> + return -ENOMEM;
> >>> +
> >>> + spin_lock(&(pool->lock));
> >>> +
> >>> + for (i = 0; (i < pages) && !ret; ++i, ++entry, tce +=
> >> IOMMU_PAGE_SIZE) {
> >>> + page = free_tce(tbl, entry);
> >>> + if (page) {
> >>> + oldpages[pages_to_put] = page;
> >>> + ++pages_to_put;
> >>> + }
> >>> +
> >>> + if (direction != DMA_NONE)
> >>> + ret = put_tce(tbl, entry, tce, direction);
> >>> +
> >>> + /* Release old pages if we reached the end of oldpages[] or
> >>> + it is the last page or we are about to exit the loop */
> >>> + if ((pages_to_put == oldpagesnum) || (i == pages - 1) || ret)
> >> {
> >>> + tce_flush(tbl);
> >>
> >> Avoiding tce_flush() is the reason for all this extra overhead, right?
> >> I wonder if it'd be cleaner separating map vs unmap, where the map case
> >> can avoid the oldpages array... but that means inserting new mappings on
> >> top of old ones wouldn't put the pages.
>
>
> Yes, we do not want to loose pages if the guest forgot to unmap them.
Hmm, does that mean we're not actively clearing tce entries or somehow
disabling the iommu window when the iommu is released through vfio?
> >>> +
> >>> + /* Release pages after removing them from TCE table */
> >>> + while (pages_to_put) {
> >>> + --pages_to_put;
> >>> + put_page(oldpages[pages_to_put]);
> >>> + }
> >>> + }
> >>> + }
> >>> +
> >>> + spin_unlock(&(pool->lock));
> >>> + kfree(oldpages);
> >>> +
> >>> + return ret;
> >>> +}
> >>> +EXPORT_SYMBOL_GPL(iommu_put_tces);
> >>> +#endif /* CONFIG_IOMMU_API */
> >>> diff --git a/arch/powerpc/platforms/powernv/pci.c
> >>> b/arch/powerpc/platforms/powernv/pci.c
> >>> index 05205cf..676f4d9 100644
> >>> --- a/arch/powerpc/platforms/powernv/pci.c
> >>> +++ b/arch/powerpc/platforms/powernv/pci.c
> >>> @@ -8,30 +8,31 @@
> >>> * This program is free software; you can redistribute it and/or
> >>> * modify it under the terms of the GNU General Public License
> >>> * as published by the Free Software Foundation; either version
> >>> * 2 of the License, or (at your option) any later version.
> >>> */
> >>>
> >>> #include <linux/kernel.h>
> >>> #include <linux/pci.h>
> >>> #include <linux/delay.h>
> >>> #include <linux/string.h>
> >>> #include <linux/init.h>
> >>> #include <linux/bootmem.h>
> >>> #include <linux/irq.h>
> >>> #include <linux/io.h>
> >>> #include <linux/msi.h>
> >>> +#include <linux/iommu.h>
> >>>
> >>> #include <asm/sections.h>
> >>> #include <asm/io.h>
> >>> #include <asm/prom.h>
> >>> #include <asm/pci-bridge.h>
> >>> #include <asm/machdep.h>
> >>> #include <asm/ppc-pci.h>
> >>> #include <asm/opal.h>
> >>> #include <asm/iommu.h>
> >>> #include <asm/tce.h>
> >>> #include <asm/abs_addr.h>
> >>> #include <asm/firmware.h>
> >>>
> >>> #include "powernv.h"
> >>> #include "pci.h"
> >>> @@ -601,15 +602,149 @@ void __init pnv_pci_init(void)
> >>> /* Configure IOMMU DMA hooks */
> >>> ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup;
> >>> ppc_md.tce_build = pnv_tce_build;
> >>> ppc_md.tce_free = pnv_tce_free;
> >>> ppc_md.tce_get = pnv_tce_get;
> >>> ppc_md.pci_probe_mode = pnv_pci_probe_mode;
> >>> set_pci_dma_ops(&dma_iommu_ops);
> >>>
> >>> /* Configure MSIs */
> >>> #ifdef CONFIG_PCI_MSI
> >>> ppc_md.msi_check_device = pnv_msi_check_device;
> >>> ppc_md.setup_msi_irqs = pnv_setup_msi_irqs;
> >>> ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs; #endif }
> >>> +
> >>> +#ifdef CONFIG_IOMMU_API
> >>> +/*
> >>> + * IOMMU groups support required by VFIO */ static int
> >>> +add_device(struct device *dev) {
> >>> + struct iommu_table *tbl;
> >>> + int ret = 0;
> >>> +
> >>> + if (WARN_ON(dev->iommu_group)) {
> >>> + printk(KERN_WARNING "tce_vfio: device %s is already in iommu
> >> group %d, skipping\n",
> >>> + dev->kobj.name,
> >>
> >> dev_name(dev)
> >>
> >>> + iommu_group_id(dev->iommu_group));
> >>> + return -EBUSY;
> >>> + }
> >>> +
> >>> + tbl = get_iommu_table_base(dev);
> >>> + if (!tbl) {
> >>> + pr_debug("tce_vfio: skipping device %s with no tbl\n",
> >>> + dev->kobj.name);
> >>> + return 0;
> >>> + }
> >>> +
> >>> + pr_debug("tce_vfio: adding %s to iommu group %d\n",
> >>> + dev->kobj.name, iommu_group_id(tbl->it_group));
> >>> +
> >>> + ret = iommu_group_add_device(tbl->it_group, dev);
> >>> + if (ret < 0)
> >>> + printk(KERN_ERR "tce_vfio: %s has not been added, ret=%d\n",
> >>> + dev->kobj.name, ret);
> >>> +
> >>> + return ret;
> >>> +}
> >>> +
> >>> +static void del_device(struct device *dev) {
> >>> + iommu_group_remove_device(dev);
> >>> +}
> >>> +
> >>> +static int iommu_bus_notifier(struct notifier_block *nb,
> >>> + unsigned long action, void *data) {
> >>> + struct device *dev = data;
> >>> +
> >>> + switch (action) {
> >>> + case BUS_NOTIFY_ADD_DEVICE:
> >>> + return add_device(dev);
> >>> + case BUS_NOTIFY_DEL_DEVICE:
> >>> + del_device(dev);
> >>> + return 0;
> >>> + default:
> >>> + return 0;
> >>> + }
> >>> +}
> >>> +
> >>> +static struct notifier_block tce_iommu_bus_nb = {
> >>> + .notifier_call = iommu_bus_notifier, };
> >>> +
> >>> +static void group_release(void *iommu_data) {
> >>> + struct iommu_table *tbl = iommu_data;
> >>> + tbl->it_group = NULL;
> >>> +}
> >>> +
> >>> +static int __init tce_iommu_init(void) {
> >>> + struct pci_dev *pdev = NULL;
> >>> + struct iommu_table *tbl;
> >>> + struct iommu_group *grp;
> >>> +
> >>> + bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
> >>
> >> There's already a notifier in the iommu code if you were to register an
> >> iommu_ops with the add/remove_device entries. That would allow you to
> >> remove the notifier block and notifier function below and the second loop
> >> below. Are you avoiding that to avoid the rest of iommu_ops?
>
> Yes. I need to implement either a small part of iommu_ops (especially the
> part which I think should not be there at all) or notifier, cannot how how
> the first is simpler.
>
>
> > [Sethi Varun-B16395] Could be one reason, also they are associating the iommu group with the tce table entry and not the device.
>
> Also true.
> I would actually allocate IOMMU groups right after we discovered the new
> one but this is done during PCI scan which works before
> subsys_initcall(iommu_init) is called so I added this first loop.
>
>
> >> Also, shouldn't this notifier only be registered after the first loop
> >> below? Otherwise ADD_DEVICE could race with setting up groups, which we
> >> assume are present in the add_device() above.
> > [Sethi Varun-B16395] Isn't this similar to how how the notifier is registered in iommu_bus_init? First a notifier is registered and then we check for devices that have already been probed.
>
> Yep. Not very familiar with this stuff but if it is done one way and it is
> already upstream, I cannot see why I should go another way :)
The existing notifier callback and loop should be able to operate in
parallel... of course they don't because we're not actively adding new
devices at the point where it's setup. IIRC, the notifier callback
blindly uses something that's not setup at the point it's registered.
That's a bit sloppy. Maybe I'm mis-remembering, I'll verify in your new
version. Thanks,
Alex
^ permalink raw reply
* Re: [PATCH] vfio powerpc: enabled and supported on powernv platform
From: Alex Williamson @ 2012-11-26 15:08 UTC (permalink / raw)
To: Sethi Varun-B16395
Cc: kvm@vger.kernel.org, Alexey Kardashevskiy,
linux-kernel@vger.kernel.org, Paul Mackerras,
linuxppc-dev@lists.ozlabs.org, David Gibson
In-Reply-To: <C5ECD7A89D1DC44195F34B25E172658D294605@039-SN2MPN1-013.039d.mgd.msft.net>
On Thu, 2012-11-22 at 11:56 +0000, Sethi Varun-B16395 wrote:
>
> > -----Original Message-----
> > From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
> > owner@vger.kernel.org] On Behalf Of Alex Williamson
> > Sent: Tuesday, November 20, 2012 11:50 PM
> > To: Alexey Kardashevskiy
> > Cc: Benjamin Herrenschmidt; Paul Mackerras; linuxppc-
> > dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; kvm@vger.kernel.org;
> > David Gibson
> > Subject: Re: [PATCH] vfio powerpc: enabled and supported on powernv
> > platform
> >
> > On Tue, 2012-11-20 at 11:48 +1100, Alexey Kardashevskiy wrote:
> > > VFIO implements platform independent stuff such as a PCI driver, BAR
> > > access (via read/write on a file descriptor or direct mapping when
> > > possible) and IRQ signaling.
> > > The platform dependent part includes IOMMU initialization and
> > > handling.
> > >
> > > This patch initializes IOMMU groups based on the IOMMU configuration
> > > discovered during the PCI scan, only POWERNV platform is supported at
> > > the moment.
> > >
> > > Also the patch implements an VFIO-IOMMU driver which manages DMA
> > > mapping/unmapping requests coming from the client (now QEMU). It also
> > > returns a DMA window information to let the guest initialize the
> > > device tree for a guest OS properly. Although this driver has been
> > > tested only on POWERNV, it should work on any platform supporting TCE
> > > tables.
> > >
> > > To enable VFIO on POWER, enable SPAPR_TCE_IOMMU config option.
> > >
> > > Cc: David Gibson <david@gibson.dropbear.id.au>
> > > Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> > > ---
> > > arch/powerpc/include/asm/iommu.h | 6 +
> > > arch/powerpc/kernel/iommu.c | 140 +++++++++++++++++++
> > > arch/powerpc/platforms/powernv/pci.c | 135 +++++++++++++++++++
> > > drivers/iommu/Kconfig | 8 ++
> > > drivers/vfio/Kconfig | 6 +
> > > drivers/vfio/Makefile | 1 +
> > > drivers/vfio/vfio_iommu_spapr_tce.c | 247
> > ++++++++++++++++++++++++++++++++++
> > > include/linux/vfio.h | 20 +++
> > > 8 files changed, 563 insertions(+)
> > > create mode 100644 drivers/vfio/vfio_iommu_spapr_tce.c
> > >
> > > diff --git a/arch/powerpc/include/asm/iommu.h
> > > b/arch/powerpc/include/asm/iommu.h
> > > index cbfe678..5ba66cb 100644
> > > --- a/arch/powerpc/include/asm/iommu.h
> > > +++ b/arch/powerpc/include/asm/iommu.h
> > > @@ -64,30 +64,33 @@ struct iommu_pool { }
> > > ____cacheline_aligned_in_smp;
> > >
> > > struct iommu_table {
> > > unsigned long it_busno; /* Bus number this table belongs to */
> > > unsigned long it_size; /* Size of iommu table in entries */
> > > unsigned long it_offset; /* Offset into global table */
> > > unsigned long it_base; /* mapped address of tce table */
> > > unsigned long it_index; /* which iommu table this is */
> > > unsigned long it_type; /* type: PCI or Virtual Bus */
> > > unsigned long it_blocksize; /* Entries in each block (cacheline)
> > */
> > > unsigned long poolsize;
> > > unsigned long nr_pools;
> > > struct iommu_pool large_pool;
> > > struct iommu_pool pools[IOMMU_NR_POOLS];
> > > unsigned long *it_map; /* A simple allocation bitmap for now
> > */
> > > +#ifdef CONFIG_IOMMU_API
> > > + struct iommu_group *it_group;
> > > +#endif
> > > };
> > >
> > > struct scatterlist;
> > >
> > > static inline void set_iommu_table_base(struct device *dev, void
> > > *base) {
> > > dev->archdata.dma_data.iommu_table_base = base; }
> > >
> > > static inline void *get_iommu_table_base(struct device *dev) {
> > > return dev->archdata.dma_data.iommu_table_base;
> > > }
> > >
> > > /* Frees table for an individual device node */ @@ -135,17 +138,20 @@
> > > static inline void pci_iommu_init(void) { } extern void
> > > alloc_dart_table(void); #if defined(CONFIG_PPC64) &&
> > > defined(CONFIG_PM) static inline void iommu_save(void) {
> > > if (ppc_md.iommu_save)
> > > ppc_md.iommu_save();
> > > }
> > >
> > > static inline void iommu_restore(void) {
> > > if (ppc_md.iommu_restore)
> > > ppc_md.iommu_restore();
> > > }
> > > #endif
> > >
> > > +extern long iommu_put_tces(struct iommu_table *tbl, unsigned long
> > entry, uint64_t tce,
> > > + enum dma_data_direction direction, unsigned long pages);
> > > +
> > > #endif /* __KERNEL__ */
> > > #endif /* _ASM_IOMMU_H */
> > > diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
> > > index ff5a6ce..94f614b 100644
> > > --- a/arch/powerpc/kernel/iommu.c
> > > +++ b/arch/powerpc/kernel/iommu.c
> > > @@ -32,30 +32,31 @@
> > > #include <linux/dma-mapping.h>
> > > #include <linux/bitmap.h>
> > > #include <linux/iommu-helper.h>
> > > #include <linux/crash_dump.h>
> > > #include <linux/hash.h>
> > > #include <linux/fault-inject.h>
> > > #include <linux/pci.h>
> > > #include <asm/io.h>
> > > #include <asm/prom.h>
> > > #include <asm/iommu.h>
> > > #include <asm/pci-bridge.h>
> > > #include <asm/machdep.h>
> > > #include <asm/kdump.h>
> > > #include <asm/fadump.h>
> > > #include <asm/vio.h>
> > > +#include <asm/tce.h>
> > >
> > > #define DBG(...)
> > >
> > > static int novmerge;
> > >
> > > static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned
> > > int);
> > >
> > > static int __init setup_iommu(char *str) {
> > > if (!strcmp(str, "novmerge"))
> > > novmerge = 1;
> > > else if (!strcmp(str, "vmerge"))
> > > novmerge = 0;
> > > return 1;
> > > }
> > > @@ -844,15 +845,154 @@ void *iommu_alloc_coherent(struct device *dev,
> > > struct iommu_table *tbl, }
> > >
> > > void iommu_free_coherent(struct iommu_table *tbl, size_t size,
> > > void *vaddr, dma_addr_t dma_handle) {
> > > if (tbl) {
> > > unsigned int nio_pages;
> > >
> > > size = PAGE_ALIGN(size);
> > > nio_pages = size >> IOMMU_PAGE_SHIFT;
> > > iommu_free(tbl, dma_handle, nio_pages);
> > > size = PAGE_ALIGN(size);
> > > free_pages((unsigned long)vaddr, get_order(size));
> > > }
> > > }
> > > +
> > > +#ifdef CONFIG_IOMMU_API
> > > +/*
> > > + * SPAPR TCE API
> > > + */
> > > +static struct page *free_tce(struct iommu_table *tbl, unsigned long
> > > +entry) {
> > > + struct page *page = NULL;
> >
> > NULL initialization doesn't appear to be necessary
> >
> > > + unsigned long oldtce;
> > > +
> > > + oldtce = ppc_md.tce_get(tbl, entry);
> > > +
> > > + if (!(oldtce & (TCE_PCI_WRITE | TCE_PCI_READ)))
> > > + return NULL;
> > > +
> > > + page = pfn_to_page(oldtce >> PAGE_SHIFT);
> > > +
> > > + WARN_ON(!page);
> > > + if (page && (oldtce & TCE_PCI_WRITE))
> > > + SetPageDirty(page);
> > > + ppc_md.tce_free(tbl, entry, 1);
> > > +
> > > + return page;
> > > +}
> > > +
> > > +static int put_tce(struct iommu_table *tbl, unsigned long entry,
> > > + uint64_t tce, enum dma_data_direction direction) {
> > > + int ret;
> > > + struct page *page = NULL;
> > > + unsigned long kva, offset;
> > > +
> > > + /* Map new TCE */
> > > + offset = (tce & IOMMU_PAGE_MASK) - (tce & PAGE_MASK);
> > > + ret = get_user_pages_fast(tce & PAGE_MASK, 1,
> > > + direction != DMA_TO_DEVICE, &page);
> > > + if (ret < 1) {
> > > + printk(KERN_ERR "tce_vfio: get_user_pages_fast failed
> > tce=%llx ioba=%lx ret=%d\n",
> > > + tce, entry << IOMMU_PAGE_SHIFT, ret);
> > > + if (!ret)
> > > + ret = -EFAULT;
> >
> > Missing return ret? Otherwise we've got some bogus uses of page below
> > and we're setting ret for no reason here.
> >
> > > + }
> > > +
> > > + kva = (unsigned long) page_address(page);
> > > + kva += offset;
> > > +
> > > + /* tce_build receives a virtual address */
> > > + entry += tbl->it_offset; /* Offset into real TCE table */
> > > + ret = ppc_md.tce_build(tbl, entry, 1, kva, direction, NULL);
> > > +
> > > + /* tce_build() only returns non-zero for transient errors */
> > > + if (unlikely(ret)) {
> > > + printk(KERN_ERR "tce_vfio: tce_put failed on tce=%llx
> > ioba=%lx kva=%lx ret=%d\n",
> > > + tce, entry << IOMMU_PAGE_SHIFT, kva, ret);
> > > + put_page(page);
> > > + return -EIO;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void tce_flush(struct iommu_table *tbl) {
> > > + /* Flush/invalidate TLB caches if necessary */
> > > + if (ppc_md.tce_flush)
> > > + ppc_md.tce_flush(tbl);
> > > +
> > > + /* Make sure updates are seen by hardware */
> > > + mb();
> > > +}
> > > +
> > > +long iommu_put_tces(struct iommu_table *tbl, unsigned long entry,
> > uint64_t tce,
> > > + enum dma_data_direction direction, unsigned long pages) {
> > > + int i, ret = 0, pages_to_put = 0;
> > > + struct page *page;
> > > + struct iommu_pool *pool = get_pool(tbl, entry);
> > > + struct page **oldpages;
> > > + const int oldpagesnum = PAGE_SIZE/sizeof(*oldpages);
> > > +
> > > + BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE);
> > > +
> > > + /* Handle a single page request without allocation
> > > + of pages-to-release array */
> > > + if (pages == 1) {
> > > + spin_lock(&(pool->lock));
> > > + page = free_tce(tbl, entry);
> > > +
> > > + if (direction != DMA_NONE)
> > > + ret = put_tce(tbl, entry, tce, direction);
> > > +
> > > + tce_flush(tbl);
> > > +
> > > + if (page)
> > > + put_page(page);
> > > +
> > > + spin_unlock(&(pool->lock));
> > > + return ret;
> > > + }
> > > +
> > > + /* Releasing multiple pages */
> > > + /* Allocate an array for pages to be released after TCE table
> > > + is updated */
> > > + oldpages = kmalloc(PAGE_SIZE, GFP_KERNEL);
> > > + if (!oldpages)
> > > + return -ENOMEM;
> > > +
> > > + spin_lock(&(pool->lock));
> > > +
> > > + for (i = 0; (i < pages) && !ret; ++i, ++entry, tce +=
> > IOMMU_PAGE_SIZE) {
> > > + page = free_tce(tbl, entry);
> > > + if (page) {
> > > + oldpages[pages_to_put] = page;
> > > + ++pages_to_put;
> > > + }
> > > +
> > > + if (direction != DMA_NONE)
> > > + ret = put_tce(tbl, entry, tce, direction);
> > > +
> > > + /* Release old pages if we reached the end of oldpages[] or
> > > + it is the last page or we are about to exit the loop */
> > > + if ((pages_to_put == oldpagesnum) || (i == pages - 1) || ret)
> > {
> > > + tce_flush(tbl);
> >
> > Avoiding tce_flush() is the reason for all this extra overhead, right?
> > I wonder if it'd be cleaner separating map vs unmap, where the map case
> > can avoid the oldpages array... but that means inserting new mappings on
> > top of old ones wouldn't put the pages.
> >
> > > +
> > > + /* Release pages after removing them from TCE table */
> > > + while (pages_to_put) {
> > > + --pages_to_put;
> > > + put_page(oldpages[pages_to_put]);
> > > + }
> > > + }
> > > + }
> > > +
> > > + spin_unlock(&(pool->lock));
> > > + kfree(oldpages);
> > > +
> > > + return ret;
> > > +}
> > > +EXPORT_SYMBOL_GPL(iommu_put_tces);
> > > +#endif /* CONFIG_IOMMU_API */
> > > diff --git a/arch/powerpc/platforms/powernv/pci.c
> > > b/arch/powerpc/platforms/powernv/pci.c
> > > index 05205cf..676f4d9 100644
> > > --- a/arch/powerpc/platforms/powernv/pci.c
> > > +++ b/arch/powerpc/platforms/powernv/pci.c
> > > @@ -8,30 +8,31 @@
> > > * This program is free software; you can redistribute it and/or
> > > * modify it under the terms of the GNU General Public License
> > > * as published by the Free Software Foundation; either version
> > > * 2 of the License, or (at your option) any later version.
> > > */
> > >
> > > #include <linux/kernel.h>
> > > #include <linux/pci.h>
> > > #include <linux/delay.h>
> > > #include <linux/string.h>
> > > #include <linux/init.h>
> > > #include <linux/bootmem.h>
> > > #include <linux/irq.h>
> > > #include <linux/io.h>
> > > #include <linux/msi.h>
> > > +#include <linux/iommu.h>
> > >
> > > #include <asm/sections.h>
> > > #include <asm/io.h>
> > > #include <asm/prom.h>
> > > #include <asm/pci-bridge.h>
> > > #include <asm/machdep.h>
> > > #include <asm/ppc-pci.h>
> > > #include <asm/opal.h>
> > > #include <asm/iommu.h>
> > > #include <asm/tce.h>
> > > #include <asm/abs_addr.h>
> > > #include <asm/firmware.h>
> > >
> > > #include "powernv.h"
> > > #include "pci.h"
> > > @@ -601,15 +602,149 @@ void __init pnv_pci_init(void)
> > > /* Configure IOMMU DMA hooks */
> > > ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup;
> > > ppc_md.tce_build = pnv_tce_build;
> > > ppc_md.tce_free = pnv_tce_free;
> > > ppc_md.tce_get = pnv_tce_get;
> > > ppc_md.pci_probe_mode = pnv_pci_probe_mode;
> > > set_pci_dma_ops(&dma_iommu_ops);
> > >
> > > /* Configure MSIs */
> > > #ifdef CONFIG_PCI_MSI
> > > ppc_md.msi_check_device = pnv_msi_check_device;
> > > ppc_md.setup_msi_irqs = pnv_setup_msi_irqs;
> > > ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs; #endif }
> > > +
> > > +#ifdef CONFIG_IOMMU_API
> > > +/*
> > > + * IOMMU groups support required by VFIO */ static int
> > > +add_device(struct device *dev) {
> > > + struct iommu_table *tbl;
> > > + int ret = 0;
> > > +
> > > + if (WARN_ON(dev->iommu_group)) {
> > > + printk(KERN_WARNING "tce_vfio: device %s is already in iommu
> > group %d, skipping\n",
> > > + dev->kobj.name,
> >
> > dev_name(dev)
> >
> > > + iommu_group_id(dev->iommu_group));
> > > + return -EBUSY;
> > > + }
> > > +
> > > + tbl = get_iommu_table_base(dev);
> > > + if (!tbl) {
> > > + pr_debug("tce_vfio: skipping device %s with no tbl\n",
> > > + dev->kobj.name);
> > > + return 0;
> > > + }
> > > +
> > > + pr_debug("tce_vfio: adding %s to iommu group %d\n",
> > > + dev->kobj.name, iommu_group_id(tbl->it_group));
> > > +
> > > + ret = iommu_group_add_device(tbl->it_group, dev);
> > > + if (ret < 0)
> > > + printk(KERN_ERR "tce_vfio: %s has not been added, ret=%d\n",
> > > + dev->kobj.name, ret);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static void del_device(struct device *dev) {
> > > + iommu_group_remove_device(dev);
> > > +}
> > > +
> > > +static int iommu_bus_notifier(struct notifier_block *nb,
> > > + unsigned long action, void *data) {
> > > + struct device *dev = data;
> > > +
> > > + switch (action) {
> > > + case BUS_NOTIFY_ADD_DEVICE:
> > > + return add_device(dev);
> > > + case BUS_NOTIFY_DEL_DEVICE:
> > > + del_device(dev);
> > > + return 0;
> > > + default:
> > > + return 0;
> > > + }
> > > +}
> > > +
> > > +static struct notifier_block tce_iommu_bus_nb = {
> > > + .notifier_call = iommu_bus_notifier, };
> > > +
> > > +static void group_release(void *iommu_data) {
> > > + struct iommu_table *tbl = iommu_data;
> > > + tbl->it_group = NULL;
> > > +}
> > > +
> > > +static int __init tce_iommu_init(void) {
> > > + struct pci_dev *pdev = NULL;
> > > + struct iommu_table *tbl;
> > > + struct iommu_group *grp;
> > > +
> > > + bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
> >
> > There's already a notifier in the iommu code if you were to register an
> > iommu_ops with the add/remove_device entries. That would allow you to
> > remove the notifier block and notifier function below and the second loop
> > below. Are you avoiding that to avoid the rest of iommu_ops?
> >
> [Sethi Varun-B16395] Could be one reason, also they are associating
> the iommu group with the tce table entry and not the device.
That's fine, the tce is the level they claim to have isolation.
>
> > Also, shouldn't this notifier only be registered after the first loop
> > below? Otherwise ADD_DEVICE could race with setting up groups, which we
> > assume are present in the add_device() above.
> [Sethi Varun-B16395] Isn't this similar to how how the notifier is
> registered in iommu_bus_init? First a notifier is registered and then
> we check for devices that have already been probed.
It's not quite the same because the existing notifier callbacks to add
devices also creates groups as necessary. My point here was that we
register a notifier that assumes a group prior to setting up the groups.
In the existing code the order doesn't matter so much because the system
isn't susceptible to hot device adds at that point. That's likely the
case here too, but registering a notifier before setting up the data the
callback references seems unnecessary. Thanks,
Alex
^ permalink raw reply
* Re: [PATCH v3 11/12] memory-hotplug: remove sysfs file of node
From: Jianguo Wu @ 2012-11-26 14:27 UTC (permalink / raw)
To: Wen Congyang
Cc: linux-s390, linux-ia64, Len Brown, linux-acpi, linux-sh, x86,
linux-kernel, cmetcalf, Jianguo Wu, linux-mm, Yasuaki Ishimatsu,
paulus, Minchan Kim, KOSAKI Motohiro, David Rientjes, sparclinux,
Christoph Lameter, linuxppc-dev, Andrew Morton, Jiang Liu
In-Reply-To: <1351763083-7905-12-git-send-email-wency@cn.fujitsu.com>
On 2012/11/1 17:44, Wen Congyang wrote:
> This patch introduces a new function try_offline_node() to
> remove sysfs file of node when all memory sections of this
> node are removed. If some memory sections of this node are
> not removed, this function does nothing.
>
> CC: David Rientjes <rientjes@google.com>
> CC: Jiang Liu <liuj97@gmail.com>
> CC: Len Brown <len.brown@intel.com>
> CC: Christoph Lameter <cl@linux.com>
> Cc: Minchan Kim <minchan.kim@gmail.com>
> CC: Andrew Morton <akpm@linux-foundation.org>
> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> CC: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> ---
> drivers/acpi/acpi_memhotplug.c | 8 +++++-
> include/linux/memory_hotplug.h | 2 +-
> mm/memory_hotplug.c | 58 ++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 64 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
> index 24c807f..0780f99 100644
> --- a/drivers/acpi/acpi_memhotplug.c
> +++ b/drivers/acpi/acpi_memhotplug.c
> @@ -310,7 +310,9 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
> {
> int result;
> struct acpi_memory_info *info, *n;
> + int node;
>
> + node = acpi_get_node(mem_device->device->handle);
>
> /*
> * Ask the VM to offline this memory range.
> @@ -318,7 +320,11 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
> */
> list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
> if (info->enabled) {
> - result = remove_memory(info->start_addr, info->length);
> + if (node < 0)
> + node = memory_add_physaddr_to_nid(
> + info->start_addr);
> + result = remove_memory(node, info->start_addr,
> + info->length);
> if (result)
> return result;
> }
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index d4c4402..7b4cfe6 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -231,7 +231,7 @@ extern int arch_add_memory(int nid, u64 start, u64 size);
> extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
> extern int offline_memory_block(struct memory_block *mem);
> extern bool is_memblock_offlined(struct memory_block *mem);
> -extern int remove_memory(u64 start, u64 size);
> +extern int remove_memory(int node, u64 start, u64 size);
> extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
> int nr_pages);
> extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms);
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 7bcced0..d965da3 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -29,6 +29,7 @@
> #include <linux/suspend.h>
> #include <linux/mm_inline.h>
> #include <linux/firmware-map.h>
> +#include <linux/stop_machine.h>
>
> #include <asm/tlbflush.h>
>
> @@ -1299,7 +1300,58 @@ static int is_memblock_offlined_cb(struct memory_block *mem, void *arg)
> return ret;
> }
>
> -int __ref remove_memory(u64 start, u64 size)
> +static int check_cpu_on_node(void *data)
> +{
> + struct pglist_data *pgdat = data;
> + int cpu;
> +
> + for_each_present_cpu(cpu) {
> + if (cpu_to_node(cpu) == pgdat->node_id)
> + /*
> + * the cpu on this node isn't removed, and we can't
> + * offline this node.
> + */
> + return -EBUSY;
> + }
> +
> + return 0;
> +}
> +
> +/* offline the node if all memory sections of this node are removed */
> +static void try_offline_node(int nid)
> +{
> + unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
> + unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
> + unsigned long pfn;
> +
> + for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
> + unsigned long section_nr = pfn_to_section_nr(pfn);
> +
> + if (!present_section_nr(section_nr))
> + continue;
> +
> + if (pfn_to_nid(pfn) != nid)
> + continue;
> +
> + /*
> + * some memory sections of this node are not removed, and we
> + * can't offline node now.
> + */
> + return;
> + }
> +
> + if (stop_machine(check_cpu_on_node, NODE_DATA(nid), NULL))
> + return;
how about:
if (nr_cpus_node(nid))
return;
> +
> + /*
> + * all memory/cpu of this node are removed, we can offline this
> + * node now.
> + */
> + node_set_offline(nid);
> + unregister_one_node(nid);
> +}
> +
> +int __ref remove_memory(int nid, u64 start, u64 size)
> {
> unsigned long start_pfn, end_pfn;
> int ret = 0;
> @@ -1346,6 +1398,8 @@ repeat:
>
> arch_remove_memory(start, size);
>
> + try_offline_node(nid);
> +
> unlock_memory_hotplug();
>
> return 0;
> @@ -1355,7 +1409,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
> {
> return -EINVAL;
> }
> -int remove_memory(u64 start, u64 size)
> +int remove_memory(int nid, u64 start, u64 size)
> {
> return -EINVAL;
> }
>
^ permalink raw reply
* Re: [PATCH 065/493] i2c: remove use of __devexit_p
From: Bill Pemberton @ 2012-11-26 13:52 UTC (permalink / raw)
To: Wolfram Sang
Cc: Rudolf Marek, Tony Lindgren, gregkh, Olof Johansson, linux-omap,
Mark M. Hoffman, linux-i2c, Ben Dooks, Barry Song, Jean Delvare,
Guan Xuetao, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20121122214915.GD14851@pengutronix.de>
Wolfram Sang writes:
>
>
> --osDK9TLjxFScVI/L
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
> Content-Transfer-Encoding: quoted-printable
>
> On Tue, Nov 20, 2012 at 02:46:21PM +0100, Jean Delvare wrote:
> > On Mon, 19 Nov 2012 13:20:14 -0500, Bill Pemberton wrote:
> > > CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer
> > > needed.
> >=20
> > As mentioned on the lm-sensors list for hwmon patches already, I think
> > it would be much clearer to not split __devexit, __devexit_p, __devinit
> > etc. removal into separate patches. One patch per subsystem would be
> > easier to review and apply. If patches grow too large then you'd rather
> > split in a different direction, for example drivers/i2c/muxes vs.
> > drivers/i2c/busses or even grouped by related bus drivers (see entries
> > "I2C OVER PARALLEL PORT" and "I2C/SMBUS CONTROLLER DRIVERS FOR PC" in
> > MAINTAINERS for examples of meaningful groups.)
>
> I agree with Jean here. Is there a V2 planned? With a change like this?
>
Yes, my plan is to redo the patches for the i2c subsystem.
--
Bill
^ permalink raw reply
* Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEBUG_API
From: Joerg Roedel @ 2012-11-26 11:22 UTC (permalink / raw)
To: Shuah Khan
Cc: linux-mips, linux-ia64, a-jacquiot, catalin.marinas, Ming Lei,
shuahkhan, sparclinux, m.szyprowski, linux-c6x-dev, linux-sh,
msalter, fenghua.yu, microblaze-uclinux, linux-arm-kernel, monstr,
tony.luck, LKML, ralf, lethal, linuxppc-dev, davem
In-Reply-To: <1353706142.5270.93.camel@lorien2>
Hi Shuah,
On Fri, Nov 23, 2012 at 02:29:02PM -0700, Shuah Khan wrote:
> x86 - done in the first patch that added the feature.
>
> ARM64: dma_debug: add debug_dma_mapping_error support
> c6x: dma_debug: add debug_dma_mapping_error support
> ia64: dma_debug: add debug_dma_mapping_error support
> microblaze: dma-mapping: support debug_dma_mapping_error
> mips: dma_debug: add debug_dma_mapping_error support
> powerpc: dma_debug: add debug_dma_mapping_error support
> sh: dma_debug: add debug_dma_mapping_error support
> sparc: dma_debug: add debug_dma_mapping_error support
> tile: dma_debug: add debug_dma_mapping_error support
Have you compile-tested the invididual archs you are changing here?
Joerg
^ permalink raw reply
* Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEBUG_API
From: Joerg Roedel @ 2012-11-26 11:20 UTC (permalink / raw)
To: Marek Szyprowski
Cc: linux-mips, linux-ia64, a-jacquiot, catalin.marinas, Ming Lei,
shuahkhan, sparclinux, linux-c6x-dev, linux-sh, msalter,
shuah.khan, fenghua.yu, microblaze-uclinux, linux-arm-kernel,
monstr, tony.luck, LKML, ralf, lethal, linuxppc-dev, davem
In-Reply-To: <50B34B0F.3080204@samsung.com>
On Mon, Nov 26, 2012 at 11:57:19AM +0100, Marek Szyprowski wrote:
> I've took all the patches to the next-dma-debug branch in my tree, I sorry
> that You have to wait so long for it. My branch is based on Joerg's
> dma-debug branch and I've included it for testing in linux-next branch.
>
> Joerg: would You mind if I handle pushing the whole branch to v3.8
> via my kernel tree? Those changes should be kept close together to
> avoid build breaks for bisecting.
I'll apply the patches to my tree soon enough. But before that I'll wait
a little bit longer to give the arch maintainers the chance to add the
missing Acked-bys.
Joerg
^ permalink raw reply
* Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEBUG_API
From: Marek Szyprowski @ 2012-11-26 10:57 UTC (permalink / raw)
To: shuah.khan
Cc: linux-mips, linux-ia64, a-jacquiot, catalin.marinas, Ming Lei,
shuahkhan, sparclinux, linux-c6x-dev, Joerg Roedel, linux-sh,
msalter, fenghua.yu, microblaze-uclinux, linux-arm-kernel, monstr,
tony.luck, LKML, ralf, lethal, linuxppc-dev, davem
In-Reply-To: <1353706142.5270.93.camel@lorien2>
Hello,
On 11/23/2012 10:29 PM, Shuah Khan wrote:
> An earlier patch added dma mapping error debug feature to dma_debug
> infrastructure. References:
>
> https://lkml.org/lkml/2012/10/8/296
> https://lkml.org/lkml/2012/11/3/219
>
> The following series of patches adds the call to debug_dma_mapping_error() to
> architecture specific dma_mapping_error() interfaces on the following
> architectures that support CONFIG_DMA_API_DEBUG.
I've took all the patches to the next-dma-debug branch in my tree, I sorry
that You have to wait so long for it. My branch is based on Joerg's
dma-debug branch and I've included it for testing in linux-next branch.
Joerg: would You mind if I handle pushing the whole branch to v3.8
via my kernel tree? Those changes should be kept close together to
avoid build breaks for bisecting.
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
^ permalink raw reply
* [PATCH] powerpc/pasemi: enable PRINTK_TIME in defconfig
From: Olof Johansson @ 2012-11-26 6:51 UTC (permalink / raw)
To: benh; +Cc: Olof Johansson, linuxppc-dev
Enable PRINTK_TIME in pasemi_defconfig. Also regenerate it, it seems
that a lot of options have moved around since last time savedefconfig
was ran on it.
Signed-off-by: Olof Johansson <olof@lixom.net>
---
arch/powerpc/configs/pasemi_defconfig | 31 ++++++++-----------------------
1 file changed, 8 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig
index 840a2c2..bd8a6f7 100644
--- a/arch/powerpc/configs/pasemi_defconfig
+++ b/arch/powerpc/configs/pasemi_defconfig
@@ -1,28 +1,27 @@
CONFIG_PPC64=y
CONFIG_ALTIVEC=y
-# CONFIG_VIRT_CPU_ACCOUNTING is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_PASEMI=y
CONFIG_PPC_PASEMI_IOMMU=y
CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
CONFIG_HZ_1000=y
CONFIG_PPC_64K_PAGES=y
# CONFIG_SECCOMP is not set
@@ -47,7 +46,6 @@ CONFIG_INET_ESP=y
# CONFIG_IPV6 is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_SLRAM=y
@@ -58,7 +56,6 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
@@ -91,21 +88,19 @@ CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
-CONFIG_MARVELL_PHY=y
-CONFIG_NET_ETHERNET=y
CONFIG_MII=y
-CONFIG_NET_PCI=y
-CONFIG_E1000=y
CONFIG_TIGON3=y
+CONFIG_E1000=y
CONFIG_PASEMI_MAC=y
+CONFIG_MARVELL_PHY=y
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_MOUSE_PS2 is not set
# CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=4
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=4
CONFIG_HW_RANDOM=y
CONFIG_RAW_DRIVER=y
CONFIG_I2C_CHARDEV=y
@@ -146,14 +141,11 @@ CONFIG_HID_TOPSEED=y
CONFIG_HID_THRUSTMASTER=y
CONFIG_HID_ZEROPLUS=y
CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_SL811_HCD=y
CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_PASEMI=y
@@ -164,8 +156,6 @@ CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
CONFIG_ISO9660_FS=y
CONFIG_UDF_FS=y
@@ -177,27 +167,22 @@ CONFIG_HUGETLBFS=y
CONFIG_CONFIGFS_FS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V4=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_CRC_CCITT=y
+CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_SCHED_DEBUG is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_XMON=y
CONFIG_XMON_DEFAULT=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_BLOWFISH=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
--
1.7.10.1.488.g05fbf7a
^ permalink raw reply related
* RE: [PATCH 1/4 v2] iommu/fsl: Store iommu domain information pointer in archdata.
From: Sethi Varun-B16395 @ 2012-11-26 5:33 UTC (permalink / raw)
To: Kumar Gala
Cc: Wood Scott-B07421, joerg.roedel@amd.com, Tabi Timur-B04825,
linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
Sethi Varun-B16395, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1353419697-31269-2-git-send-email-Varun.Sethi@freescale.com>
Hi Kumar,
Can you please apply this patch.
Regards
Varun
> -----Original Message-----
> From: Sethi Varun-B16395
> Sent: Tuesday, November 20, 2012 7:25 PM
> To: joerg.roedel@amd.com; iommu@lists.linux-foundation.org; linuxppc-
> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; Wood Scott-B07421;
> Tabi Timur-B04825
> Cc: Sethi Varun-B16395
> Subject: [PATCH 1/4 v2] iommu/fsl: Store iommu domain information pointer
> in archdata.
>=20
> Add a new field in the device (powerpc) archdata structure for storing
> iommu domain information pointer. This pointer is stored when the device
> is attached to a particular domain.
>=20
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> ---
> arch/powerpc/include/asm/device.h | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/device.h
> b/arch/powerpc/include/asm/device.h
> index 77e97dd..6dc79fe 100644
> --- a/arch/powerpc/include/asm/device.h
> +++ b/arch/powerpc/include/asm/device.h
> @@ -28,6 +28,10 @@ struct dev_archdata {
> void *iommu_table_base;
> } dma_data;
>=20
> + /* IOMMU domain information pointer. This would be set
> + * when this device is attached to an iommu_domain.
> + */
> + void *iommu_domain;
> #ifdef CONFIG_SWIOTLB
> dma_addr_t max_direct_dma_addr;
> #endif
> --
> 1.7.4.1
^ permalink raw reply
* Re: [PATCH] powerpc/pci-hotplug: fix the rescanned pci device's dma_set_mask issue
From: Chen Yuanquan-B41889 @ 2012-11-26 5:29 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, r61911
In-Reply-To: <455E76A9-ABB3-4FF6-A19E-612E43223C4A@kernel.crashing.org>
On 11/25/2012 08:41 PM, Kumar Gala wrote:
> On Nov 22, 2012, at 10:29 PM, Yuanquan Chen wrote:
>
>> On powerpc arch, dma_ops of rescanned pci device after system's booting up won't be
>> initialized by system, so it will fail to execute the dma_set_mask in the device's
>> driver. Initialize it to solve this issue.
>>
>> Signed-off-by: Yuanquan Chen <B41889@freescale.com>
>> ---
>> arch/powerpc/include/asm/dma-mapping.h | 7 +++++--
>> 1 file changed, 5 insertions(+), 2 deletions(-)
> This is not the right way to get the dma_ops setup. You need to find some other point for the hotplug scenario to get the dma_ops setup.
>
> - k
Hi Kumar,
I read the code about pci bus scan and rescan. Only the
pcibios_fixup_bus in pci_scan_child_bus and
pcibios_enable_device in pci_rescan_bus are arch related code. The
pcibios_fixup_bus won't be called
for the rescanned PCI devices due to the bus->is_added has been set for
the first scanning at boot time.
So I think it's more reasonable to do the same work as pcibios_fixup_bus
for rescanned PCI device in
pcibios_enable_device. The patch code is a copy of
pcibios_setup_bus_devices called by pcibios_fixup_bus,
It can solve the dma_set_mask and irq related issues of rescanned PCI
device on powerpc arch. What's
your opinion?
Thanks,
yuanquan
diff --git a/arch/powerpc/kernel/pci-common.c
b/arch/powerpc/kernel/pci-common.c
index 7f94f76..30f7d61 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1496,6 +1496,23 @@ int pcibios_enable_device(struct pci_dev *dev,
int mask)
if (ppc_md.pcibios_enable_device_hook(dev))
return -EINVAL;
+ if (!dev->is_added) {
+ set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+ /* Hook up default DMA ops */
+ set_dma_ops(&dev->dev, pci_dma_ops);
+ set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
+
+ /* Additional platform DMA/iommu setup */
+ if (ppc_md.pci_dma_dev_setup)
+ ppc_md.pci_dma_dev_setup(dev);
+
+ /* Read default IRQs and fixup if necessary */
+ pci_read_irq_line(dev);
+ if (ppc_md.pci_irq_fixup)
+ ppc_md.pci_irq_fixup(dev);
+ }
+
return pci_enable_resources(dev, mask);
}
>> diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
>> index 7816087..22eae53 100644
>> --- a/arch/powerpc/include/asm/dma-mapping.h
>> +++ b/arch/powerpc/include/asm/dma-mapping.h
>> @@ -126,8 +126,11 @@ static inline int dma_supported(struct device *dev, u64 mask)
>> {
>> struct dma_map_ops *dma_ops = get_dma_ops(dev);
>>
>> - if (unlikely(dma_ops == NULL))
>> - return 0;
>> + if (unlikely(dma_ops == NULL)) {
>> + set_dma_ops(dev, &dma_direct_ops);
>> + set_dma_offset(dev, PCI_DRAM_OFFSET);
>> + dma_ops = &dma_direct_ops;
>> + }
>> if (dma_ops->dma_supported == NULL)
>> return 1;
>> return dma_ops->dma_supported(dev, mask);
>> --
>> 1.7.9.5
>>
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
>
^ permalink raw reply related
* RE: [PATCH 3/4 v5] iommu/fsl: Add iommu domain attributes required by fsl PAMU driver.
From: Sethi Varun-B16395 @ 2012-11-26 5:24 UTC (permalink / raw)
To: joerg.roedel@amd.com
Cc: Wood Scott-B07421, Tabi Timur-B04825,
linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
Sethi Varun-B16395, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1353419697-31269-4-git-send-email-Varun.Sethi@freescale.com>
Hi Joerg,
Any comments? Can we apply this patch?
Regards
Varun
> -----Original Message-----
> From: Sethi Varun-B16395
> Sent: Tuesday, November 20, 2012 7:25 PM
> To: joerg.roedel@amd.com; iommu@lists.linux-foundation.org; linuxppc-
> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; Wood Scott-B07421;
> Tabi Timur-B04825
> Cc: Sethi Varun-B16395
> Subject: [PATCH 3/4 v5] iommu/fsl: Add iommu domain attributes required
> by fsl PAMU driver.
>=20
> Added the following domain attributes required by FSL PAMU driver:
> 1. Subwindows field added to the iommu domain geometry attribute.
> 2. Added new iommu stash attribute, which allows setting of the
> LIODN specific stash id parameter through IOMMU API.
> 3. Added an attribute for enabling/disabling DMA to a particular
> memory window.
>=20
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> ---
> changes in v5:
> - Updated description of the subwindows field.
> changes in v4:
> - Updated comment explaining subwindows(as mentioned by Scott).
> change in v3:
> -renamed the stash attribute targets
> include/linux/iommu.h | 43 +++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 43 insertions(+), 0 deletions(-)
>=20
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h index
> f3b99e1..7ca1cda 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -44,6 +44,41 @@ struct iommu_domain_geometry {
> dma_addr_t aperture_start; /* First address that can be mapped
> */
> dma_addr_t aperture_end; /* Last address that can be mapped
> */
> bool force_aperture; /* DMA only allowed in mappable range?
> */
> +
> + /*
> + * A geometry mapping can be created in one of the following ways
> + * for an IOMMU:
> + * 1. A single contiguous window
> + * 2. Through arbritary paging throughout the aperture.
> + * 3. Using multiple subwindows
> + *
> + * In absence of arbritary paging, subwindows allow for supporting
> + * physically discontiguous mappings.
> + *
> + * This attribute indicates number of DMA subwindows supported by
> + * the geometry. If there is a single window that maps the entire
> + * geometry, attribute must be set to "1". A value of "0" implies
> + * that this mechanism is not used at all(normal paging is used).
> + * Value other than* "0" or "1" indicates the actual number of
> + * subwindows.
> + */
> + u32 subwindows;
> +};
> +
> +/* cache stash targets */
> +#define IOMMU_ATTR_CACHE_L1 1
> +#define IOMMU_ATTR_CACHE_L2 2
> +#define IOMMU_ATTR_CACHE_L3 3
> +
> +/* This attribute corresponds to IOMMUs capable of generating
> + * a stash transaction. A stash transaction is typically a
> + * hardware initiated prefetch of data from memory to cache.
> + * This attribute allows configuring stashig specific parameters
> + * in the IOMMU hardware.
> + */
> +struct iommu_stash_attribute {
> + u32 cpu; /* cpu number */
> + u32 cache; /* cache to stash to: L1,L2,L3 */
> };
>=20
> struct iommu_domain {
> @@ -60,6 +95,14 @@ struct iommu_domain { enum iommu_attr {
> DOMAIN_ATTR_MAX,
> DOMAIN_ATTR_GEOMETRY,
> + /* Set the IOMMU hardware stashing
> + * parameters.
> + */
> + DOMAIN_ATTR_STASH,
> + /* Explicity enable/disable DMA for a
> + * particular memory window.
> + */
> + DOMAIN_ATTR_ENABLE,
> };
>=20
> #ifdef CONFIG_IOMMU_API
> --
> 1.7.4.1
^ permalink raw reply
* Re: [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2012-11-25 22:08 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev list, Linux Kernel list
In-Reply-To: <1353881249.16666.4.camel@pasglop>
On Mon, 2012-11-26 at 09:07 +1100, Benjamin Herrenschmidt wrote:
> Hi Linus !
>
> Here's a patch that would be good to still have in 3.7. It's a one liner fixing
> a regression introduced by the new EEH code in .37 (potential oops on some
> PCI setups when configuring MSIs).
>
> Cheers,
> Ben.
>
> The following changes since commit d6dc24613c222f9057131ccbd5264a10bcba9f97:
>
> Merge remote-tracking branch 'agust/merge' into merge (2012-11-21 13:24:49 +1100)
>
> are available in the git repository at:
>
>
> git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
And the branch is "merge".
Cheers,
Ben.
>
> for you to fetch changes up to bb4618823a3389086f157fafb2a0d97cade8d89f:
>
> powerpc/pseries: Fix oops with MSIs when missing EEH PEs (2012-11-23 13:26:05 +1100)
>
> ----------------------------------------------------------------
> Alexey Kardashevskiy (1):
> powerpc/pseries: Fix oops with MSIs when missing EEH PEs
>
> arch/powerpc/platforms/pseries/msi.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
^ permalink raw reply
* Re: [PATCH] i2c-cpm: Fix to takeback i2c bus master-ship after a collision
From: sachin surendran @ 2012-11-25 22:57 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <B8BB551F-BD07-41A9-BCA6-7451C3D12CAA@kernel.crashing.org>
Hi Kumar,
I have resent the updated patch.
Regards
Sachin
On Mon, Nov 26, 2012 at 2:21 AM, Kumar Gala <galak@kernel.crashing.org> wrote:
>
> On Oct 30, 2012, at 10:00 PM, sachin surendran wrote:
>
>> In case of collision on i2c bus the controller which lost bus mastership stays as a slave
>> for all subsequent transfers. This results in the i2c controller never writing to the bus
>> for future transactions, resulting in i2c transfer timeouts.
>> This fix checks for a collision on last I2C transaction and sets the I2COM_MASTER
>> bit for the new transaction.
>>
>> Signed-off-by: Sachin Surendran <sachin.surendran@alliedtelesis.co.nz>
>> ---
>> drivers/i2c/busses/i2c-cpm.c | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>
> patch doesn't apply, please resend properly.
>
> - k
>
>>
>> diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
>> index c1e1096..bb94c6d 100644
>> --- a/drivers/i2c/busses/i2c-cpm.c
>> +++ b/drivers/i2c/busses/i2c-cpm.c
>> @@ -338,6 +338,14 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
>> tptr = 0;
>> rptr = 0;
>>
>> + /*
>> + * If there was a collision in the last i2c transaction,
>> + * Set I2COM_MASTER as it was cleared during collision.
>> + */
>> + if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) {
>> + out_8(&cpm->i2c_reg->i2com, I2COM_MASTER);
>> + }
>> +
>> while (tptr < num) {
>> pmsg = &msgs[tptr];
>> dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr);
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: [git pull] Please pull powerpc.git next branch
From: Benjamin Herrenschmidt @ 2012-11-25 22:26 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <alpine.LFD.2.00.1211250726550.14762@right.am.freescale.net>
On Sun, 2012-11-25 at 07:27 -0600, Kumar Gala wrote:
Next time, put a little message with "highlights" that I can include in
the merge commit, that's how we tend to do things nowadays :-)
Cheers,
Ben.
> The following changes since commit cedddd812a79a4fda3885a15711aee3de78c4a24:
>
> powerpc: Disable relocation on exceptions when kexecing (2012-11-15 15:08:08 +1100)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git next
>
> for you to fetch changes up to 1723d90915d4689fa2e8cd4151d45ea38c96cb99:
>
> powerpc/dma/raidengine: add raidengine device (2012-11-25 07:19:51 -0600)
>
> ----------------------------------------------------------------
> Jia Hongtao (1):
> powerpc/fsl-pci: Add PCI controller ATMU PM support
>
> Timur Tabi (2):
> drivers/virt: the Freescale hypervisor driver doesn't need to check MSR[GS]
> powerpc/86xx: fsl_pcibios_fixup_bus requires CONFIG_PCI
>
> Tushar Behera (1):
> powerpc/85xx: p1022ds: Use NULL instead of 0 for pointers
>
> Varun Sethi (1):
> powerpc/iommu/fsl: Add PAMU bypass enable register to ccsr_guts struct
>
> Xuelin Shi (1):
> powerpc/dma/raidengine: add raidengine device
>
> York Sun (1):
> powerpc/mpc85xx: Change spin table to cached memory
>
> .../devicetree/bindings/powerpc/fsl/raideng.txt | 81 +++++++++++++++++++
> arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 1 +
> arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 6 ++
> arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi | 85 ++++++++++++++++++++
> arch/powerpc/include/asm/fsl_guts.h | 4 +-
> arch/powerpc/platforms/85xx/p1022_ds.c | 2 +-
> arch/powerpc/platforms/85xx/smp.c | 49 ++++++++---
> arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 2 +
> arch/powerpc/sysdev/fsl_pci.c | 37 ++++++++-
> drivers/virt/fsl_hypervisor.c | 3 -
> 10 files changed, 250 insertions(+), 20 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/raideng.txt
> create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi
^ permalink raw reply
* [PATCH 1/1] i2c-cpm: Fix to takeback i2c bus master-ship after a collision
From: sachin.surendran @ 2012-11-25 22:20 UTC (permalink / raw)
To: galak, jochen; +Cc: Sachin Surendran, sachin.surendran, linuxppc-dev
From: Sachin Surendran <sachin.surendran@alliedtelesis.co.nz>
In case of collision on i2c bus the controller which lost bus mastership
stays as a slave for all subsequent transfers. This results in the i2c
controller never writing to the bus for future transactions, resulting
in i2c transfer timeouts.
This fix checks for a collision on last I2C transaction and sets the
I2COM_MASTER bit for the new transaction.
Signed-off-by: Sachin Surendran <sachin.surendran@alliedtelesis.co.nz>
---
drivers/i2c/busses/i2c-cpm.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index c1e1096..bb94c6d 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -338,6 +338,14 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
tptr = 0;
rptr = 0;
+ /*
+ * If there was a collision in the last i2c transaction,
+ * Set I2COM_MASTER as it was cleared during collision.
+ */
+ if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) {
+ out_8(&cpm->i2c_reg->i2com, I2COM_MASTER);
+ }
+
while (tptr < num) {
pmsg = &msgs[tptr];
dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr);
--
1.7.9.5
^ permalink raw reply related
* Re: [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2012-11-25 22:16 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev list, Linux Kernel list
In-Reply-To: <1353881283.16666.5.camel@pasglop>
On Mon, 2012-11-26 at 09:08 +1100, Benjamin Herrenschmidt wrote:
> On Mon, 2012-11-26 at 09:07 +1100, Benjamin Herrenschmidt wrote:
> > Hi Linus !
> >
> > Here's a patch that would be good to still have in 3.7. It's a one liner fixing
> > a regression introduced by the new EEH code in .37 (potential oops on some
> > PCI setups when configuring MSIs).
I've just added a second fix for EEH (Gavin found another issue) which
is trivial enough (and tested) so it should still go in. Updated pull
request:
The following changes since commit
d6dc24613c222f9057131ccbd5264a10bcba9f97:
Merge remote-tracking branch 'agust/merge' into merge (2012-11-21
13:24:49 +1100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge
for you to fetch changes up to e716e014384688d1a50d1aa5213ee74748c6d4e0:
powerpc/eeh: Do not invalidate PE properly (2012-11-26 09:14:16 +1100)
----------------------------------------------------------------
Alexey Kardashevskiy (1):
powerpc/pseries: Fix oops with MSIs when missing EEH PEs
Gavin Shan (1):
powerpc/eeh: Do not invalidate PE properly
arch/powerpc/platforms/pseries/eeh_pe.c | 2 +-
arch/powerpc/platforms/pseries/msi.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
^ permalink raw reply
* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2012-11-25 22:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev list, Linux Kernel list
Hi Linus !
Here's a patch that would be good to still have in 3.7. It's a one liner fixing
a regression introduced by the new EEH code in .37 (potential oops on some
PCI setups when configuring MSIs).
Cheers,
Ben.
The following changes since commit d6dc24613c222f9057131ccbd5264a10bcba9f97:
Merge remote-tracking branch 'agust/merge' into merge (2012-11-21 13:24:49 +1100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
for you to fetch changes up to bb4618823a3389086f157fafb2a0d97cade8d89f:
powerpc/pseries: Fix oops with MSIs when missing EEH PEs (2012-11-23 13:26:05 +1100)
----------------------------------------------------------------
Alexey Kardashevskiy (1):
powerpc/pseries: Fix oops with MSIs when missing EEH PEs
arch/powerpc/platforms/pseries/msi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
^ 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