LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] KVM: PPC: 64-bit Book3E arch support
From: Mihai Caraman @ 2012-10-11 16:13 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

This patchset adds arch support to KVM for 64-bit Book3E PowerPC procesosrs
with Embedded.Hypervisor category. The support is limited to the bolted TLB miss
exception handlers version and was validated on Freescale's e5500 cores
using P5020DS boards.

This patchset is based on Alex G. kvm-ppc-next branch with the following
core prerequisites:

The changes since commit 8b7b80b9ebb46dd88fbb94e918297295cf312b59:

    powerpc: Uprobes port to powerpc

up to commit 8b64a9dfb091f1eca8b7e58da82f1e7d1d5fe0ad:

    powerpc/booke64: Use SPRG0/3 scratch for bolted TLB miss & crit int


and the changes since commit d0832a75075b1119635e0f48549e378040cf5e67:

    powerpc/85xx: add HOTPLUG_CPU support

up to commit 39be5b4a7f232870aad0b3c130791eacd0d34347:

    powerpc/booke: Add CPU_FTR_EMB_HV check for e5500.


available in the git repository

    git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git



Mihai Caraman (12):
  KVM: PPC: e500: Silence bogus GCC warning in tlb code
  KVM: PPC: booke: Fix get_tb() compile error on 64-bit
  KVM: PPC: bookehv: Remove GET_VCPU macro from exception handler
  KVM: PPC64: bookehv: Add support for interrupt handling
  KVM: PPC: Add emulation helper for getting instruction ea
  KVM: PPC: Mask ea's high 32-bits in 32/64 instr emulation
  KVM: PPC: e500: Mask MAS2 EPN high 32-bits in 32/64 tlbwe emulation
  KVM: PPC: booke: Extend MAS2 EPN mask for 64-bit
  KVM: PPC: bookehv: Add guest computation mode for irq delivery
  KVM: PPC: bookehv: Add EPCR support in mtspr/mfspr emulation
  KVM: PPC: booke: Add EPCR support in sregs
  KVM: PPC: booke: Get/set guest EPCR register using ONE_REG interface

 Documentation/virtual/kvm/api.txt           |    1 +
 arch/powerpc/include/asm/kvm.h              |    2 +
 arch/powerpc/include/asm/kvm_booke_hv_asm.h |   25 +++++
 arch/powerpc/include/asm/kvm_ppc.h          |   21 ++++
 arch/powerpc/include/asm/mmu-book3e.h       |    2 +-
 arch/powerpc/kvm/booke.c                    |   43 ++++++++-
 arch/powerpc/kvm/booke.h                    |    1 +
 arch/powerpc/kvm/booke_emulate.c            |   12 ++-
 arch/powerpc/kvm/bookehv_interrupts.S       |  145 ++++++++++++++++++++++++---
 arch/powerpc/kvm/e500.h                     |    8 +-
 arch/powerpc/kvm/e500_emulate.c             |   15 ++-
 arch/powerpc/kvm/e500_tlb.c                 |   38 +++----
 12 files changed, 265 insertions(+), 48 deletions(-)

-- 
1.7.4.1

^ permalink raw reply

* [PATCH 08/12] KVM: PPC: booke: Extend MAS2 EPN mask for 64-bit
From: Mihai Caraman @ 2012-10-11 16:13 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1349972009-23027-1-git-send-email-mihai.caraman@freescale.com>

Extend MAS2 EPN mask to retain most significant bits on 64-bit hosts.
Use this mask in tlb effective address accessor.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
 arch/powerpc/include/asm/mmu-book3e.h |    2 +-
 arch/powerpc/kvm/e500.h               |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h
index eeabcdb..99d43e0 100644
--- a/arch/powerpc/include/asm/mmu-book3e.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -59,7 +59,7 @@
 #define MAS1_TSIZE_SHIFT	7
 #define MAS1_TSIZE(x)		(((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK)
 
-#define MAS2_EPN		0xFFFFF000
+#define MAS2_EPN		(~0xFFFUL)
 #define MAS2_X0			0x00000040
 #define MAS2_X1			0x00000020
 #define MAS2_W			0x00000010
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 32e98a7..c70d37e 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -154,7 +154,7 @@ get_tlb_size(const struct kvm_book3e_206_tlb_entry *tlbe)
 
 static inline gva_t get_tlb_eaddr(const struct kvm_book3e_206_tlb_entry *tlbe)
 {
-	return tlbe->mas2 & 0xfffff000;
+	return tlbe->mas2 & MAS2_EPN;
 }
 
 static inline u64 get_tlb_bytes(const struct kvm_book3e_206_tlb_entry *tlbe)
-- 
1.7.4.1

^ permalink raw reply related

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: David Howells @ 2012-10-11 16:05 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Stephen Rothwell, Liu Yu, B04825, linux-kernel, Stuart Yoder,
	dhowells, linux-next, Paul Mackerras, linuxppc-dev
In-Reply-To: <4C573632-7629-4E7A-8A67-FD4698B7430D@suse.de>

Alexander Graf <agraf@suse.de> wrote:

> Do I have to move them to their own header file or can I just #ifdef
> __KERNEL__ around the place where __ASSEMBLY__ starts to the end of the
> file?

That depends on whether it happens before or after my disintegration script is
run on the header.  Ben has pulled my powerpc thing into the powerpc tree
already.  If he doesn't mind repulling, then if you give me a patch or a git
branch to fix it, I can apply that and regenerate the powerpc branch.

Otherwise, you need to disintegrate manually:

 (1) Move the public part to arch/powerpc/include/uapi/asm/epapr_hcalls.h

 (2) #include the public part from arch/powerpc/include/asm/epapr_hcalls.h

 (3) Move the "headers-y += epapr_hcalls.h" line from .../asm/Kbuild to
     .../uapi/asm/Kbuild.

You should not then need __KERNEL__ guards in either header.

David

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Alexander Graf @ 2012-10-11 15:56 UTC (permalink / raw)
  To: Scott Wood
  Cc: Stephen Rothwell, Tabi Timur-B04825, linux-kernel@vger.kernel.org,
	David Howells, linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1349970603.6903.2@snotra>


On 11.10.2012, at 17:50, Scott Wood wrote:

> On 10/11/2012 08:04:58 AM, Alexander Graf wrote:
>> On 11.10.2012, at 05:32, Tabi Timur-B04825 wrote:
>> > On Wed, Oct 10, 2012 at 9:47 PM, Stephen Rothwell =
<sfr@canb.auug.org.au> wrote:
>> >
>> >> Commit 549d62d889b4 ("KVM: PPC: use definitions in epapr header
>> >> for hcalls") from the kvm-ppc tree added an include of =
asm/epapr_hcall.h
>> >> to the user visible part of asm/kvm_para.h so asm/epapr_hcall.h =
became a
>> >> user visible header file.
>> >
>> > Any real user-space code that tries to call any of the functions in
>> > epapr_hcall.h will cause an exception.
>=20
> Actually it'll cause a linker error, as of the "Don't use hardcoded =
opcode for ePAPR hcall invocation" patch.
>=20
>> > Claiming that kernel header files that KVM needs are suddenly
>> > user-space header files doesn't make much sense to me, but I guess
>> > it's not my decision.
>> This is about kvm_host.h, which is the part that is exported to user =
space. It usually contains constants and structs that are required for =
the API.
>=20
> s/kvm_host/kvm_para/
>=20
> I'm not sure anything in kvm_para.h or epapr_hcalls.h would be of use =
to userspace, but it would be of use to the guest OS, so it's still not =
kernel-internal.
>=20
> The variable externs should be #ifdef __KERNEL__ as David points out.  =
The asm stuff could still be useful in a guest OS if the guest provides =
epapr_hypercall_start.

I don't think we should worry about guest kernel code potentially having =
use for this. Let's make the user space headers be great for user space =
usage, not for guest code usage :).

Alex=

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Timur Tabi @ 2012-10-11 15:55 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Stephen Rothwell, linux-kernel@vger.kernel.org, David Howells,
	linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <6201AAAD-F575-4D2C-9A97-3EB41DA3491C@suse.de>

Alexander Graf wrote:


> This is about kvm_host.h, which is the part that is exported to user
> space. It usually contains constants and structs that are required for
> the API.

Which API?  I'm not familiar with KVM internals.

My concern is that when I think of a user-space header file, I think of a
user-space application that calls ioctls.  I know that KVM guest kernels
run as user-space processes, but that does not seem like a reason to
combine all of the header files that the KVM guest kernel needs with
"real" user-space header files.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Scott Wood @ 2012-10-11 15:50 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Stephen Rothwell, Tabi Timur-B04825, linux-kernel@vger.kernel.org,
	David Howells, linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <6201AAAD-F575-4D2C-9A97-3EB41DA3491C@suse.de>

On 10/11/2012 08:04:58 AM, Alexander Graf wrote:
>=20
> On 11.10.2012, at 05:32, Tabi Timur-B04825 wrote:
>=20
> > On Wed, Oct 10, 2012 at 9:47 PM, Stephen Rothwell =20
> <sfr@canb.auug.org.au> wrote:
> >
> >> Commit 549d62d889b4 ("KVM: PPC: use definitions in epapr header
> >> for hcalls") from the kvm-ppc tree added an include of =20
> asm/epapr_hcall.h
> >> to the user visible part of asm/kvm_para.h so asm/epapr_hcall.h =20
> became a
> >> user visible header file.
> >
> > Any real user-space code that tries to call any of the functions in
> > epapr_hcall.h will cause an exception.

Actually it'll cause a linker error, as of the "Don't use hardcoded =20
opcode for ePAPR hcall invocation" patch.

> > Claiming that kernel header files that KVM needs are suddenly
> > user-space header files doesn't make much sense to me, but I guess
> > it's not my decision.
>=20
> This is about kvm_host.h, which is the part that is exported to user =20
> space. It usually contains constants and structs that are required =20
> for the API.

s/kvm_host/kvm_para/

I'm not sure anything in kvm_para.h or epapr_hcalls.h would be of use =20
to userspace, but it would be of use to the guest OS, so it's still not =20
kernel-internal.

The variable externs should be #ifdef __KERNEL__ as David points out.  =20
The asm stuff could still be useful in a guest OS if the guest provides =20
epapr_hypercall_start.

-Scott=

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Alexander Graf @ 2012-10-11 13:08 UTC (permalink / raw)
  To: David Howells
  Cc: Stephen Rothwell, Liu Yu, B04825, linux-kernel, Stuart Yoder,
	linux-next, Paul Mackerras, linuxppc-dev
In-Reply-To: <13876.1349947620@warthog.procyon.org.uk>


On 11.10.2012, at 11:27, David Howells wrote:

> Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>=20
>> I just removed epapr_hcalls.h from the Kbuild file as I am not sure =
how
>> it should be broken up.  David, can you have a look at this, please?
>=20
> Files should be broken up along around __KERNEL__ conditionals.  If =
there are
> no __KERNEL__ conditionals, it is assumed that the file is entirely =
UAPI and
> can just be moved.
>=20
> The problem appears to be this commit:
>=20
> 	=
https://github.com/agraf/linux-2.6/commit/4c09029a5639c955fcf6d65205796e4f=
1208aed3
>=20
> 	From: Liu Yu <yu.liu@freescale.com>
> 	Subject: KVM: PPC: Add support for ePAPR idle hcall in host =
kernel
>=20
> Just makes epapr_hcalls.h part of the userspace API in its entirety by =
this bit
> of the patch:
>=20
> 	+header-y +=3D epapr_hcalls.h
>=20
> whilst not adding any __KERNEL__ guards - which is almost certainly =
incorrect.
>=20
> At the very least, I would say that the global variable declarations =
need
> limiting to kernel space, and thus so do the inline functions as they =
emit
> inline assembly to jump somewhere specified by one of the global =
variables
> (actually a code array).
>=20
> So for manual splitting purposes, I would go with just moving all the =
#defines
> prior to the __ASSEMBLY__ guard out to uapi.  Everything within the
> __ASSEMBLY__ guard is KABI only by the looks of it.

Do I have to move them to their own header file or can I just #ifdef =
__KERNEL__ around the place where __ASSEMBLY__ starts to the end of the =
file?


Alex

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Alexander Graf @ 2012-10-11 13:04 UTC (permalink / raw)
  To: Tabi Timur-B04825
  Cc: Stephen Rothwell, linux-kernel@vger.kernel.org, David Howells,
	linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <6AE080B68D46FC4BA2D2769E68D765B7080FA9F8@039-SN2MPN1-023.039d.mgd.msft.net>


On 11.10.2012, at 05:32, Tabi Timur-B04825 wrote:

> On Wed, Oct 10, 2012 at 9:47 PM, Stephen Rothwell =
<sfr@canb.auug.org.au> wrote:
>=20
>> Commit 549d62d889b4 ("KVM: PPC: use definitions in epapr header
>> for hcalls") from the kvm-ppc tree added an include of =
asm/epapr_hcall.h
>> to the user visible part of asm/kvm_para.h so asm/epapr_hcall.h =
became a
>> user visible header file.
>=20
> Any real user-space code that tries to call any of the functions in
> epapr_hcall.h will cause an exception.
>=20
> Claiming that kernel header files that KVM needs are suddenly
> user-space header files doesn't make much sense to me, but I guess
> it's not my decision.

This is about kvm_host.h, which is the part that is exported to user =
space. It usually contains constants and structs that are required for =
the API.


Alex

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: David Howells @ 2012-10-11  9:28 UTC (permalink / raw)
  To: Tabi Timur-B04825
  Cc: Stephen Rothwell, Alexander Graf, linux-kernel@vger.kernel.org,
	dhowells, linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <6AE080B68D46FC4BA2D2769E68D765B7080FA8F8@039-SN2MPN1-023.039d.mgd.msft.net>

Tabi Timur-B04825 <B04825@freescale.com> wrote:

> What is include/uapi?

Take a look at http://lwn.net/Articles/507794/

David

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: David Howells @ 2012-10-11  9:27 UTC (permalink / raw)
  To: Stephen Rothwell, B04825
  Cc: Liu Yu, linux-kernel, Stuart Yoder, Alexander Graf, dhowells,
	linux-next, Paul Mackerras, linuxppc-dev
In-Reply-To: <20121011120502.0211f1267dedf3776e4cf85b@canb.auug.org.au>

Stephen Rothwell <sfr@canb.auug.org.au> wrote:

> I just removed epapr_hcalls.h from the Kbuild file as I am not sure how
> it should be broken up.  David, can you have a look at this, please?

Files should be broken up along around __KERNEL__ conditionals.  If there are
no __KERNEL__ conditionals, it is assumed that the file is entirely UAPI and
can just be moved.

The problem appears to be this commit:

	https://github.com/agraf/linux-2.6/commit/4c09029a5639c955fcf6d65205796e4f1208aed3

	From: Liu Yu <yu.liu@freescale.com>
	Subject: KVM: PPC: Add support for ePAPR idle hcall in host kernel

Just makes epapr_hcalls.h part of the userspace API in its entirety by this bit
of the patch:

	+header-y += epapr_hcalls.h

whilst not adding any __KERNEL__ guards - which is almost certainly incorrect.

At the very least, I would say that the global variable declarations need
limiting to kernel space, and thus so do the inline functions as they emit
inline assembly to jump somewhere specified by one of the global variables
(actually a code array).

So for manual splitting purposes, I would go with just moving all the #defines
prior to the __ASSEMBLY__ guard out to uapi.  Everything within the
__ASSEMBLY__ guard is KABI only by the looks of it.

David

^ permalink raw reply

* [PATCH v2] powerpc: 52xx: nop out unsupported critical IRQs
From: Wolfram Sang @ 2012-10-11  9:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: John Bonesio, Anatolij Gustschin, Wolfram Sang
In-Reply-To: <1349902593-16431-1-git-send-email-w.sang@pengutronix.de>

Currently, when booting MPC52xx based platforms, we get:

        mpc52xx_irqhost_map: invalid irq: virq=16, l1=0, l2=3
        irq: irq-16==>hwirq-0x3 mapping failed: -22
        [WARNing skipped]

The warning is wrong since the mapping itself is valid. However, there is no
support for that type of IRQ currently. Print a proper warning and bind the irq
to a no_irq chip.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: John Bonesio <bones@secretlab.ca>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
---

Change since V1: drop the default state since all possibilities for l1 are now
		 covered in the switch-statement.

 arch/powerpc/platforms/52xx/mpc52xx_pic.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8520b58..b89ef65 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
 	case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
 	case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
 	case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
-	default:
-		pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
-		       __func__, virq, l1irq, l2irq);
-		return -EINVAL;
+	case MPC52xx_IRQ_L1_CRIT:
+		pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n",
+			__func__, l2irq);
+		irq_set_chip(virq, &no_irq_chip);
+		return 0;
 	}
 
 	irq_set_chip_and_handler(virq, irqchip, handle_level_irq);
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH] vfio: enabled and supported on power (v7)
From: Alexey Kardashevskiy @ 2012-10-11  8:19 UTC (permalink / raw)
  To: Alex Williamson; +Cc: Paul Mackerras, linuxppc-dev, David Gibson
