LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] macio: don't dereference pointer before null check
From: Andreas Schwab @ 2010-06-01 15:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1275385607.1931.712.camel__30394.2679115154$1275385651$gmane$org@pasglop>

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
---
 drivers/macintosh/macio_asic.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 9714780..40390ac 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -492,8 +492,8 @@ static void macio_pci_add_devices(struct macio_chip *chip)
 	}
 
 	/* Add media bay devices if any */
-	pnode = mbdev->ofdev.dev.of_node;
-	if (mbdev)
+	if (mbdev) {
+		pnode = mbdev->ofdev.dev.of_node;
 		for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
 			if (macio_skip_device(np))
 				continue;
@@ -502,10 +502,11 @@ static void macio_pci_add_devices(struct macio_chip *chip)
 						 mbdev,  root_res) == NULL)
 				of_node_put(np);
 		}
+	}
 
 	/* Add serial ports if any */
-	pnode = sdev->ofdev.dev.of_node;
 	if (sdev) {
+		pnode = sdev->ofdev.dev.of_node;
 		for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
 			if (macio_skip_device(np))
 				continue;
-- 
1.7.1

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply related

* Re: [PATCH] drivers: remove all i2c_set_clientdata(client, NULL)
From: Jean Delvare @ 2010-06-01 13:53 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Dmitry Torokhov, linuxppc-dev, linux-mtd, linux-i2c, devel,
	Samuel Ortiz, lm-sensors, linux-input, linux-media,
	Paul Gortmaker, Riku Voipio, rtc-linux, Alessandro Rubini,
	Mauro Carvalho Chehab, Ben Dooks (embedded platforms),
	Greg Kroah-Hartman, Liam Girdwood, Alessandro Zummo,
	Guillaume Ligneul, George Joseph, Mark Brown, linux-kernel,
	Richard Purdie, Colin Leroy, David Woodhouse
In-Reply-To: <1275310552-14685-1-git-send-email-w.sang@pengutronix.de>

On Mon, 31 May 2010 14:55:48 +0200, Wolfram Sang wrote:
> I2C-drivers can use the clientdata-pointer to point to private data. As I2C
> devices are not really unregistered, but merely detached from their driver, it
> used to be the drivers obligation to clear this pointer during remove() or a
> failed probe(). As a couple of drivers forgot to do this, it was agreed that it
> was cleaner if the i2c-core does this clearance when appropriate, as there is
> no guarantee for the lifetime of the clientdata-pointer after remove() anyhow.
> This feature was added to the core with commit
> e4a7b9b04de15f6b63da5ccdd373ffa3057a3681 to fix the faulty drivers.
> 
> As there is no need anymore to clear the clientdata-pointer, remove all current
> occurrences in the drivers to simplify the code and prevent confusion.
> 
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> Cc: Jean Delvare <khali@linux-fr.org>
> (...)

Applied, thanks. Will go to Linus in the next few days.

-- 
Jean Delvare

^ permalink raw reply

* Re: [PATCH] PowerPC: Remove hardcoded BAT configuration of IMMR in CPM early debug console
From: Martyn Welch @ 2010-06-01 13:43 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <4C050295.408@ge.com>

Martyn Welch wrote:
> Scott Wood wrote:
>   
>> On 05/28/2010 10:18 AM, Martyn Welch wrote:
>>     
>>> The CPM early debug console hardcodes the BAT to cover the IMMR at
>>> 0xf0000000. The IMMR (on the mpc8270 at the very least) can be set to a
>>> number of locations with bootstrap configuration, which are outside the
>>> hardcoded BAT configuration.
>>>
>>> This patch determines the correct location at which to configure a BAT
>>> during the boot process from the supplied PPC_EARLY_DEBUG_CPM_ADDR.
>>>
>>> Signed-off-by: Martyn Welch<martyn.welch@ge.com>
>>> ---
>>>
>>>   arch/powerpc/kernel/head_32.S    |    5 +++--
>>>   arch/powerpc/sysdev/cpm_common.c |    4 +++-
>>>   2 files changed, 6 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/powerpc/kernel/head_32.S
>>> b/arch/powerpc/kernel/head_32.S
>>> index e025e89..861cace 100644
>>> --- a/arch/powerpc/kernel/head_32.S
>>> +++ b/arch/powerpc/kernel/head_32.S
>>> @@ -1194,12 +1194,13 @@ setup_disp_bat:
>>>   #endif /* CONFIG_BOOTX_TEXT */
>>>
>>>   #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
>>> +#define PPC_EARLY_DEBUG_CPM_ADDR
>>> ASM_CONST(CONFIG_PPC_EARLY_DEBUG_CPM_ADDR)
>>>   setup_cpm_bat:
>>> -    lis    r8, 0xf000
>>> +    lis    r8, PPC_EARLY_DEBUG_CPM_ADDR@ha
>>>       ori    r8, r8,    0x002a
>>>       mtspr    SPRN_DBAT1L, r8
>>>
>>> -    lis    r11, 0xf000
>>> +    lis    r11, PPC_EARLY_DEBUG_CPM_ADDR@ha
>>>       ori    r11, r11, (BL_1M << 2) | 2
>>>       mtspr    SPRN_DBAT1U, r11
>>>       
>> Only the physical address should depend on where IMMR is.  We should
>> use fixmap instead of an arbitrary address for the effective address.
>> There's a existing FIX_EARLY_DEBUG_BASE, but it's only 128 KiB so
>> we'll have to either grow it, or map only a subset of IMMR.
>>
>>     
>
> I think that's a more fundamental change to CPM early debug than I can
> handle right now.
>
>   
>> Plus, CONFIG_PPC_EARLY_DEBUG_CPM_ADDR points to the TX descriptor, not
>> to the beginning of IMMR, so you should mask off the lower 20 bits
>> (the offset is probably less than 64K, and the BAT might just ignore
>> the extra bits anyway, but why take chances?).
>>
>>     
>
> I assume that an extra instruction "andi   r8, r8, 0xfff0" after each
> "lis" instruction  would be what you are looking for?
>
>   
"andis" even.

Martyn

> Martyn
>
>   
>> -Scott
>>     
>
>
>   


-- 
Martyn Welch (Principal Software Engineer)   |   Registered in England and
GE Intelligent Platforms                     |   Wales (3828642) at 100
T +44(0)127322748                            |   Barbirolli Square, Manchester,
E martyn.welch@ge.com                        |   M2 3AB  VAT:GB 927559189

^ permalink raw reply

* Re: [PATCH] PowerPC: Remove hardcoded BAT configuration of IMMR in CPM early debug console
From: Martyn Welch @ 2010-06-01 12:52 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <4BFFECF1.9060809@freescale.com>

Scott Wood wrote:
> On 05/28/2010 10:18 AM, Martyn Welch wrote:
>> The CPM early debug console hardcodes the BAT to cover the IMMR at
>> 0xf0000000. The IMMR (on the mpc8270 at the very least) can be set to a
>> number of locations with bootstrap configuration, which are outside the
>> hardcoded BAT configuration.
>>
>> This patch determines the correct location at which to configure a BAT
>> during the boot process from the supplied PPC_EARLY_DEBUG_CPM_ADDR.
>>
>> Signed-off-by: Martyn Welch<martyn.welch@ge.com>
>> ---
>>
>>   arch/powerpc/kernel/head_32.S    |    5 +++--
>>   arch/powerpc/sysdev/cpm_common.c |    4 +++-
>>   2 files changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/head_32.S
>> b/arch/powerpc/kernel/head_32.S
>> index e025e89..861cace 100644
>> --- a/arch/powerpc/kernel/head_32.S
>> +++ b/arch/powerpc/kernel/head_32.S
>> @@ -1194,12 +1194,13 @@ setup_disp_bat:
>>   #endif /* CONFIG_BOOTX_TEXT */
>>
>>   #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
>> +#define PPC_EARLY_DEBUG_CPM_ADDR
>> ASM_CONST(CONFIG_PPC_EARLY_DEBUG_CPM_ADDR)
>>   setup_cpm_bat:
>> -    lis    r8, 0xf000
>> +    lis    r8, PPC_EARLY_DEBUG_CPM_ADDR@ha
>>       ori    r8, r8,    0x002a
>>       mtspr    SPRN_DBAT1L, r8
>>
>> -    lis    r11, 0xf000
>> +    lis    r11, PPC_EARLY_DEBUG_CPM_ADDR@ha
>>       ori    r11, r11, (BL_1M << 2) | 2
>>       mtspr    SPRN_DBAT1U, r11
>
> Only the physical address should depend on where IMMR is.  We should
> use fixmap instead of an arbitrary address for the effective address.
> There's a existing FIX_EARLY_DEBUG_BASE, but it's only 128 KiB so
> we'll have to either grow it, or map only a subset of IMMR.
>

I think that's a more fundamental change to CPM early debug than I can
handle right now.

> Plus, CONFIG_PPC_EARLY_DEBUG_CPM_ADDR points to the TX descriptor, not
> to the beginning of IMMR, so you should mask off the lower 20 bits
> (the offset is probably less than 64K, and the BAT might just ignore
> the extra bits anyway, but why take chances?).
>

I assume that an extra instruction "andi   r8, r8, 0xfff0" after each
"lis" instruction  would be what you are looking for?

Martyn

> -Scott


-- 
Martyn Welch (Principal Software Engineer)   |   Registered in England and
GE Intelligent Platforms                     |   Wales (3828642) at 100
T +44(0)127322748                            |   Barbirolli Square, Manchester,
E martyn.welch@ge.com                        |   M2 3AB  VAT:GB 927559189

^ permalink raw reply

* Re: [PATCH v3] powerpc: Add i8042 keyboard and mouse irq parsing
From: Martyn Welch @ 2010-06-01 12:41 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Dmitry Torokhov, linux-input
In-Reply-To: <1275104126.1931.521.camel@pasglop>

Benjamin Herrenschmidt wrote:
> O
>   
>> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
>> index 48f0a00..3d169bb 100644
>> --- a/arch/powerpc/kernel/setup-common.c
>> +++ b/arch/powerpc/kernel/setup-common.c
>> @@ -94,6 +94,10 @@ struct screen_info screen_info = {
>>  	.orig_video_points = 16
>>  };
>>  
>> +/* Variables required to store legacy IO irq routing */
>> +int of_i8042_kbd_irq;
>> +int of_i8042_aux_irq;
>>     
>
> Is there a reasonable ifdef to use for the above or we don't care ?
>
>   
>>  #ifdef __DO_IRQ_CANON
>>  /* XXX should go elsewhere eventually */
>>  int ppc_do_canonicalize_irqs;
>> @@ -567,6 +571,15 @@ int check_legacy_ioport(unsigned long base_port)
>>  			np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03");
>>  		if (np) {
>>  			parent = of_get_parent(np);
>> +
>> +			of_i8042_kbd_irq = irq_of_parse_and_map(parent, 0);
>> +			if (!of_i8042_kbd_irq)
>> +				of_i8042_kbd_irq = 1;
>> +
>> +			of_i8042_aux_irq = irq_of_parse_and_map(parent, 1);
>> +			if (!of_i8042_aux_irq)
>> +				of_i8042_aux_irq = 12;
>> +
>>  			of_node_put(np);
>>  			np = parent;
>>  			break;
>> diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
>> index 847f4aa..5d48bb6 100644
>> --- a/drivers/input/serio/i8042-io.h
>> +++ b/drivers/input/serio/i8042-io.h
>> @@ -27,6 +27,11 @@
>>  #include <asm/irq.h>
>>  #elif defined(CONFIG_SH_CAYMAN)
>>  #include <asm/irq.h>
>> +#elif defined(CONFIG_PPC)
>> +extern int of_i8042_kbd_irq;
>> +extern int of_i8042_aux_irq;
>> +# define I8042_KBD_IRQ  of_i8042_kbd_irq
>> +# define I8042_AUX_IRQ  of_i8042_aux_irq
>>  #else
>>  # define I8042_KBD_IRQ	1
>>  # define I8042_AUX_IRQ	12
>>     
>
> Now while that works, I do tend to dislike global variables like that.
>
> _Maybe_ a better approach would be to have those #define resolve to
> functions:
>
> #define I8042_KBD_IRQ	of_find_i8042_kbd_irq()
>
> Or something like that ?
>
> That means ending up having 2 functions which more/less reproduce the
> loop to find the driver in the device-tree but that's a minor
> inconvenience.
>
> Now, maybe the variables are less bloat here. What do you think ? Which
> way do you prefer ?
>
>   

Personally, I'm happy either way. If you'd prefer I implement these as
functions, I can't quickly see why that wouldn't work. I thought using
variables would be the least disruptive.

I'm also happy to change it so that the irqs are specified in the kbd
and aux nodes (I agree it would make much more sense and was how the
first revision of this patch worked).

Either way, my preferred solution is that contained in this patch,
unless those with more experience agree otherwise... ;-)

Martyn

> Cheers,
> Ben.
>
>
>   


-- 
Martyn Welch (Principal Software Engineer)   |   Registered in England and
GE Intelligent Platforms                     |   Wales (3828642) at 100
T +44(0)127322748                            |   Barbirolli Square, Manchester,
E martyn.welch@ge.com                        |   M2 3AB  VAT:GB 927559189

^ permalink raw reply

* Re: [PATCH] powerpc: Don't export cvt_fd & _df when CONFIG_PPC_FPU is not set
From: Benjamin Herrenschmidt @ 2010-06-01  9:46 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev, Alexander Graf
In-Reply-To: <m3mxvfrt5n.fsf@hase.home>

On Tue, 2010-06-01 at 11:36 +0200, Andreas Schwab wrote:
> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> 
> > On Mon, 2010-05-31 at 20:06 +0200, Andreas Schwab wrote:
> >> Alexander Graf <agraf@suse.de> writes:
> >> 
> >> > Mind to send it over so I can take a look at it :)? Getting rid of the
> >> > task_struct structs lying in the stack is certainly a good idea.
> >> 
> >> Still untested, because rc1 does not boot.
> >
> > Ouch ! What machine ?
> 
> It's crashing in macio_pci_add_devices.