In-Reply-To: <1347597313.24938.375.camel@ul30vt.home>

Ok I'm back, nothing seems happened during last month :)


On 14/09/12 14:35, Alex Williamson wrote:
> On Fri, 2012-09-14 at 10:51 +1000, Alexey Kardashevskiy wrote:
>> On 14/09/12 08:34, Alex Williamson wrote:
>>> On Tue, 2012-09-11 at 18:28 +1000, Alexey Kardashevskiy wrote:
>>>> On 11/09/12 02:02, Alex Williamson wrote:
>>>>> On Tue, 2012-09-04 at 17:33 +1000, Alexey Kardashevskiy wrote:
>>>>>> Cc: David Gibson <david@gibson.dropbear.id.au>
>>>>>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>> Cc: Paul Mackerras <paulus@samba.org>
>>>>>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>>>>> ---
>>>>>
>>>>> Please at least cc kvm@vger as well since we list that as the devel list
>>>>> for vfio.
>>>>>
>>>>>>     arch/powerpc/include/asm/iommu.h    |    3 +
>>>>>
>>>>> I'll need an ack from Ben or Paul for this change.
>>>>>
>>>>>>     drivers/iommu/Kconfig               |    8 +
>>>>>>     drivers/vfio/Kconfig                |    6 +
>>>>>>     drivers/vfio/Makefile               |    1 +
>>>>>>     drivers/vfio/vfio_iommu_spapr_tce.c |  440 +++++++++++++++++++++++++++++++++++
>>>>>>     include/linux/vfio.h                |   29 +++
>>>>>>     6 files changed, 487 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 957a83f..c64bce7 100644
>>>>>> --- a/arch/powerpc/include/asm/iommu.h
>>>>>> +++ b/arch/powerpc/include/asm/iommu.h
>>>>>> @@ -66,6 +66,9 @@ struct iommu_table {
>>>>>>     	unsigned long  it_halfpoint; /* Breaking point for small/large allocs */
>>>>>>     	spinlock_t     it_lock;      /* Protects it_map */
>>>>>>     	unsigned long *it_map;       /* A simple allocation bitmap for now */
>>>>>> +#ifdef CONFIG_IOMMU_API
>>>>>> +	struct iommu_group *it_group;
>>>>>> +#endif
>>>>>>     };
>>>>>
>>>>> This seems to only be valid when vfio_iommu_spapr_tce is loaded, which
>>>>> is a bit misleading.
>>>>>
>>>>>>
>>>>>>     struct scatterlist;
>>>>>> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
>>>>>> index 3bd9fff..19cf2d9 100644
>>>>>> --- a/drivers/iommu/Kconfig
>>>>>> +++ b/drivers/iommu/Kconfig
>>>>>> @@ -162,4 +162,12 @@ config TEGRA_IOMMU_SMMU
>>>>>>     	  space through the SMMU (System Memory Management Unit)
>>>>>>     	  hardware included on Tegra SoCs.
>>>>>>
>>>>>> +config SPAPR_TCE_IOMMU
>>>>>> +	bool "sPAPR TCE IOMMU Support"
>>>>>> +	depends on PPC_PSERIES
>>>>>> +	select IOMMU_API
>>>>>> +	help
>>>>>> +	  Enables bits of IOMMU API required by VFIO. The iommu_ops is
>>>>>> +	  still not implemented.
>>>>>> +
>>>>>>     endif # IOMMU_SUPPORT
>>>>>> 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..21f1909
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c
>>>>>> @@ -0,0 +1,440 @@
>>>>>> +/*
>>>>>> + * 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_x86.c:
>>>>>
>>>>> Should this be _type1?  Only the mail archives are going to remember
>>>>> there was a _x86, so the renamed version is probably a better reference.
>>>>>
>>>>>> + * 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 <linux/spinlock.h>
>>>>>> +#include <asm/iommu.h>
>>>>>> +
>>>>>> +#define DRIVER_VERSION  "0.1"
>>>>>> +#define DRIVER_AUTHOR   "aik@ozlabs.ru"
>>>>>> +#define DRIVER_DESC     "VFIO IOMMU SPAPR TCE"
>>>>>> +
>>>>>> +
>>>>>> +/*
>>>>>> + * SPAPR TCE API
>>>>>> + */
>>>>>> +static void tce_free(struct iommu_table *tbl, unsigned long entry,
>>>>>> +		unsigned long tce)
>>>>>> +{
>>>>>> +	struct page *page = pfn_to_page(tce >> PAGE_SHIFT);
>>>>>> +
>>>>>> +	WARN_ON(!page);
>>>>>> +	if (page) {
>>>>>> +		if (tce & VFIO_SPAPR_TCE_WRITE)
>>>>>> +			SetPageDirty(page);
>>>>>> +		put_page(page);
>>>>>> +	}
>>>>>> +	ppc_md.tce_free(tbl, entry, 1);
>>>>>> +}
>>>>>> +
>>>>>> +static long tce_put(struct iommu_table *tbl,
>>>>>> +		unsigned long entry, uint64_t tce, uint32_t flags)
>>>>>> +{
>>>>>> +	int ret;
>>>>>> +	unsigned long oldtce, kva, offset;
>>>>>> +	struct page *page = NULL;
>>>>>> +	enum dma_data_direction direction = DMA_NONE;
>>>>>> +
>>>>>> +	switch (flags & VFIO_SPAPR_TCE_PUT_MASK) {
>>>>>> +	case VFIO_SPAPR_TCE_READ:
>>>>>> +		direction = DMA_TO_DEVICE;
>>>>>> +		break;
>>>>>> +	case VFIO_SPAPR_TCE_WRITE:
>>>>>> +		direction = DMA_FROM_DEVICE;
>>>>>> +		break;
>>>>>> +	case VFIO_SPAPR_TCE_BIDIRECTIONAL:
>>>>>> +		direction = DMA_BIDIRECTIONAL;
>>>>>> +		break;
>>>>>> +	}
>>>>>> +
>>>>>> +	oldtce = ppc_md.tce_get(tbl, entry);
>>>>>> +
>>>>>> +	/* Free page if still allocated */
>>>>>> +	if (oldtce & VFIO_SPAPR_TCE_PUT_MASK)
>>>>>> +		tce_free(tbl, entry, oldtce);
>>>>>> +
>>>>>> +	/* Map new TCE */
>>>>>> +	if (direction != DMA_NONE) {
>>>>>> +		offset = (tce & IOMMU_PAGE_MASK) - (tce & PAGE_MASK);
>>>>>> +		ret = get_user_pages_fast(tce & PAGE_MASK, 1,
>>>>>> +				direction != DMA_TO_DEVICE, &page);
>>>>>> +		BUG_ON(ret > 1);
>>>>>
>>>>> Can this happen?
>>>>>
>>>>>> +		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;
>>>>>> +			goto unlock_exit;
>>>>>> +		}
>>>>>> +
>>>>>> +		kva = (unsigned long) page_address(page);
>>>>>> +		kva += offset;
>>>>>> +		BUG_ON(!kva);
>>>>>
>>>>> Same here, can it happen?  If so, should it BUG or catch the below
>>>>> EINVAL?
>>>>>
>>>>>> +		if (WARN_ON(kva & ~IOMMU_PAGE_MASK))
>>>>>> +			return -EINVAL;
>>>>>
>>>>> Page leak?  Don't we want to do a put_page(), which means we probably
>>>>> want a goto exit here.
>>>>>
>>>>>> +
>>>>>> +		/* Preserve access bits */
>>>>>> +		kva |= flags & VFIO_SPAPR_TCE_PUT_MASK;
>>>>>> +
>>>>>> +		/* 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: Failed to add TCE\n");
>>>>>> +			ret = -EIO;
>>>>>> +			goto unlock_exit;
>>>>>> +		}
>>>>>> +	}
>>>>>> +	/* Flush/invalidate TLB caches if necessary */
>>>>>> +	if (ppc_md.tce_flush)
>>>>>> +		ppc_md.tce_flush(tbl);
>>>>>> +
>>>>>> +	/* Make sure updates are seen by hardware */
>>>>>> +	mb();
>>>>>> +
>>>>>> +unlock_exit:
>>>>>
>>>>> unlock seems wrong here, I had to go re-read the code looking for the
>>>>> lock.
>>>>>
>>>>>> +	if (ret && page)
>>>>>> +		put_page(page);
>>>>>> +
>>>>>> +	if (ret)
>>>>>> +		printk(KERN_ERR "tce_vfio: tce_put failed on tce=%llx "
>>>>>> +				"ioba=%lx kva=%lx\n", tce,
>>>>>> +				entry << IOMMU_PAGE_SHIFT, kva);
>>>>>> +	return ret;
>>>>>> +}
>>>>>> +
>>>>>> +/*
>>>>>> + * 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 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);
>>>>>> +
>>>>>> +	return container;
>>>>>> +}
>>>>>> +
>>>>>> +static void tce_iommu_release(void *iommu_data)
>>>>>> +{
>>>>>> +	struct tce_container *container = iommu_data;
>>>>>> +	struct iommu_table *tbl = container->tbl;
>>>>>> +	unsigned long i, tce;
>>>>>> +
>>>>>
>>>>> This will segfault if releasing a container that never had an a device
>>>>> attached.
>>>>>
>>>>>> +	/* Unmap leftovers */
>>>>>> +	spin_lock_irq(&tbl->it_lock);
>>>>>> +	for (i = tbl->it_offset; i < tbl->it_offset + tbl->it_size; ++i) {
>>>>>> +		tce = ppc_md.tce_get(tbl, i);
>>>>>> +		if (tce & VFIO_SPAPR_TCE_PUT_MASK)
>>>>>> +			tce_free(tbl, i, tce);
>>>>>> +	}
>>>>>> +	/* Flush/invalidate TLB caches if necessary */
>>>>>> +	if (ppc_md.tce_flush)
>>>>>> +		ppc_md.tce_flush(tbl);
>>>>>> +
>>>>>> +	/* Make sure updates are seen by hardware */
>>>>>> +	mb();
>>>>>> +
>>>>>> +	spin_unlock_irq(&tbl->it_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;
>>>>>> +	long ret;
>>>>>> +
>>>>>> +	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;
>>>>>> +
>>>>>> +		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;
>>>>>> +
>>>>>> +		if (!tbl)
>>>>>> +			return -ENXIO;
>>>>>
>>>>> nit: why not check this earlier?
>>>>>
>>>>>> +
>>>>>> +		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;
>>>>>> +
>>>>>> +		return copy_to_user((void __user *)arg, &info, minsz);
>>>>>> +	}
>>>>>> +	case VFIO_IOMMU_SPAPR_TCE_PUT: {
>>>>>> +		struct vfio_iommu_spapr_tce_put par;
>>>>>> +		struct iommu_table *tbl = container->tbl;
>>>>>> +
>>>>>> +		minsz = offsetofend(struct vfio_iommu_spapr_tce_put, tce);
>>>>>> +
>>>>>> +		if (copy_from_user(&par, (void __user *)arg, minsz))
>>>>>> +			return -EFAULT;
>>>>>> +
>>>>>> +		if (par.argsz < minsz)
>>>>>> +			return -EINVAL;
>>>>>> +
>>>>>> +		if (!tbl) {
>>>>>> +			return -ENXIO;
>>>>>> +		}
>>>>>
>>>>> Same, plus drop the braces.
>>>>>
>>>>>> +
>>>>>> +		spin_lock_irq(&tbl->it_lock);
>>>>>> +		ret = tce_put(tbl, par.ioba >> IOMMU_PAGE_SHIFT,
>>>>>> +				par.tce, par.flags);
>>>>>> +		spin_unlock_irq(&tbl->it_lock);
>>>>>> +
>>>>>> +		return ret;
>>>>>> +	}
>>>>>
>>>>> Is "PUT" really the name we want for this?
>>>>
>>>>
>>>> Yes, it is a single H_PUT_TCE hypercall from POWER architecture spec.
>>>
>>> Ok, if it makes sense on your arch, I won't complain (too much) about
>>> it.
>>>
>>>>>> +	default:
>>>>>> +		printk(KERN_WARNING "tce_vfio: unexpected cmd %x\n", cmd);
>>>>>> +	}
>>>>>> +
>>>>>> +	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);
>>>>>> +
>>>>>> +	printk(KERN_DEBUG "tce_vfio: Attaching group #%u to iommu %p\n",
>>>>>> +			iommu_group_id(iommu_group), iommu_group);
>>>>>
>>>>> Let's use pr_debug() and friends throughout.
>>>>>
>>>>>> +	if (container->tbl) {
>>>>>> +		printk(KERN_WARNING "tce_vfio: Only one group per IOMMU "
>>>>>> +				"container is allowed, "
>>>>>> +				"existing id=%d, attaching id=%d\n",
>>>>>> +				iommu_group_id(container->tbl->it_group),
>>>>>> +				iommu_group_id(iommu_group));
>>>>>> +		return -EBUSY;
>>>>>> +	}
>>>>>> +
>>>>>
>>>>> _type1 has a lock to avoid races here, I think you might need one too.
>>>>>
>>>>>> +	container->tbl = tbl;
>>>>>> +
>>>>>> +	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);
>>>>>
>>>>> Needed?  If so, why is there no check on attach?
>>>>
>>>> Added to attach() :)
>>>>
>>>>
>>>>>
>>>>>> +	if (tbl != container->tbl) {
>>>>>> +		printk(KERN_WARNING "tce_vfio: detaching group #%u, expected "
>>>>>> +				"group is #%u\n", iommu_group_id(iommu_group),
>>>>>> +				iommu_group_id(tbl->it_group));
>>>>>> +		return;
>>>>>> +	}
>>>>>> +	printk(KERN_DEBUG "tce_vfio: detaching group #%u from iommu %p\n",
>>>>>> +			iommu_group_id(iommu_group), iommu_group);
>>>>>
>>>>> container->tbl = NULL?
>>>>
>>>>
>>>> Then I won't be able to release pages in tce_iommu_release().
>>>> Releasing pages in tce_iommu_detach_group() caused some other problems,
>>>> cannot recall now which ones.
>>>
>>> What happens if you hot unplug a group from one VM and add it to
>>> another?  ie. we've detached it from one container and add it to another
>>> in a different instance.  Does it cause problems here?
>>
>>
>> Then the container will be released as just one group per container is
>> supported at the moment, no? Cannot check though as we do not support
>> hotplug yet.
>
> But you still have a race where the group is detached, but the container
> is not yet released and can be attached to another container in a
> different instance.