Ok, so a G5 ? I'll have a look tomorrow.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 0/5] Rework MPC5121 DIU support (for 2.6.35)
From: Anatolij Gustschin @ 2010-06-01  9:38 UTC (permalink / raw)
  To: Timur Tabi
  Cc: linux-fbdev, wd, dzu, devicetree-discuss, linuxppc-dev, yorksun
In-Reply-To: <y2med82fe3e1004291839m92dea081o6a46dc307e07c4ad@mail.gmail.com>

Hi Timur,

On Thu, 29 Apr 2010 20:39:02 -0500
Timur Tabi <timur.tabi@gmail.com> wrote:

> On Thu, Apr 29, 2010 at 6:49 PM, Anatolij Gustschin <agust@denx.de> wrote:
> > This patch series rework DIU support patches submitted
> > previously. Comments to the previos patch series have
> > been addressed, not related changes are dropped and some
> > changes are split out to separate patches to simplify
> > review. Furthermore a patch has been added to support
> > setting display mode using EDID block in the device tree.
> 
> Have you tested these changes on an MPC8610 HPCD?  If not, do you
> think your changes will break that platform?
> 
> I have an 8610 in-house, but I'm currently working on another issue on
> that board, so I can't test these patches for you just yet.

Could you please test these patches on MPC8610 HPCD? I think these
changes won't break that platform. The patches apply cleanly on
2.6.35-rc1.

Thanks,
Anatolij

^ permalink raw reply

* Re: [PATCH] powerpc: Don't export cvt_fd & _df when CONFIG_PPC_FPU is not set
From: Andreas Schwab @ 2010-06-01  9:36 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Alexander Graf
In-Reply-To: <1275384716.1931.711.camel__10281.3212587082$1275384770$gmane$org@pasglop>

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> On Mon, 2010-05-31 at 20:06 +0200, Andreas Schwab wrote:
>> Alexander Graf <agraf@suse.de> writes:
>> 
>> > Mind to send it over so I can take a look at it :)? Getting rid of the
>> > task_struct structs lying in the stack is certainly a good idea.
>> 
>> Still untested, because rc1 does not boot.
>
> Ouch ! What machine ?

It's crashing in macio_pci_add_devices.

Andreas.

-- 
Andreas Schwab, schwab@redhat.com
GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84  5EC7 45C6 250E 6F00 984E
"And now for something completely different."

^ permalink raw reply

* Re: [PATCH] powerpc: Don't export cvt_fd & _df when CONFIG_PPC_FPU is not set
From: Benjamin Herrenschmidt @ 2010-06-01  9:31 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev, Alexander Graf
In-Reply-To: <m2aargndy2.fsf@igel.home>

On Mon, 2010-05-31 at 20:06 +0200, Andreas Schwab wrote:
> Alexander Graf <agraf@suse.de> writes:
> 
> > Mind to send it over so I can take a look at it :)? Getting rid of the
> > task_struct structs lying in the stack is certainly a good idea.
> 
> Still untested, because rc1 does not boot.

Ouch ! What machine ?

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] KVM: PPC: elide struct thread_struct instances from stack
From: Alexander Graf @ 2010-06-01  9:19 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev, Paul Mackerras, kvm, kvm-ppc
In-Reply-To: <m3r5krrvy2.fsf@hase.home>


On 01.06.2010, at 10:36, Andreas Schwab wrote:

> Paul Mackerras <paulus@samba.org> writes:
>=20
>> I re-read the relevant part of the PowerPC architecture spec
>> yesterday, and it seems pretty clear that the FPSCR doesn't affect =
the
>> behaviour of lfs and stfs, and is not affected by them.  So in fact 4
>> out of the 7 instructions in each of those procedures are unnecessary
>> (and similarly for the cvt_fd/df used in the alignment fixup code).
>=20
> I'd prefer to have this deferred to a separate patch.

I agree. Andreas' patch takes the current logic and moves it to be KVM =
contained, so we don't clutter the stack. The fact that the old code was =
inefficient is a separate story.

Avi / Marcelo, please apply the patch nevertheless.


Alex

^ permalink raw reply

* Re: [PATCH] KVM: PPC: elide struct thread_struct instances from stack
From: Andreas Schwab @ 2010-06-01  8:36 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Alexander Graf, kvm-ppc, kvm
In-Reply-To: <20100531224040.GA22927@brick.ozlabs.ibm.com>

Paul Mackerras <paulus@samba.org> writes:

> I re-read the relevant part of the PowerPC architecture spec
> yesterday, and it seems pretty clear that the FPSCR doesn't affect the
> behaviour of lfs and stfs, and is not affected by them.  So in fact 4
> out of the 7 instructions in each of those procedures are unnecessary
> (and similarly for the cvt_fd/df used in the alignment fixup code).

I'd prefer to have this deferred to a separate patch.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* Re: [PATCH] powerpc: Optimise per cpu accesses on 64bit
From: Benjamin Herrenschmidt @ 2010-06-01  7:05 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: linuxppc-dev, amodra
In-Reply-To: <20100601044511.GF28295@kryten>

On Tue, 2010-06-01 at 14:45 +1000, Anton Blanchard wrote:
> Now we dynamically allocate the paca array, it takes an extra load
> whenever we want to access another cpu's paca. One place we do that a lot
> is per cpu variables. A simple example:

Can't we dedicate a GPR instead ? Or it isn't worth it ? Something we
almost never use in the kernel like r12 ?

Cheers,
Ben.