Yeah... Moved cleanup to detach(), trying to reproduce the issue I had 
before but to no avail.


>>>>>> +}
>>>>>> +
>>>>>> +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,
>>>>>> +};
>>>>>> +
>>>>>> +/*
>>>>>> + * Add/delete devices support (hotplug, module_init, module_exit)
>>>>>> + */
>>>>>> +static int add_device(struct device *dev)
>>>>>> +{
>>>>>> +	struct iommu_table *tbl;
>>>>>> +	int ret = 0;
>>>>>> +
>>>>>> +	if (dev->iommu_group) {
>>>>>> +		printk(KERN_WARNING "tce_vfio: device %s is already in iommu "
>>>>>> +				"group %d, skipping\n", dev->kobj.name,
>>>>>
>>>>> Watch line wrapping on strings.
>>>>
>>>> Pardon?
>>>
>>> Just suggesting that you try to wrap lines so that strings are
>>> searchable.  For instance, can I search cscope for "is already in iommu
>>> group".  It's generally accepted that printks can break 80 cols for
>>> this.
>>
>> Aaaa. Did not know that this is accepted but was always annoyed to wrap
>> this way, thanks :)
>>
>>
>>>>>> +				iommu_group_id(dev->iommu_group));
>>>>>> +		return -EBUSY;
>>>>>> +	}
>>>>>> +
>>>>>> +	tbl = get_iommu_table_base(dev);
>>>>>> +	if (!tbl) {
>>>>>> +		printk(KERN_DEBUG "tce_vfio: skipping device %s with no tbl\n",
>>>>>> +				dev->kobj.name);
>>>>>> +		return 0;
>>>>>> +	}
>>>>>> +
>>>>>> +	printk(KERN_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,
>>>>>> +};
>>>>>> +
>>>>>> +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;
>>>>>> +
>>>>>> +	/* If the current platform does not support tce_get
>>>>>> +	   we are unable to clean TCE table properly and
>>>>>> +	   therefore it is better not to touch it at all */
>>>>>> +	if (!ppc_md.tce_get) {
>>>>>> +		printk(KERN_ERR "tce_vfio: ppc_md.tce_get isn't implemented\n");
>>>>>> +		return -EOPNOTSUPP;
>>>>>> +	}
>>>>>> +
>>>>>> +	bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
>>>>>> +
>>>>>> +	/* Allocate and initialize VFIO groups */
>>>>>
>>>>> s/VFIO groups/IOMMU groups/
>>>>>
>>>>>> +	for_each_pci_dev(pdev) {
>>>>>> +		tbl = get_iommu_table_base(&pdev->dev);
>>>>>> +		if (!tbl)
>>>>>> +			continue;
>>>>>> +
>>>>>> +		/* Skip already initialized */
>>>>>> +		if (tbl->it_group)
>>>>>> +			continue;
>>>>>> +
>>>>>> +		grp = iommu_group_alloc();
>>>>>> +		if (IS_ERR(grp)) {
>>>>>> +			printk(KERN_INFO "tce_vfio: cannot create "
>>>>>> +					"new IOMMU group, ret=%ld\n",
>>>>>> +					PTR_ERR(grp));
>>>>>> +			return -EFAULT;
>>>>>> +		}
>>>>>> +		tbl->it_group = grp;
>>>>>> +		iommu_group_set_iommudata(grp, tbl, group_release);
>>>>>> +	}
>>>>>> +
>>>>>> +	/* Add PCI devices to VFIO groups */
>>>>>> +	for_each_pci_dev(pdev)
>>>>>> +		add_device(&pdev->dev);
>>>>>> +
>>>>>> +	return vfio_register_iommu_driver(&tce_iommu_driver_ops);
>>>>>> +}
>>>>>> +
>>>>>> +static void __exit tce_iommu_cleanup(void)
>>>>>> +{
>>>>>> +	struct pci_dev *pdev = NULL;
>>>>>> +	struct iommu_table *tbl;
>>>>>> +	struct iommu_group *grp = NULL;
>>>>>> +
>>>>>> +	bus_unregister_notifier(&pci_bus_type, &tce_iommu_bus_nb);
>>>>>> +
>>>>>> +	/* Delete PCI devices from VFIO groups */
>>>>>> +	for_each_pci_dev(pdev)
>>>>>> +		del_device(&pdev->dev);
>>>>>> +
>>>>>> +	/* Release VFIO groups */
>>>>>> +	for_each_pci_dev(pdev) {
>>>>>> +		tbl = get_iommu_table_base(&pdev->dev);
>>>>>> +		if (!tbl)
>>>>>> +			continue;
>>>>>> +		grp = tbl->it_group;
>>>>>> +
>>>>>> +		/* Skip (already) uninitialized */
>>>>>> +		if (!grp)
>>>>>> +			continue;
>>>>>> +
>>>>>> +		/* Do actual release, group_release() is expected to work */
>>>>>> +		iommu_group_put(grp);
>>>>>> +		BUG_ON(tbl->it_group);
>>>>>> +	}
>>>>>> +
>>>>>
>>>>>
>>>>> It troubles me a bit that you're using the vfio driver to initialize and
>>>>> tear down IOMMU groups on your platform.
>>>>
>>>>
>>>> I am not following you here. Could you please explain a bit?
>>>
>>> IOMMU groups are theoretically not just for VFIO.  They expose DMA
>>> dependencies between devices for anyone who cares to know about it.
>>> VFIO happens to care very much about that, but is hopefully not the only
>>> consumer.  So it's a little bit like writing a driver for a device on a
>>> new bus and incorporating the bus topology handling code into the device
>>> driver.  IOMMU groups should be created and managed independent of VFIO.
>>
>> Do you mean that we create groups only for PCI devices? Well, moving groups
>> creation where the actual powerpc groups are allocated (pci scan) is
>> problematic right now as iommu_init() is called too late.
>
> I mean IOMMU group creation should be independent of VFIO.  I'm not sure
> how to make that ordering work on POWER, but integrating them into your
> VFIO driver is contrary to many of the arguments that were made for
> making IOMMU groups part of the base device model.


I still do not get it. The creation code itself does not depend on VFIO.
And yes, I would like to create groups from the platform code when the 
actual IOMMU tables are created, the only problem is that iommu_init() is 
called too late - after PCI scan (subsys_initcall(pcibios_init) from 
arch/powerpc/kernel/pci_64.c), iommu_init is subsys_initcall as well.
I could move tce_iommu_init/tce_iommu_cleanup as a module somewhere in 
arch/powerpc but moving iommu_init() earlier looks better, then I would 
create IOMMU groups exactly when their POWER counterparts are created.



>>>>> VFIO makes use of IOMMU groups
>>>>> and is the only user so far, but they're hopefully useful beyond this.
>>>>> In fact, VFIO used to manage assembling all groups from data provided by
>>>>> the IOMMU but David wanted to see IOMMU groups be a more universally
>>>>> available feature, so it's odd to see POWER implementing it this way.
>>>>
>>>>
>>>> David, help! :)
>>>>
>>>>
>>>>>> +	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..2c0a927 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,32 @@ struct vfio_iommu_type1_dma_unmap {
>>>>>>
>>>>>>     #define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14)
>>>>>>
>>>>>> +/* -------- 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;
>>>>>> +};
>>>>>> +
>>>>>> +#define VFIO_IOMMU_SPAPR_TCE_GET_INFO	_IO(VFIO_TYPE, VFIO_BASE + 12)
>>>>>> +
>>>>>> +struct vfio_iommu_spapr_tce_put {
>>>>>> +	__u32 argsz;
>>>>>> +	__u32 flags;
>>>>>> +#define VFIO_SPAPR_TCE_READ		1
>>>>>> +#define VFIO_SPAPR_TCE_WRITE		2
>>>>>> +#define VFIO_SPAPR_TCE_BIDIRECTIONAL	(VFIO_SPAPR_TCE_READ|VFIO_SPAPR_TCE_WRITE)
>>>>>> +#define VFIO_SPAPR_TCE_PUT_MASK		VFIO_SPAPR_TCE_BIDIRECTIONAL
>>>>>> +	__u64 ioba;
>>>>>> +	__u64 tce;
>>>>>> +};
>>>>>
>>>>> Ok, so if READ & WRITE are both clear and ioba is set, that's an
>>>>> "unmap"?  This is exactly why _type1 has a MAP and UNMAP, to make it
>>>>> clear which fields are necessary for which call.  I think we should
>>>>> probably do the same here.  Besides, _put makes me think there should be
>>>>> a _get; do these have some unique meaning in POWER?
>>>>
>>>>
>>>> It is a single H_PUT_TCE for putting a record into TCE table. The guest
>>>> calls H_PUT_TCE, QEMU replaces the address and simply forwards the call to
>>>> the host. Calling them map/unmap makes it less clear for powerpc people :)
>>>
>>> In the unmap case we take an ioba and lookup a tce to clear, in the map
>>> case we take an ioba and tce and insert them into the table.  It's valid
>>> to document this and use a single ioctl, but I've opted on x86 to have
>>> separate ioctls because the documentation falls out cleaner when there
>>> aren't fields that are only used in certain conditions.  Do you really
>>> want any userspace driver making use of this to know about powerpc
>>> H_PUT_TCE or would it make more sense to have a MAP and UNMAP call?  I
>>> think it would be better for the VFIO API if we had some consistency in
>>> the mapping ioctls where possible.
>>
>>
>> I would think that passing through "as is" as much as possible is the best
>> thing here as the aim is KVM. May be one day we will implement H_PUT_TCE in
>> the kernel, so splitting H_PUT_TCE to map+unmap and then combining it back
>> in the kernel (because we will have H_PUT_TCE handler) is a bit ugly.
>
> No, KVM is a use case for VFIO, we shouldn't be assume it's _the_ use
> case.  Exposing it "as is" means anyone trying to write a VFIO userspace
> driver needs to know about the implementation of H_PUT_TCE to make the
> driver work on POWER.  The fact that the same hypercall is made for a
> map or unmap is really irrelevant to the VFIO API.
>
>>>>>> +#define VFIO_IOMMU_SPAPR_TCE_PUT	_IO(VFIO_TYPE, VFIO_BASE + 13)
>>>>>> +
>>>>>
>>>>> Please document what all of the above means.  Thanks,
>>>>
>>>>
>>>> Something like this?
>>>> /*
>>>>     * The VFIO_IOMMU_SPAPR_TCE_PUT is implemented as the H_PUT_TCE hypercall.
>>>>     * ioba - I/O Bus Address for indexing into TCE table
>>>>     * tce - logical address of storage
>>>>     *
>>>>     * The non-zero flags means adding new page into the table.
>>>>     * The zero flags means releasing the existing page and clearing the
>>>>     * TCE table entry.
>>>>     */
>>>
>>> Do you only want VFIO drivers to work on POWER if they're written by
>>> POWER people?  Ideally there are a few simple concepts: a) devices have
>>> an I/O virtual address space.  On x86 we call this the iova and it's
>>> effectively a zero-based, 64bit (not really, but close enough) address
>>> space.  You seem to have two smaller windows, one in 32bit space,
>>> another in 64bit space (maybe we could name these more consistently).
>>> b) Userspace has a buffer that they want to map and unmap to an iova,
>>> potentially with some access flags.  That's all you need to know to use
>>> the x86 _type1 VFIO IOMMU API.
>>
>>
>> Do not you have to map entire RAM to PCI bus? You use listener which
>> purpose is not very clear. This is an extra knowledge beyond qemu-to-host
>> interface which the user space program should know.
>
> In the x86 case, the buffer we want to map is all of guest RAM.  Some of
> that changes dynamically, so we have a listener setup to make updates.
> The only thing magic about doing that is that the device is then able to
> DMA to any part of guest RAM and therefore the guest doesn't need to
> know the IOMMU exists.  Device assignment is therefore transparent on
> x86.

>>> Why do I need to know about H_PUT_TCE to
>>> use this interface?  Let's assume there might be some VFIO drivers some
>>> day that aren't written by POWER people.  Thanks,
>>
>> Example of such a driver? My imagination is weak :)
>
> See Tom Lyon's original user level drivers:
>
> https://github.com/pugs/vfio-user-level-drivers
>
> These are against the original version of VFIO so no longer work, but
> he's got drivers for common devices like Intel 82576 & 82599 SR-IOV
> NICs.  There are special use cases and special devices where it makes
> sense to have a driver in userspace.  Ideally a VFIO driver for a NIC
> would work with fairly minimal IOMMU abstractions between x86 and POWER,
> but if you design the SPAPR VFIO IOMMU API so that users need to
> understand how H_PUT_TCE works to port their driver to POWER, you might
> find it more difficult to leverage such drivers.  Thanks,

A user space driver needs to know the DMA window if it wants to work on 
POWER because this is how PHB is configured. So it needs to know something 
about POWER. It could be fixed easily - we stop using IOMMU types and make 
map/unmap/info independent from the IOMMU type. You'll have to implement 
DMA window properties (which is entire RAM) and then we'll put to the spec 
that VFIO users have to call DMA map/unmap only for addresses within the 
returned DMA window boundaries. I thought this is what we wanted to avoid...
Or implement third type of IOMMU - "VFIO user space driver" (and implement 
dma_alloc() which would allocate an address for DMA on PCI bus) and name 
the first twos as "TYPE1 KVM" and "SPAPR TCE KVM".


-- 
Alexey

^ permalink raw reply

* Re: [PATCH 2/10] memory-hotplug : remove /sys/firmware/memmap/X sysfs
From: Yasuaki Ishimatsu @ 2012-10-11  7:06 UTC (permalink / raw)
  To: KOSAKI Motohiro
  Cc: linux-s390, linux-ia64, wency, len.brown, linux-acpi, linux-sh,
	x86, linux-kernel, cmetcalf, linux-mm, minchan.kim, rientjes,
	sparclinux, cl, linuxppc-dev, akpm, liuj97
In-Reply-To: <CAHGf_=rc9z7OmuH-pamQmPE=dpy3zPX3fXab=-APo2_NX7=KpQ@mail.gmail.com>

2012/10/06 4:36, KOSAKI Motohiro wrote:
> On Thu, Oct 4, 2012 at 10:26 PM, Yasuaki Ishimatsu
> <isimatu.yasuaki@jp.fujitsu.com> wrote:
>> When (hot)adding memory into system, /sys/firmware/memmap/X/{end, start, type}
>> sysfs files are created. But there is no code to remove these files. The patch
>> implements the function to remove them.
>>
>> Note : The code does not free firmware_map_entry since there is no way to free
>>         memory which is allocated by bootmem.
>
> You have to explain why this is ok. I guess the unfreed
> firmware_map_entry is reused
> at next online memory and don't make memory leak, right?

Unfortunately, it is no. It makes memory leak about firmware_map_entry size.
If we hot add memory, slab allocater prepares a other memory for
firmware_map_entry.

In my understanding, if the memory is allocated by bootmem allocator,
the memory is not managed by slab allocator. So we can not use kfree()
against the memory.
On the other hand, the page of the memory may have various data allocalted
by bootmem allocater with the exception of the firmware_map_entry. Thus we
cannot free the page.

So the patch makes memory leak. But I think the memory leak size is
very samll. And it does not affect the system.