> DEFINE_PER_CPU(unsigned long, vara);
> unsigned long test4(int cpu)
> {
> 	return per_cpu(vara, cpu);
> }
> 
> This takes 4 loads, 5 if you include the actual load of the per cpu variable:
> 
>     ld r11,-32760(r30)  # load address of paca pointer
>     ld r9,-32768(r30)   # load link address of percpu variable
>     sldi r3,r29,9       # get offset into paca (each entry is 512 bytes)
>     ld r0,0(r11)        # load paca pointer
>     add r3,r0,r3        # paca + offset
>     ld r11,64(r3)       # load paca[cpu].data_offset
> 
>     ldx r3,r9,r11       # load per cpu variable
> 
> If we remove the ppc64 specific per_cpu_offset(), we get the generic one
> which indexes into a statically allocated array. This removes one load and
> one add:
> 
>     ld r11,-32760(r30)  # load address of __per_cpu_offset
>     ld r9,-32768(r30)   # load link address of percpu variable
>     sldi r3,r29,3       # get offset into __per_cpu_offset (each entry 8 bytes)
>     ldx r11,r11,r3      # load __per_cpu_offset[cpu]
> 
>     ldx r3,r9,r11       # load per cpu variable
> 
> Having all the offsets in one array also helps when iterating over a per cpu
> variable across a number of cpus, such as in the scheduler. Before we would
> need to load one paca cacheline when calculating each per cpu offset. Now we
> have 16 (128 / sizeof(long)) per cpu offsets in each cacheline.
> 
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
> 
> Index: powerpc.git/arch/powerpc/include/asm/percpu.h
> ===================================================================
> --- powerpc.git.orig/arch/powerpc/include/asm/percpu.h	2010-06-01 11:10:16.225954322 +1000
> +++ powerpc.git/arch/powerpc/include/asm/percpu.h	2010-06-01 11:32:27.713476455 +1000
> @@ -1,7 +1,6 @@
>  #ifndef _ASM_POWERPC_PERCPU_H_
>  #define _ASM_POWERPC_PERCPU_H_
>  #ifdef __powerpc64__
> -#include <linux/compiler.h>
>  
>  /*
>   * Same as asm-generic/percpu.h, except that we store the per cpu offset
> @@ -12,9 +11,7 @@
>  
>  #include <asm/paca.h>
>  
> -#define __per_cpu_offset(cpu) (paca[cpu].data_offset)
>  #define __my_cpu_offset local_paca->data_offset
> -#define per_cpu_offset(x) (__per_cpu_offset(x))
>  
>  #endif /* CONFIG_SMP */
>  #endif /* __powerpc64__ */
> Index: powerpc.git/arch/powerpc/kernel/asm-offsets.c
> ===================================================================
> --- powerpc.git.orig/arch/powerpc/kernel/asm-offsets.c	2010-06-01 11:10:16.195958268 +1000
> +++ powerpc.git/arch/powerpc/kernel/asm-offsets.c	2010-06-01 11:32:27.713476455 +1000
> @@ -194,7 +194,6 @@ int main(void)
>  	DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
>  	DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
>  	DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
> -	DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
>  	DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
>  #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
>  	DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu));
> Index: powerpc.git/arch/powerpc/kernel/setup_64.c
> ===================================================================
> --- powerpc.git.orig/arch/powerpc/kernel/setup_64.c	2010-06-01 11:10:16.205958158 +1000
> +++ powerpc.git/arch/powerpc/kernel/setup_64.c	2010-06-01 11:32:27.713476455 +1000
> @@ -604,6 +604,9 @@ static int pcpu_cpu_distance(unsigned in
>  		return REMOTE_DISTANCE;
>  }
>  
> +unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
> +EXPORT_SYMBOL(__per_cpu_offset);
> +
>  void __init setup_per_cpu_areas(void)
>  {
>  	const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
> @@ -628,8 +631,10 @@ void __init setup_per_cpu_areas(void)
>  		panic("cannot initialize percpu area (err=%d)", rc);
>  
>  	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
> -	for_each_possible_cpu(cpu)
> -		paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu];
> +	for_each_possible_cpu(cpu) {
> +                __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
> +		paca[cpu].data_offset = __per_cpu_offset[cpu];
> +	}
>  }
>  #endif
>  

^ permalink raw reply

* Re: [PATCH] drivers: remove all i2c_set_clientdata(client, NULL)
From: Dmitry Torokhov @ 2010-06-01  5:05 UTC (permalink / raw)
  To: Richard Purdie
  Cc: Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-mtd,
	linux-i2c, Alessandro Rubini, Samuel Ortiz, lm-sensors,
	linux-input, linux-media, Paul Gortmaker, devel, rtc-linux,
	Riku Voipio, Mauro Carvalho Chehab, Jean Delvare,
	Ben Dooks (embedded platforms), Liam Girdwood, Alessandro Zummo,
	Guillaume Ligneul, George Joseph, Mark Brown, Colin Leroy,
	David Woodhouse
In-Reply-To: <1275342512.24079.1559.camel@rex>

On Mon, May 31, 2010 at 10:48:32PM +0100, Richard Purdie wrote:
> On Mon, 2010-05-31 at 12:09 -0700, Dmitry Torokhov wrote:
> > On Mon, May 31, 2010 at 02:55:48PM +0200, Wolfram Sang wrote:
> > > I2C-drivers can use the clientdata-pointer to point to private data. As I2C
> > > devices are not really unregistered, but merely detached from their driver, it
> > > used to be the drivers obligation to clear this pointer during remove() or a
> > > failed probe(). As a couple of drivers forgot to do this, it was agreed that it
> > > was cleaner if the i2c-core does this clearance when appropriate, as there is
> > > no guarantee for the lifetime of the clientdata-pointer after remove() anyhow.
> > > This feature was added to the core with commit
> > > e4a7b9b04de15f6b63da5ccdd373ffa3057a3681 to fix the faulty drivers.
> > > 
> > > As there is no need anymore to clear the clientdata-pointer, remove all current
> > > occurrences in the drivers to simplify the code and prevent confusion.
> > > 
> > > Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> > > Cc: Jean Delvare <khali@linux-fr.org>
> > > ---
> > > 
> > > Some more notes:
> > > 
> > > I waited for rc1 as I knew there were some drivers/patches coming along which
> > > needed to be processed, too.
> > > 
> > > I'd suggest that this goes via the i2c-tree, so we get rid of all occurences at
> > > once.
> > > 
> > 
> > Frankly I'd prefer taking input stuff through my tree with the goal of
> > .36 merge window just to minimize potential merge issues. This is a
> > simple cleanup patch that has no dependencies, so there is little gain
> > from doing it all in one go.
> 
> How about asking Linus to take this one now, then its done and we can
> all move on rather than queuing up problems for the next merge window?
> 

That should work.

Acked-by: Dmitry Torokhov <dtor@mail.ru>

> Acked-by: Richard Purdie <rpurdie@linux.intel.com>
> 

-- 
Dmitry

^ permalink raw reply

* [PATCH] powerpc: Optimise per cpu accesses on 64bit
From: Anton Blanchard @ 2010-06-01  4:45 UTC (permalink / raw)
  To: benh, michael, amodra; +Cc: linuxppc-dev


Now we dynamically allocate the paca array, it takes an extra load
whenever we want to access another cpu's paca. One place we do that a lot
is per cpu variables. A simple example:

DEFINE_PER_CPU(unsigned long, vara);
unsigned long test4(int cpu)
{
	return per_cpu(vara, cpu);
}

This takes 4 loads, 5 if you include the actual load of the per cpu variable:

    ld r11,-32760(r30)  # load address of paca pointer
    ld r9,-32768(r30)   # load link address of percpu variable
    sldi r3,r29,9       # get offset into paca (each entry is 512 bytes)
    ld r0,0(r11)        # load paca pointer
    add r3,r0,r3        # paca + offset
    ld r11,64(r3)       # load paca[cpu].data_offset

    ldx r3,r9,r11       # load per cpu variable

If we remove the ppc64 specific per_cpu_offset(), we get the generic one
which indexes into a statically allocated array. This removes one load and
one add:

    ld r11,-32760(r30)  # load address of __per_cpu_offset
    ld r9,-32768(r30)   # load link address of percpu variable
    sldi r3,r29,3       # get offset into __per_cpu_offset (each entry 8 bytes)
    ldx r11,r11,r3      # load __per_cpu_offset[cpu]

    ldx r3,r9,r11       # load per cpu variable

Having all the offsets in one array also helps when iterating over a per cpu
variable across a number of cpus, such as in the scheduler. Before we would
need to load one paca cacheline when calculating each per cpu offset. Now we
have 16 (128 / sizeof(long)) per cpu offsets in each cacheline.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: powerpc.git/arch/powerpc/include/asm/percpu.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/percpu.h	2010-06-01 11:10:16.225954322 +1000
+++ powerpc.git/arch/powerpc/include/asm/percpu.h	2010-06-01 11:32:27.713476455 +1000
@@ -1,7 +1,6 @@
 #ifndef _ASM_POWERPC_PERCPU_H_
 #define _ASM_POWERPC_PERCPU_H_
 #ifdef __powerpc64__
-#include <linux/compiler.h>
 
 /*
  * Same as asm-generic/percpu.h, except that we store the per cpu offset
@@ -12,9 +11,7 @@
 
 #include <asm/paca.h>
 
-#define __per_cpu_offset(cpu) (paca[cpu].data_offset)
 #define __my_cpu_offset local_paca->data_offset
-#define per_cpu_offset(x) (__per_cpu_offset(x))
 
 #endif /* CONFIG_SMP */
 #endif /* __powerpc64__ */
Index: powerpc.git/arch/powerpc/kernel/asm-offsets.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/asm-offsets.c	2010-06-01 11:10:16.195958268 +1000
+++ powerpc.git/arch/powerpc/kernel/asm-offsets.c	2010-06-01 11:32:27.713476455 +1000
@@ -194,7 +194,6 @@ int main(void)
 	DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
 	DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
 	DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
-	DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
 	DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 	DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu));
Index: powerpc.git/arch/powerpc/kernel/setup_64.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/setup_64.c	2010-06-01 11:10:16.205958158 +1000
+++ powerpc.git/arch/powerpc/kernel/setup_64.c	2010-06-01 11:32:27.713476455 +1000
@@ -604,6 +604,9 @@ static int pcpu_cpu_distance(unsigned in
 		return REMOTE_DISTANCE;
 }
 
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(__per_cpu_offset);
+
 void __init setup_per_cpu_areas(void)
 {
 	const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
@@ -628,8 +631,10 @@ void __init setup_per_cpu_areas(void)
 		panic("cannot initialize percpu area (err=%d)", rc);
 
 	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
-	for_each_possible_cpu(cpu)
-		paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu];
+	for_each_possible_cpu(cpu) {
+                __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
+		paca[cpu].data_offset = __per_cpu_offset[cpu];
+	}
 }
 #endif
 

^ permalink raw reply

* Re: [PATCH] KVM: PPC: elide struct thread_struct instances from stack
From: Alexander Graf @ 2010-05-31 23:27 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Andreas Schwab, kvm, kvm-ppc
In-Reply-To: <20100531224040.GA22927@brick.ozlabs.ibm.com>


On 01.06.2010, at 00:40, Paul Mackerras wrote:

> On Mon, May 31, 2010 at 09:59:13PM +0200, Andreas Schwab wrote:
>=20
>> Instead of instantiating a whole thread_struct on the stack use only =
the
>> required parts of it.
>=20
> ...
>=20
>> +_GLOBAL(kvm_cvt_fd)
>> +	lfd	0,0(r5)			/* load up fpscr value */
>> +	MTFSF_L(0)
>> +	lfs	0,0(r3)
>> +	stfd	0,0(r4)
>> +	mffs	0
>> +	stfd	0,0(r5)			/* save new fpscr value */
>> +	blr
>> +
>> +_GLOBAL(kvm_cvt_df)
>> +	lfd	0,0(r5)			/* load up fpscr value */
>> +	MTFSF_L(0)
>> +	lfd	0,0(r3)
>> +	stfs	0,0(r4)
>> +	mffs	0
>> +	stfd	0,0(r5)			/* save new fpscr value */
>> +	blr
>=20
> I re-read the relevant part of the PowerPC architecture spec
> yesterday, and it seems pretty clear that the FPSCR doesn't affect the
> behaviour of lfs and stfs, and is not affected by them.  So in fact 4
> out of the 7 instructions in each of those procedures are unnecessary
> (and similarly for the cvt_fd/df used in the alignment fixup code).

So the rounding control field is not used on lfs? Interesting. I =
couldn't find a reference to it being used or modified either though.

Alex

^ permalink raw reply

* Re: [PATCH] KVM: PPC: elide struct thread_struct instances from stack
From: Paul Mackerras @ 2010-05-31 22:40 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev, Alexander Graf, kvm-ppc, kvm
In-Reply-To: <m26323onam.fsf@igel.home>

On Mon, May 31, 2010 at 09:59:13PM +0200, Andreas Schwab wrote:

> Instead of instantiating a whole thread_struct on the stack use only the
> required parts of it.

...

> +_GLOBAL(kvm_cvt_fd)
> +	lfd	0,0(r5)			/* load up fpscr value */
> +	MTFSF_L(0)
> +	lfs	0,0(r3)
> +	stfd	0,0(r4)
> +	mffs	0
> +	stfd	0,0(r5)			/* save new fpscr value */
> +	blr
> +
> +_GLOBAL(kvm_cvt_df)
> +	lfd	0,0(r5)			/* load up fpscr value */
> +	MTFSF_L(0)
> +	lfd	0,0(r3)
> +	stfs	0,0(r4)
> +	mffs	0
> +	stfd	0,0(r5)			/* save new fpscr value */
> +	blr

I re-read the relevant part of the PowerPC architecture spec
yesterday, and it seems pretty clear that the FPSCR doesn't affect the
behaviour of lfs and stfs, and is not affected by them.  So in fact 4
out of the 7 instructions in each of those procedures are unnecessary
(and similarly for the cvt_fd/df used in the alignment fixup code).

Paul.

^ permalink raw reply

* Re: [PATCH] drivers: remove all i2c_set_clientdata(client, NULL)
From: Richard Purdie @ 2010-05-31 21:48 UTC (permalink / raw)
  To: Dmitry Torokhov, Wolfram Sang
  Cc: Greg Kroah-Hartman, linuxppc-dev, linux-mtd, linux-i2c,
	Alessandro Rubini, Samuel Ortiz, lm-sensors, linux-input,
	linux-media, Paul Gortmaker, devel, rtc-linux, Riku Voipio,
	Mauro Carvalho Chehab, Jean Delvare,
	Ben Dooks (embedded platforms), Liam Girdwood, Alessandro Zummo,
	Guillaume Ligneul, George Joseph, Mark Brown, linux-kernel,
	Colin Leroy, David Woodhouse
In-Reply-To: <20100531190911.GC30712@core.coreip.homeip.net>

On Mon, 2010-05-31 at 12:09 -0700, Dmitry Torokhov wrote:
> On Mon, May 31, 2010 at 02:55:48PM +0200, Wolfram Sang wrote:
> > I2C-drivers can use the clientdata-pointer to point to private data. As I2C
> > devices are not really unregistered, but merely detached from their driver, it
> > used to be the drivers obligation to clear this pointer during remove() or a
> > failed probe(). As a couple of drivers forgot to do this, it was agreed that it
> > was cleaner if the i2c-core does this clearance when appropriate, as there is
> > no guarantee for the lifetime of the clientdata-pointer after remove() anyhow.
> > This feature was added to the core with commit
> > e4a7b9b04de15f6b63da5ccdd373ffa3057a3681 to fix the faulty drivers.
> > 
> > As there is no need anymore to clear the clientdata-pointer, remove all current
> > occurrences in the drivers to simplify the code and prevent confusion.
> > 
> > Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> > Cc: Jean Delvare <khali@linux-fr.org>
> > ---
> > 
> > Some more notes:
> > 
> > I waited for rc1 as I knew there were some drivers/patches coming along which
> > needed to be processed, too.
> > 
> > I'd suggest that this goes via the i2c-tree, so we get rid of all occurences at
> > once.
> > 
> 
> Frankly I'd prefer taking input stuff through my tree with the goal of
> .36 merge window just to minimize potential merge issues. This is a
> simple cleanup patch that has no dependencies, so there is little gain
> from doing it all in one go.

How about asking Linus to take this one now, then its done and we can
all move on rather than queuing up problems for the next merge window?

Acked-by: Richard Purdie <rpurdie@linux.intel.com>

Cheers,

Richard

^ permalink raw reply

* Re: [PATCH] drivers: remove all i2c_set_clientdata(client, NULL)
From: Jean Delvare @ 2010-05-31 20:57 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Greg Kroah-Hartman, linux-kernel, linuxppc-dev, linux-mtd,
	linux-i2c, devel, Samuel Ortiz, lm-sensors, linux-input,
	linux-media, Paul Gortmaker, Riku Voipio, rtc-linux,
	Alessandro Rubini, Mauro Carvalho Chehab,
	Ben Dooks (embedded platforms), Liam Girdwood, Alessandro Zummo,
	Guillaume Ligneul, George Joseph, Mark Brown, Richard Purdie,
	Colin Leroy, David Woodhouse
In-Reply-To: <20100531190911.GC30712@core.coreip.homeip.net>

Hi Dmitry,

On Mon, 31 May 2010 12:09:12 -0700, Dmitry Torokhov wrote:
> Frankly I'd prefer taking input stuff through my tree with the goal of
> .36 merge window just to minimize potential merge issues. This is a
> simple cleanup patch that has no dependencies, so there is little gain
> from doing it all in one go.

If I take the patch in my i2c tree, the aim is to merge it upstream
immediately, so merge issues won't exist.

-- 
Jean Delvare

^ permalink raw reply

* Re: [PATCH] KVM: PPC: elide struct thread_struct instances from stack
From: Alexander Graf @ 2010-05-31 20:00 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <m26323onam.fsf@igel.home>


On 31.05.2010, at 21:59, Andreas Schwab wrote:

> Instead of instantiating a whole thread_struct on the stack use only the
> required parts of it.
> 
> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
> Tested-by: Alexander Graf <agraf@suse.de>

Avi or Marcelo, please pull this in through kvm.git.

Signed-off-by: Alexander Graf <agraf@suse.de>


Alex

^ permalink raw reply

* [PATCH] KVM: PPC: elide struct thread_struct instances from stack
From: Andreas Schwab @ 2010-05-31 19:59 UTC (permalink / raw)
  To: kvm-ppc; +Cc: linuxppc-dev, Alexander Graf, kvm

Instead of instantiating a whole thread_struct on the stack use only the
required parts of it.

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
Tested-by: Alexander Graf <agraf@suse.de>
---
 arch/powerpc/include/asm/kvm_fpu.h       |   27 +++++----
 arch/powerpc/kernel/ppc_ksyms.c          |    4 -
 arch/powerpc/kvm/book3s.c                |   49 +++++++++-------
 arch/powerpc/kvm/book3s_paired_singles.c |   94 ++++++++++++------------------
 arch/powerpc/kvm/fpu.S                   |   18 ++++++
 5 files changed, 97 insertions(+), 95 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_fpu.h b/arch/powerpc/include/asm/kvm_fpu.h
index 94f05de..c3d4f05 100644
--- a/arch/powerpc/include/asm/kvm_fpu.h
+++ b/arch/powerpc/include/asm/kvm_fpu.h
@@ -22,24 +22,24 @@
 
 #include <linux/types.h>
 
-extern void fps_fres(struct thread_struct *t, u32 *dst, u32 *src1);
-extern void fps_frsqrte(struct thread_struct *t, u32 *dst, u32 *src1);
-extern void fps_fsqrts(struct thread_struct *t, u32 *dst, u32 *src1);
+extern void fps_fres(u64 *fpscr, u32 *dst, u32 *src1);
+extern void fps_frsqrte(u64 *fpscr, u32 *dst, u32 *src1);
+extern void fps_fsqrts(u64 *fpscr, u32 *dst, u32 *src1);
 
-extern void fps_fadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
-extern void fps_fdivs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
-extern void fps_fmuls(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
-extern void fps_fsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fdivs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fmuls(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
 
-extern void fps_fmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fmadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		       u32 *src3);
-extern void fps_fmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fmsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		       u32 *src3);
-extern void fps_fnmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fnmadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		        u32 *src3);
-extern void fps_fnmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fnmsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		        u32 *src3);
-extern void fps_fsel(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fsel(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		     u32 *src3);
 
 #define FPD_ONE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \
@@ -82,4 +82,7 @@ FPD_THREE_IN(fmadd)
 FPD_THREE_IN(fnmsub)
 FPD_THREE_IN(fnmadd)
 
+extern void kvm_cvt_fd(u32 *from, u64 *to, u64 *fpscr);
+extern void kvm_cvt_df(u64 *from, u32 *to, u64 *fpscr);
+
 #endif
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index bc9f39d..ab3e392 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -101,10 +101,6 @@ EXPORT_SYMBOL(pci_dram_offset);
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(kernel_thread);
 
-#ifndef CONFIG_BOOKE
-EXPORT_SYMBOL_GPL(cvt_df);
-EXPORT_SYMBOL_GPL(cvt_fd);
-#endif
 EXPORT_SYMBOL(giveup_fpu);
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(giveup_altivec);
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index b998abf..3fea19d 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1309,12 +1309,17 @@ extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
 int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
 	int ret;
-	struct thread_struct ext_bkp;
+	double fpr[32][TS_FPRWIDTH];
+	unsigned int fpscr;
+	int fpexc_mode;
 #ifdef CONFIG_ALTIVEC
-	bool save_vec = current->thread.used_vr;
+	vector128 vr[32];
+	vector128 vscr;
+	unsigned long uninitialized_var(vrsave);
+	int used_vr;
 #endif
 #ifdef CONFIG_VSX
-	bool save_vsx = current->thread.used_vsr;
+	int used_vsr;
 #endif
 	ulong ext_msr;
 
@@ -1327,27 +1332,27 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 	/* Save FPU state in stack */
 	if (current->thread.regs->msr & MSR_FP)
 		giveup_fpu(current);
-	memcpy(ext_bkp.fpr, current->thread.fpr, sizeof(current->thread.fpr));
-	ext_bkp.fpscr = current->thread.fpscr;
-	ext_bkp.fpexc_mode = current->thread.fpexc_mode;
+	memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr));
+	fpscr = current->thread.fpscr.val;
+	fpexc_mode = current->thread.fpexc_mode;
 
 #ifdef CONFIG_ALTIVEC
 	/* Save Altivec state in stack */