>
>
>
>>
>> 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>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>>
>> ---
>>   drivers/firmware/memmap.c    |   98 ++++++++++++++++++++++++++++++++++++++++++-
>>   include/linux/firmware-map.h |    6 ++
>>   mm/memory_hotplug.c          |    7 ++-
>>   3 files changed, 108 insertions(+), 3 deletions(-)
>>
>> Index: linux-3.6/drivers/firmware/memmap.c
>> ===================================================================
>> --- linux-3.6.orig/drivers/firmware/memmap.c    2012-10-04 18:27:05.195500420 +0900
>> +++ linux-3.6/drivers/firmware/memmap.c 2012-10-04 18:27:18.901514330 +0900
>> @@ -21,6 +21,7 @@
>>   #include <linux/types.h>
>>   #include <linux/bootmem.h>
>>   #include <linux/slab.h>
>> +#include <linux/mm.h>
>>
>>   /*
>>    * Data types ------------------------------------------------------------------
>> @@ -41,6 +42,7 @@ struct firmware_map_entry {
>>          const char              *type;  /* type of the memory range */
>>          struct list_head        list;   /* entry for the linked list */
>>          struct kobject          kobj;   /* kobject for each entry */
>> +       unsigned int            bootmem:1; /* allocated from bootmem */
>
> Use bool.

We'll update it.

>
>>   };
>>
>>   /*
>> @@ -79,7 +81,26 @@ static const struct sysfs_ops memmap_att
>>          .show = memmap_attr_show,
>>   };
>>
>> +
>> +static inline struct firmware_map_entry *
>> +to_memmap_entry(struct kobject *kobj)
>> +{
>> +       return container_of(kobj, struct firmware_map_entry, kobj);
>> +}
>> +
>> +static void release_firmware_map_entry(struct kobject *kobj)
>> +{
>> +       struct firmware_map_entry *entry = to_memmap_entry(kobj);
>> +
>> +       if (entry->bootmem)
>> +               /* There is no way to free memory allocated from bootmem */
>> +               return;
>> +
>> +       kfree(entry);
>> +}
>> +
>>   static struct kobj_type memmap_ktype = {
>> +       .release        = release_firmware_map_entry,
>>          .sysfs_ops      = &memmap_attr_ops,
>>          .default_attrs  = def_attrs,
>>   };
>> @@ -94,6 +115,7 @@ static struct kobj_type memmap_ktype = {
>>    * in firmware initialisation code in one single thread of execution.
>>    */
>>   static LIST_HEAD(map_entries);
>> +static DEFINE_SPINLOCK(map_entries_lock);
>>
>>   /**
>>    * firmware_map_add_entry() - Does the real work to add a firmware memmap entry.
>> @@ -118,11 +140,25 @@ static int firmware_map_add_entry(u64 st
>>          INIT_LIST_HEAD(&entry->list);
>>          kobject_init(&entry->kobj, &memmap_ktype);
>>
>> +       spin_lock(&map_entries_lock);
>>          list_add_tail(&entry->list, &map_entries);
>> +       spin_unlock(&map_entries_lock);
>>
>>          return 0;
>>   }
>>
>> +/**
>> + * firmware_map_remove_entry() - Does the real work to remove a firmware
>> + * memmap entry.
>> + * @entry: removed entry.
>> + **/
>> +static inline void firmware_map_remove_entry(struct firmware_map_entry *entry)
>
> Don't use inline in *.c file. gcc is wise than you.

We'll update it.

>> +{
>> +       spin_lock(&map_entries_lock);
>> +       list_del(&entry->list);
>> +       spin_unlock(&map_entries_lock);
>> +}
>> +
>>   /*
>>    * Add memmap entry on sysfs
>>    */
>> @@ -144,6 +180,35 @@ static int add_sysfs_fw_map_entry(struct
>>          return 0;
>>   }
>>
>> +/*
>> + * Remove memmap entry on sysfs
>> + */
>> +static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry)
>> +{
>> +       kobject_put(&entry->kobj);
>> +}
>> +
>> +/*
>> + * Search memmap entry
>> + */
>> +
>> +static struct firmware_map_entry * __meminit
>> +firmware_map_find_entry(u64 start, u64 end, const char *type)
>> +{
>> +       struct firmware_map_entry *entry;
>> +
>> +       spin_lock(&map_entries_lock);
>> +       list_for_each_entry(entry, &map_entries, list)
>> +               if ((entry->start == start) && (entry->end == end) &&
>> +                   (!strcmp(entry->type, type))) {
>> +                       spin_unlock(&map_entries_lock);
>> +                       return entry;
>> +               }
>> +
>> +       spin_unlock(&map_entries_lock);
>> +       return NULL;
>> +}
>> +
>>   /**
>>    * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
>>    * memory hotplug.
>> @@ -193,9 +258,36 @@ int __init firmware_map_add_early(u64 st
>>          if (WARN_ON(!entry))
>>                  return -ENOMEM;
>>
>> +       entry->bootmem = 1;
>>          return firmware_map_add_entry(start, end, type, entry);
>>   }
>>
>> +/**
>> + * firmware_map_remove() - remove a firmware mapping entry
>> + * @start: Start of the memory range.
>> + * @end:   End of the memory range.
>> + * @type:  Type of the memory range.
>> + *
>> + * removes a firmware mapping entry.
>> + *
>> + * Returns 0 on success, or -EINVAL if no entry.
>> + **/
>> +int __meminit firmware_map_remove(u64 start, u64 end, const char *type)
>
> Remove type argument if this is always passed "System RAM".

Probably, the type is always "System RAM". But we need to check whether
that the range of start and end variables are "System RAM" or not.
So I want to keep it.

Thanks,
Yasuaki Ishimatsu

>
>> +{
>> +       struct firmware_map_entry *entry;
>> +
>> +       entry = firmware_map_find_entry(start, end - 1, type);
>> +       if (!entry)
>> +               return -EINVAL;
>> +
>> +       firmware_map_remove_entry(entry);
>> +
>> +       /* remove the memmap entry */
>> +       remove_sysfs_fw_map_entry(entry);
>> +
>> +       return 0;
>> +}
>> +
>>   /*
>>    * Sysfs functions -------------------------------------------------------------
>>    */
>> @@ -217,8 +309,10 @@ static ssize_t type_show(struct firmware
>>          return snprintf(buf, PAGE_SIZE, "%s\n", entry->type);
>>   }
>>
>> -#define to_memmap_attr(_attr) container_of(_attr, struct memmap_attribute, attr)
>> -#define to_memmap_entry(obj) container_of(obj, struct firmware_map_entry, kobj)
>> +static inline struct memmap_attribute *to_memmap_attr(struct attribute *attr)
>> +{
>> +       return container_of(attr, struct memmap_attribute, attr);
>> +}
>>
>>   static ssize_t memmap_attr_show(struct kobject *kobj,
>>                                  struct attribute *attr, char *buf)
>> Index: linux-3.6/include/linux/firmware-map.h
>> ===================================================================
>> --- linux-3.6.orig/include/linux/firmware-map.h 2012-10-04 18:27:05.197500422 +0900
>> +++ linux-3.6/include/linux/firmware-map.h      2012-10-04 18:27:18.904514333 +0900
>> @@ -25,6 +25,7 @@
>>
>>   int firmware_map_add_early(u64 start, u64 end, const char *type);
>>   int firmware_map_add_hotplug(u64 start, u64 end, const char *type);
>> +int firmware_map_remove(u64 start, u64 end, const char *type);
>>
>>   #else /* CONFIG_FIRMWARE_MEMMAP */
>>
>> @@ -38,6 +39,11 @@ static inline int firmware_map_add_hotpl
>>          return 0;
>>   }
>>
>> +static inline int firmware_map_remove(u64 start, u64 end, const char *type)
>> +{
>> +       return 0;
>> +}
>> +
>>   #endif /* CONFIG_FIRMWARE_MEMMAP */
>>
>>   #endif /* _LINUX_FIRMWARE_MAP_H */
>> Index: linux-3.6/mm/memory_hotplug.c
>> ===================================================================
>> --- linux-3.6.orig/mm/memory_hotplug.c  2012-10-04 18:27:03.000000000 +0900
>> +++ linux-3.6/mm/memory_hotplug.c       2012-10-04 18:28:42.851599524 +0900
>> @@ -1043,7 +1043,7 @@ int offline_memory(u64 start, u64 size)
>>          return 0;
>>   }
>>
>> -int remove_memory(int nid, u64 start, u64 size)
>> +int __ref remove_memory(int nid, u64 start, u64 size)
>>   {
>>          int ret = 0;
>>          lock_memory_hotplug();
>> @@ -1056,8 +1056,13 @@ int remove_memory(int nid, u64 start, u6
>>                          "because the memmory range is online\n",
>>                          start, start + size);
>>                  ret = -EAGAIN;
>> +               goto out;
>>          }
>>
>> +       /* remove memmap entry */
>> +       firmware_map_remove(start, start + size, "System RAM");
>> +
>> +out:
>>          unlock_memory_hotplug();
>>          return ret;
>>   }
>
>
> Other than that, looks ok to me.
>

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Tabi Timur-B04825 @ 2012-10-11  3:32 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: Alexander Graf, linux-kernel@vger.kernel.org, David Howells,
	linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20121011134754.2e2cbb24842fa991e61cf97c@canb.auug.org.au>

On Wed, Oct 10, 2012 at 9:47 PM, Stephen Rothwell <sfr@canb.auug.org.au> wr=
ote:

> Commit 549d62d889b4 ("KVM: PPC: use definitions in epapr header
> for hcalls") from the kvm-ppc tree added an include of asm/epapr_hcall.h
> to the user visible part of asm/kvm_para.h so asm/epapr_hcall.h became a
> user visible header file.

Any real user-space code that tries to call any of the functions in
epapr_hcall.h will cause an exception.

Claiming that kernel header files that KVM needs are suddenly
user-space header files doesn't make much sense to me, but I guess
it's not my decision.

--=20
Timur Tabi
Linux kernel developer at Freescale=

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Stephen Rothwell @ 2012-10-11  2:47 UTC (permalink / raw)
  To: Tabi Timur-B04825
  Cc: Alexander Graf, linux-kernel@vger.kernel.org, David Howells,
	linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <6AE080B68D46FC4BA2D2769E68D765B7080FA8F8@039-SN2MPN1-023.039d.mgd.msft.net>

[-- Attachment #1: Type: text/plain, Size: 1063 bytes --]

On Thu, 11 Oct 2012 01:47:13 +0000 Tabi Timur-B04825 <B04825@freescale.com> wrote:
>
> On Wed, Oct 10, 2012 at 8:18 PM, Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> 
> >  arch/powerpc/include/asm/epapr_hcalls.h      |  511 --------------------------
> >  arch/powerpc/include/uapi/asm/Kbuild         |    1 +
> >  arch/powerpc/include/uapi/asm/epapr_hcalls.h |  511 ++++++++++++++++++++++++++
> 
> What is include/uapi?  epapr_hcalls.h is not a user-space header file.
>  I don't remember seeing the original patch which moved it, so I don't
> know where this comes from.

Commit 549d62d889b4 ("KVM: PPC: use definitions in epapr header
for hcalls") from the kvm-ppc tree added an include of asm/epapr_hcall.h
to the user visible part of asm/kvm_para.h so asm/epapr_hcall.h became a
user visible header file.

The UAPI changes are moving the user visible parts of export header files
into a separate include directory called uapi.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Tabi Timur-B04825 @ 2012-10-11  1:47 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: Alexander Graf, linux-kernel@vger.kernel.org, David Howells,
	linux-next@vger.kernel.org, Paul Mackerras,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20121011121841.1b946f996cba995d9a5a2be7@canb.auug.org.au>

On Wed, Oct 10, 2012 at 8:18 PM, Stephen Rothwell <sfr@canb.auug.org.au> wr=
ote:

>  arch/powerpc/include/asm/epapr_hcalls.h      |  511 --------------------=
------
>  arch/powerpc/include/uapi/asm/Kbuild         |    1 +
>  arch/powerpc/include/uapi/asm/epapr_hcalls.h |  511 ++++++++++++++++++++=
++++++

What is include/uapi?  epapr_hcalls.h is not a user-space header file.
 I don't remember seeing the original patch which moved it, so I don't
know where this comes from.


--=20
Timur Tabi
Linux kernel developer at Freescale=

^ permalink raw reply

* linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Stephen Rothwell @ 2012-10-11  1:18 UTC (permalink / raw)
  To: Alexander Graf
  Cc: linux-kernel, Stuart Yoder, David Howells, linux-next,
	Paul Mackerras, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 39440 bytes --]

Hi Alexander,

Today's linux-next merge of the kvm-ppc tree got a conflict in
arch/powerpc/include/asm/kvm_para.h between commit c3617f72036c ("UAPI:
(Scripted) Disintegrate arch/powerpc/include/asm") from the powerpc-merge
tree and commit 549d62d889b4 ("KVM: PPC: use definitions in epapr header
for hcalls") from the kvm-ppc tree.

I fixed it up (see at the end) and can carry the fix as necessary (no action
is required, though you need to remember to tell Linus about this).

I also added this merge fix patch:

From 61d39136e4228e62e27c11ac8d27cd6664b39639 Mon Sep 17 00:00:00 2001
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Thu, 11 Oct 2012 12:13:51 +1100
Subject: [PATCH] KVM: PPC: fix fallout from UAPI changes

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/include/asm/epapr_hcalls.h      |  511 --------------------------
 arch/powerpc/include/uapi/asm/Kbuild         |    1 +
 arch/powerpc/include/uapi/asm/epapr_hcalls.h |  511 ++++++++++++++++++++++++++
 arch/powerpc/include/uapi/asm/kvm_para.h     |    7 +-
 4 files changed, 516 insertions(+), 514 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/epapr_hcalls.h
 create mode 100644 arch/powerpc/include/uapi/asm/epapr_hcalls.h

diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h
deleted file mode 100644
index b8d9445..0000000
--- a/arch/powerpc/include/asm/epapr_hcalls.h
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * ePAPR hcall interface
- *
- * Copyright 2008-2011 Freescale Semiconductor, Inc.
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * This file is provided under a dual BSD/GPL license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Freescale Semiconductor nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* A "hypercall" is an "sc 1" instruction.  This header file file provides C
- * wrapper functions for the ePAPR hypervisor interface.  It is inteded
- * for use by Linux device drivers and other operating systems.
- *
- * The hypercalls are implemented as inline assembly, rather than assembly
- * language functions in a .S file, for optimization.  It allows
- * the caller to issue the hypercall instruction directly, improving both
- * performance and memory footprint.
- */
-
-#ifndef _EPAPR_HCALLS_H
-#define _EPAPR_HCALLS_H
-
-#define EV_BYTE_CHANNEL_SEND		1
-#define EV_BYTE_CHANNEL_RECEIVE		2
-#define EV_BYTE_CHANNEL_POLL		3
-#define EV_INT_SET_CONFIG		4
-#define EV_INT_GET_CONFIG		5
-#define EV_INT_SET_MASK			6
-#define EV_INT_GET_MASK			7
-#define EV_INT_IACK			9
-#define EV_INT_EOI			10
-#define EV_INT_SEND_IPI			11
-#define EV_INT_SET_TASK_PRIORITY	12
-#define EV_INT_GET_TASK_PRIORITY	13
-#define EV_DOORBELL_SEND		14
-#define EV_MSGSND			15
-#define EV_IDLE				16
-
-/* vendor ID: epapr */
-#define EV_LOCAL_VENDOR_ID		0	/* for private use */
-#define EV_EPAPR_VENDOR_ID		1
-#define EV_FSL_VENDOR_ID		2	/* Freescale Semiconductor */
-#define EV_IBM_VENDOR_ID		3	/* IBM */
-#define EV_GHS_VENDOR_ID		4	/* Green Hills Software */
-#define EV_ENEA_VENDOR_ID		5	/* Enea */
-#define EV_WR_VENDOR_ID			6	/* Wind River Systems */
-#define EV_AMCC_VENDOR_ID		7	/* Applied Micro Circuits */
-#define EV_KVM_VENDOR_ID		42	/* KVM */
-
-/* The max number of bytes that a byte channel can send or receive per call */
-#define EV_BYTE_CHANNEL_MAX_BYTES	16
-
-
-#define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))
-#define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num)
-
-/* epapr return codes */
-#define EV_SUCCESS		0
-#define EV_EPERM		1	/* Operation not permitted */
-#define EV_ENOENT		2	/*  Entry Not Found */
-#define EV_EIO			3	/* I/O error occured */
-#define EV_EAGAIN		4	/* The operation had insufficient
-					 * resources to complete and should be
-					 * retried
-					 */
-#define EV_ENOMEM		5	/* There was insufficient memory to
-					 * complete the operation */
-#define EV_EFAULT		6	/* Bad guest address */
-#define EV_ENODEV		7	/* No such device */
-#define EV_EINVAL		8	/* An argument supplied to the hcall
-					   was out of range or invalid */
-#define EV_INTERNAL		9	/* An internal error occured */
-#define EV_CONFIG		10	/* A configuration error was detected */
-#define EV_INVALID_STATE	11	/* The object is in an invalid state */
-#define EV_UNIMPLEMENTED	12	/* Unimplemented hypercall */
-#define EV_BUFFER_OVERFLOW	13	/* Caller-supplied buffer too small */
-
-#ifndef __ASSEMBLY__
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <asm/byteorder.h>
-
-/*
- * Hypercall register clobber list
- *
- * These macros are used to define the list of clobbered registers during a
- * hypercall.  Technically, registers r0 and r3-r12 are always clobbered,
- * but the gcc inline assembly syntax does not allow us to specify registers
- * on the clobber list that are also on the input/output list.  Therefore,
- * the lists of clobbered registers depends on the number of register
- * parmeters ("+r" and "=r") passed to the hypercall.
- *
- * Each assembly block should use one of the HCALL_CLOBBERSx macros.  As a
- * general rule, 'x' is the number of parameters passed to the assembly
- * block *except* for r11.
- *
- * If you're not sure, just use the smallest value of 'x' that does not
- * generate a compilation error.  Because these are static inline functions,
- * the compiler will only check the clobber list for a function if you
- * compile code that calls that function.
- *
- * r3 and r11 are not included in any clobbers list because they are always
- * listed as output registers.
- *
- * XER, CTR, and LR are currently listed as clobbers because it's uncertain
- * whether they will be clobbered.
- *
- * Note that r11 can be used as an output parameter.
- *
- * The "memory" clobber is only necessary for hcalls where the Hypervisor
- * will read or write guest memory. However, we add it to all hcalls because
- * the impact is minimal, and we want to ensure that it's present for the
- * hcalls that need it.
-*/
-
-/* List of common clobbered registers.  Do not use this macro. */
-#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory"
-
-#define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS
-#define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10"
-#define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9"
-#define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8"
-#define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7"
-#define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6"
-#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
-#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
-
-extern bool epapr_paravirt_enabled;
-extern u32 epapr_hypercall_start[];
-
-/*
- * We use "uintptr_t" to define a register because it's guaranteed to be a
- * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
- * platform.
- *
- * All registers are either input/output or output only.  Registers that are
- * initialized before making the hypercall are input/output.  All
- * input/output registers are represented with "+r".  Output-only registers
- * are represented with "=r".  Do not specify any unused registers.  The
- * clobber list will tell the compiler that the hypercall modifies those
- * registers, which is good enough.
- */
-
-/**
- * ev_int_set_config - configure the specified interrupt
- * @interrupt: the interrupt number
- * @config: configuration for this interrupt
- * @priority: interrupt priority
- * @destination: destination CPU number
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_int_set_config(unsigned int interrupt,
-	uint32_t config, unsigned int priority, uint32_t destination)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-	register uintptr_t r5 __asm__("r5");
-	register uintptr_t r6 __asm__("r6");
-
-	r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG);
-	r3  = interrupt;
-	r4  = config;
-	r5  = priority;
-	r6  = destination;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6)
-		: : EV_HCALL_CLOBBERS4
-	);
-
-	return r3;
-}
-
-/**
- * ev_int_get_config - return the config of the specified interrupt
- * @interrupt: the interrupt number
- * @config: returned configuration for this interrupt
- * @priority: returned interrupt priority
- * @destination: returned destination CPU number
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_int_get_config(unsigned int interrupt,
-	uint32_t *config, unsigned int *priority, uint32_t *destination)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-	register uintptr_t r5 __asm__("r5");
-	register uintptr_t r6 __asm__("r6");
-
-	r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG);
-	r3 = interrupt;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6)
-		: : EV_HCALL_CLOBBERS4
-	);
-
-	*config = r4;
-	*priority = r5;
-	*destination = r6;
-
-	return r3;
-}
-
-/**
- * ev_int_set_mask - sets the mask for the specified interrupt source
- * @interrupt: the interrupt number
- * @mask: 0=enable interrupts, 1=disable interrupts
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_int_set_mask(unsigned int interrupt,
-	unsigned int mask)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-
-	r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK);
-	r3 = interrupt;
-	r4 = mask;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3), "+r" (r4)
-		: : EV_HCALL_CLOBBERS2
-	);
-
-	return r3;
-}
-
-/**
- * ev_int_get_mask - returns the mask for the specified interrupt source
- * @interrupt: the interrupt number
- * @mask: returned mask for this interrupt (0=enabled, 1=disabled)
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_int_get_mask(unsigned int interrupt,
-	unsigned int *mask)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-
-	r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK);
-	r3 = interrupt;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3), "=r" (r4)
-		: : EV_HCALL_CLOBBERS2
-	);
-
-	*mask = r4;
-
-	return r3;
-}
-
-/**
- * ev_int_eoi - signal the end of interrupt processing
- * @interrupt: the interrupt number
- *
- * This function signals the end of processing for the the specified
- * interrupt, which must be the interrupt currently in service. By
- * definition, this is also the highest-priority interrupt.
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_int_eoi(unsigned int interrupt)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-
-	r11 = EV_HCALL_TOKEN(EV_INT_EOI);
-	r3 = interrupt;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3)
-		: : EV_HCALL_CLOBBERS1
-	);
-
-	return r3;
-}
-
-/**
- * ev_byte_channel_send - send characters to a byte stream
- * @handle: byte stream handle
- * @count: (input) num of chars to send, (output) num chars sent
- * @buffer: pointer to a 16-byte buffer
- *
- * @buffer must be at least 16 bytes long, because all 16 bytes will be
- * read from memory into registers, even if count < 16.
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_byte_channel_send(unsigned int handle,
-	unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-	register uintptr_t r5 __asm__("r5");
-	register uintptr_t r6 __asm__("r6");
-	register uintptr_t r7 __asm__("r7");
-	register uintptr_t r8 __asm__("r8");
-	const uint32_t *p = (const uint32_t *) buffer;
-
-	r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND);
-	r3 = handle;
-	r4 = *count;
-	r5 = be32_to_cpu(p[0]);
-	r6 = be32_to_cpu(p[1]);
-	r7 = be32_to_cpu(p[2]);
-	r8 = be32_to_cpu(p[3]);
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3),
-		  "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8)
-		: : EV_HCALL_CLOBBERS6
-	);
-
-	*count = r4;
-
-	return r3;
-}
-
-/**
- * ev_byte_channel_receive - fetch characters from a byte channel
- * @handle: byte channel handle
- * @count: (input) max num of chars to receive, (output) num chars received
- * @buffer: pointer to a 16-byte buffer
- *
- * The size of @buffer must be at least 16 bytes, even if you request fewer
- * than 16 characters, because we always write 16 bytes to @buffer.  This is
- * for performance reasons.
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_byte_channel_receive(unsigned int handle,
-	unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-	register uintptr_t r5 __asm__("r5");
-	register uintptr_t r6 __asm__("r6");
-	register uintptr_t r7 __asm__("r7");
-	register uintptr_t r8 __asm__("r8");
-	uint32_t *p = (uint32_t *) buffer;
-
-	r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE);
-	r3 = handle;
-	r4 = *count;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3), "+r" (r4),
-		  "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8)
-		: : EV_HCALL_CLOBBERS6
-	);
-
-	*count = r4;
-	p[0] = cpu_to_be32(r5);
-	p[1] = cpu_to_be32(r6);
-	p[2] = cpu_to_be32(r7);
-	p[3] = cpu_to_be32(r8);
-
-	return r3;
-}
-
-/**
- * ev_byte_channel_poll - returns the status of the byte channel buffers
- * @handle: byte channel handle
- * @rx_count: returned count of bytes in receive queue
- * @tx_count: returned count of free space in transmit queue
- *
- * This function reports the amount of data in the receive queue (i.e. the
- * number of bytes you can read), and the amount of free space in the transmit
- * queue (i.e. the number of bytes you can write).
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_byte_channel_poll(unsigned int handle,
-	unsigned int *rx_count,	unsigned int *tx_count)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-	register uintptr_t r5 __asm__("r5");
-
-	r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL);
-	r3 = handle;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5)
-		: : EV_HCALL_CLOBBERS3
-	);
-
-	*rx_count = r4;
-	*tx_count = r5;
-
-	return r3;
-}
-
-/**
- * ev_int_iack - acknowledge an interrupt
- * @handle: handle to the target interrupt controller
- * @vector: returned interrupt vector
- *
- * If handle is zero, the function returns the next interrupt source
- * number to be handled irrespective of the hierarchy or cascading
- * of interrupt controllers. If non-zero, specifies a handle to the
- * interrupt controller that is the target of the acknowledge.
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_int_iack(unsigned int handle,
-	unsigned int *vector)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-	register uintptr_t r4 __asm__("r4");
-
-	r11 = EV_HCALL_TOKEN(EV_INT_IACK);
-	r3 = handle;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3), "=r" (r4)
-		: : EV_HCALL_CLOBBERS2
-	);
-
-	*vector = r4;
-
-	return r3;
-}
-
-/**
- * ev_doorbell_send - send a doorbell to another partition
- * @handle: doorbell send handle
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_doorbell_send(unsigned int handle)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-
-	r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND);
-	r3 = handle;
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "+r" (r3)
-		: : EV_HCALL_CLOBBERS1
-	);
-
-	return r3;
-}
-
-/**
- * ev_idle -- wait for next interrupt on this core
- *
- * Returns 0 for success, or an error code.
- */
-static inline unsigned int ev_idle(void)
-{
-	register uintptr_t r11 __asm__("r11");
-	register uintptr_t r3 __asm__("r3");
-
-	r11 = EV_HCALL_TOKEN(EV_IDLE);
-
-	asm volatile("bl	epapr_hypercall_start"
-		: "+r" (r11), "=r" (r3)
-		: : EV_HCALL_CLOBBERS1
-	);
-
-	return r3;
-}
-#endif /* !__ASSEMBLY__ */
-#endif
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild
index a33c3c0..c62a732 100644
--- a/arch/powerpc/include/uapi/asm/Kbuild
+++ b/arch/powerpc/include/uapi/asm/Kbuild
@@ -8,6 +8,7 @@ header-y += byteorder.h
 header-y += cputable.h
 header-y += elf.h
 header-y += errno.h
+header-y += epapr_hcalls.h
 header-y += fcntl.h
 header-y += ioctl.h
 header-y += ioctls.h
diff --git a/arch/powerpc/include/uapi/asm/epapr_hcalls.h b/arch/powerpc/include/uapi/asm/epapr_hcalls.h
new file mode 100644
index 0000000..b8d9445
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/epapr_hcalls.h
@@ -0,0 +1,511 @@
+/*
+ * ePAPR hcall interface
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * This file is provided under a dual BSD/GPL license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* A "hypercall" is an "sc 1" instruction.  This header file file provides C
+ * wrapper functions for the ePAPR hypervisor interface.  It is inteded
+ * for use by Linux device drivers and other operating systems.
+ *
+ * The hypercalls are implemented as inline assembly, rather than assembly
+ * language functions in a .S file, for optimization.  It allows
+ * the caller to issue the hypercall instruction directly, improving both
+ * performance and memory footprint.
+ */
+
+#ifndef _EPAPR_HCALLS_H
+#define _EPAPR_HCALLS_H
+
+#define EV_BYTE_CHANNEL_SEND		1
+#define EV_BYTE_CHANNEL_RECEIVE		2
+#define EV_BYTE_CHANNEL_POLL		3
+#define EV_INT_SET_CONFIG		4
+#define EV_INT_GET_CONFIG		5
+#define EV_INT_SET_MASK			6
+#define EV_INT_GET_MASK			7
+#define EV_INT_IACK			9
+#define EV_INT_EOI			10
+#define EV_INT_SEND_IPI			11
+#define EV_INT_SET_TASK_PRIORITY	12
+#define EV_INT_GET_TASK_PRIORITY	13
+#define EV_DOORBELL_SEND		14
+#define EV_MSGSND			15
+#define EV_IDLE				16
+
+/* vendor ID: epapr */
+#define EV_LOCAL_VENDOR_ID		0	/* for private use */
+#define EV_EPAPR_VENDOR_ID		1
+#define EV_FSL_VENDOR_ID		2	/* Freescale Semiconductor */
+#define EV_IBM_VENDOR_ID		3	/* IBM */
+#define EV_GHS_VENDOR_ID		4	/* Green Hills Software */
+#define EV_ENEA_VENDOR_ID		5	/* Enea */
+#define EV_WR_VENDOR_ID			6	/* Wind River Systems */
+#define EV_AMCC_VENDOR_ID		7	/* Applied Micro Circuits */
+#define EV_KVM_VENDOR_ID		42	/* KVM */
+
+/* The max number of bytes that a byte channel can send or receive per call */
+#define EV_BYTE_CHANNEL_MAX_BYTES	16
+
+
+#define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))
+#define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num)
+
+/* epapr return codes */
+#define EV_SUCCESS		0
+#define EV_EPERM		1	/* Operation not permitted */
+#define EV_ENOENT		2	/*  Entry Not Found */
+#define EV_EIO			3	/* I/O error occured */
+#define EV_EAGAIN		4	/* The operation had insufficient
+					 * resources to complete and should be
+					 * retried
+					 */
+#define EV_ENOMEM		5	/* There was insufficient memory to
+					 * complete the operation */
+#define EV_EFAULT		6	/* Bad guest address */
+#define EV_ENODEV		7	/* No such device */
+#define EV_EINVAL		8	/* An argument supplied to the hcall
+					   was out of range or invalid */
+#define EV_INTERNAL		9	/* An internal error occured */
+#define EV_CONFIG		10	/* A configuration error was detected */
+#define EV_INVALID_STATE	11	/* The object is in an invalid state */
+#define EV_UNIMPLEMENTED	12	/* Unimplemented hypercall */
+#define EV_BUFFER_OVERFLOW	13	/* Caller-supplied buffer too small */
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/byteorder.h>
+
+/*
+ * Hypercall register clobber list
+ *
+ * These macros are used to define the list of clobbered registers during a
+ * hypercall.  Technically, registers r0 and r3-r12 are always clobbered,
+ * but the gcc inline assembly syntax does not allow us to specify registers
+ * on the clobber list that are also on the input/output list.  Therefore,
+ * the lists of clobbered registers depends on the number of register
+ * parmeters ("+r" and "=r") passed to the hypercall.
+ *
+ * Each assembly block should use one of the HCALL_CLOBBERSx macros.  As a
+ * general rule, 'x' is the number of parameters passed to the assembly
+ * block *except* for r11.
+ *
+ * If you're not sure, just use the smallest value of 'x' that does not
+ * generate a compilation error.  Because these are static inline functions,
+ * the compiler will only check the clobber list for a function if you
+ * compile code that calls that function.
+ *
+ * r3 and r11 are not included in any clobbers list because they are always
+ * listed as output registers.
+ *
+ * XER, CTR, and LR are currently listed as clobbers because it's uncertain
+ * whether they will be clobbered.
+ *
+ * Note that r11 can be used as an output parameter.
+ *
+ * The "memory" clobber is only necessary for hcalls where the Hypervisor
+ * will read or write guest memory. However, we add it to all hcalls because
+ * the impact is minimal, and we want to ensure that it's present for the
+ * hcalls that need it.
+*/
+
+/* List of common clobbered registers.  Do not use this macro. */
+#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory"
+
+#define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS
+#define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10"
+#define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9"
+#define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8"
+#define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7"
+#define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6"
+#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
+#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
+
+extern bool epapr_paravirt_enabled;
+extern u32 epapr_hypercall_start[];
+
+/*
+ * We use "uintptr_t" to define a register because it's guaranteed to be a
+ * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
+ * platform.
+ *
+ * All registers are either input/output or output only.  Registers that are
+ * initialized before making the hypercall are input/output.  All
+ * input/output registers are represented with "+r".  Output-only registers
+ * are represented with "=r".  Do not specify any unused registers.  The
+ * clobber list will tell the compiler that the hypercall modifies those
+ * registers, which is good enough.
+ */
+
+/**
+ * ev_int_set_config - configure the specified interrupt
+ * @interrupt: the interrupt number
+ * @config: configuration for this interrupt
+ * @priority: interrupt priority
+ * @destination: destination CPU number
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_int_set_config(unsigned int interrupt,
+	uint32_t config, unsigned int priority, uint32_t destination)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+	register uintptr_t r5 __asm__("r5");
+	register uintptr_t r6 __asm__("r6");
+
+	r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG);
+	r3  = interrupt;
+	r4  = config;
+	r5  = priority;
+	r6  = destination;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6)
+		: : EV_HCALL_CLOBBERS4
+	);
+
+	return r3;
+}
+
+/**
+ * ev_int_get_config - return the config of the specified interrupt
+ * @interrupt: the interrupt number
+ * @config: returned configuration for this interrupt
+ * @priority: returned interrupt priority
+ * @destination: returned destination CPU number
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_int_get_config(unsigned int interrupt,
+	uint32_t *config, unsigned int *priority, uint32_t *destination)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+	register uintptr_t r5 __asm__("r5");
+	register uintptr_t r6 __asm__("r6");
+
+	r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG);
+	r3 = interrupt;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6)
+		: : EV_HCALL_CLOBBERS4
+	);
+
+	*config = r4;
+	*priority = r5;
+	*destination = r6;
+
+	return r3;
+}
+
+/**
+ * ev_int_set_mask - sets the mask for the specified interrupt source
+ * @interrupt: the interrupt number
+ * @mask: 0=enable interrupts, 1=disable interrupts
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_int_set_mask(unsigned int interrupt,
+	unsigned int mask)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+
+	r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK);
+	r3 = interrupt;
+	r4 = mask;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3), "+r" (r4)
+		: : EV_HCALL_CLOBBERS2
+	);
+
+	return r3;
+}
+
+/**
+ * ev_int_get_mask - returns the mask for the specified interrupt source
+ * @interrupt: the interrupt number
+ * @mask: returned mask for this interrupt (0=enabled, 1=disabled)
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_int_get_mask(unsigned int interrupt,
+	unsigned int *mask)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+
+	r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK);
+	r3 = interrupt;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3), "=r" (r4)
+		: : EV_HCALL_CLOBBERS2
+	);
+
+	*mask = r4;
+
+	return r3;
+}
+
+/**
+ * ev_int_eoi - signal the end of interrupt processing
+ * @interrupt: the interrupt number
+ *
+ * This function signals the end of processing for the the specified
+ * interrupt, which must be the interrupt currently in service. By
+ * definition, this is also the highest-priority interrupt.
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_int_eoi(unsigned int interrupt)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+
+	r11 = EV_HCALL_TOKEN(EV_INT_EOI);
+	r3 = interrupt;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3)
+		: : EV_HCALL_CLOBBERS1
+	);
+
+	return r3;
+}
+
+/**
+ * ev_byte_channel_send - send characters to a byte stream
+ * @handle: byte stream handle
+ * @count: (input) num of chars to send, (output) num chars sent
+ * @buffer: pointer to a 16-byte buffer
+ *
+ * @buffer must be at least 16 bytes long, because all 16 bytes will be
+ * read from memory into registers, even if count < 16.
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_byte_channel_send(unsigned int handle,
+	unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+	register uintptr_t r5 __asm__("r5");
+	register uintptr_t r6 __asm__("r6");
+	register uintptr_t r7 __asm__("r7");
+	register uintptr_t r8 __asm__("r8");
+	const uint32_t *p = (const uint32_t *) buffer;
+
+	r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND);
+	r3 = handle;
+	r4 = *count;
+	r5 = be32_to_cpu(p[0]);
+	r6 = be32_to_cpu(p[1]);
+	r7 = be32_to_cpu(p[2]);
+	r8 = be32_to_cpu(p[3]);
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3),
+		  "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8)
+		: : EV_HCALL_CLOBBERS6
+	);
+
+	*count = r4;
+
+	return r3;
+}
+
+/**
+ * ev_byte_channel_receive - fetch characters from a byte channel
+ * @handle: byte channel handle
+ * @count: (input) max num of chars to receive, (output) num chars received
+ * @buffer: pointer to a 16-byte buffer
+ *
+ * The size of @buffer must be at least 16 bytes, even if you request fewer
+ * than 16 characters, because we always write 16 bytes to @buffer.  This is
+ * for performance reasons.
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_byte_channel_receive(unsigned int handle,
+	unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+	register uintptr_t r5 __asm__("r5");
+	register uintptr_t r6 __asm__("r6");
+	register uintptr_t r7 __asm__("r7");
+	register uintptr_t r8 __asm__("r8");
+	uint32_t *p = (uint32_t *) buffer;
+
+	r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE);
+	r3 = handle;
+	r4 = *count;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3), "+r" (r4),
+		  "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8)
+		: : EV_HCALL_CLOBBERS6
+	);
+
+	*count = r4;
+	p[0] = cpu_to_be32(r5);
+	p[1] = cpu_to_be32(r6);
+	p[2] = cpu_to_be32(r7);
+	p[3] = cpu_to_be32(r8);
+
+	return r3;
+}
+
+/**
+ * ev_byte_channel_poll - returns the status of the byte channel buffers
+ * @handle: byte channel handle
+ * @rx_count: returned count of bytes in receive queue
+ * @tx_count: returned count of free space in transmit queue
+ *
+ * This function reports the amount of data in the receive queue (i.e. the
+ * number of bytes you can read), and the amount of free space in the transmit
+ * queue (i.e. the number of bytes you can write).
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_byte_channel_poll(unsigned int handle,
+	unsigned int *rx_count,	unsigned int *tx_count)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+	register uintptr_t r5 __asm__("r5");
+
+	r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL);
+	r3 = handle;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5)
+		: : EV_HCALL_CLOBBERS3
+	);
+
+	*rx_count = r4;
+	*tx_count = r5;
+
+	return r3;
+}
+
+/**
+ * ev_int_iack - acknowledge an interrupt
+ * @handle: handle to the target interrupt controller
+ * @vector: returned interrupt vector
+ *
+ * If handle is zero, the function returns the next interrupt source
+ * number to be handled irrespective of the hierarchy or cascading
+ * of interrupt controllers. If non-zero, specifies a handle to the
+ * interrupt controller that is the target of the acknowledge.
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_int_iack(unsigned int handle,
+	unsigned int *vector)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+	register uintptr_t r4 __asm__("r4");
+
+	r11 = EV_HCALL_TOKEN(EV_INT_IACK);
+	r3 = handle;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3), "=r" (r4)
+		: : EV_HCALL_CLOBBERS2
+	);
+
+	*vector = r4;
+
+	return r3;
+}
+
+/**
+ * ev_doorbell_send - send a doorbell to another partition
+ * @handle: doorbell send handle
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_doorbell_send(unsigned int handle)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+
+	r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND);
+	r3 = handle;
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "+r" (r3)
+		: : EV_HCALL_CLOBBERS1
+	);
+
+	return r3;
+}
+
+/**
+ * ev_idle -- wait for next interrupt on this core
+ *
+ * Returns 0 for success, or an error code.
+ */
+static inline unsigned int ev_idle(void)
+{
+	register uintptr_t r11 __asm__("r11");
+	register uintptr_t r3 __asm__("r3");
+
+	r11 = EV_HCALL_TOKEN(EV_IDLE);
+
+	asm volatile("bl	epapr_hypercall_start"
+		: "+r" (r11), "=r" (r3)
+		: : EV_HCALL_CLOBBERS1
+	);
+
+	return r3;
+}
+#endif /* !__ASSEMBLY__ */
+#endif
diff --git a/arch/powerpc/include/uapi/asm/kvm_para.h b/arch/powerpc/include/uapi/asm/kvm_para.h
index 5e04383..34d8b1c 100644
--- a/arch/powerpc/include/uapi/asm/kvm_para.h
+++ b/arch/powerpc/include/uapi/asm/kvm_para.h
@@ -75,9 +75,10 @@ struct kvm_vcpu_arch_shared {
 };
 
 #define KVM_SC_MAGIC_R0		0x4b564d21 /* "KVM!" */
-#define HC_VENDOR_KVM		(42 << 16)
-#define HC_EV_SUCCESS		0
-#define HC_EV_UNIMPLEMENTED	12
+
+#define KVM_HCALL_TOKEN(num)	_EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num)
+
+#include <asm/epapr_hcalls.h>
 
 #define KVM_FEATURE_MAGIC_PAGE	1
 
-- 
1.7.10.280.gaa39

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc arch/powerpc/include/asm/kvm_para.h
index 9365860,a168ce3..0000000
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@@ -19,9 -19,76 +19,8 @@@
  #ifndef __POWERPC_KVM_PARA_H__
  #define __POWERPC_KVM_PARA_H__
  
 -#include <linux/types.h>
 -
 -/*
 - * Additions to this struct must only occur at the end, and should be
 - * accompanied by a KVM_MAGIC_FEAT flag to advertise that they are present
 - * (albeit not necessarily relevant to the current target hardware platform).
 - *
 - * Struct fields are always 32 or 64 bit aligned, depending on them being 32
 - * or 64 bit wide respectively.
 - *
 - * See Documentation/virtual/kvm/ppc-pv.txt
 - */
 -struct kvm_vcpu_arch_shared {
 -	__u64 scratch1;
 -	__u64 scratch2;
 -	__u64 scratch3;
 -	__u64 critical;		/* Guest may not get interrupts if == r1 */
 -	__u64 sprg0;
 -	__u64 sprg1;
 -	__u64 sprg2;
 -	__u64 sprg3;
 -	__u64 srr0;
 -	__u64 srr1;
 -	__u64 dar;		/* dear on BookE */
 -	__u64 msr;
 -	__u32 dsisr;
 -	__u32 int_pending;	/* Tells the guest if we have an interrupt */
 -	__u32 sr[16];
 -	__u32 mas0;
 -	__u32 mas1;
 -	__u64 mas7_3;
 -	__u64 mas2;
 -	__u32 mas4;
 -	__u32 mas6;
 -	__u32 esr;
 -	__u32 pir;
 -
 -	/*
 -	 * SPRG4-7 are user-readable, so we can only keep these consistent
 -	 * between the shared area and the real registers when there's an
 -	 * intervening exit to KVM.  This also applies to SPRG3 on some
 -	 * chips.
 -	 *
 -	 * This suffices for access by guest userspace, since in PR-mode
 -	 * KVM, an exit must occur when changing the guest's MSR[PR].
 -	 * If the guest kernel writes to SPRG3-7 via the shared area, it
 -	 * must also use the shared area for reading while in kernel space.
 -	 */
 -	__u64 sprg4;
 -	__u64 sprg5;
 -	__u64 sprg6;
 -	__u64 sprg7;
 -};
 -
 -#define KVM_SC_MAGIC_R0		0x4b564d21 /* "KVM!" */
 -
 -#define KVM_HCALL_TOKEN(num)     _EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num)
 -
 -#include <asm/epapr_hcalls.h>
 -
 -#define KVM_FEATURE_MAGIC_PAGE	1
 -
 -#define KVM_MAGIC_FEAT_SR		(1 << 0)
 -
 -/* MASn, ESR, PIR, and high SPRGs */
 -#define KVM_MAGIC_FEAT_MAS0_TO_SPRG7	(1 << 1)
 -
 -#ifdef __KERNEL__
 +#include <uapi/asm/kvm_para.h>
  
- 
  #ifdef CONFIG_KVM_GUEST
  
  #include <linux/of.h>

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* linux-next: manual merge of the kvm-ppc tree with the powerpc-merge tree
From: Stephen Rothwell @ 2012-10-11  1:05 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Liu Yu, linux-kernel, Stuart Yoder, David Howells, linux-next,
	Paul Mackerras, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 560 bytes --]

Hi Alexander,

Today's linux-next merge of the kvm-ppc tree got a conflict in
arch/powerpc/include/asm/Kbuild between commit c3617f72036c ("UAPI:
(Scripted) Disintegrate arch/powerpc/include/asm") from the powerpc-merge
tree and commit 4c09029a5639 ("KVM: PPC: Add support for ePAPR idle hcall
in host kernel") from the kvm-ppc tree.

I just removed epapr_hcalls.h from the Kbuild file as I am not sure how
it should be broken up.  David, can you have a look at this, please?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH 8/10] memory-hotplug : remove page table of x86_64 architecture
From: Ni zhan Chen @ 2012-10-11  0:35 UTC (permalink / raw)
  To: Wen Congyang
  Cc: linux-s390, linux-ia64, len.brown, linux-acpi, linux-sh, x86,
	linux-kernel, cmetcalf, linux-mm, Yasuaki Ishimatsu, Andi Kleen,
	minchan.kim, kosaki.motohiro, rientjes, sparclinux, cl,
	linuxppc-dev, akpm, liuj97
In-Reply-To: <50726354.60803@cn.fujitsu.com>

On 10/08/2012 01:23 PM, Wen Congyang wrote:
> At 10/08/2012 12:37 PM, Andi Kleen Wrote:
>> Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> writes:
>>> +			}
>>> +
>>> +			/*
>>> +			 * We use 2M page, but we need to remove part of them,
>>> +			 * so split 2M page to 4K page.
>>> +			 */
>>> +			pte = alloc_low_page(&pte_phys);
>> What happens when the allocation fails?
>>
>> alloc_low_page seems to be buggy there too, it would __pa a NULL
>> pointer.
> Yes, it will cause kernek panicked in __pa() if CONFI_DEBUG_VIRTUAL is set.
> Otherwise, it will return a NULL pointer. I will update this patch to deal
> with NULL pointer.
>
>>> +		if (pud_large(*pud)) {
>>> +			if ((addr & ~PUD_MASK) == 0 && next <= end) {
>>> +				set_pud(pud, __pud(0));
>>> +				pages++;
>>> +				continue;
>>> +			}
>>> +
>>> +			/*
>>> +			 * We use 1G page, but we need to remove part of them,
>>> +			 * so split 1G page to 2M page.
>>> +			 */
>>> +			pmd = alloc_low_page(&pmd_phys);
>> Same here
>>
>>> +			__split_large_page((pte_t *)pud, addr, (pte_t *)pmd);
>>> +
>>> +			spin_lock(&init_mm.page_table_lock);
>>> +			pud_populate(&init_mm, pud, __va(pmd_phys));
>>> +			spin_unlock(&init_mm.page_table_lock);
>>> +		}
>>> +
>>> +		pmd = map_low_page(pmd_offset(pud, 0));
>>> +		phys_pmd_remove(pmd, addr, end);
>>> +		unmap_low_page(pmd);
>>> +		__flush_tlb_all();
>>> +	}
>>> +	__flush_tlb_all();

Hi Congyang,

I see you call __flush_tlb_all() every pud entry(all pmd, pte related to 
it changed) modified, then how to determine the flush frequency? why not 
every pmd entry?

Regards,
Chen

>> This doesn't flush the other CPUs doesn't it?
> How to flush the other CPU's tlb? use on_each_cpu() to run __flush_tlb_all()
> on each online cpu?
>
> Thanks
> Wen Congyang
>
>> -Andi
>>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
>

^ permalink raw reply

* Re: Contents of Linuxppc-dev digest..."
From: Sam Shen @ 2012-10-10 22:15 UTC (permalink / raw)
  To: linuxppc-dev



-----Original Message-----
From: Linuxppc-dev
[mailto:linuxppc-dev-bounces+sshen=3Dhaliplex.com@lists.ozlabs.org] On
Behalf Of linuxppc-dev-request@lists.ozlabs.org
Sent: Thursday, 11 October 2012 7:57 AM
To: linuxppc-dev@lists.ozlabs.org
Subject: Linuxppc-dev Digest, Vol 98, Issue 38

Send Linuxppc-dev mailing list submissions to
	linuxppc-dev@lists.ozlabs.org

To subscribe or unsubscribe via the World Wide Web, visit
	https://lists.ozlabs.org/listinfo/linuxppc-dev
or, via email, send a message with subject or body 'help' to
	linuxppc-dev-request@lists.ozlabs.org

You can reach the person managing the list at
	linuxppc-dev-owner@lists.ozlabs.org

When replying, please edit your Subject line so it is more specific than
"Re: Contents of Linuxppc-dev digest..."


Today's Topics:

   1. [RESEND PATCH v1 3/3] cpuidle: (POWER) Fix snooze state
      problem persistant in the current cpuidle design on pseries.
      (Deepthi Dharwar)
   2. [RESEND PATCH v1 1/3] cpuidle: (POWER) Fix target residency
      initialisation in pseries cpuidle (Deepthi Dharwar)
   3. [PATCH 3.6.0- 2/2] powerpc/sysdev: use module_platform_driver
      macro (Srinivas KANDAGATLA)
   4. [PATCH 3.6.0- 1/2] powerpc/mpc52xx: use
      module_platform_driver macro (Srinivas KANDAGATLA)
   5. [PATCH 3.6.0- 0/2] POWERPC: use module_platform_driver macro
      (Srinivas KANDAGATLA)
   6. Re: Changing TASK_UNMAPPED_BASE to a low address
      (Thomas De Schampheleire)
   7. [PATCH] powerpc: 52xx: nop out unsupported critical IRQs
      (Wolfram Sang)


----------------------------------------------------------------------

Message: 1
Date: Wed, 10 Oct 2012 12:59:23 +0530
From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	benh@kernel.crashing.org
Subject: [RESEND PATCH v1 3/3] cpuidle: (POWER) Fix snooze state
	problem persistant in the current cpuidle design on pseries.
Message-ID: <20121010072921.29317.67508.stgit@deepthi.in.ibm.com>
Content-Type: text/plain; charset=3D"utf-8"

Earlier without cpuidle framework on pseries, the native arch idle
routine comprised of both snooze and nap states.  smt_snooze_delay
variable was used to delay the idle process entry to deeper idle state
like  nap.
With the coming of cpuidle, this arch specific idle was replaced by two
different idle routines, one for supporting snooze and other for nap.
This enabled addition of more low level idle states on pseries in the
future.

On adopting the generic cpuidle framework for POWER systems, the
decision of which idle state to choose from,  given a predicted idle
time is taken by the menu governor based on target_residency and
exit_latency of the idle states.
target_residency is the minimum time to be resident in that idle state.
Exit_latency is time taken to exit out of idle state.
Deeper the idle state, both the target residency and exit latency would
be higher.

In the current design, smt_snooze_delay is used as target_residency for
the  snooze state which is incorrect, as it is not the minimum but the
maximum duration to be in snooze state.
This would  result in the governor in taking bad decision, as presently
target_residency of nap < target_residency of snooze inspite of nap
being deeper idle state.

This patch aims to fix this problem by replacing the smt_snooze_delay
loop in snooze state, with the need_resched()  as the governor is aware
of entry and exit of various idle transitions based on which next idle
time prediction.

The governor is intelligent enough to determine the idle state the needs
to be transitioned to and maintains a whole of heuristics including io
load, previous idle states predictions etc for the same, based on which
idle state entry decision is taken.

With this fix, of setting target_residency of snooze to 0
					     nap to smt_snooze_delay
if the predicted idle time is less
than smt_snooze_delay (target_residency of nap) value governor would
pick snooze state, else nap. This adhers to the previous native idle
design.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---

 arch/powerpc/platforms/pseries/processor_idle.c |   36
++++++++---------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/processor_idle.c
b/arch/powerpc/platforms/pseries/processor_idle.c
index a32d56d..45d00e5 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -59,32 +59,22 @@ static int snooze_loop(struct cpuidle_device *dev,
{
 	unsigned long in_purr;
 	ktime_t kt_before;
-	unsigned long start_snooze;
-	long snooze =3D drv->states[0].target_residency;
+	int cpu =3D dev->cpu;
=20
 	idle_loop_prolog(&in_purr, &kt_before);
+	local_irq_enable();
+	set_thread_flag(TIF_POLLING_NRFLAG);
=20
-	if (snooze) {
-		start_snooze =3D get_tb() + snooze * tb_ticks_per_usec;
-		local_irq_enable();
-		set_thread_flag(TIF_POLLING_NRFLAG);
-
-		while ((snooze < 0) || (get_tb() < start_snooze)) {
-			if (need_resched() || cpu_is_offline(dev->cpu))
-				goto out;
-			ppc64_runlatch_off();
-			HMT_low();
-			HMT_very_low();
-		}
-
-		HMT_medium();
-		clear_thread_flag(TIF_POLLING_NRFLAG);
-		smp_mb();
-		local_irq_disable();
+	while ((!need_resched()) && cpu_online(cpu)) {
+		ppc64_runlatch_off();
+		HMT_low();
+		HMT_very_low();
 	}
=20
-out:
 	HMT_medium();
+	clear_thread_flag(TIF_POLLING_NRFLAG);
+	smp_mb();
+
 	dev->last_residency =3D
 		(int)idle_loop_epilog(in_purr, kt_before);
 	return index;
@@ -165,8 +155,8 @@ static struct cpuidle_state
dedicated_states[MAX_IDLE_STATE_COUNT] =3D {
 		.name =3D "CEDE",
 		.desc =3D "CEDE",
 		.flags =3D CPUIDLE_FLAG_TIME_VALID,
-		.exit_latency =3D 1,
-		.target_residency =3D 10,
+		.exit_latency =3D 10,
+		.target_residency =3D 100,
 		.enter =3D &dedicated_cede_loop },
 };
=20
@@ -197,7 +187,7 @@ void update_smt_snooze_delay(int cpu, int residency)
 			dev->states_usage[1].disable =3D 1;
 	} else
 		if (drv)
-			drv->states[0].target_residency =3D residency;
+			drv->states[1].target_residency =3D residency;
 }
=20
 static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,



------------------------------

Message: 2
Date: Wed, 10 Oct 2012 12:59:08 +0530
From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	benh@kernel.crashing.org
Subject: [RESEND PATCH v1 1/3] cpuidle: (POWER) Fix target residency
	initialisation in pseries cpuidle
Message-ID: <20121010072906.29317.32144.stgit@deepthi.in.ibm.com>
Content-Type: text/plain; charset=3D"utf-8"

Remove the redundant target residency initialisation in
pseries_cpuidle_driver_init().
This is currently over-writing the residency time updated as part of the
static table, resulting in  all the idle states having the same target
residency of 100us which is incorrect. This may result in the menu
governor making wrong state decisions.

Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---

 arch/powerpc/platforms/pseries/processor_idle.c |    4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/processor_idle.c
b/arch/powerpc/platforms/pseries/processor_idle.c
index 455760b..02e425a 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -246,10 +246,6 @@ static int pseries_cpuidle_driver_init(void)
 		drv->states[drv->state_count] =3D	/* structure copy */
 			cpuidle_state_table[idle_state];
=20
-		if (cpuidle_state_table =3D=3D dedicated_states)
-			drv->states[drv->state_count].target_residency =3D
-				__get_cpu_var(smt_snooze_delay);
-
 		drv->state_count +=3D 1;
 	}
=20



------------------------------

Message: 3
Date: Wed, 10 Oct 2012 19:32:30 +0100
From: Srinivas KANDAGATLA <srinivas.kandagatla@st.com>
To: grant.likely@secretlab.ca
Cc: krafft@de.ibm.com, agust@denx.de, linuxppc-dev@lists.ozlabs.org,
	srinivas.kandagatla@st.com
Subject: [PATCH 3.6.0- 2/2] powerpc/sysdev: use module_platform_driver
	macro
Message-ID:
	<1349893950-7710-1-git-send-email-srinivas.kandagatla@st.com>

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch removes some code duplication by using
module_platform_driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 arch/powerpc/sysdev/pmi.c |   13 +------------
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index
8f04654..5aaf86c 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -214,18 +214,7 @@ static struct platform_driver
pmi_of_platform_driver =3D {
 		.of_match_table =3D pmi_match,
 	},
 };
-
-static int __init pmi_module_init(void) -{
-	return platform_driver_register(&pmi_of_platform_driver);
-}
-module_init(pmi_module_init);
-
-static void __exit pmi_module_exit(void) -{
-	platform_driver_unregister(&pmi_of_platform_driver);
-}
-module_exit(pmi_module_exit);
+module_platform_driver(pmi_of_platform_driver);
=20
 int pmi_send_message(pmi_message_t msg)  {
--
1.7.0.4



------------------------------

Message: 4
Date: Wed, 10 Oct 2012 19:32:24 +0100
From: Srinivas KANDAGATLA <srinivas.kandagatla@st.com>
To: grant.likely@secretlab.ca
Cc: krafft@de.ibm.com, agust@denx.de, linuxppc-dev@lists.ozlabs.org,
	srinivas.kandagatla@st.com
Subject: [PATCH 3.6.0- 1/2] powerpc/mpc52xx: use
	module_platform_driver macro
Message-ID:
	<1349893944-7675-1-git-send-email-srinivas.kandagatla@st.com>

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch removes some code duplication by using
module_platform_driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c |   16 +---------------
 1 files changed, 1 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 2351f9e..16150fa 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -578,18 +578,4 @@ static struct platform_driver
mpc52xx_lpbfifo_driver =3D {
 	.probe =3D mpc52xx_lpbfifo_probe,
 	.remove =3D __devexit_p(mpc52xx_lpbfifo_remove),
 };
-
-/**********************************************************************
*
- * Module init/exit
- */
-static int __init mpc52xx_lpbfifo_init(void)
-{
-	return platform_driver_register(&mpc52xx_lpbfifo_driver);
-}
-module_init(mpc52xx_lpbfifo_init);
-
-static void __exit mpc52xx_lpbfifo_exit(void)
-{
-	platform_driver_unregister(&mpc52xx_lpbfifo_driver);
-}
-module_exit(mpc52xx_lpbfifo_exit);
+module_platform_driver(mpc52xx_lpbfifo_driver);
--=20
1.7.0.4



------------------------------

Message: 5
Date: Wed, 10 Oct 2012 19:32:17 +0100
From: Srinivas KANDAGATLA <srinivas.kandagatla@st.com>
To: grant.likely@secretlab.ca
Cc: krafft@de.ibm.com, agust@denx.de, linuxppc-dev@lists.ozlabs.org,
	srinivas.kandagatla@st.com
Subject: [PATCH 3.6.0- 0/2] POWERPC: use module_platform_driver macro
Message-ID:
	<1349893937-7642-1-git-send-email-srinivas.kandagatla@st.com>

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Running below Coccinelle lookup pattern like below on the=20
latest kernel showed about 52 hits. This patch series is a subset=20
of those 52 patches, so that it will be easy for maintainers to review.
Hopefully these patches will get rid of some code duplication in kernel.

@  @
- initfunc(void)
- { return platform_driver_register(&dr); }

...

- module_init(initfunc);
...

- exitfunc(void)
- { platform_driver_unregister(&dr); }

...

- module_exit(exitfunc);
+ module_platform_driver(dr);=20

Srinivas Kandagatla (2):
  powerpc/mpc52xx: use module_platform_driver macro
  powerpc/sysdev: use module_platform_driver macro

 arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c |   16 +---------------
 arch/powerpc/sysdev/pmi.c                     |   13 +------------
 2 files changed, 2 insertions(+), 27 deletions(-)



------------------------------

Message: 6
Date: Wed, 10 Oct 2012 21:05:37 +0200
From: Thomas De Schampheleire <patrickdepinguin+linuxppc@gmail.com>
To: linuxppc-dev <linuxppc-dev@ozlabs.org>
Cc: Ronny Meeus <Ronny.Meeus@gmail.com>,
	patrickdepinguin+linuxppc@gmail.com
Subject: Re: Changing TASK_UNMAPPED_BASE to a low address
Message-ID:
=09
<CAAXf6LUXWB_BxTO+go-CSdV+R8XYav1y7TaeMQTy-5GA=3DGXagA@mail.gmail.com>
Content-Type: text/plain; charset=3DISO-8859-1

Hi,

On Fri, Oct 5, 2012 at 11:47 AM, Thomas De Schampheleire
<patrickdepinguin+linuxppc@gmail.com> wrote:
> Hi,
>
> The current virtual address space of a 32-bit userspace process looks
> like this on powerpc:
> # cat /proc/28922/maps
> 00100000-00102000 r-xp 00000000 00:00 0          [vdso]
> 0fe70000-0ffd8000 r-xp 00000000 00:01 754        /lib/libc-2.10.1.so
> 0ffd8000-0ffe8000 ---p 00168000 00:01 754        /lib/libc-2.10.1.so
> 0ffe8000-0ffea000 r--p 00168000 00:01 754        /lib/libc-2.10.1.so
> 0ffea000-0ffed000 rwxp 0016a000 00:01 754        /lib/libc-2.10.1.so
> 0ffed000-0fff0000 rwxp 00000000 00:00 0
> 10000000-10001000 r-xp 00000000 00:12 73         /tmp/memory_alloc
> 10010000-10011000 rwxp 00000000 00:12 73         /tmp/memory_alloc
> 10011000-47a32000 rwxp 00000000 00:00 0          [heap]
> 48000000-4801d000 r-xp 00000000 00:01 793        /lib/ld-2.10.1.so
> 4801d000-4801f000 rw-p 00000000 00:00 0
> 4801f000-48021000 rw-p 00000000 00:00 0
> 4802d000-4802e000 r--p 0001d000 00:01 793        /lib/ld-2.10.1.so
> 4802e000-4802f000 rwxp 0001e000 00:01 793        /lib/ld-2.10.1.so
> 4802f000-bf6ee000 rw-p 00000000 00:00 0
> bfa18000-bfa39000 rw-p 00000000 00:00 0          [stack]
>
> The process text and data area are at 0x10000000 (fixed), the
> mmap_base is at 0x48000000 (TASK_UNMAPPED_BASE =3D 3/8*0xc0000000), =
and
> shared libraries are put directly above 0x10000000.
>
> When your application starts allocating memory, the first blocks are
> taken starting from mmap_base (0x48000000) until you reached the stack
> area (0xbfa18000 in this example). Then, a 'heap' region is created
> after the process text/data area (0x10011000 in this example) and the
> mmap_base (0x48000000). When this is also filled, any further
> allocation fails.
> However, between 0x0 and the first shared library, there is still
> plenty of space. Without any shared library, there would be approx.
> 256 MB free. Even with a few shared libraries, this typically is >200
> MB, at least in the type of applications I'm envisioning.
>
> Because of the 3GB/1GB userspace/kernelspace virtual address split,
> one expects an application to be able to allocate close to 3GB =3D =
3072
> MB. Due to the 256MB 'unused' area mentioned, you can only allocate
> something like 2800 MB. If your application needs more than that, and
> you're bound to 32-bit processors, this is a problem.
>
> I've been looking at two ways to use the extra memory:
> 1. do an anonymous mmap with an address hint in that range, e.g. at
> address 0x00110000. This does return memory, and if you know how much
> is free there, you can take all of it.
>
> 2. change the TASK_UNMAPPED_BASE setting in the kernel
> (arch/powerpc/include/asm/processor.h) to a low address, e.g. 0x40000.
> The advantage of this is that applications need no change.
>
> The second approach seems to work fine. The memory map changes to:
>
> # cat /proc/6954/maps
> 00040000-0005d000 r-xp 00000000 00:01 787        /lib/ld-2.10.1.so
> 0005d000-0005f000 rw-p 00000000 00:00 0
> 0005f000-00061000 rw-p 00000000 00:00 0
> 0006d000-0006e000 r--p 0001d000 00:01 787        /lib/ld-2.10.1.so
> 0006e000-0006f000 rwxp 0001e000 00:01 787        /lib/ld-2.10.1.so
> 00100000-00102000 r-xp 00000000 00:00 0          [vdso]
> 00102000-0c904000 rw-p 00000000 00:00 0
> 0ca00000-0ca21000 rw-p 00000000 00:00 0
> 0ca21000-0cb00000 ---p 00000000 00:00 0
> 0fe70000-0ffd8000 r-xp 00000000 00:01 750        /lib/libc-2.10.1.so
> 0ffd8000-0ffe8000 ---p 00168000 00:01 750        /lib/libc-2.10.1.so
> 0ffe8000-0ffea000 r--p 00168000 00:01 750        /lib/libc-2.10.1.so
> 0ffea000-0ffed000 rwxp 0016a000 00:01 750        /lib/libc-2.10.1.so
> 0ffed000-0fff0000 rwxp 00000000 00:00 0
> 10000000-10001000 r-xp 00000000 00:12 119
> /mnt/repo/tdescham/reborn/isam-linux-target-apps/memory_alloc
> 10010000-10011000 rwxp 00000000 00:12 119
> /mnt/repo/tdescham/reborn/isam-linux-target-apps/memory_alloc
> 10011000-cb82f000 rw-p 00000000 00:00 0          [heap]
> bffaf000-bffd0000 rw-p 00000000 00:00 0          [stack]
>
>
> I have not seen anything 'weird' about this change.
> I found the following thread that also discusses such a change:
>
https://lists.ozlabs.org/pipermail/linuxppc-dev/2004-February/016513.htm
l
> The thread talks about a few problems, but later concludes that these
> have been fixed. Since the thread dates from 2004, I assume that
> indeed this has been fixed.
>
> Is there any reason why this change is not OK? I'm not necessarily
> talking about mainlining the change. I first would like to know if it
> is 'dangerous' or if there are other reasons not to do it.
>
> This post is using linux-2.6.36.4 as base, but I looked at more recent
> kernels and the settings seem the same.


Any feedback on this topic?

Thanks,
Thomas


------------------------------

Message: 7
Date: Wed, 10 Oct 2012 22:56:33 +0200
From: Wolfram Sang <w.sang@pengutronix.de>
To: linuxppc-dev@ozlabs.org
Cc: John Bonesio <bones@secretlab.ca>, Anatolij Gustschin
	<agust@denx.de>, Wolfram Sang <w.sang@pengutronix.de>
Subject: [PATCH] powerpc: 52xx: nop out unsupported critical IRQs
Message-ID: <1349902593-16431-1-git-send-email-w.sang@pengutronix.de>

Currently, when booting MPC52xx based platforms, we get:

        mpc52xx_irqhost_map: invalid irq: virq=3D16, l1=3D0, l2=3D3
        irq: irq-16=3D=3D>hwirq-0x3 mapping failed: -22
        [WARNing skipped]

The warning is wrong since the mapping itself is valid. However, there
is no
support for that type of IRQ currently. Print a proper warning and bind
the irq
to a no_irq chip.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: John Bonesio <bones@secretlab.ca>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
 arch/powerpc/platforms/52xx/mpc52xx_pic.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8520b58..703ad42 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -372,6 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain
*h, unsigned int virq,
 	case MPC52xx_IRQ_L1_MAIN: irqchip =3D &mpc52xx_main_irqchip;
break;
 	case MPC52xx_IRQ_L1_PERP: irqchip =3D &mpc52xx_periph_irqchip;
break;
 	case MPC52xx_IRQ_L1_SDMA: irqchip =3D &mpc52xx_sdma_irqchip;
break;
+	case MPC52xx_IRQ_L1_CRIT:
+		pr_warn("%s: Critical IRQ #%d is unsupported! Nopping
it.\n",
+			__func__, l2irq);
+		irq_set_chip(virq, &no_irq_chip);
+		return 0;
 	default:
 		pr_err("%s: invalid irq: virq=3D%i, l1=3D%i, l2=3D%i\n",
 		       __func__, virq, l1irq, l2irq);
--=20
1.7.10.4



------------------------------

Subject: Digest Footer

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

------------------------------

End of Linuxppc-dev Digest, Vol 98, Issue 38
********************************************

^ permalink raw reply related

* [PATCH] powerpc: 52xx: nop out unsupported critical IRQs
From: Wolfram Sang @ 2012-10-10 20:56 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: John Bonesio, Anatolij Gustschin, Wolfram Sang

Currently, when booting MPC52xx based platforms, we get:

        mpc52xx_irqhost_map: invalid irq: virq=16, l1=0, l2=3
        irq: irq-16==>hwirq-0x3 mapping failed: -22
        [WARNing skipped]

The warning is wrong since the mapping itself is valid. However, there is no
support for that type of IRQ currently. Print a proper warning and bind the irq
to a no_irq chip.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: John Bonesio <bones@secretlab.ca>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
 arch/powerpc/platforms/52xx/mpc52xx_pic.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8520b58..703ad42 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -372,6 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
 	case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
 	case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
 	case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
+	case MPC52xx_IRQ_L1_CRIT:
+		pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n",
+			__func__, l2irq);
+		irq_set_chip(virq, &no_irq_chip);
+		return 0;
 	default:
 		pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
 		       __func__, virq, l1irq, l2irq);