-	if (save_vec) {
+	used_vr = current->thread.used_vr;
+	if (used_vr) {
 		if (current->thread.regs->msr & MSR_VEC)
 			giveup_altivec(current);
-		memcpy(ext_bkp.vr, current->thread.vr, sizeof(ext_bkp.vr));
-		ext_bkp.vscr = current->thread.vscr;
-		ext_bkp.vrsave = current->thread.vrsave;
+		memcpy(vr, current->thread.vr, sizeof(current->thread.vr));
+		vscr = current->thread.vscr;
+		vrsave = current->thread.vrsave;
 	}
-	ext_bkp.used_vr = current->thread.used_vr;
 #endif
 
 #ifdef CONFIG_VSX
 	/* Save VSX state in stack */
-	if (save_vsx && (current->thread.regs->msr & MSR_VSX))
+	used_vsr = current->thread.used_vsr;
+	if (used_vsr && (current->thread.regs->msr & MSR_VSX))
 			__giveup_vsx(current);
-	ext_bkp.used_vsr = current->thread.used_vsr;
 #endif
 
 	/* Remember the MSR with disabled extensions */
@@ -1372,22 +1377,22 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 	kvmppc_giveup_ext(vcpu, MSR_VSX);
 
 	/* Restore FPU state from stack */
-	memcpy(current->thread.fpr, ext_bkp.fpr, sizeof(ext_bkp.fpr));
-	current->thread.fpscr = ext_bkp.fpscr;
-	current->thread.fpexc_mode = ext_bkp.fpexc_mode;
+	memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr));
+	current->thread.fpscr.val = fpscr;
+	current->thread.fpexc_mode = fpexc_mode;
 
 #ifdef CONFIG_ALTIVEC
 	/* Restore Altivec state from stack */
-	if (save_vec && current->thread.used_vr) {
-		memcpy(current->thread.vr, ext_bkp.vr, sizeof(ext_bkp.vr));
-		current->thread.vscr = ext_bkp.vscr;
-		current->thread.vrsave= ext_bkp.vrsave;
+	if (used_vr && current->thread.used_vr) {
+		memcpy(current->thread.vr, vr, sizeof(current->thread.vr));
+		current->thread.vscr = vscr;
+		current->thread.vrsave = vrsave;
 	}
-	current->thread.used_vr = ext_bkp.used_vr;
+	current->thread.used_vr = used_vr;
 #endif
 
 #ifdef CONFIG_VSX
-	current->thread.used_vsr = ext_bkp.used_vsr;
+	current->thread.used_vsr = used_vsr;
 #endif
 
 	return ret;
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c
index a9f66ab..474f2e2 100644
--- a/arch/powerpc/kvm/book3s_paired_singles.c
+++ b/arch/powerpc/kvm/book3s_paired_singles.c
@@ -159,10 +159,7 @@
 
 static inline void kvmppc_sync_qpr(struct kvm_vcpu *vcpu, int rt)
 {
-	struct thread_struct t;
-
-	t.fpscr.val = vcpu->arch.fpscr;
-	cvt_df((double*)&vcpu->arch.fpr[rt], (float*)&vcpu->arch.qpr[rt], &t);
+	kvm_cvt_df(&vcpu->arch.fpr[rt], &vcpu->arch.qpr[rt], &vcpu->arch.fpscr);
 }
 
 static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store)
@@ -183,7 +180,6 @@ static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
 				   int rs, ulong addr, int ls_type)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	char tmp[8];
 	int len = sizeof(u32);
@@ -191,8 +187,6 @@ static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	if (ls_type == FPU_LS_DOUBLE)
 		len = sizeof(u64);
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	/* read from memory */
 	r = kvmppc_ld(vcpu, &addr, len, tmp, true);
 	vcpu->arch.paddr_accessed = addr;
@@ -210,7 +204,7 @@ static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	/* put in registers */
 	switch (ls_type) {
 	case FPU_LS_SINGLE:
-		cvt_fd((float*)tmp, (double*)&vcpu->arch.fpr[rs], &t);
+		kvm_cvt_fd((u32*)tmp, &vcpu->arch.fpr[rs], &vcpu->arch.fpscr);
 		vcpu->arch.qpr[rs] = *((u32*)tmp);
 		break;
 	case FPU_LS_DOUBLE:
@@ -229,17 +223,14 @@ static int kvmppc_emulate_fpr_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
 				    int rs, ulong addr, int ls_type)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	char tmp[8];
 	u64 val;
 	int len;
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	switch (ls_type) {
 	case FPU_LS_SINGLE:
-		cvt_df((double*)&vcpu->arch.fpr[rs], (float*)tmp, &t);
+		kvm_cvt_df(&vcpu->arch.fpr[rs], (u32*)tmp, &vcpu->arch.fpscr);
 		val = *((u32*)tmp);
 		len = sizeof(u32);
 		break;
@@ -278,13 +269,10 @@ static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
 				   int rs, ulong addr, bool w, int i)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	float one = 1.0;
 	u32 tmp[2];
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	/* read from memory */
 	if (w) {
 		r = kvmppc_ld(vcpu, &addr, sizeof(u32), tmp, true);
@@ -308,7 +296,7 @@ static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	emulated = EMULATE_DONE;
 
 	/* put in registers */
-	cvt_fd((float*)&tmp[0], (double*)&vcpu->arch.fpr[rs], &t);
+	kvm_cvt_fd(&tmp[0], &vcpu->arch.fpr[rs], &vcpu->arch.fpscr);
 	vcpu->arch.qpr[rs] = tmp[1];
 
 	dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0],
@@ -322,14 +310,11 @@ static int kvmppc_emulate_psq_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
 				    int rs, ulong addr, bool w, int i)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	u32 tmp[2];
 	int len = w ? sizeof(u32) : sizeof(u64);
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
-	cvt_df((double*)&vcpu->arch.fpr[rs], (float*)&tmp[0], &t);
+	kvm_cvt_df(&vcpu->arch.fpr[rs], &tmp[0], &vcpu->arch.fpscr);
 	tmp[1] = vcpu->arch.qpr[rs];
 
 	r = kvmppc_st(vcpu, &addr, len, tmp, true);
@@ -517,7 +502,7 @@ static int get_d_signext(u32 inst)
 static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
 				      int reg_out, int reg_in1, int reg_in2,
 				      int reg_in3, int scalar,
-				      void (*func)(struct thread_struct *t,
+				      void (*func)(u64 *fpscr,
 						 u32 *dst, u32 *src1,
 						 u32 *src2, u32 *src3))
 {
@@ -526,27 +511,25 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
 	u32 ps0_out;
 	u32 ps0_in1, ps0_in2, ps0_in3;
 	u32 ps1_in1, ps1_in2, ps1_in3;
-	struct thread_struct t;
-	t.fpscr.val = vcpu->arch.fpscr;
 
 	/* RC */
 	WARN_ON(rc);
 
 	/* PS0 */
-	cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t);
-	cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t);
-	cvt_df((double*)&fpr[reg_in3], (float*)&ps0_in3, &t);
+	kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr);
+	kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr);
+	kvm_cvt_df(&fpr[reg_in3], &ps0_in3, &vcpu->arch.fpscr);
 
 	if (scalar & SCALAR_LOW)
 		ps0_in2 = qpr[reg_in2];
 
-	func(&t, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3);
+	func(&vcpu->arch.fpscr, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3);
 
 	dprintk(KERN_INFO "PS3 ps0 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n",
 			  ps0_in1, ps0_in2, ps0_in3, ps0_out);
 
 	if (!(scalar & SCALAR_NO_PS0))
-		cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t);
+		kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
 
 	/* PS1 */
 	ps1_in1 = qpr[reg_in1];
@@ -557,7 +540,7 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
 		ps1_in2 = ps0_in2;
 
 	if (!(scalar & SCALAR_NO_PS1))
-		func(&t, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3);
+		func(&vcpu->arch.fpscr, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3);
 
 	dprintk(KERN_INFO "PS3 ps1 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n",
 			  ps1_in1, ps1_in2, ps1_in3, qpr[reg_out]);
@@ -568,7 +551,7 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
 static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc,
 				    int reg_out, int reg_in1, int reg_in2,
 				    int scalar,
-				    void (*func)(struct thread_struct *t,
+				    void (*func)(u64 *fpscr,
 						 u32 *dst, u32 *src1,
 						 u32 *src2))
 {
@@ -578,27 +561,25 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc,
 	u32 ps0_in1, ps0_in2;
 	u32 ps1_out;
 	u32 ps1_in1, ps1_in2;
-	struct thread_struct t;
-	t.fpscr.val = vcpu->arch.fpscr;
 
 	/* RC */
 	WARN_ON(rc);
 
 	/* PS0 */
-	cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t);
+	kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr);
 
 	if (scalar & SCALAR_LOW)
 		ps0_in2 = qpr[reg_in2];
 	else
-		cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t);
+		kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr);
 
-	func(&t, &ps0_out, &ps0_in1, &ps0_in2);
+	func(&vcpu->arch.fpscr, &ps0_out, &ps0_in1, &ps0_in2);
 
 	if (!(scalar & SCALAR_NO_PS0)) {
 		dprintk(KERN_INFO "PS2 ps0 -> f(0x%x, 0x%x) = 0x%x\n",
 				  ps0_in1, ps0_in2, ps0_out);
 
-		cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t);
+		kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
 	}
 
 	/* PS1 */
@@ -608,7 +589,7 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc,
 	if (scalar & SCALAR_HIGH)
 		ps1_in2 = ps0_in2;
 
-	func(&t, &ps1_out, &ps1_in1, &ps1_in2);
+	func(&vcpu->arch.fpscr, &ps1_out, &ps1_in1, &ps1_in2);
 
 	if (!(scalar & SCALAR_NO_PS1)) {
 		qpr[reg_out] = ps1_out;
@@ -622,31 +603,29 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc,
 
 static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc,
 				    int reg_out, int reg_in,
-				    void (*func)(struct thread_struct *t,
+				    void (*func)(u64 *t,
 						 u32 *dst, u32 *src1))
 {
 	u32 *qpr = vcpu->arch.qpr;
 	u64 *fpr = vcpu->arch.fpr;
 	u32 ps0_out, ps0_in;
 	u32 ps1_in;
-	struct thread_struct t;
-	t.fpscr.val = vcpu->arch.fpscr;
 
 	/* RC */
 	WARN_ON(rc);
 
 	/* PS0 */
-	cvt_df((double*)&fpr[reg_in], (float*)&ps0_in, &t);
-	func(&t, &ps0_out, &ps0_in);
+	kvm_cvt_df(&fpr[reg_in], &ps0_in, &vcpu->arch.fpscr);
+	func(&vcpu->arch.fpscr, &ps0_out, &ps0_in);
 
 	dprintk(KERN_INFO "PS1 ps0 -> f(0x%x) = 0x%x\n",
 			  ps0_in, ps0_out);
 
-	cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t);
+	kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
 
 	/* PS1 */
 	ps1_in = qpr[reg_in];
-	func(&t, &qpr[reg_out], &ps1_in);
+	func(&vcpu->arch.fpscr, &qpr[reg_out], &ps1_in);
 
 	dprintk(KERN_INFO "PS1 ps1 -> f(0x%x) = 0x%x\n",
 			  ps1_in, qpr[reg_out]);
@@ -672,13 +651,10 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
 
 	bool rcomp = (inst & 1) ? true : false;
 	u32 cr = kvmppc_get_cr(vcpu);
-	struct thread_struct t;
 #ifdef DEBUG
 	int i;
 #endif
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	if (!kvmppc_inst_is_paired_single(vcpu, inst))
 		return EMULATE_FAIL;
 
@@ -695,7 +671,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
 #ifdef DEBUG
 	for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) {
 		u32 f;
-		cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t);
+		kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr);
 		dprintk(KERN_INFO "FPR[%d] = 0x%x / 0x%llx    QPR[%d] = 0x%x\n",
 			i, f, vcpu->arch.fpr[i], i, vcpu->arch.qpr[i]);
 	}
@@ -819,8 +795,9 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
 			WARN_ON(rcomp);
 			vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra];
 			/* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */
-			cvt_df((double*)&vcpu->arch.fpr[ax_rb],
-			       (float*)&vcpu->arch.qpr[ax_rd], &t);
+			kvm_cvt_df(&vcpu->arch.fpr[ax_rb],
+				   &vcpu->arch.qpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			break;
 		case OP_4X_PS_MERGE01:
 			WARN_ON(rcomp);
@@ -830,17 +807,20 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		case OP_4X_PS_MERGE10:
 			WARN_ON(rcomp);
 			/* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */
-			cvt_fd((float*)&vcpu->arch.qpr[ax_ra],
-			       (double*)&vcpu->arch.fpr[ax_rd], &t);
+			kvm_cvt_fd(&vcpu->arch.qpr[ax_ra],
+				   &vcpu->arch.fpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			/* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */
-			cvt_df((double*)&vcpu->arch.fpr[ax_rb],
-			       (float*)&vcpu->arch.qpr[ax_rd], &t);
+			kvm_cvt_df(&vcpu->arch.fpr[ax_rb],
+				   &vcpu->arch.qpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			break;
 		case OP_4X_PS_MERGE11:
 			WARN_ON(rcomp);
 			/* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */
-			cvt_fd((float*)&vcpu->arch.qpr[ax_ra],
-			       (double*)&vcpu->arch.fpr[ax_rd], &t);
+			kvm_cvt_fd(&vcpu->arch.qpr[ax_ra],
+				   &vcpu->arch.fpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb];
 			break;
 		}
@@ -1275,7 +1255,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
 #ifdef DEBUG
 	for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) {
 		u32 f;
-		cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t);
+		kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr);
 		dprintk(KERN_INFO "FPR[%d] = 0x%x\n", i, f);
 	}
 #endif
diff --git a/arch/powerpc/kvm/fpu.S b/arch/powerpc/kvm/fpu.S
index 2b340a3..cb34bbe 100644
--- a/arch/powerpc/kvm/fpu.S
+++ b/arch/powerpc/kvm/fpu.S
@@ -271,3 +271,21 @@ FPD_THREE_IN(fmsub)
 FPD_THREE_IN(fmadd)
 FPD_THREE_IN(fnmsub)
 FPD_THREE_IN(fnmadd)
+
+_GLOBAL(kvm_cvt_fd)
+	lfd	0,0(r5)			/* load up fpscr value */
+	MTFSF_L(0)
+	lfs	0,0(r3)
+	stfd	0,0(r4)
+	mffs	0
+	stfd	0,0(r5)			/* save new fpscr value */
+	blr
+
+_GLOBAL(kvm_cvt_df)
+	lfd	0,0(r5)			/* load up fpscr value */
+	MTFSF_L(0)
+	lfd	0,0(r3)
+	stfs	0,0(r4)
+	mffs	0
+	stfd	0,0(r5)			/* save new fpscr value */
+	blr
-- 
1.7.1


Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply related

* Re: [PATCH] drivers: remove all i2c_set_clientdata(client, NULL)
From: Dmitry Torokhov @ 2010-05-31 19:09 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Greg Kroah-Hartman, linuxppc-dev, linux-mtd, linux-i2c, devel,
	Samuel Ortiz, lm-sensors, linux-input, linux-media,
	Paul Gortmaker, Riku Voipio, rtc-linux, Alessandro Rubini,
	Mauro Carvalho Chehab, Jean Delvare,
	Ben Dooks (embedded platforms), Liam Girdwood, Alessandro Zummo,
	Guillaume Ligneul, George Joseph, Mark Brown, linux-kernel,
	Richard Purdie, Colin Leroy, David Woodhouse
In-Reply-To: <1275310552-14685-1-git-send-email-w.sang@pengutronix.de>

Hi Wolfram,

On Mon, May 31, 2010 at 02:55:48PM +0200, Wolfram Sang wrote:
> I2C-drivers can use the clientdata-pointer to point to private data. As I2C
> devices are not really unregistered, but merely detached from their driver, it
> used to be the drivers obligation to clear this pointer during remove() or a
> failed probe(). As a couple of drivers forgot to do this, it was agreed that it
> was cleaner if the i2c-core does this clearance when appropriate, as there is
> no guarantee for the lifetime of the clientdata-pointer after remove() anyhow.
> This feature was added to the core with commit
> e4a7b9b04de15f6b63da5ccdd373ffa3057a3681 to fix the faulty drivers.
> 
> As there is no need anymore to clear the clientdata-pointer, remove all current
> occurrences in the drivers to simplify the code and prevent confusion.
> 
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> Cc: Jean Delvare <khali@linux-fr.org>
> ---
> 
> Some more notes:
> 
> I waited for rc1 as I knew there were some drivers/patches coming along which
> needed to be processed, too.
> 
> I'd suggest that this goes via the i2c-tree, so we get rid of all occurences at
> once.
> 

Frankly I'd prefer taking input stuff through my tree with the goal of
.36 merge window just to minimize potential merge issues. This is a
simple cleanup patch that has no dependencies, so there is little gain
from doing it all in one go.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] powerpc: Don't export cvt_fd & _df when CONFIG_PPC_FPU is not set
From: Alexander Graf @ 2010-05-31 18:52 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev
In-Reply-To: <m2aargndy2.fsf@igel.home>

Andreas Schwab wrote:
> Alexander Graf <agraf@suse.de> writes:
>
>   
>> Mind to send it over so I can take a look at it :)? Getting rid of the
>> task_struct structs lying in the stack is certainly a good idea.
>>     
>
> Still untested, because rc1 does not boot.
>   

Normal guests work great with the patch and from a quick look over it,
it seems sane. I couldn't test the paired single implementation yet,
because my userspace app for that is in a flux right now.

Either way, thanks a lot for the patch. Mind to wrap it up and submit
it? I'll fix breakages later on. Please CC kvm-ppc@vger.kernel.org and
kvm@vger.kernel.org, so Avi or Marcelo can pick it up on the KVM tree.

Alex

^ permalink raw reply

* Re: [PATCH] powerpc: Don't export cvt_fd & _df when CONFIG_PPC_FPU is not set
From: Andreas Schwab @ 2010-05-31 18:06 UTC (permalink / raw)
  To: Alexander Graf; +Cc: linuxppc-dev
In-Reply-To: <4C03DB3D.7090007__38063.9078132392$1275321190$gmane$org@suse.de>

Alexander Graf <agraf@suse.de> writes:

> Mind to send it over so I can take a look at it :)? Getting rid of the
> task_struct structs lying in the stack is certainly a good idea.

Still untested, because rc1 does not boot.

Andreas.

---
 arch/powerpc/include/asm/kvm_fpu.h       |   29 +++++----
 arch/powerpc/kvm/book3s.c                |   49 ++++++++--------
 arch/powerpc/kvm/book3s_paired_singles.c |   94 ++++++++++++-------------------
 arch/powerpc/kvm/fpu.S                   |   18 +++++
 4 files changed, 98 insertions(+), 92 deletions(-)

--- linux-2.6.35-rc1.orig/arch/powerpc/include/asm/kvm_fpu.h
+++ linux-2.6.35-rc1/arch/powerpc/include/asm/kvm_fpu.h
@@ -22,24 +22,24 @@
 
 #include <linux/types.h>
 