-- 
1.7.10.4

^ permalink raw reply related

* Re: Changing TASK_UNMAPPED_BASE to a low address
From: Thomas De Schampheleire @ 2012-10-10 19:05 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Ronny Meeus, patrickdepinguin+linuxppc
In-Reply-To: <CAAXf6LVxFHGytLiiGXs77kqJkBF24H7e3yOOzkWsnvuEkhU6iw@mail.gmail.com>

Hi,

On Fri, Oct 5, 2012 at 11:47 AM, Thomas De Schampheleire
<patrickdepinguin+linuxppc@gmail.com> wrote:
> Hi,
>
> The current virtual address space of a 32-bit userspace process looks
> like this on powerpc:
> # cat /proc/28922/maps
> 00100000-00102000 r-xp 00000000 00:00 0          [vdso]
> 0fe70000-0ffd8000 r-xp 00000000 00:01 754        /lib/libc-2.10.1.so
> 0ffd8000-0ffe8000 ---p 00168000 00:01 754        /lib/libc-2.10.1.so
> 0ffe8000-0ffea000 r--p 00168000 00:01 754        /lib/libc-2.10.1.so
> 0ffea000-0ffed000 rwxp 0016a000 00:01 754        /lib/libc-2.10.1.so
> 0ffed000-0fff0000 rwxp 00000000 00:00 0
> 10000000-10001000 r-xp 00000000 00:12 73         /tmp/memory_alloc
> 10010000-10011000 rwxp 00000000 00:12 73         /tmp/memory_alloc
> 10011000-47a32000 rwxp 00000000 00:00 0          [heap]
> 48000000-4801d000 r-xp 00000000 00:01 793        /lib/ld-2.10.1.so
> 4801d000-4801f000 rw-p 00000000 00:00 0
> 4801f000-48021000 rw-p 00000000 00:00 0
> 4802d000-4802e000 r--p 0001d000 00:01 793        /lib/ld-2.10.1.so
> 4802e000-4802f000 rwxp 0001e000 00:01 793        /lib/ld-2.10.1.so
> 4802f000-bf6ee000 rw-p 00000000 00:00 0
> bfa18000-bfa39000 rw-p 00000000 00:00 0          [stack]
>
> The process text and data area are at 0x10000000 (fixed), the
> mmap_base is at 0x48000000 (TASK_UNMAPPED_BASE = 3/8*0xc0000000), and
> shared libraries are put directly above 0x10000000.
>
> When your application starts allocating memory, the first blocks are
> taken starting from mmap_base (0x48000000) until you reached the stack
> area (0xbfa18000 in this example). Then, a 'heap' region is created
> after the process text/data area (0x10011000 in this example) and the
> mmap_base (0x48000000). When this is also filled, any further
> allocation fails.
> However, between 0x0 and the first shared library, there is still
> plenty of space. Without any shared library, there would be approx.
> 256 MB free. Even with a few shared libraries, this typically is >200
> MB, at least in the type of applications I'm envisioning.
>
> Because of the 3GB/1GB userspace/kernelspace virtual address split,
> one expects an application to be able to allocate close to 3GB = 3072
> MB. Due to the 256MB 'unused' area mentioned, you can only allocate
> something like 2800 MB. If your application needs more than that, and
> you're bound to 32-bit processors, this is a problem.
>
> I've been looking at two ways to use the extra memory:
> 1. do an anonymous mmap with an address hint in that range, e.g. at
> address 0x00110000. This does return memory, and if you know how much
> is free there, you can take all of it.
>
> 2. change the TASK_UNMAPPED_BASE setting in the kernel
> (arch/powerpc/include/asm/processor.h) to a low address, e.g. 0x40000.
> The advantage of this is that applications need no change.
>
> The second approach seems to work fine. The memory map changes to:
>
> # cat /proc/6954/maps
> 00040000-0005d000 r-xp 00000000 00:01 787        /lib/ld-2.10.1.so
> 0005d000-0005f000 rw-p 00000000 00:00 0
> 0005f000-00061000 rw-p 00000000 00:00 0
> 0006d000-0006e000 r--p 0001d000 00:01 787        /lib/ld-2.10.1.so
> 0006e000-0006f000 rwxp 0001e000 00:01 787        /lib/ld-2.10.1.so
> 00100000-00102000 r-xp 00000000 00:00 0          [vdso]
> 00102000-0c904000 rw-p 00000000 00:00 0
> 0ca00000-0ca21000 rw-p 00000000 00:00 0
> 0ca21000-0cb00000 ---p 00000000 00:00 0
> 0fe70000-0ffd8000 r-xp 00000000 00:01 750        /lib/libc-2.10.1.so
> 0ffd8000-0ffe8000 ---p 00168000 00:01 750        /lib/libc-2.10.1.so
> 0ffe8000-0ffea000 r--p 00168000 00:01 750        /lib/libc-2.10.1.so
> 0ffea000-0ffed000 rwxp 0016a000 00:01 750        /lib/libc-2.10.1.so
> 0ffed000-0fff0000 rwxp 00000000 00:00 0
> 10000000-10001000 r-xp 00000000 00:12 119
> /mnt/repo/tdescham/reborn/isam-linux-target-apps/memory_alloc
> 10010000-10011000 rwxp 00000000 00:12 119
> /mnt/repo/tdescham/reborn/isam-linux-target-apps/memory_alloc
> 10011000-cb82f000 rw-p 00000000 00:00 0          [heap]
> bffaf000-bffd0000 rw-p 00000000 00:00 0          [stack]
>
>
> I have not seen anything 'weird' about this change.
> I found the following thread that also discusses such a change:
> https://lists.ozlabs.org/pipermail/linuxppc-dev/2004-February/016513.html
> The thread talks about a few problems, but later concludes that these
> have been fixed. Since the thread dates from 2004, I assume that
> indeed this has been fixed.
>
> Is there any reason why this change is not OK? I'm not necessarily
> talking about mainlining the change. I first would like to know if it
> is 'dangerous' or if there are other reasons not to do it.
>
> This post is using linux-2.6.36.4 as base, but I looked at more recent
> kernels and the settings seem the same.