-extern void fps_fres(struct thread_struct *t, u32 *dst, u32 *src1);
-extern void fps_frsqrte(struct thread_struct *t, u32 *dst, u32 *src1);
-extern void fps_fsqrts(struct thread_struct *t, u32 *dst, u32 *src1);
-
-extern void fps_fadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
-extern void fps_fdivs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
-extern void fps_fmuls(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
-extern void fps_fsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fres(u64 *fpscr, u32 *dst, u32 *src1);
+extern void fps_frsqrte(u64 *fpscr, u32 *dst, u32 *src1);
+extern void fps_fsqrts(u64 *fpscr, u32 *dst, u32 *src1);
+
+extern void fps_fadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fdivs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fmuls(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
+extern void fps_fsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2);
 
-extern void fps_fmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fmadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		       u32 *src3);
-extern void fps_fmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fmsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		       u32 *src3);
-extern void fps_fnmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fnmadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		        u32 *src3);
-extern void fps_fnmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fnmsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		        u32 *src3);
-extern void fps_fsel(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2,
+extern void fps_fsel(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2,
 		     u32 *src3);
 
 #define FPD_ONE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \
@@ -82,4 +82,7 @@ FPD_THREE_IN(fmadd)
 FPD_THREE_IN(fnmsub)
 FPD_THREE_IN(fnmadd)
 
+extern void kvm_cvt_fd(u32 *from, u64 *to, u64 *fpscr);
+extern void kvm_cvt_df(u64 *from, u32 *to, u64 *fpscr);
+
 #endif
--- linux-2.6.35-rc1.orig/arch/powerpc/kvm/book3s.c
+++ linux-2.6.35-rc1/arch/powerpc/kvm/book3s.c
@@ -1309,12 +1309,17 @@ extern int __kvmppc_vcpu_entry(struct kv
 int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
 	int ret;
-	struct thread_struct ext_bkp;
+	double fpr[32][TS_FPRWIDTH];
+	unsigned int fpscr;
+	int fpexc_mode;
 #ifdef CONFIG_ALTIVEC
-	bool save_vec = current->thread.used_vr;
+	vector128 vr[32];
+	vector128 vscr;
+	unsigned long uninitialized_var(vrsave);
+	int used_vr;
 #endif
 #ifdef CONFIG_VSX
-	bool save_vsx = current->thread.used_vsr;
+	int used_vsr;
 #endif
 	ulong ext_msr;
 
@@ -1327,27 +1332,27 @@ int __kvmppc_vcpu_run(struct kvm_run *kv
 	/* Save FPU state in stack */
 	if (current->thread.regs->msr & MSR_FP)
 		giveup_fpu(current);
-	memcpy(ext_bkp.fpr, current->thread.fpr, sizeof(current->thread.fpr));
-	ext_bkp.fpscr = current->thread.fpscr;
-	ext_bkp.fpexc_mode = current->thread.fpexc_mode;
+	memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr));
+	fpscr = current->thread.fpscr.val;
+	fpexc_mode = current->thread.fpexc_mode;
 
 #ifdef CONFIG_ALTIVEC
 	/* Save Altivec state in stack */
-	if (save_vec) {
+	used_vr = current->thread.used_vr;
+	if (used_vr) {
 		if (current->thread.regs->msr & MSR_VEC)
 			giveup_altivec(current);
-		memcpy(ext_bkp.vr, current->thread.vr, sizeof(ext_bkp.vr));
-		ext_bkp.vscr = current->thread.vscr;
-		ext_bkp.vrsave = current->thread.vrsave;
+		memcpy(vr, current->thread.vr, sizeof(current->thread.vr));
+		vscr = current->thread.vscr;
+		vrsave = current->thread.vrsave;
 	}
-	ext_bkp.used_vr = current->thread.used_vr;
 #endif
 
 #ifdef CONFIG_VSX
 	/* Save VSX state in stack */
-	if (save_vsx && (current->thread.regs->msr & MSR_VSX))
+	used_vsr = current->thread.used_vsr;
+	if (used_vsr && (current->thread.regs->msr & MSR_VSX))
 			__giveup_vsx(current);
-	ext_bkp.used_vsr = current->thread.used_vsr;
 #endif
 
 	/* Remember the MSR with disabled extensions */
@@ -1372,22 +1377,22 @@ int __kvmppc_vcpu_run(struct kvm_run *kv
 	kvmppc_giveup_ext(vcpu, MSR_VSX);
 
 	/* Restore FPU state from stack */
-	memcpy(current->thread.fpr, ext_bkp.fpr, sizeof(ext_bkp.fpr));
-	current->thread.fpscr = ext_bkp.fpscr;
-	current->thread.fpexc_mode = ext_bkp.fpexc_mode;
+	memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr));
+	current->thread.fpscr.val = fpscr;
+	current->thread.fpexc_mode = fpexc_mode;
 
 #ifdef CONFIG_ALTIVEC
 	/* Restore Altivec state from stack */
-	if (save_vec && current->thread.used_vr) {
-		memcpy(current->thread.vr, ext_bkp.vr, sizeof(ext_bkp.vr));
-		current->thread.vscr = ext_bkp.vscr;
-		current->thread.vrsave= ext_bkp.vrsave;
+	if (used_vr && current->thread.used_vr) {
+		memcpy(current->thread.vr, vr, sizeof(current->thread.vr));
+		current->thread.vscr = vscr;
+		current->thread.vrsave = vrsave;
 	}
-	current->thread.used_vr = ext_bkp.used_vr;
+	current->thread.used_vr = used_vr;
 #endif
 
 #ifdef CONFIG_VSX
-	current->thread.used_vsr = ext_bkp.used_vsr;
+	current->thread.used_vsr = used_vsr;
 #endif
 
 	return ret;
--- linux-2.6.35-rc1.orig/arch/powerpc/kvm/book3s_paired_singles.c
+++ linux-2.6.35-rc1/arch/powerpc/kvm/book3s_paired_singles.c
@@ -159,10 +159,7 @@
 
 static inline void kvmppc_sync_qpr(struct kvm_vcpu *vcpu, int rt)
 {
-	struct thread_struct t;
-
-	t.fpscr.val = vcpu->arch.fpscr;
-	cvt_df((double*)&vcpu->arch.fpr[rt], (float*)&vcpu->arch.qpr[rt], &t);
+	kvm_cvt_df(&vcpu->arch.fpr[rt], &vcpu->arch.qpr[rt], &vcpu->arch.fpscr);
 }
 
 static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store)
@@ -183,7 +180,6 @@ static int kvmppc_emulate_fpr_load(struc
 				   int rs, ulong addr, int ls_type)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	char tmp[8];
 	int len = sizeof(u32);
@@ -191,8 +187,6 @@ static int kvmppc_emulate_fpr_load(struc
 	if (ls_type == FPU_LS_DOUBLE)
 		len = sizeof(u64);
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	/* read from memory */
 	r = kvmppc_ld(vcpu, &addr, len, tmp, true);
 	vcpu->arch.paddr_accessed = addr;
@@ -210,7 +204,7 @@ static int kvmppc_emulate_fpr_load(struc
 	/* put in registers */
 	switch (ls_type) {
 	case FPU_LS_SINGLE:
-		cvt_fd((float*)tmp, (double*)&vcpu->arch.fpr[rs], &t);
+		kvm_cvt_fd((u32*)tmp, &vcpu->arch.fpr[rs], &vcpu->arch.fpscr);
 		vcpu->arch.qpr[rs] = *((u32*)tmp);
 		break;
 	case FPU_LS_DOUBLE:
@@ -229,17 +223,14 @@ static int kvmppc_emulate_fpr_store(stru
 				    int rs, ulong addr, int ls_type)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	char tmp[8];
 	u64 val;
 	int len;
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	switch (ls_type) {
 	case FPU_LS_SINGLE:
-		cvt_df((double*)&vcpu->arch.fpr[rs], (float*)tmp, &t);
+		kvm_cvt_df(&vcpu->arch.fpr[rs], (u32*)tmp, &vcpu->arch.fpscr);
 		val = *((u32*)tmp);
 		len = sizeof(u32);
 		break;
@@ -278,13 +269,10 @@ static int kvmppc_emulate_psq_load(struc
 				   int rs, ulong addr, bool w, int i)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	float one = 1.0;
 	u32 tmp[2];
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	/* read from memory */
 	if (w) {
 		r = kvmppc_ld(vcpu, &addr, sizeof(u32), tmp, true);
@@ -308,7 +296,7 @@ static int kvmppc_emulate_psq_load(struc
 	emulated = EMULATE_DONE;
 
 	/* put in registers */
-	cvt_fd((float*)&tmp[0], (double*)&vcpu->arch.fpr[rs], &t);
+	kvm_cvt_fd(&tmp[0], &vcpu->arch.fpr[rs], &vcpu->arch.fpscr);
 	vcpu->arch.qpr[rs] = tmp[1];
 
 	dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0],
@@ -322,14 +310,11 @@ static int kvmppc_emulate_psq_store(stru
 				    int rs, ulong addr, bool w, int i)
 {
 	int emulated = EMULATE_FAIL;
-	struct thread_struct t;
 	int r;
 	u32 tmp[2];
 	int len = w ? sizeof(u32) : sizeof(u64);
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
-	cvt_df((double*)&vcpu->arch.fpr[rs], (float*)&tmp[0], &t);
+	kvm_cvt_df(&vcpu->arch.fpr[rs], &tmp[0], &vcpu->arch.fpscr);
 	tmp[1] = vcpu->arch.qpr[rs];
 
 	r = kvmppc_st(vcpu, &addr, len, tmp, true);
@@ -517,7 +502,7 @@ static int get_d_signext(u32 inst)
 static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
 				      int reg_out, int reg_in1, int reg_in2,
 				      int reg_in3, int scalar,
-				      void (*func)(struct thread_struct *t,
+				      void (*func)(u64 *fpscr,
 						 u32 *dst, u32 *src1,
 						 u32 *src2, u32 *src3))
 {
@@ -526,27 +511,25 @@ static int kvmppc_ps_three_in(struct kvm
 	u32 ps0_out;
 	u32 ps0_in1, ps0_in2, ps0_in3;
 	u32 ps1_in1, ps1_in2, ps1_in3;
-	struct thread_struct t;
-	t.fpscr.val = vcpu->arch.fpscr;
 
 	/* RC */
 	WARN_ON(rc);
 
 	/* PS0 */
-	cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t);
-	cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t);
-	cvt_df((double*)&fpr[reg_in3], (float*)&ps0_in3, &t);
+	kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr);
+	kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr);
+	kvm_cvt_df(&fpr[reg_in3], &ps0_in3, &vcpu->arch.fpscr);
 
 	if (scalar & SCALAR_LOW)
 		ps0_in2 = qpr[reg_in2];
 
-	func(&t, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3);
+	func(&vcpu->arch.fpscr, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3);
 
 	dprintk(KERN_INFO "PS3 ps0 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n",
 			  ps0_in1, ps0_in2, ps0_in3, ps0_out);
 
 	if (!(scalar & SCALAR_NO_PS0))
-		cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t);
+		kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
 
 	/* PS1 */
 	ps1_in1 = qpr[reg_in1];
@@ -557,7 +540,7 @@ static int kvmppc_ps_three_in(struct kvm
 		ps1_in2 = ps0_in2;
 
 	if (!(scalar & SCALAR_NO_PS1))
-		func(&t, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3);
+		func(&vcpu->arch.fpscr, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3);
 
 	dprintk(KERN_INFO "PS3 ps1 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n",
 			  ps1_in1, ps1_in2, ps1_in3, qpr[reg_out]);
@@ -568,7 +551,7 @@ static int kvmppc_ps_three_in(struct kvm
 static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc,
 				    int reg_out, int reg_in1, int reg_in2,
 				    int scalar,
-				    void (*func)(struct thread_struct *t,
+				    void (*func)(u64 *fpscr,
 						 u32 *dst, u32 *src1,
 						 u32 *src2))
 {
@@ -578,27 +561,25 @@ static int kvmppc_ps_two_in(struct kvm_v
 	u32 ps0_in1, ps0_in2;
 	u32 ps1_out;
 	u32 ps1_in1, ps1_in2;
-	struct thread_struct t;
-	t.fpscr.val = vcpu->arch.fpscr;
 
 	/* RC */
 	WARN_ON(rc);
 
 	/* PS0 */
-	cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t);
+	kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr);
 
 	if (scalar & SCALAR_LOW)
 		ps0_in2 = qpr[reg_in2];
 	else
-		cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t);
+		kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr);
 
-	func(&t, &ps0_out, &ps0_in1, &ps0_in2);
+	func(&vcpu->arch.fpscr, &ps0_out, &ps0_in1, &ps0_in2);
 
 	if (!(scalar & SCALAR_NO_PS0)) {
 		dprintk(KERN_INFO "PS2 ps0 -> f(0x%x, 0x%x) = 0x%x\n",
 				  ps0_in1, ps0_in2, ps0_out);
 
-		cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t);
+		kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
 	}
 
 	/* PS1 */
@@ -608,7 +589,7 @@ static int kvmppc_ps_two_in(struct kvm_v
 	if (scalar & SCALAR_HIGH)
 		ps1_in2 = ps0_in2;
 
-	func(&t, &ps1_out, &ps1_in1, &ps1_in2);
+	func(&vcpu->arch.fpscr, &ps1_out, &ps1_in1, &ps1_in2);
 
 	if (!(scalar & SCALAR_NO_PS1)) {
 		qpr[reg_out] = ps1_out;
@@ -622,31 +603,29 @@ static int kvmppc_ps_two_in(struct kvm_v
 
 static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc,
 				    int reg_out, int reg_in,
-				    void (*func)(struct thread_struct *t,
+				    void (*func)(u64 *t,
 						 u32 *dst, u32 *src1))
 {
 	u32 *qpr = vcpu->arch.qpr;
 	u64 *fpr = vcpu->arch.fpr;
 	u32 ps0_out, ps0_in;
 	u32 ps1_in;
-	struct thread_struct t;
-	t.fpscr.val = vcpu->arch.fpscr;
 
 	/* RC */
 	WARN_ON(rc);
 
 	/* PS0 */
-	cvt_df((double*)&fpr[reg_in], (float*)&ps0_in, &t);
-	func(&t, &ps0_out, &ps0_in);
+	kvm_cvt_df(&fpr[reg_in], &ps0_in, &vcpu->arch.fpscr);
+	func(&vcpu->arch.fpscr, &ps0_out, &ps0_in);
 
 	dprintk(KERN_INFO "PS1 ps0 -> f(0x%x) = 0x%x\n",
 			  ps0_in, ps0_out);
 
-	cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t);
+	kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr);
 
 	/* PS1 */
 	ps1_in = qpr[reg_in];
-	func(&t, &qpr[reg_out], &ps1_in);
+	func(&vcpu->arch.fpscr, &qpr[reg_out], &ps1_in);
 
 	dprintk(KERN_INFO "PS1 ps1 -> f(0x%x) = 0x%x\n",
 			  ps1_in, qpr[reg_out]);
@@ -672,13 +651,10 @@ int kvmppc_emulate_paired_single(struct
 
 	bool rcomp = (inst & 1) ? true : false;
 	u32 cr = kvmppc_get_cr(vcpu);
-	struct thread_struct t;
 #ifdef DEBUG
 	int i;
 #endif
 
-	t.fpscr.val = vcpu->arch.fpscr;
-
 	if (!kvmppc_inst_is_paired_single(vcpu, inst))
 		return EMULATE_FAIL;
 
@@ -695,7 +671,7 @@ int kvmppc_emulate_paired_single(struct
 #ifdef DEBUG
 	for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) {
 		u32 f;
-		cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t);
+		kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr);
 		dprintk(KERN_INFO "FPR[%d] = 0x%x / 0x%llx    QPR[%d] = 0x%x\n",
 			i, f, vcpu->arch.fpr[i], i, vcpu->arch.qpr[i]);
 	}
@@ -819,8 +795,9 @@ int kvmppc_emulate_paired_single(struct
 			WARN_ON(rcomp);
 			vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra];
 			/* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */
-			cvt_df((double*)&vcpu->arch.fpr[ax_rb],
-			       (float*)&vcpu->arch.qpr[ax_rd], &t);
+			kvm_cvt_df(&vcpu->arch.fpr[ax_rb],
+				   &vcpu->arch.qpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			break;
 		case OP_4X_PS_MERGE01:
 			WARN_ON(rcomp);
@@ -830,17 +807,20 @@ int kvmppc_emulate_paired_single(struct
 		case OP_4X_PS_MERGE10:
 			WARN_ON(rcomp);
 			/* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */
-			cvt_fd((float*)&vcpu->arch.qpr[ax_ra],
-			       (double*)&vcpu->arch.fpr[ax_rd], &t);
+			kvm_cvt_fd(&vcpu->arch.qpr[ax_ra],
+				   &vcpu->arch.fpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			/* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */
-			cvt_df((double*)&vcpu->arch.fpr[ax_rb],
-			       (float*)&vcpu->arch.qpr[ax_rd], &t);
+			kvm_cvt_df(&vcpu->arch.fpr[ax_rb],
+				   &vcpu->arch.qpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			break;
 		case OP_4X_PS_MERGE11:
 			WARN_ON(rcomp);
 			/* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */
-			cvt_fd((float*)&vcpu->arch.qpr[ax_ra],
-			       (double*)&vcpu->arch.fpr[ax_rd], &t);
+			kvm_cvt_fd(&vcpu->arch.qpr[ax_ra],
+				   &vcpu->arch.fpr[ax_rd],
+				   &vcpu->arch.fpscr);
 			vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb];
 			break;
 		}
@@ -1275,7 +1255,7 @@ int kvmppc_emulate_paired_single(struct
 #ifdef DEBUG
 	for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) {
 		u32 f;
-		cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t);
+		kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr);
 		dprintk(KERN_INFO "FPR[%d] = 0x%x\n", i, f);
 	}
 #endif
--- linux-2.6.35-rc1.orig/arch/powerpc/kvm/fpu.S
+++ linux-2.6.35-rc1/arch/powerpc/kvm/fpu.S
@@ -271,3 +271,21 @@ FPD_THREE_IN(fmsub)
 FPD_THREE_IN(fmadd)
 FPD_THREE_IN(fnmsub)
 FPD_THREE_IN(fnmadd)
+
+_GLOBAL(kvm_cvt_fd)
+	lfd	0,0(r5)			/* load up fpscr value */
+	MTFSF_L(0)
+	lfs	0,0(r3)
+	stfd	0,0(r4)
+	mffs	0
+	stfd	0,0(r5)			/* save new fpscr value */
+	blr
+
+_GLOBAL(kvm_cvt_df)
+	lfd	0,0(r5)			/* load up fpscr value */
+	MTFSF_L(0)
+	lfd	0,0(r3)
+	stfs	0,0(r4)
+	mffs	0
+	stfd	0,0(r5)			/* save new fpscr value */
+	blr

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* Re: [PATCH] drivers: remove all i2c_set_clientdata(client, NULL)
From: Greg KH @ 2010-05-31 16:54 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Dmitry Torokhov, linuxppc-dev, linux-mtd, linux-i2c, devel,
	Samuel Ortiz, lm-sensors, linux-input, linux-media,
	Paul Gortmaker, Riku Voipio, rtc-linux, Alessandro Rubini,
	Mauro Carvalho Chehab, Jean Delvare,
	Ben Dooks (embedded platforms), Liam Girdwood, Alessandro Zummo,
	Guillaume Ligneul, George Joseph, Mark Brown, linux-kernel,
	Richard Purdie, Colin Leroy, David Woodhouse
In-Reply-To: <1275310552-14685-1-git-send-email-w.sang@pengutronix.de>

On Mon, May 31, 2010 at 02:55:48PM +0200, Wolfram Sang wrote:
> I2C-drivers can use the clientdata-pointer to point to private data. As I2C
> devices are not really unregistered, but merely detached from their driver, it
> used to be the drivers obligation to clear this pointer during remove() or a
> failed probe(). As a couple of drivers forgot to do this, it was agreed that it
> was cleaner if the i2c-core does this clearance when appropriate, as there is
> no guarantee for the lifetime of the clientdata-pointer after remove() anyhow.
> This feature was added to the core with commit
> e4a7b9b04de15f6b63da5ccdd373ffa3057a3681 to fix the faulty drivers.
> 
> As there is no need anymore to clear the clientdata-pointer, remove all current
> occurrences in the drivers to simplify the code and prevent confusion.
> 
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> Cc: Jean Delvare <khali@linux-fr.org>

Acked-by: Greg Kroah-Hartman <gregkh@suse.de>

^ permalink raw reply

* Re: [PATCH] powerpc: Don't export cvt_fd & _df when CONFIG_PPC_FPU is not set
From: Alexander Graf @ 2010-05-31 15:52 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev
In-Reply-To: <m3ljb0tn2l.fsf@hase.home>

Andreas Schwab wrote:
> Alexander Graf <agraf@suse.de> writes:
>
>   
>> On 31.05.2010, at 04:00, Benjamin Herrenschmidt wrote:
>>
>>     
>>> On Mon, 2010-05-31 at 11:50 +1000, Benjamin Herrenschmidt wrote:
>>>       
>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>> ---
>>>> arch/powerpc/kernel/ppc_ksyms.c |    2 +-
>>>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>>>         
>>> Alex, this is just a temporary fix to remove the build breakage for 40x
>>> etc... but please, update KVM to just build-in its own.
>>>       
>> What's the bad part in reusing the existing code?
>>     
>
> The bad part is that KVM is wasting a ridiculous amount of stack space
> by allocating multiple instances of struct task_struct on it.  I have a
> patch removing all of it, but I haven't tested it yet.
>   

Mind to send it over so I can take a look at it :)? Getting rid of the
task_struct structs lying in the stack is certainly a good idea.

Alex

^ permalink raw reply


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