Any feedback on this topic?

Thanks,
Thomas

^ permalink raw reply

* [PATCH 3.6.0- 0/2] POWERPC: use module_platform_driver macro
From: Srinivas KANDAGATLA @ 2012-10-10 18:32 UTC (permalink / raw)
  To: grant.likely; +Cc: krafft, agust, linuxppc-dev, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Running below Coccinelle lookup pattern like below on the 
latest kernel showed about 52 hits. This patch series is a subset 
of those 52 patches, so that it will be easy for maintainers to review.
Hopefully these patches will get rid of some code duplication in kernel.

@  @
- initfunc(void)
- { return platform_driver_register(&dr); }

...

- module_init(initfunc);
...

- exitfunc(void)
- { platform_driver_unregister(&dr); }

...

- module_exit(exitfunc);
+ module_platform_driver(dr); 

Srinivas Kandagatla (2):
  powerpc/mpc52xx: use module_platform_driver macro
  powerpc/sysdev: use module_platform_driver macro

 arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c |   16 +---------------
 arch/powerpc/sysdev/pmi.c                     |   13 +------------
 2 files changed, 2 insertions(+), 27 deletions(-)

^ permalink raw reply

* [PATCH 3.6.0- 1/2] powerpc/mpc52xx: use module_platform_driver macro
From: Srinivas KANDAGATLA @ 2012-10-10 18:32 UTC (permalink / raw)
  To: grant.likely; +Cc: krafft, agust, linuxppc-dev, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch removes some code duplication by using
module_platform_driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c |   16 +---------------
 1 files changed, 1 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 2351f9e..16150fa 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -578,18 +578,4 @@ static struct platform_driver mpc52xx_lpbfifo_driver = {
 	.probe = mpc52xx_lpbfifo_probe,
 	.remove = __devexit_p(mpc52xx_lpbfifo_remove),
 };
-
-/***********************************************************************
- * Module init/exit
- */
-static int __init mpc52xx_lpbfifo_init(void)
-{
-	return platform_driver_register(&mpc52xx_lpbfifo_driver);
-}
-module_init(mpc52xx_lpbfifo_init);
-
-static void __exit mpc52xx_lpbfifo_exit(void)
-{
-	platform_driver_unregister(&mpc52xx_lpbfifo_driver);
-}
-module_exit(mpc52xx_lpbfifo_exit);
+module_platform_driver(mpc52xx_lpbfifo_driver);
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 3.6.0- 2/2] powerpc/sysdev: use module_platform_driver macro
From: Srinivas KANDAGATLA @ 2012-10-10 18:32 UTC (permalink / raw)
  To: grant.likely; +Cc: krafft, agust, linuxppc-dev, srinivas.kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch removes some code duplication by using
module_platform_driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 arch/powerpc/sysdev/pmi.c |   13 +------------
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index 8f04654..5aaf86c 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -214,18 +214,7 @@ static struct platform_driver pmi_of_platform_driver = {
 		.of_match_table = pmi_match,
 	},
 };
-
-static int __init pmi_module_init(void)
-{
-	return platform_driver_register(&pmi_of_platform_driver);
-}
-module_init(pmi_module_init);
-
-static void __exit pmi_module_exit(void)
-{
-	platform_driver_unregister(&pmi_of_platform_driver);
-}
-module_exit(pmi_module_exit);
+module_platform_driver(pmi_of_platform_driver);
 
 int pmi_send_message(pmi_message_t msg)
 {
-- 
1.7.0.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox