LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4] powerpc/kvm: support to handle sw breakpoint
From: Madhavan Srinivasan @ 2014-08-20  5:52 UTC (permalink / raw)
  To: agraf, benh, paulus, mpe; +Cc: Madhavan Srinivasan, linuxppc-dev, kvm-ppc, kvm

This patch adds kernel side support for software breakpoint.
Design is that, by using an illegal instruction, we trap to hypervisor
via Emulation Assistance interrupt, where we check for the illegal instruction
and accordingly we return to Host or Guest. Patch also adds support for
software breakpoint in PR KVM.

Changes v3->v4:
 Made changes to code comments and removed #define of zero opcode
 Added a new function to handle the debug instruction emulation in book3s_hv
 Rebased the code to latest upstream source.

Changes v2->v3:
 Changed the debug instructions. Using the all zero opcode in the instruction word
  as illegal instruction as mentioned in Power ISA instead of ABS
 Removed reg updated in emulation assist and added a call to
  kvmppc_emulate_instruction for reg update.

Changes v1->v2:

 Moved the debug instruction #def to kvm_book3s.h. This way PR_KVM can also share it.
 Added code to use KVM get one reg infrastructure to get debug opcode.
 Updated emulate.c to include emulation of debug instruction incase of PR_KVM.
 Made changes to commit message.

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_book3s.h |  7 +++++++
 arch/powerpc/kvm/book3s.c             |  3 ++-
 arch/powerpc/kvm/book3s_hv.c          | 32 ++++++++++++++++++++++++++++++--
 arch/powerpc/kvm/book3s_pr.c          |  3 +++
 arch/powerpc/kvm/emulate.c            | 11 +++++++++++
 5 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 6acf0c2..a1944f8 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -24,6 +24,13 @@
 #include <linux/kvm_host.h>
 #include <asm/kvm_book3s_asm.h>
 
+/*
+ * KVMPPC_INST_BOOK3S_DEBUG is debug Instruction for supporting Software Breakpoint.
+ * Based on PowerISA v2.07, Instruction with primary opcode 0 will be treated as illegal
+ * instruction.
+ */
+#define KVMPPC_INST_BOOK3S_DEBUG	0x00dddd00
+
 struct kvmppc_bat {
 	u64 raw;
 	u32 bepi;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index dd03f6b..00e9c9f 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -778,7 +778,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 					struct kvm_guest_debug *dbg)
 {
-	return -EINVAL;
+	vcpu->guest_debug = dbg->control;
+	return 0;
 }
 
 void kvmppc_decrementer_func(unsigned long data)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 27cced9..0a92e45 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -725,6 +725,14 @@ static int kvmppc_hcall_impl_hv(unsigned long cmd)
 	return kvmppc_hcall_impl_hv_realmode(cmd);
 }
 
+static int kvmppc_emulate_debug_instruction_hv(struct kvm_run *run,
+					struct kvm_vcpu *vcpu)
+{
+	run->exit_reason = KVM_EXIT_DEBUG;
+	run->debug.arch.address = kvmppc_get_pc(vcpu);
+	return 0;
+}
+
 static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
 				 struct task_struct *tsk)
 {
@@ -811,9 +819,26 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	 * we don't emulate any guest instructions at this stage.
 	 */
 	case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
-		kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
-		r = RESUME_GUEST;
+	{
+		u32 last_inst;
+		if(kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst) !=
+					EMULATE_DONE) {
+			/*
+			 * Fetch failed, so return to guest and
+			 * try executing it again.
+			 */
+			r = RESUME_GUEST;
+		} else {
+			if (last_inst == KVMPPC_INST_BOOK3S_DEBUG) {
+				kvmppc_emulate_debug_instruction_hv(run, vcpu);
+				r = RESUME_HOST;
+			} else {
+				kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
+				r = RESUME_GUEST;
+			}
+		}
 		break;
+	}
 	/*
 	 * This occurs if the guest (kernel or userspace), does something that
 	 * is prohibited by HFSCR.  We just generate a program interrupt to
@@ -922,6 +947,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
 	long int i;
 
 	switch (id) {
+	case KVM_REG_PPC_DEBUG_INST:
+		*val = get_reg_val(id, KVMPPC_INST_BOOK3S_DEBUG);
+		break;
 	case KVM_REG_PPC_HIOR:
 		*val = get_reg_val(id, 0);
 		break;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index faffb27..cd2a39d 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1319,6 +1319,9 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id,
 	int r = 0;
 
 	switch (id) {
+	case KVM_REG_PPC_DEBUG_INST:
+		*val = get_reg_val(id, KVMPPC_INST_BOOK3S_DEBUG);
+		break;
 	case KVM_REG_PPC_HIOR:
 		*val = get_reg_val(id, to_book3s(vcpu)->hior);
 		break;
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index e96b50d..68f38b2 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -274,6 +274,17 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		}
 		break;
 
+	case 0:
+		/*
+		 * Instruction with primary opcode 0. Based on PowerISA
+		 * these are illegal instructions.
+		 */
+		run->exit_reason = KVM_EXIT_DEBUG;
+		run->debug.arch.address = kvmppc_get_pc(vcpu);
+		emulated = EMULATE_EXIT_USER;
+		advance = 0;
+		break;
+
 	default:
 		emulated = EMULATE_FAIL;
 	}
-- 
1.7.11.4

^ permalink raw reply related

* Re: [PATCH V7 04/17] PCI: Take additional IOV BAR alignment in sizing and assigning
From: Wei Yang @ 2014-08-20  6:14 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Wei Yang, benh, linux-pci, gwshan, yan, qiudayu, linuxppc-dev
In-Reply-To: <20140820030841.GD6295@google.com>

On Tue, Aug 19, 2014 at 09:08:41PM -0600, Bjorn Helgaas wrote:
>On Thu, Jul 24, 2014 at 02:22:14PM +0800, Wei Yang wrote:
>> At resource sizing/assigning stage, resources are divided into two lists,
>> requested list and additional list, while the alignement of the additional
>> IOV BAR is not taken into the sizeing and assigning procedure.
>> 
>> This is reasonable in the original implementation, since IOV BAR's alignment is
>> mostly the size of a PF BAR alignemt. This means the alignment is already taken
>> into consideration. While this rule may be violated on some platform.
>> 
>> This patch take the additional IOV BAR alignment in sizing and assigning stage
>> explicitly.
>> 
>> Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
>> ---
>>  drivers/pci/setup-bus.c |   68 +++++++++++++++++++++++++++++++++++++++++------
>>  1 file changed, 60 insertions(+), 8 deletions(-)
>> 
>> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
>> index a5a63ec..d83681f 100644
>> --- a/drivers/pci/setup-bus.c
>> +++ b/drivers/pci/setup-bus.c
>> @@ -120,6 +120,28 @@ static resource_size_t get_res_add_size(struct list_head *head,
>>  	return 0;
>>  }
>>  
>> +static resource_size_t get_res_add_align(struct list_head *head,
>> +		struct resource *res)
>> +{
>> +	struct pci_dev_resource *dev_res;
>> +
>> +	list_for_each_entry(dev_res, head, list) {
>> +		if (dev_res->res == res) {
>> +			int idx = res - &dev_res->dev->resource[0];
>> +
>> +			dev_printk(KERN_DEBUG, &dev_res->dev->dev,
>> +				   "res[%d]=%pR get_res_add_align min_align %llx\n",
>> +				   idx, dev_res->res,
>> +				   (unsigned long long)dev_res->min_align);
>> +
>> +			return dev_res->min_align;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>
>I see that you copied the structure of the existing get_res_add_size()
>here.  But I don't understand *that* function.  It looks basically like
>this:
>
>  resource_size_t get_res_add_size(list, res)
>  {
>    list_for_each_entry(dev_res, head, list) {
>      if (dev_res->res == res)
>        return dev_res->add_size;
>    }
>    return 0;
>  }
>
>and we call it like this:
>
>  dev_res->res->end += get_res_add_size(realloc_head, dev_res->res);
>
>So we start out with dev_res", pass in dev_res->res, search the
>realloc_head list to find dev_res again, and return dev_res->add_size.
>That looks equivalent to just:
>
>  dev_res->res->end += dev_res->add_size;
>
>It looks like get_res_add_size() merely adds a printk and some complexity.
>Am I missing something?
>

Let me try to explain it, if not correct, please let know :-)

  dev_res->res->end += get_res_add_size(realloc_head, dev_res->res);

would be expanded to:

  dev_res->res->end += dev_res_1->add_size;

with the dev_res_1 is another one from dev_res which is stored in realloc_head.

>I do see that there are other callers where we don't actually start with
>dev_res, which makes it a little more complicated.  But I think you should
>either add something like this:
>
>  struct pci_dev_resource *res_to_dev_res(list, res)
>  {
>    list_for_each_entry(dev_res, head, list) {
>      if (dev_res->res == res)
>        return dev_res;
>    }
>    return NULL;
>  }
>

Ok, we can extract the common part of these two functions.

>which can be used to replace get_res_add_size() and get_res_add_align(), OR
>figure out whether the dev_res of interest is always one we've just added.
>If it is, maybe you can just make add_to_list() return the dev_res pointer
>instead of an errno, and hang onto the pointer.  I'd like that much better
>if that's possible.
>

Sorry, I don't get this point.

add_to_list() is used to create the pci_dev_resource list, get_res_add_size()
and get_res_add_align() is to retrieve the information in the list. I am not
sure how to leverage add_to_list() in these two functions?

>> +
>> +
>>  /* Sort resources by alignment */
>>  static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
>>  {
>> @@ -368,8 +390,9 @@ static void __assign_resources_sorted(struct list_head *head,
>>  	LIST_HEAD(save_head);
>>  	LIST_HEAD(local_fail_head);
>>  	struct pci_dev_resource *save_res;
>> -	struct pci_dev_resource *dev_res, *tmp_res;
>> +	struct pci_dev_resource *dev_res, *tmp_res, *dev_res2;
>>  	unsigned long fail_type;
>> +	resource_size_t add_align, align;
>>  
>>  	/* Check if optional add_size is there */
>>  	if (!realloc_head || list_empty(realloc_head))
>> @@ -384,10 +407,31 @@ static void __assign_resources_sorted(struct list_head *head,
>>  	}
>>  
>>  	/* Update res in head list with add_size in realloc_head list */
>> -	list_for_each_entry(dev_res, head, list)
>> +	list_for_each_entry_safe(dev_res, tmp_res, head, list) {
>>  		dev_res->res->end += get_res_add_size(realloc_head,
>>  							dev_res->res);
>>  
>> +		if (!(dev_res->res->flags & IORESOURCE_STARTALIGN))
>> +			continue;
>> +
>> +		add_align = get_res_add_align(realloc_head, dev_res->res);
>> +
>> +		if (add_align > dev_res->res->start) {
>> +			dev_res->res->start = add_align;
>> +			dev_res->res->end = add_align +
>> +				            resource_size(dev_res->res);
>> +
>> +			list_for_each_entry(dev_res2, head, list) {
>> +				align = pci_resource_alignment(dev_res2->dev,
>> +							       dev_res2->res);
>> +				if (add_align > align)
>> +					list_move_tail(&dev_res->list,
>> +						       &dev_res2->list);
>> +			}
>> +               }
>> +
>> +	}
>> +
>>  	/* Try updated head list with add_size added */
>>  	assign_requested_resources_sorted(head, &local_fail_head);
>>  
>> @@ -930,6 +974,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
>>  	struct resource *b_res = find_free_bus_resource(bus,
>>  					mask | IORESOURCE_PREFETCH, type);
>>  	resource_size_t children_add_size = 0;
>> +	resource_size_t children_add_align = 0;
>> +	resource_size_t add_align = 0;
>>  
>>  	if (!b_res)
>>  		return -ENOSPC;
>> @@ -954,6 +1000,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
>>  			/* put SRIOV requested res to the optional list */
>>  			if (realloc_head && i >= PCI_IOV_RESOURCES &&
>>  					i <= PCI_IOV_RESOURCE_END) {
>> +				add_align = max(pci_resource_alignment(dev, r), add_align);
>>  				r->end = r->start - 1;
>>  				add_to_list(realloc_head, dev, r, r_size, 0/* don't care */);
>>  				children_add_size += r_size;
>> @@ -984,8 +1031,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
>>  			if (order > max_order)
>>  				max_order = order;
>>  
>> -			if (realloc_head)
>> +			if (realloc_head) {
>>  				children_add_size += get_res_add_size(realloc_head, r);
>> +				children_add_align = get_res_add_align(realloc_head, r);
>> +				add_align = max(add_align, children_add_align);
>> +			}
>>  		}
>>  	}
>>  
>> @@ -996,7 +1046,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
>>  		add_size = children_add_size;
>>  	size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
>>  		calculate_memsize(size, min_size, add_size,
>> -				resource_size(b_res), min_align);
>> +				resource_size(b_res), max(min_align, add_align));
>>  	if (!size0 && !size1) {
>>  		if (b_res->start || b_res->end)
>>  			dev_info(&bus->self->dev, "disabling bridge window %pR to %pR (unused)\n",
>> @@ -1008,10 +1058,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
>>  	b_res->end = size0 + min_align - 1;
>>  	b_res->flags |= IORESOURCE_STARTALIGN;
>>  	if (size1 > size0 && realloc_head) {
>> -		add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
>> -		dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window %pR to %pR add_size %llx\n",
>> -			   b_res, &bus->busn_res,
>> -			   (unsigned long long)size1-size0);
>> +		add_to_list(realloc_head, bus->self, b_res, size1-size0,
>> +				max(min_align, add_align));
>> +		dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
>> +				 "%pR to %pR add_size %llx add_align %llx\n", b_res,
>> +				 &bus->busn_res, (unsigned long long)size1-size0,
>> +				 max(min_align, add_align));
>
>Factor out this "max(min_align, add_align)" thing so we don't have to
>change these lines.  Bonus points if you can also factor it out of the
>calculate_memsize() call above.  That one is a pretty complicated ternary
>expression that should probably be turned into an "if" instead anyway.
>

Ok, I get your point. Let me make it more easy to read.

>>  	}
>>  	return 0;
>>  }
>> -- 
>> 1.7.9.5
>> 

-- 
Richard Yang
Help you, Help me

^ permalink raw reply

* Re: [RFC PATCH] powerpc: Make SPU_FS depend on SPARSEMEM
From: Geert Uytterhoeven @ 2014-08-20  7:49 UTC (permalink / raw)
  To: Pranith Kumar
  Cc: open list:CELL BROADBAND EN..., Arnd Bergmann, open list,
	Paul Mackerras, open list:CELL BROADBAND EN...
In-Reply-To: <1408483010-32689-1-git-send-email-bobby.prani@gmail.com>

Hi Pranith,

On Tue, Aug 19, 2014 at 11:16 PM, Pranith Kumar <bobby.prani@gmail.com> wrote:
> SPU_FS unconditionally enables MEMORY_HOTPLUG, which will fail to build if
> SPARSEMEM=n.
>
> Make SPU_FS depend on SPARSEMEM so that hotplug-memory.c does not fail to
> compile.
>
> Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
> ---
>  arch/powerpc/platforms/cell/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
> index 9978f59..832872e 100644
> --- a/arch/powerpc/platforms/cell/Kconfig
> +++ b/arch/powerpc/platforms/cell/Kconfig
> @@ -60,7 +60,7 @@ menu "Cell Broadband Engine options"
>  config SPU_FS
>         tristate "SPU file system"
>         default m
> -       depends on PPC_CELL
> +       depends on PPC_CELL && SPARSEMEM
>         select SPU_BASE
>         select MEMORY_HOTPLUG
>         help
> --
> 1.9.1

Is this a randconfig kernel?

config ARCH_SPARSEMEM_DEFAULT
       def_bool y
       depends on (SMP && PPC_PSERIES) || PPC_PS3

Why is this not enabled? !SMP? !PPC_PSERIES? !PPC_PS3?

If PPC_CELL is enabled, this issue was introduced by

commit 78bde53e351bc89cff85d1c2c7e6d7c2ffdf120d
Author: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date:   Tue Feb 13 11:46:06 2007 +1100

    [POWERPC] spufs: remove need for struct page for SPEs

    This patch removes the need for struct page for SPE local store
    and registers from spufs. It also makes the locking much more
    obvious and no longer relying on the truncate logic black magic
    for protecting against races between unmap_mapping_range() and
    new pages faulted in. It does so by switching to a nopfn() handler
    and using the new vm_insert_pfn() to setup the PTEs itself while
    holding a lock on the SPE.

    The nice thing is that this patch actually removes a lot more code
    than it adds :-)

    Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Signed-off-by: Paul Mackerras <paulus@samba.org>


Another question: why does SPU_FS select MEMORY_HOTPLUG?

commit 4da30d15b6d5036b0d96422d6946ca758111fae3
Author: Geoff Levand <geoffrey.levand@am.sony.com>
Date:   Fri Jun 23 20:57:49 2006 +0200

    [POWERPC] spufs: fix memory hotplug dependency

    spufs_base.c calls __add_pages, which depends on CONFIG_MEMORY_HOTPLUG.

    Moved the selection of CONFIG_MEMORY_HOTPLUG from CONFIG_SPUFS_MMAP
    to CONFIG_SPU_FS.

    Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
    Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
    Signed-off-by: Paul Mackerras <paulus@samba.org>

However, the call to __add_pages() has been moved a few times afterwards,
to be finally removed in the aforementioned commit
78bde53e351bc89cff85d1c2c7e6d7c2ffdf120d.

Does it still build/work if you just drop the "select MEMORY_HOTPLUG"?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH] powerpc: Fix build failure when MEMORY_HOTPLUG=y
From: Geert Uytterhoeven @ 2014-08-20  8:00 UTC (permalink / raw)
  To: Pranith Kumar
  Cc: open list, Paul Mackerras, Andew Morton,
	open list:LINUX FOR POWERPC...
In-Reply-To: <1408482065-18457-1-git-send-email-bobby.prani@gmail.com>

On Tue, Aug 19, 2014 at 11:01 PM, Pranith Kumar <bobby.prani@gmail.com> wrote:
> ARCH_ENABLE_MEMORY_HOTPLUG is enabled by default for powerpc. This causes build
> failures when SPARSEMEM=n as memory hotplug needs definition which are defined
> only when SPARSEMEM=y. The error is as follows:
>
> arch/powerpc/platforms/pseries/hotplug-memory.c:27:31: error: 'SECTION_SIZE_BITS' undeclared (first use in this function)
> arch/powerpc/platforms/pseries/hotplug-memory.c:27:31: note: each undeclared identifier is reported only once for each function it appears in
> arch/powerpc/platforms/pseries/hotplug-memory.c: In function 'pseries_remove_memblock':
> arch/powerpc/platforms/pseries/hotplug-memory.c:98:34: error: 'SECTION_SIZE_BITS' undeclared (first use in this function)
> make[2]: *** [arch/powerpc/platforms/pseries/hotplug-memory.o] Error 1
>
> Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
> CC: Andew Morton <akpm@linux-foundation.org>
> ---
>  arch/powerpc/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 9c1aa77..da16ffe 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -383,6 +383,7 @@ config ARCH_CPU_PROBE_RELEASE
>
>  config ARCH_ENABLE_MEMORY_HOTPLUG
>         def_bool y
> +       depends on SPARSEMEM
>
>  config ARCH_HAS_WALK_MEMORY
>         def_bool y
> --
> 1.9.1

In light of my investigation for your spufs patch, I guess this is a non-SMP
PSERIES config?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [RFC PATCH 6/6] rtc: rtc-isl12057: Change vendor prefix for Intersil Corporation to isil
From: Philipp Zabel @ 2014-08-20  8:43 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Rob Herring, Paul Mackerras, Philipp Zabel,
	Kumar Gala, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-1-git-send-email-p.zabel@pengutronix.de>

Currently there is a wild mixture of isl, isil, and intersil
compatibles in the kernel. At this point, changing the vendor
symbol to the most often used variant, which is equal to the
NASDAQ symbol, isil, should not hurt, since the isl1208 driver
doesn't care either way.
Patch 70e123373c05 added this driver with device tree support
using the then documented isl vendor prefix, so we keep that
around for backwards compatibility.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/rtc/rtc-isl12057.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c
index 455b601..8276bd6 100644
--- a/drivers/rtc/rtc-isl12057.c
+++ b/drivers/rtc/rtc-isl12057.c
@@ -279,7 +279,8 @@ static int isl12057_probe(struct i2c_client *client,
 
 #ifdef CONFIG_OF
 static const struct of_device_id isl12057_dt_match[] = {
-	{ .compatible = "isl,isl12057" },
+	{ .compatible = "isil,isl12057" },
+	{ .compatible = "isl,isl12057" }, /* for backwards compatibility */
 	{ },
 };
 #endif
-- 
2.1.0.rc1

^ permalink raw reply related

* [RFC PATCH 4/6] powerpc/85xx: Change vendor prefix for Intersil Corporation to isil
From: Philipp Zabel @ 2014-08-20  8:43 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Rob Herring, Paul Mackerras, Philipp Zabel,
	Kumar Gala, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-1-git-send-email-p.zabel@pengutronix.de>

Currently there is a wild mixture of isl, isil, and intersil
compatibles in the kernel. At this point, changing the vendor
symbol to the most often used variant, which is equal to the
NASDAQ symbol, isil, should not hurt, since the isl1208 driver
doesn't care either way.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/powerpc/boot/dts/ppa8548.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/ppa8548.dts b/arch/powerpc/boot/dts/ppa8548.dts
index 27b0699..000262b 100644
--- a/arch/powerpc/boot/dts/ppa8548.dts
+++ b/arch/powerpc/boot/dts/ppa8548.dts
@@ -89,7 +89,7 @@
 &soc {
 	i2c@3000 {
 		rtc@6f {
-			compatible = "intersil,isl1208";
+			compatible = "isil,isl1208";
 			reg = <0x6f>;
 		};
 	};
-- 
2.1.0.rc1

^ permalink raw reply related

* [RFC PATCH 2/6] Documentation: Add isl1208 and isl12022 to trivial-devices list
From: Philipp Zabel @ 2014-08-20  8:43 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Rob Herring, Paul Mackerras, Philipp Zabel,
	Kumar Gala, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-1-git-send-email-p.zabel@pengutronix.de>

This patch adds the Intersil ISL1208 and ISL12022 I2C RTCs to the
trivial-devices list.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index 6504297..ec4c6b2 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -56,6 +56,8 @@ fsl,sgtl5000		SGTL5000: Ultra Low-Power Audio Codec
 gmt,g751		G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface
 infineon,slb9635tt	Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
 infineon,slb9645tt	Infineon SLB9645 I2C TPM (new protocol, max 400khz)
+isil,isl1208		Intersil ISL1208 I2C RTC Chip
+isil,isl12022		Intersil ISL12022 I2C RTC Chip
 isil,isl12057		Intersil ISL12057 I2C RTC Chip
 maxim,ds1050		5 Bit Programmable, Pulse-Width Modulator
 maxim,max1237		Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
-- 
2.1.0.rc1

^ permalink raw reply related

* [RFC PATCH 1/6] of: Change vendor prefix for Intersil Corporation to isil
From: Philipp Zabel @ 2014-08-20  8:42 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Rob Herring, Paul Mackerras, Philipp Zabel,
	Kumar Gala, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-1-git-send-email-p.zabel@pengutronix.de>

Currently there is a wild mixture of isl, isil, and intersil
compatibles in the kernel. At this point, changing the vendor
symbol to the most often used variant, which is equal to the
NASDAQ symbol, isil, should not hurt.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 +-
 Documentation/devicetree/bindings/vendor-prefixes.txt     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index 6af570e..6504297 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -56,7 +56,7 @@ fsl,sgtl5000		SGTL5000: Ultra Low-Power Audio Codec
 gmt,g751		G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface
 infineon,slb9635tt	Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
 infineon,slb9645tt	Infineon SLB9645 I2C TPM (new protocol, max 400khz)
-isl,isl12057		Intersil ISL12057 I2C RTC Chip
+isil,isl12057		Intersil ISL12057 I2C RTC Chip
 maxim,ds1050		5 Bit Programmable, Pulse-Width Modulator
 maxim,max1237		Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
 maxim,max6625		9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index ac7269f..938e0ce 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -68,7 +68,7 @@ img	Imagination Technologies Ltd.
 intel	Intel Corporation
 intercontrol	Inter Control Group
 isee	ISEE 2007 S.L.
-isl	Intersil
+isil	Intersil Corporation
 karo	Ka-Ro electronics GmbH
 keymile	Keymile GmbH
 lacie	LaCie
-- 
2.1.0.rc1

^ permalink raw reply related

* [RFC PATCH 3/6] ARM: mvebu: Change vendor prefix for Intersil Corporation to isil
From: Philipp Zabel @ 2014-08-20  8:43 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Rob Herring, Paul Mackerras, Philipp Zabel,
	Kumar Gala, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-1-git-send-email-p.zabel@pengutronix.de>

Currently there is a wild mixture of isl, isil, and intersil
compatibles in the kernel. At this point, changing the vendor
symbol to the most often used variant, which is equal to the
NASDAQ symbol, isil, should not hurt.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/arm/boot/dts/armada-370-netgear-rn102.dts | 2 +-
 arch/arm/boot/dts/armada-370-netgear-rn104.dts | 2 +-
 arch/arm/boot/dts/armada-xp-netgear-rn2120.dts | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
index d6d572e..edc381c 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -122,7 +122,7 @@
 				status = "okay";
 
 				isl12057: isl12057@68 {
-					compatible = "isl,isl12057";
+					compatible = "isil,isl12057";
 					reg = <0x68>;
 				};
 
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
index c5fe8b5..7367b4c 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -117,7 +117,7 @@
 				status = "okay";
 
 				isl12057: isl12057@68 {
-					compatible = "isl,isl12057";
+					compatible = "isil,isl12057";
 					reg = <0x68>;
 				};
 
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
index 0cf999a..252def8 100644
--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -174,7 +174,7 @@
 				status = "okay";
 
 				isl12057: isl12057@68 {
-					compatible = "isl,isl12057";
+					compatible = "isil,isl12057";
 					reg = <0x68>;
 				};
 
-- 
2.1.0.rc1

^ permalink raw reply related

* [RFC PATCH 5/6] rtc: rtc-isl12022: Change vendor prefix for Intersil Corporation to isil
From: Philipp Zabel @ 2014-08-20  8:43 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Rob Herring, Paul Mackerras, Philipp Zabel,
	Kumar Gala, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-1-git-send-email-p.zabel@pengutronix.de>

Currently there is a wild mixture of isl, isil, and intersil
compatibles in the kernel. At this point, changing the vendor
symbol to the most often used variant, which is equal to the
NASDAQ symbol, isil, should not hurt, since the isl1208 driver
doesn't care either way.
Patch db04d6284e2a added device tree support using the then
documented isl vendor prefix, so we keep that around for
backwards compatibility.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/rtc/rtc-isl12022.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index aa55f08..df20f18 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -275,7 +275,8 @@ static int isl12022_probe(struct i2c_client *client,
 
 #ifdef CONFIG_OF
 static struct of_device_id isl12022_dt_match[] = {
-	{ .compatible = "isl,isl12022" },
+	{ .compatible = "isil,isl12022" },
+	{ .compatible = "isl,isl12022" }, /* for backwards compatibility */
 	{ },
 };
 #endif
-- 
2.1.0.rc1

^ permalink raw reply related

* [RFC PATCH 0/6] Change vendor prefix for Intersil Corporation
From: Philipp Zabel @ 2014-08-20  8:42 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Rob Herring, Paul Mackerras, Philipp Zabel,
	Kumar Gala, linuxppc-dev, linux-arm-kernel

Hi,

currently there is a wild mixture of isl, isil, and intersil
compatibles in the kernel. I figure at this point it is still
possible to change this to use "isil" everywhere without too
much pain, but it might be preferred to keep the already
documented "isl" prefix, even though it doesn't follow the
convention to use the NASDAQ symbol where available.

The current users of the "isil" prefix are the following drivers
and device trees, so we could just as well change those instead:
	arch/arm/boot/dts/tegra20-seaboard.dts
	arch/arm/boot/dts/tegra20-ventana.dts
	arch/arm/boot/dts/tegra30-cardhu.dtsi
	arch/powerpc/boot/dts/p1022rdk.dts
	drivers/staging/iio/light/isl29018.c
	drivers/staging/iio/light/isl29028.c

regards
Philipp

Philipp Zabel (6):
  of: Change vendor prefix for Intersil Corporation to isil
  Documentation: Add isl1208 and isl12022 to trivial-devices list
  ARM: mvebu: Change vendor prefix for Intersil Corporation to isil
  powerpc/85xx: Change vendor prefix for Intersil Corporation to isil
  rtc: rtc-isl12022: Change vendor prefix for Intersil Corporation to
    isil
  rtc: rtc-isl12057: Change vendor prefix for Intersil Corporation to
    isil

 Documentation/devicetree/bindings/i2c/trivial-devices.txt | 4 +++-
 Documentation/devicetree/bindings/vendor-prefixes.txt     | 2 +-
 arch/arm/boot/dts/armada-370-netgear-rn102.dts            | 2 +-
 arch/arm/boot/dts/armada-370-netgear-rn104.dts            | 2 +-
 arch/arm/boot/dts/armada-xp-netgear-rn2120.dts            | 2 +-
 arch/powerpc/boot/dts/ppa8548.dts                         | 2 +-
 drivers/rtc/rtc-isl12022.c                                | 3 ++-
 drivers/rtc/rtc-isl12057.c                                | 3 ++-
 8 files changed, 12 insertions(+), 8 deletions(-)

-- 
2.1.0.rc1

^ permalink raw reply

* Re: [RFC PATCH 6/6] rtc: rtc-isl12057: Change vendor prefix for Intersil Corporation to isil
From: Sergei Shtylyov @ 2014-08-20 12:40 UTC (permalink / raw)
  To: Philipp Zabel, devicetree
  Cc: Mark Rutland, Alessandro Zummo, Russell King, Pawel Moll,
	Ian Campbell, Kumar Gala, Rob Herring, Paul Mackerras,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-7-git-send-email-p.zabel@pengutronix.de>

Hello.

On 8/20/2014 12:43 PM, Philipp Zabel wrote:

> Currently there is a wild mixture of isl, isil, and intersil
> compatibles in the kernel. At this point, changing the vendor
> symbol to the most often used variant, which is equal to the
> NASDAQ symbol, isil, should not hurt, since the isl1208 driver
> doesn't care either way.
> Patch 70e123373c05 added this driver with device tree support

    Please also specify that commit's summary line in parens.

> using the then documented isl vendor prefix, so we keep that
> around for backwards compatibility.

> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

WBR, Sergei

^ permalink raw reply

* Re: [RFC PATCH] powerpc: Make SPU_FS depend on SPARSEMEM
From: Pranith Kumar @ 2014-08-20 13:09 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: open list:CELL BROADBAND EN..., Geoff Levand, Arnd Bergmann,
	open list, Paul Mackerras, open list:CELL BROADBAND EN...
In-Reply-To: <CAMuHMdX4HXf91RcuxzdU=HRvqtikBd=7Q62msQUMGVFuHuJ4+g@mail.gmail.com>

On Wed, Aug 20, 2014 at 3:49 AM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:

> Is this a randconfig kernel?

Yes, randconfig with ARCH=powerpc.

>
> config ARCH_SPARSEMEM_DEFAULT
>        def_bool y
>        depends on (SMP && PPC_PSERIES) || PPC_PS3
>
> Why is this not enabled? !SMP? !PPC_PSERIES? !PPC_PS3?

This was indeed enabled, but that does not do much. We will need
CONFIG_SPARSEMEM which depends on CONFIG_SPARSEMEM_MANUAL which was
not enabled.


>
> If PPC_CELL is enabled, this issue was introduced by
>
> commit 78bde53e351bc89cff85d1c2c7e6d7c2ffdf120d
> Author: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Date:   Tue Feb 13 11:46:06 2007 +1100
>
>     [POWERPC] spufs: remove need for struct page for SPEs
>
>     This patch removes the need for struct page for SPE local store
>     and registers from spufs. It also makes the locking much more
>     obvious and no longer relying on the truncate logic black magic
>     for protecting against races between unmap_mapping_range() and
>     new pages faulted in. It does so by switching to a nopfn() handler
>     and using the new vm_insert_pfn() to setup the PTEs itself while
>     holding a lock on the SPE.
>
>     The nice thing is that this patch actually removes a lot more code
>     than it adds :-)
>
>     Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>     Signed-off-by: Paul Mackerras <paulus@samba.org>
>
>
> Another question: why does SPU_FS select MEMORY_HOTPLUG?

Not really sure :(

>
> commit 4da30d15b6d5036b0d96422d6946ca758111fae3
> Author: Geoff Levand <geoffrey.levand@am.sony.com>
> Date:   Fri Jun 23 20:57:49 2006 +0200
>
>     [POWERPC] spufs: fix memory hotplug dependency
>
>     spufs_base.c calls __add_pages, which depends on CONFIG_MEMORY_HOTPLUG.
>
>     Moved the selection of CONFIG_MEMORY_HOTPLUG from CONFIG_SPUFS_MMAP
>     to CONFIG_SPU_FS.
>
>     Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
>     Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
>     Signed-off-by: Paul Mackerras <paulus@samba.org>
>
> However, the call to __add_pages() has been moved a few times afterwards,
> to be finally removed in the aforementioned commit
> 78bde53e351bc89cff85d1c2c7e6d7c2ffdf120d.
>
> Does it still build/work if you just drop the "select MEMORY_HOTPLUG"?

I should have saved the config file :(. I think it will build since
the problem was that hotplug-memory.o needs CONFIG_SPARSEMEM.



-- 
Pranith

^ permalink raw reply

* [PATCH v2 2/2] powerpc/booke: Revert SPE/AltiVec common defines for interrupt numbers
From: Mihai Caraman @ 2014-08-20 13:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Scott Wood, Mihai Caraman, Alexander Graf, kvm-ppc
In-Reply-To: <1408540144-24436-1-git-send-email-mihai.caraman@freescale.com>

Book3E specification defines shared interrupt numbers for SPE and AltiVec
units. Still SPE is present in e200/e500v2 cores while AltiVec is present in
e6500 core. So we can currently decide at compile-time which unit to support
exclusively. As Alexander Graf suggested, this will improve code readability
especially in KVM.

Use distinct defines to identify SPE/AltiVec interrupt numbers, reverting
c58ce397 and 6b310fc5 patches that added common defines.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Alexander Graf <agraf@suse.de>
---
 arch/powerpc/kernel/exceptions-64e.S | 4 ++--
 arch/powerpc/kernel/head_fsl_booke.S | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index bb9cac6..3e68d1c 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -635,7 +635,7 @@ interrupt_end_book3e:
 
 /* Altivec Unavailable Interrupt */
 	START_EXCEPTION(altivec_unavailable);
-	NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL,
+	NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL,
 				PROLOG_ADDITION_NONE)
 	/* we can probably do a shorter exception entry for that one... */
 	EXCEPTION_COMMON(0x200)
@@ -658,7 +658,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 /* AltiVec Assist */
 	START_EXCEPTION(altivec_assist);
 	NORMAL_EXCEPTION_PROLOG(0x220,
-				BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST,
+				BOOKE_INTERRUPT_ALTIVEC_ASSIST,
 				PROLOG_ADDITION_NONE)
 	EXCEPTION_COMMON(0x220)
 	INTS_DISABLE
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 90f487f..fffd1f9 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -617,27 +617,27 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 #ifdef CONFIG_SPE
 	/* SPE Unavailable */
 	START_EXCEPTION(SPEUnavailable)
-	NORMAL_EXCEPTION_PROLOG(SPE_ALTIVEC_UNAVAIL)
+	NORMAL_EXCEPTION_PROLOG(SPE_UNAVAIL)
 	beq	1f
 	bl	load_up_spe
 	b	fast_exception_return
 1:	addi	r3,r1,STACK_FRAME_OVERHEAD
 	EXC_XFER_EE_LITE(0x2010, KernelSPE)
 #elif defined(CONFIG_SPE_POSSIBLE)
-	EXCEPTION(0x2020, SPE_ALTIVEC_UNAVAIL, SPEUnavailable, \
+	EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \
 		  unknown_exception, EXC_XFER_EE)
 #endif /* CONFIG_SPE_POSSIBLE */
 
 	/* SPE Floating Point Data */
 #ifdef CONFIG_SPE
-	EXCEPTION(0x2030, SPE_FP_DATA_ALTIVEC_ASSIST, SPEFloatingPointData,
+	EXCEPTION(0x2030, SPE_FP_DATA, SPEFloatingPointData,
 		  SPEFloatingPointException, EXC_XFER_EE)
 
 	/* SPE Floating Point Round */
 	EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
 		  SPEFloatingPointRoundException, EXC_XFER_EE)
 #elif defined(CONFIG_SPE_POSSIBLE)
-	EXCEPTION(0x2040, SPE_FP_DATA_ALTIVEC_ASSIST, SPEFloatingPointData,
+	EXCEPTION(0x2040, SPE_FP_DATA, SPEFloatingPointData,
 		  unknown_exception, EXC_XFER_EE)
 	EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
 		  unknown_exception, EXC_XFER_EE)
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v2 1/2] powerpc/booke: Restrict SPE exception handlers to e200/e500 cores
From: Mihai Caraman @ 2014-08-20 13:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Scott Wood, Mihai Caraman, Alexander Graf, kvm-ppc

SPE exception handlers are now defined for 32-bit e500mc cores even though
SPE unit is not present and CONFIG_SPE is undefined.

Restrict SPE exception handlers to e200/e500 cores adding CONFIG_SPE_POSSIBLE
and consequently guard __stup_ivors and __setup_cpu functions.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Alexander Graf <agraf@suse.de>
---
v2:
 - use CONFIG_PPC_E500MC without CONFIG_E500
 - use elif defined()

 arch/powerpc/kernel/cpu_setup_fsl_booke.S | 12 +++++++++++-
 arch/powerpc/kernel/cputable.c            |  5 +++++
 arch/powerpc/kernel/head_fsl_booke.S      | 18 +++++++++++++-----
 arch/powerpc/platforms/Kconfig.cputype    |  6 +++++-
 4 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 4f1393d..dddba3e 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -91,6 +91,7 @@ _GLOBAL(setup_altivec_idle)
 
 	blr
 
+#ifdef CONFIG_PPC_E500MC
 _GLOBAL(__setup_cpu_e6500)
 	mflr	r6
 #ifdef CONFIG_PPC64
@@ -107,14 +108,20 @@ _GLOBAL(__setup_cpu_e6500)
 	bl	__setup_cpu_e5500
 	mtlr	r6
 	blr
+#endif /* CONFIG_PPC_E500MC */
 
 #ifdef CONFIG_PPC32
+#ifdef CONFIG_E200
 _GLOBAL(__setup_cpu_e200)
 	/* enable dedicated debug exception handling resources (Debug APU) */
 	mfspr	r3,SPRN_HID0
 	ori	r3,r3,HID0_DAPUEN@l
 	mtspr	SPRN_HID0,r3
 	b	__setup_e200_ivors
+#endif /* CONFIG_E200 */
+
+#ifdef CONFIG_E500
+#ifndef CONFIG_PPC_E500MC
 _GLOBAL(__setup_cpu_e500v1)
 _GLOBAL(__setup_cpu_e500v2)
 	mflr	r4
@@ -129,6 +136,7 @@ _GLOBAL(__setup_cpu_e500v2)
 #endif
 	mtlr	r4
 	blr
+#else /* CONFIG_PPC_E500MC */
 _GLOBAL(__setup_cpu_e500mc)
 _GLOBAL(__setup_cpu_e5500)
 	mflr	r5
@@ -159,7 +167,9 @@ _GLOBAL(__setup_cpu_e5500)
 2:
 	mtlr	r5
 	blr
-#endif
+#endif /* CONFIG_PPC_E500MC */
+#endif /* CONFIG_E500 */
+#endif /* CONFIG_PPC32 */
 
 #ifdef CONFIG_PPC_BOOK3E_64
 _GLOBAL(__restore_cpu_e6500)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 0c15764..df979c5f 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -2051,6 +2051,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 #endif /* CONFIG_PPC32 */
 #ifdef CONFIG_E500
 #ifdef CONFIG_PPC32
+#ifndef CONFIG_PPC_E500MC
 	{	/* e500 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x80200000,
@@ -2090,6 +2091,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_e500,
 		.platform		= "ppc8548",
 	},
+#else
 	{	/* e500mc */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x80230000,
@@ -2108,7 +2110,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_e500mc,
 		.platform		= "ppce500mc",
 	},
+#endif /* CONFIG_PPC_E500MC */
 #endif /* CONFIG_PPC32 */
+#ifdef CONFIG_PPC_E500MC
 	{	/* e5500 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x80240000,
@@ -2152,6 +2156,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_e500mc,
 		.platform		= "ppce6500",
 	},
+#endif /* CONFIG_PPC_E500MC */
 #ifdef CONFIG_PPC32
 	{	/* default match */
 		.pvr_mask		= 0x00000000,
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index b497188..90f487f 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -613,6 +613,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 	mfspr	r10, SPRN_SPRG_RSCRATCH0
 	b	InstructionStorage
 
+/* Define SPE handlers for e200 and e500v2 */
 #ifdef CONFIG_SPE
 	/* SPE Unavailable */
 	START_EXCEPTION(SPEUnavailable)
@@ -622,10 +623,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 	b	fast_exception_return
 1:	addi	r3,r1,STACK_FRAME_OVERHEAD
 	EXC_XFER_EE_LITE(0x2010, KernelSPE)
-#else
+#elif defined(CONFIG_SPE_POSSIBLE)
 	EXCEPTION(0x2020, SPE_ALTIVEC_UNAVAIL, SPEUnavailable, \
 		  unknown_exception, EXC_XFER_EE)
-#endif /* CONFIG_SPE */
+#endif /* CONFIG_SPE_POSSIBLE */
 
 	/* SPE Floating Point Data */
 #ifdef CONFIG_SPE
@@ -635,12 +636,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 	/* SPE Floating Point Round */
 	EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
 		  SPEFloatingPointRoundException, EXC_XFER_EE)
-#else
+#elif defined(CONFIG_SPE_POSSIBLE)
 	EXCEPTION(0x2040, SPE_FP_DATA_ALTIVEC_ASSIST, SPEFloatingPointData,
 		  unknown_exception, EXC_XFER_EE)
 	EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
 		  unknown_exception, EXC_XFER_EE)
-#endif /* CONFIG_SPE */
+#endif /* CONFIG_SPE_POSSIBLE */
+
 
 	/* Performance Monitor */
 	EXCEPTION(0x2060, PERFORMANCE_MONITOR, PerformanceMonitor, \
@@ -947,6 +949,7 @@ get_phys_addr:
  * Global functions
  */
 
+#ifdef CONFIG_E200
 /* Adjust or setup IVORs for e200 */
 _GLOBAL(__setup_e200_ivors)
 	li	r3,DebugDebug@l
@@ -959,7 +962,10 @@ _GLOBAL(__setup_e200_ivors)
 	mtspr	SPRN_IVOR34,r3
 	sync
 	blr
+#endif
 
+#ifdef CONFIG_E500
+#ifndef CONFIG_PPC_E500MC
 /* Adjust or setup IVORs for e500v1/v2 */
 _GLOBAL(__setup_e500_ivors)
 	li	r3,DebugCrit@l
@@ -974,7 +980,7 @@ _GLOBAL(__setup_e500_ivors)
 	mtspr	SPRN_IVOR35,r3
 	sync
 	blr
-
+#else
 /* Adjust or setup IVORs for e500mc */
 _GLOBAL(__setup_e500mc_ivors)
 	li	r3,DebugDebug@l
@@ -1000,6 +1006,8 @@ _GLOBAL(__setup_ehv_ivors)
 	mtspr	SPRN_IVOR41,r3
 	sync
 	blr
+#endif /* CONFIG_PPC_E500MC */
+#endif /* CONFIG_E500 */
 
 #ifdef CONFIG_SPE
 /*
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index a41bd02..bb81571 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -311,9 +311,13 @@ config PPC_ICSWX_USE_SIGILL
 
 	  If in doubt, say N here.
 
+config SPE_POSSIBLE
+	def_bool y
+	depends on E200 || (E500 && !PPC_E500MC)
+
 config SPE
 	bool "SPE Support"
-	depends on E200 || (E500 && !PPC_E500MC)
+	depends on SPE_POSSIBLE
 	default y
 	---help---
 	  This option enables kernel support for the Signal Processing
-- 
1.7.11.7

^ permalink raw reply related

* Re: [PATCH] powerpc: Fix build failure when MEMORY_HOTPLUG=y
From: Pranith Kumar @ 2014-08-20 13:12 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: open list, Paul Mackerras, Andew Morton,
	open list:LINUX FOR POWERPC...
In-Reply-To: <CAMuHMdWz+4ctGr92fJmi0GB1QrxRMy3GKC_KDpZfK-sriYP-FQ@mail.gmail.com>

On Wed, Aug 20, 2014 at 4:00 AM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:

>> 1.9.1
>
> In light of my investigation for your spufs patch, I guess this is a non-SMP
> PSERIES config?

So what happens is SELECT_MEMORY_MODEL choses FLATMEM_MANUAL because
of which SPARSEMEM is not enabled despite having
ARCH_SPARSEMEM_ENABLE=y.

-- 
Pranith

^ permalink raw reply

* Re: [RFC PATCH 0/6] Change vendor prefix for Intersil Corporation
From: Jason Cooper @ 2014-08-20 12:16 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, devicetree, Alessandro Zummo, Russell King,
	Pawel Moll, Ian Campbell, Rob Herring, Paul Mackerras, Kumar Gala,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1408524184-31928-1-git-send-email-p.zabel@pengutronix.de>

Philipp,

On Wed, Aug 20, 2014 at 10:42:58AM +0200, Philipp Zabel wrote:
> Hi,
> 
> currently there is a wild mixture of isl, isil, and intersil
> compatibles in the kernel. I figure at this point it is still
> possible to change this to use "isil" everywhere without too
> much pain, but it might be preferred to keep the already
> documented "isl" prefix, even though it doesn't follow the
> convention to use the NASDAQ symbol where available.
> 
> The current users of the "isil" prefix are the following drivers
> and device trees, so we could just as well change those instead:
> 	arch/arm/boot/dts/tegra20-seaboard.dts
> 	arch/arm/boot/dts/tegra20-ventana.dts
> 	arch/arm/boot/dts/tegra30-cardhu.dtsi
> 	arch/powerpc/boot/dts/p1022rdk.dts
> 	drivers/staging/iio/light/isl29018.c
> 	drivers/staging/iio/light/isl29028.c
> 
> regards
> Philipp
> 
> Philipp Zabel (6):
>   of: Change vendor prefix for Intersil Corporation to isil
>   Documentation: Add isl1208 and isl12022 to trivial-devices list
>   ARM: mvebu: Change vendor prefix for Intersil Corporation to isil
>   powerpc/85xx: Change vendor prefix for Intersil Corporation to isil
>   rtc: rtc-isl12022: Change vendor prefix for Intersil Corporation to
>     isil
>   rtc: rtc-isl12057: Change vendor prefix for Intersil Corporation to
>     isil
> 
>  Documentation/devicetree/bindings/i2c/trivial-devices.txt | 4 +++-
>  Documentation/devicetree/bindings/vendor-prefixes.txt     | 2 +-
>  arch/arm/boot/dts/armada-370-netgear-rn102.dts            | 2 +-
>  arch/arm/boot/dts/armada-370-netgear-rn104.dts            | 2 +-
>  arch/arm/boot/dts/armada-xp-netgear-rn2120.dts            | 2 +-
>  arch/powerpc/boot/dts/ppa8548.dts                         | 2 +-
>  drivers/rtc/rtc-isl12022.c                                | 3 ++-
>  drivers/rtc/rtc-isl12057.c                                | 3 ++-
>  8 files changed, 12 insertions(+), 8 deletions(-)

This looks good overall.  My only nit is that I'd like to see the legacy
name(s) captured in the binding docs.

I'll take the Armada dts changes through mvebu/arm-soc after a few days.

thx,

Jason.

^ permalink raw reply

* [PATCH v4 1/6] KVM: PPC: Book3E: Increase FPU laziness
From: Mihai Caraman @ 2014-08-20 13:36 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1408541787-24625-1-git-send-email-mihai.caraman@freescale.com>

Increase FPU laziness by loading the guest state into the unit before entering
the guest instead of doing it on each vcpu schedule. Without this improvement
an interrupt may claim floating point corrupting guest state.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v4:
 - update commit message

v3:
 - no changes

v2:
 - remove fpu_active
 - add descriptive comments

 arch/powerpc/kvm/booke.c  | 43 ++++++++++++++++++++++++++++++++++++-------
 arch/powerpc/kvm/booke.h  | 34 ----------------------------------
 arch/powerpc/kvm/e500mc.c |  2 --
 3 files changed, 36 insertions(+), 43 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 074b7fc..91e7217 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -124,6 +124,40 @@ static void kvmppc_vcpu_sync_spe(struct kvm_vcpu *vcpu)
 }
 #endif
 
+/*
+ * Load up guest vcpu FP state if it's needed.
+ * It also set the MSR_FP in thread so that host know
+ * we're holding FPU, and then host can help to save
+ * guest vcpu FP state if other threads require to use FPU.
+ * This simulates an FP unavailable fault.
+ *
+ * It requires to be called with preemption disabled.
+ */
+static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_PPC_FPU
+	if (!(current->thread.regs->msr & MSR_FP)) {
+		enable_kernel_fp();
+		load_fp_state(&vcpu->arch.fp);
+		current->thread.fp_save_area = &vcpu->arch.fp;
+		current->thread.regs->msr |= MSR_FP;
+	}
+#endif
+}
+
+/*
+ * Save guest vcpu FP state into thread.
+ * It requires to be called with preemption disabled.
+ */
+static inline void kvmppc_save_guest_fp(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_PPC_FPU
+	if (current->thread.regs->msr & MSR_FP)
+		giveup_fpu(current);
+	current->thread.fp_save_area = NULL;
+#endif
+}
+
 static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
 {
 #if defined(CONFIG_PPC_FPU) && !defined(CONFIG_KVM_BOOKE_HV)
@@ -658,12 +692,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 
 	/*
 	 * Since we can't trap on MSR_FP in GS-mode, we consider the guest
-	 * as always using the FPU.  Kernel usage of FP (via
-	 * enable_kernel_fp()) in this thread must not occur while
-	 * vcpu->fpu_active is set.
+	 * as always using the FPU.
 	 */
-	vcpu->fpu_active = 1;
-
 	kvmppc_load_guest_fp(vcpu);
 #endif
 
@@ -687,8 +717,6 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 
 #ifdef CONFIG_PPC_FPU
 	kvmppc_save_guest_fp(vcpu);
-
-	vcpu->fpu_active = 0;
 #endif
 
 out:
@@ -1194,6 +1222,7 @@ out:
 		else {
 			/* interrupts now hard-disabled */
 			kvmppc_fix_ee_before_entry();
+			kvmppc_load_guest_fp(vcpu);
 		}
 	}
 
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index f753543..e73d513 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -116,40 +116,6 @@ extern int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn,
 extern int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn,
 					  ulong *spr_val);
 
-/*
- * Load up guest vcpu FP state if it's needed.
- * It also set the MSR_FP in thread so that host know
- * we're holding FPU, and then host can help to save
- * guest vcpu FP state if other threads require to use FPU.
- * This simulates an FP unavailable fault.
- *
- * It requires to be called with preemption disabled.
- */
-static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu)
-{
-#ifdef CONFIG_PPC_FPU
-	if (vcpu->fpu_active && !(current->thread.regs->msr & MSR_FP)) {
-		enable_kernel_fp();
-		load_fp_state(&vcpu->arch.fp);
-		current->thread.fp_save_area = &vcpu->arch.fp;
-		current->thread.regs->msr |= MSR_FP;
-	}
-#endif
-}
-
-/*
- * Save guest vcpu FP state into thread.
- * It requires to be called with preemption disabled.
- */
-static inline void kvmppc_save_guest_fp(struct kvm_vcpu *vcpu)
-{
-#ifdef CONFIG_PPC_FPU
-	if (vcpu->fpu_active && (current->thread.regs->msr & MSR_FP))
-		giveup_fpu(current);
-	current->thread.fp_save_area = NULL;
-#endif
-}
-
 static inline void kvmppc_clear_dbsr(void)
 {
 	mtspr(SPRN_DBSR, mfspr(SPRN_DBSR));
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 000cf82..4549349 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -145,8 +145,6 @@ static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu)
 		kvmppc_e500_tlbil_all(vcpu_e500);
 		__get_cpu_var(last_vcpu_of_lpid)[vcpu->kvm->arch.lpid] = vcpu;
 	}
-
-	kvmppc_load_guest_fp(vcpu);
 }
 
 static void kvmppc_core_vcpu_put_e500mc(struct kvm_vcpu *vcpu)
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v4 0/6] KVM: PPC: Book3e: AltiVec support
From: Mihai Caraman @ 2014-08-20 13:36 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

Add KVM Book3e AltiVec support.

Changes:

v4:
 - use CONFIG_SPE_POSSIBLE and a new ifdef for CONFIG_ALTIVEC
 - remove SPE handlers from bookehv
 - split ONE_REG powerpc generic and ONE_REG AltiVec
 - add setters for IVPR, IVOR2 and IVOR8
 - add api documentation for ONE_REG IVPR and IVORs
 - don't enable e6500 core since hardware threads are not yet supported

v3:
 - use distinct SPE/AltiVec exception handlers
 - make ONE_REG AltiVec support powerpc generic
 - add ONE_REG IVORs support

 v2:
 - integrate Paul's FP/VMX/VSX changes that landed in kvm-ppc-queue
   in January and take into account feedback

Mihai Caraman (6):
  KVM: PPC: Book3E: Increase FPU laziness
  KVM: PPC: Book3e: Add AltiVec support
  KVM: PPC: Make ONE_REG powerpc generic
  KVM: PPC: Move ONE_REG AltiVec support to powerpc
  KVM: PPC: Booke: Add setter functions for IVPR, IVOR2 and IVOR8
    emulation
  KVM: PPC: Booke: Add ONE_REG support for IVPR and IVORs

 Documentation/virtual/kvm/api.txt     |   7 +
 arch/powerpc/include/uapi/asm/kvm.h   |  30 +++
 arch/powerpc/kvm/book3s.c             | 151 ++++----------
 arch/powerpc/kvm/booke.c              | 371 ++++++++++++++++++++++++++++------
 arch/powerpc/kvm/booke.h              |  43 +---
 arch/powerpc/kvm/booke_emulate.c      |  15 +-
 arch/powerpc/kvm/bookehv_interrupts.S |   9 +-
 arch/powerpc/kvm/e500.c               |  42 +++-
 arch/powerpc/kvm/e500_emulate.c       |  20 ++
 arch/powerpc/kvm/e500mc.c             |  18 +-
 arch/powerpc/kvm/powerpc.c            |  97 +++++++++
 11 files changed, 576 insertions(+), 227 deletions(-)

-- 
1.7.11.7

^ permalink raw reply

* [PATCH v4 2/6] KVM: PPC: Book3e: Add AltiVec support
From: Mihai Caraman @ 2014-08-20 13:36 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1408541787-24625-1-git-send-email-mihai.caraman@freescale.com>

Add AltiVec support in KVM for Book3e. FPU support gracefully reuse host
infrastructure so follow the same approach for AltiVec.

Book3e specification defines shared interrupt numbers for SPE and AltiVec
units. Still SPE is present in e200/e500v2 cores while AltiVec is present in
e6500 core. So we can currently decide at compile-time which of the SPE or
AltiVec units to support exclusively by using CONFIG_SPE_POSSIBLE and
CONFIG_PPC_E500MC defines. As Alexander Graf suggested, keep SPE and AltiVec
exception handlers distinct to improve code readability.

Guests have the privilege to enable AltiVec, so we always need to support
AltiVec in KVM and implicitly in host to reflect interrupts and to save/restore
the unit context. KVM will be loaded on cores with AltiVec unit only if
CONFIG_ALTIVEC is defined. Use this define to guard KVM AltiVec logic.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v4:
 - use CONFIG_SPE_POSSIBLE and a new ifdef for CONFIG_ALTIVEC
 - remove SPE handlers from bookehv
 - update commit message

v3:
 - use distinct SPE/AltiVec exception handlers

v2:
 - integrate Paul's FP/VMX/VSX changes

 arch/powerpc/kvm/booke.c              | 74 ++++++++++++++++++++++++++++++++++-
 arch/powerpc/kvm/booke.h              |  6 +++
 arch/powerpc/kvm/bookehv_interrupts.S |  9 +----
 arch/powerpc/kvm/e500_emulate.c       | 20 ++++++++++
 4 files changed, 101 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 91e7217..8ace612 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -168,6 +168,40 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
 #endif
 }
 
+/*
+ * Simulate AltiVec unavailable fault to load guest state
+ * from thread to AltiVec unit.
+ * It requires to be called with preemption disabled.
+ */
+static inline void kvmppc_load_guest_altivec(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_ALTIVEC
+	if (cpu_has_feature(CPU_FTR_ALTIVEC)) {
+		if (!(current->thread.regs->msr & MSR_VEC)) {
+			enable_kernel_altivec();
+			load_vr_state(&vcpu->arch.vr);
+			current->thread.vr_save_area = &vcpu->arch.vr;
+			current->thread.regs->msr |= MSR_VEC;
+		}
+	}
+#endif
+}
+
+/*
+ * Save guest vcpu AltiVec state into thread.
+ * It requires to be called with preemption disabled.
+ */
+static inline void kvmppc_save_guest_altivec(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_ALTIVEC
+	if (cpu_has_feature(CPU_FTR_ALTIVEC)) {
+		if (current->thread.regs->msr & MSR_VEC)
+			giveup_altivec(current);
+		current->thread.vr_save_area = NULL;
+	}
+#endif
+}
+
 static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu)
 {
 	/* Synchronize guest's desire to get debug interrupts into shadow MSR */
@@ -375,9 +409,15 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
 	case BOOKE_IRQPRIO_ITLB_MISS:
 	case BOOKE_IRQPRIO_SYSCALL:
 	case BOOKE_IRQPRIO_FP_UNAVAIL:
+#ifdef CONFIG_SPE_POSSIBLE
 	case BOOKE_IRQPRIO_SPE_UNAVAIL:
 	case BOOKE_IRQPRIO_SPE_FP_DATA:
 	case BOOKE_IRQPRIO_SPE_FP_ROUND:
+#endif
+#ifdef CONFIG_ALTIVEC
+	case BOOKE_IRQPRIO_ALTIVEC_UNAVAIL:
+	case BOOKE_IRQPRIO_ALTIVEC_ASSIST:
+#endif
 	case BOOKE_IRQPRIO_AP_UNAVAIL:
 		allowed = 1;
 		msr_mask = MSR_CE | MSR_ME | MSR_DE;
@@ -697,6 +737,17 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 	kvmppc_load_guest_fp(vcpu);
 #endif
 
+#ifdef CONFIG_ALTIVEC
+	/* Save userspace AltiVec state in stack */
+	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+		enable_kernel_altivec();
+	/*
+	 * Since we can't trap on MSR_VEC in GS-mode, we consider the guest
+	 * as always using the AltiVec.
+	 */
+	kvmppc_load_guest_altivec(vcpu);
+#endif
+
 	/* Switch to guest debug context */
 	debug = vcpu->arch.dbg_reg;
 	switch_booke_debug_regs(&debug);
@@ -719,6 +770,10 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 	kvmppc_save_guest_fp(vcpu);
 #endif
 
+#ifdef CONFIG_ALTIVEC
+	kvmppc_save_guest_altivec(vcpu);
+#endif
+
 out:
 	vcpu->mode = OUTSIDE_GUEST_MODE;
 	return ret;
@@ -1025,7 +1080,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND);
 		r = RESUME_GUEST;
 		break;
-#else
+#elif defined(CONFIG_SPE_POSSIBLE)
 	case BOOKE_INTERRUPT_SPE_UNAVAIL:
 		/*
 		 * Guest wants SPE, but host kernel doesn't support it.  Send
@@ -1046,6 +1101,22 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 		run->hw.hardware_exit_reason = exit_nr;
 		r = RESUME_HOST;
 		break;
+#endif /* CONFIG_SPE_POSSIBLE */
+
+/*
+ * On cores with Vector category, KVM is loaded only if CONFIG_ALTIVEC,
+ * see kvmppc_core_check_processor_compat().
+ */
+#ifdef CONFIG_ALTIVEC
+	case BOOKE_INTERRUPT_ALTIVEC_UNAVAIL:
+		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ALTIVEC_UNAVAIL);
+		r = RESUME_GUEST;
+		break;
+
+	case BOOKE_INTERRUPT_ALTIVEC_ASSIST:
+		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ALTIVEC_ASSIST);
+		r = RESUME_GUEST;
+		break;
 #endif
 
 	case BOOKE_INTERRUPT_DATA_STORAGE:
@@ -1223,6 +1294,7 @@ out:
 			/* interrupts now hard-disabled */
 			kvmppc_fix_ee_before_entry();
 			kvmppc_load_guest_fp(vcpu);
+			kvmppc_load_guest_altivec(vcpu);
 		}
 	}
 
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index e73d513..22ba08e 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -32,9 +32,15 @@
 #define BOOKE_IRQPRIO_ALIGNMENT 2
 #define BOOKE_IRQPRIO_PROGRAM 3
 #define BOOKE_IRQPRIO_FP_UNAVAIL 4
+#ifdef CONFIG_SPE_POSSIBLE
 #define BOOKE_IRQPRIO_SPE_UNAVAIL 5
 #define BOOKE_IRQPRIO_SPE_FP_DATA 6
 #define BOOKE_IRQPRIO_SPE_FP_ROUND 7
+#endif
+#ifdef CONFIG_PPC_E500MC
+#define BOOKE_IRQPRIO_ALTIVEC_UNAVAIL 5
+#define BOOKE_IRQPRIO_ALTIVEC_ASSIST 6
+#endif
 #define BOOKE_IRQPRIO_SYSCALL 8
 #define BOOKE_IRQPRIO_AP_UNAVAIL 9
 #define BOOKE_IRQPRIO_DTLB_MISS 10
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S
index e9fa56a..c8e4da5 100644
--- a/arch/powerpc/kvm/bookehv_interrupts.S
+++ b/arch/powerpc/kvm/bookehv_interrupts.S
@@ -256,11 +256,9 @@ kvm_handler BOOKE_INTERRUPT_DTLB_MISS, EX_PARAMS_TLB, \
 	SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
 kvm_handler BOOKE_INTERRUPT_ITLB_MISS, EX_PARAMS_TLB, \
 	SPRN_SRR0, SPRN_SRR1, 0
-kvm_handler BOOKE_INTERRUPT_SPE_UNAVAIL, EX_PARAMS(GEN), \
+kvm_handler BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, EX_PARAMS(GEN), \
 	SPRN_SRR0, SPRN_SRR1, 0
-kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA, EX_PARAMS(GEN), \
-	SPRN_SRR0, SPRN_SRR1, 0
-kvm_handler BOOKE_INTERRUPT_SPE_FP_ROUND, EX_PARAMS(GEN), \
+kvm_handler BOOKE_INTERRUPT_ALTIVEC_ASSIST, EX_PARAMS(GEN), \
 	SPRN_SRR0, SPRN_SRR1, 0
 kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, EX_PARAMS(GEN), \
 	SPRN_SRR0, SPRN_SRR1, 0
@@ -361,9 +359,6 @@ kvm_lvl_handler BOOKE_INTERRUPT_WATCHDOG, \
 kvm_handler BOOKE_INTERRUPT_DTLB_MISS, \
 	SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
 kvm_handler BOOKE_INTERRUPT_ITLB_MISS, SPRN_SRR0, SPRN_SRR1, 0
-kvm_handler BOOKE_INTERRUPT_SPE_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
-kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA, SPRN_SRR0, SPRN_SRR1, 0
-kvm_handler BOOKE_INTERRUPT_SPE_FP_ROUND, SPRN_SRR0, SPRN_SRR1, 0
 kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, SPRN_SRR0, SPRN_SRR1, 0
 kvm_handler BOOKE_INTERRUPT_DOORBELL, SPRN_SRR0, SPRN_SRR1, 0
 kvm_lvl_handler BOOKE_INTERRUPT_DOORBELL_CRITICAL, \
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index c99c40e..ce7291c 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -259,6 +259,7 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va
 		break;
 
 	/* extra exceptions */
+#ifdef CONFIG_SPE_POSSIBLE
 	case SPRN_IVOR32:
 		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val;
 		break;
@@ -268,6 +269,15 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va
 	case SPRN_IVOR34:
 		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val;
 		break;
+#endif
+#ifdef CONFIG_ALTIVEC
+	case SPRN_IVOR32:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL] = spr_val;
+		break;
+	case SPRN_IVOR33:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST] = spr_val;
+		break;
+#endif
 	case SPRN_IVOR35:
 		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
 		break;
@@ -381,6 +391,7 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v
 		break;
 
 	/* extra exceptions */
+#ifdef CONFIG_SPE_POSSIBLE
 	case SPRN_IVOR32:
 		*spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
 		break;
@@ -390,6 +401,15 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v
 	case SPRN_IVOR34:
 		*spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
 		break;
+#endif
+#ifdef CONFIG_ALTIVEC
+	case SPRN_IVOR32:
+		*spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL];
+		break;
+	case SPRN_IVOR33:
+		*spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST];
+		break;
+#endif
 	case SPRN_IVOR35:
 		*spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
 		break;
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v4 4/6] KVM: PPC: Move ONE_REG AltiVec support to powerpc
From: Mihai Caraman @ 2014-08-20 13:36 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1408541787-24625-1-git-send-email-mihai.caraman@freescale.com>

Move ONE_REG AltiVec support to powerpc generic layer.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v4:
 - split ONE_REG powerpc generic and ONE_REG AltiVec

v3:
 - make ONE_REG AltiVec support powerpc generic

v2:
 - add comment describing VCSR register representation in KVM vs kernel

 arch/powerpc/include/uapi/asm/kvm.h |  5 +++++
 arch/powerpc/kvm/book3s.c           | 42 -------------------------------------
 arch/powerpc/kvm/powerpc.c          | 42 +++++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 3ca357a..ab4d473 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -476,6 +476,11 @@ struct kvm_get_htab_header {
 
 /* FP and vector status/control registers */
 #define KVM_REG_PPC_FPSCR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80)
+/*
+ * VSCR register is documented as a 32-bit register in the ISA, but it can
+ * only be accesses via a vector register. Expose VSCR as a 32-bit register
+ * even though the kernel represents it as a 128-bit vector.
+ */
 #define KVM_REG_PPC_VSCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81)
 
 /* Virtual processor areas */
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 26868e2..1b5adda 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -558,25 +558,6 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
 		case KVM_REG_PPC_FPSCR:
 			*val = get_reg_val(id, vcpu->arch.fp.fpscr);
 			break;
-#ifdef CONFIG_ALTIVEC
-		case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
-			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
-				r = -ENXIO;
-				break;
-			}
-			val->vval = vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0];
-			break;
-		case KVM_REG_PPC_VSCR:
-			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
-				r = -ENXIO;
-				break;
-			}
-			*val = get_reg_val(id, vcpu->arch.vr.vscr.u[3]);
-			break;
-		case KVM_REG_PPC_VRSAVE:
-			*val = get_reg_val(id, vcpu->arch.vrsave);
-			break;
-#endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
 		case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
 			if (cpu_has_feature(CPU_FTR_VSX)) {
@@ -653,29 +634,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
 		case KVM_REG_PPC_FPSCR:
 			vcpu->arch.fp.fpscr = set_reg_val(id, *val);
 			break;
-#ifdef CONFIG_ALTIVEC
-		case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
-			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
-				r = -ENXIO;
-				break;
-			}
-			vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0] = val->vval;
-			break;
-		case KVM_REG_PPC_VSCR:
-			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
-				r = -ENXIO;
-				break;
-			}
-			vcpu->arch.vr.vscr.u[3] = set_reg_val(id, *val);
-			break;
-		case KVM_REG_PPC_VRSAVE:
-			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
-				r = -ENXIO;
-				break;
-			}
-			vcpu->arch.vrsave = set_reg_val(id, *val);
-			break;
-#endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
 		case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
 			if (cpu_has_feature(CPU_FTR_VSX)) {
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 1326116..19d4755 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -941,6 +941,25 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 	if (r == -EINVAL) {
 		r = 0;
 		switch (reg->id) {
+#ifdef CONFIG_ALTIVEC
+		case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
+			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
+				r = -ENXIO;
+				break;
+			}
+			val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
+			break;
+		case KVM_REG_PPC_VSCR:
+			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
+				r = -ENXIO;
+				break;
+			}
+			val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
+			break;
+		case KVM_REG_PPC_VRSAVE:
+			val = get_reg_val(reg->id, vcpu->arch.vrsave);
+			break;
+#endif /* CONFIG_ALTIVEC */
 		default:
 			r = -EINVAL;
 			break;
@@ -973,6 +992,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 	if (r == -EINVAL) {
 		r = 0;
 		switch (reg->id) {
+#ifdef CONFIG_ALTIVEC
+		case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
+			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
+				r = -ENXIO;
+				break;
+			}
+			vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
+			break;
+		case KVM_REG_PPC_VSCR:
+			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
+				r = -ENXIO;
+				break;
+			}
+			vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
+			break;
+		case KVM_REG_PPC_VRSAVE:
+			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
+				r = -ENXIO;
+				break;
+			}
+			vcpu->arch.vrsave = set_reg_val(reg->id, val);
+			break;
+#endif /* CONFIG_ALTIVEC */
 		default:
 			r = -EINVAL;
 			break;
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v4 5/6] KVM: PPC: Booke: Add setter functions for IVPR, IVOR2 and IVOR8 emulation
From: Mihai Caraman @ 2014-08-20 13:36 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1408541787-24625-1-git-send-email-mihai.caraman@freescale.com>

Add setter functions for IVPR, IVOR2 and IVOR8 emulation in preparation
for ONE_REG support.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v4:
 - new patch
 - add api documentation for ONE_REG IVPR and IVORs

 arch/powerpc/kvm/booke.c         | 24 ++++++++++++++++++++++++
 arch/powerpc/kvm/booke.h         |  3 +++
 arch/powerpc/kvm/booke_emulate.c | 15 +++------------
 3 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 831c1b4..d4df648 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1782,6 +1782,30 @@ void kvmppc_clr_tsr_bits(struct kvm_vcpu *vcpu, u32 tsr_bits)
 	update_timer_ints(vcpu);
 }
 
+void kvmppc_set_ivpr(struct kvm_vcpu *vcpu, ulong new_ivpr)
+{
+	vcpu->arch.ivpr = new_ivpr;
+#ifdef CONFIG_KVM_BOOKE_HV
+	mtspr(SPRN_GIVPR, new_ivpr);
+#endif
+}
+
+void kvmppc_set_ivor2(struct kvm_vcpu *vcpu, u32 new_ivor)
+{
+	vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = new_ivor;
+#ifdef CONFIG_KVM_BOOKE_HV
+	mtspr(SPRN_GIVOR2, new_ivor);
+#endif
+}
+
+void kvmppc_set_ivor8(struct kvm_vcpu *vcpu, u32 new_ivor)
+{
+	vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = new_ivor;
+#ifdef CONFIG_KVM_BOOKE_HV
+	mtspr(SPRN_GIVOR8, new_ivor);
+#endif
+}
+
 void kvmppc_decrementer_func(unsigned long data)
 {
 	struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data;
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index 22ba08e..0242530 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -80,6 +80,9 @@ void kvmppc_set_epcr(struct kvm_vcpu *vcpu, u32 new_epcr);
 void kvmppc_set_tcr(struct kvm_vcpu *vcpu, u32 new_tcr);
 void kvmppc_set_tsr_bits(struct kvm_vcpu *vcpu, u32 tsr_bits);
 void kvmppc_clr_tsr_bits(struct kvm_vcpu *vcpu, u32 tsr_bits);
+void kvmppc_set_ivpr(struct kvm_vcpu *vcpu, ulong new_ivpr);
+void kvmppc_set_ivor2(struct kvm_vcpu *vcpu, u32 new_ivor);
+void kvmppc_set_ivor8(struct kvm_vcpu *vcpu, u32 new_ivor);
 
 int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                             unsigned int inst, int *advance);
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index 92bc668..94c64e3 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -191,10 +191,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
 		break;
 
 	case SPRN_IVPR:
-		vcpu->arch.ivpr = spr_val;
-#ifdef CONFIG_KVM_BOOKE_HV
-		mtspr(SPRN_GIVPR, spr_val);
-#endif
+		kvmppc_set_ivpr(vcpu, spr_val);
 		break;
 	case SPRN_IVOR0:
 		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val;
@@ -203,10 +200,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
 		vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = spr_val;
 		break;
 	case SPRN_IVOR2:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val;
-#ifdef CONFIG_KVM_BOOKE_HV
-		mtspr(SPRN_GIVOR2, spr_val);
-#endif
+		kvmppc_set_ivor2(vcpu, spr_val);
 		break;
 	case SPRN_IVOR3:
 		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val;
@@ -224,10 +218,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
 		vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = spr_val;
 		break;
 	case SPRN_IVOR8:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val;
-#ifdef CONFIG_KVM_BOOKE_HV
-		mtspr(SPRN_GIVOR8, spr_val);
-#endif
+		kvmppc_set_ivor8(vcpu, spr_val);
 		break;
 	case SPRN_IVOR9:
 		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val;
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v4 6/6] KVM: PPC: Booke: Add ONE_REG support for IVPR and IVORs
From: Mihai Caraman @ 2014-08-20 13:36 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1408541787-24625-1-git-send-email-mihai.caraman@freescale.com>

Add ONE_REG support for IVPR and IVORs registers. Implement IVPR, IVORs 0-15
and 35 in booke common layer.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v4:
 - add ONE_REG IVPR
 - use IVPR, IVOR2 and IVOR8 setters
 - add api documentation for ONE_REG IVPR and IVORs

v3:
 - new patch

 Documentation/virtual/kvm/api.txt   |   7 ++
 arch/powerpc/include/uapi/asm/kvm.h |  25 +++++++
 arch/powerpc/kvm/booke.c            | 145 ++++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/e500.c             |  42 ++++++++++-
 arch/powerpc/kvm/e500mc.c           |  16 ++++
 5 files changed, 233 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index beae3fd..cd7b171 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1917,6 +1917,13 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TM_VSCR           | 32
   PPC   | KVM_REG_PPC_TM_DSCR           | 64
   PPC   | KVM_REG_PPC_TM_TAR            | 64
+  PPC   | KVM_REG_PPC_IVPR              | 64
+  PPC   | KVM_REG_PPC_IVOR0             | 32
+          ...
+  PPC   | KVM_REG_PPC_IVOR15            | 32
+  PPC   | KVM_REG_PPC_IVOR32            | 32
+          ...
+  PPC   | KVM_REG_PPC_IVOR37            | 32
         |                               |
   MIPS  | KVM_REG_MIPS_R0               | 64
           ...
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ab4d473..c97f119 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -564,6 +564,31 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_SPRG9	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba)
 #define KVM_REG_PPC_DBSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbb)
 
+/* Booke IVPR & IVOR registers */
+#define KVM_REG_PPC_IVPR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)
+#define KVM_REG_PPC_IVOR0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbd)
+#define KVM_REG_PPC_IVOR1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbe)
+#define KVM_REG_PPC_IVOR2	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf)
+#define KVM_REG_PPC_IVOR3	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc0)
+#define KVM_REG_PPC_IVOR4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc1)
+#define KVM_REG_PPC_IVOR5	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc2)
+#define KVM_REG_PPC_IVOR6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc3)
+#define KVM_REG_PPC_IVOR7	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc4)
+#define KVM_REG_PPC_IVOR8	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc5)
+#define KVM_REG_PPC_IVOR9	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc6)
+#define KVM_REG_PPC_IVOR10	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc7)
+#define KVM_REG_PPC_IVOR11	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc8)
+#define KVM_REG_PPC_IVOR12	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xc9)
+#define KVM_REG_PPC_IVOR13	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xca)
+#define KVM_REG_PPC_IVOR14	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xcb)
+#define KVM_REG_PPC_IVOR15	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xcc)
+#define KVM_REG_PPC_IVOR32	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xcd)
+#define KVM_REG_PPC_IVOR33	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xce)
+#define KVM_REG_PPC_IVOR34	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xcf)
+#define KVM_REG_PPC_IVOR35	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd0)
+#define KVM_REG_PPC_IVOR36	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd1)
+#define KVM_REG_PPC_IVOR37	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd2)
+
 /* Transactional Memory checkpointed state:
  * This is all GPRs, all VSX regs and a subset of SPRs
  */
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index d4df648..1cb2a2a 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1570,6 +1570,75 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
 	int r = 0;
 
 	switch (id) {
+	case KVM_REG_PPC_IVPR:
+		*val = get_reg_val(id, vcpu->arch.ivpr);
+		break;
+	case KVM_REG_PPC_IVOR0:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]);
+		break;
+	case KVM_REG_PPC_IVOR1:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK]);
+		break;
+	case KVM_REG_PPC_IVOR2:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]);
+		break;
+	case KVM_REG_PPC_IVOR3:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE]);
+		break;
+	case KVM_REG_PPC_IVOR4:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL]);
+		break;
+	case KVM_REG_PPC_IVOR5:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT]);
+		break;
+	case KVM_REG_PPC_IVOR6:
+		*val = get_reg_val(id, vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM]);
+		break;
+	case KVM_REG_PPC_IVOR7:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL]);
+		break;
+	case KVM_REG_PPC_IVOR8:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]);
+		break;
+	case KVM_REG_PPC_IVOR9:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL]);
+		break;
+	case KVM_REG_PPC_IVOR10:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER]);
+		break;
+	case KVM_REG_PPC_IVOR11:
+		*val = get_reg_val(id, vcpu->arch.ivor[BOOKE_IRQPRIO_FIT]);
+		break;
+	case KVM_REG_PPC_IVOR12:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG]);
+		break;
+	case KVM_REG_PPC_IVOR13:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]);
+		break;
+	case KVM_REG_PPC_IVOR14:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]);
+		break;
+	case KVM_REG_PPC_IVOR15:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]);
+		break;
+	case KVM_REG_PPC_IVOR35:
+		*val = get_reg_val(id,
+			vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]);
+		break;
 	case KVM_REG_PPC_IAC1:
 		*val = get_reg_val(id, vcpu->arch.dbg_reg.iac1);
 		break;
@@ -1626,6 +1695,82 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
 	int r = 0;
 
 	switch (id) {
+	case KVM_REG_PPC_IVPR: {
+		ulong new_ivpr = set_reg_val(id, *val);
+
+		kvmppc_set_ivpr(vcpu, new_ivpr);
+		break;
+	}
+	case KVM_REG_PPC_IVOR0:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR1:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR2: {
+		u32 new_ivor = set_reg_val(id, *val);
+
+		kvmppc_set_ivor2(vcpu, new_ivor);
+		break;
+	}
+	case KVM_REG_PPC_IVOR3:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR4:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR5:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR6:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR7:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR8: {
+		u32 new_ivor = set_reg_val(id, *val);
+
+		kvmppc_set_ivor8(vcpu, new_ivor);
+		break;
+	}
+	case KVM_REG_PPC_IVOR9:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR10:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR11:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR12:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR13:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR14:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR15:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR35:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] =
+			set_reg_val(id, *val);
+		break;
 	case KVM_REG_PPC_IAC1:
 		vcpu->arch.dbg_reg.iac1 = set_reg_val(id, *val);
 		break;
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 2e02ed8..08f61bf 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -433,14 +433,52 @@ static int kvmppc_core_set_sregs_e500(struct kvm_vcpu *vcpu,
 static int kvmppc_get_one_reg_e500(struct kvm_vcpu *vcpu, u64 id,
 				   union kvmppc_one_reg *val)
 {
-	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	int r = 0;
+
+	switch (id) {
+	case KVM_REG_PPC_IVOR32:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]);
+		break;
+	case KVM_REG_PPC_IVOR33:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]);
+		break;
+	case KVM_REG_PPC_IVOR34:
+		*val = get_reg_val(id,
+				vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]);
+		break;
+	default:
+		r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+		break;
+	}
+
 	return r;
 }
 
 static int kvmppc_set_one_reg_e500(struct kvm_vcpu *vcpu, u64 id,
 				   union kvmppc_one_reg *val)
 {
-	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	int r = 0;
+
+	switch (id) {
+	case KVM_REG_PPC_IVOR32:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR33:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] =
+			set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_IVOR34:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] =
+			set_reg_val(id, *val);
+		break;
+	default:
+		r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+		break;
+	}
+
 	return r;
 }
 
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 4549349..0668bc7 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -268,6 +268,22 @@ static int kvmppc_get_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id,
 	int r = 0;
 
 	switch (id) {
+	case KVM_REG_PPC_IVOR32:
+		*val = get_reg_val(id,
+			vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL]);
+		break;
+	case KVM_REG_PPC_IVOR33:
+		*val = get_reg_val(id,
+			vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST]);
+		break;
+	case KVM_REG_PPC_IVOR36:
+		*val = get_reg_val(id,
+			vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL]);
+		break;
+	case KVM_REG_PPC_IVOR37:
+		*val = get_reg_val(id,
+			vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT]);
+		break;
 	case KVM_REG_PPC_SPRG9:
 		*val = get_reg_val(id, vcpu->arch.sprg9);
 		break;
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v4 3/6] KVM: PPC: Make ONE_REG powerpc generic
From: Mihai Caraman @ 2014-08-20 13:36 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1408541787-24625-1-git-send-email-mihai.caraman@freescale.com>

Make ONE_REG generic for server and embedded architectures by moving
kvm_vcpu_ioctl_get_one_reg() and kvm_vcpu_ioctl_set_one_reg() functions
to powerpc layer.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v4:
 - split ONE_REG powerpc generic and ONE_REG AltiVec

v3:
 - make ONE_REG AltiVec support powerpc generic

v2:
 - add comment describing VCSR register representation in KVM vs kernel

 arch/powerpc/kvm/book3s.c  | 121 +++++++++++++++++++--------------------------
 arch/powerpc/kvm/booke.c   |  91 +++++++++++++---------------------
 arch/powerpc/kvm/powerpc.c |  55 +++++++++++++++++++++
 3 files changed, 138 insertions(+), 129 deletions(-)

diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index dd03f6b..26868e2 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -535,33 +535,28 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 	return -ENOTSUPP;
 }
 
-int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
 {
-	int r;
-	union kvmppc_one_reg val;
-	int size;
+	int r = 0;
 	long int i;
 
-	size = one_reg_size(reg->id);
-	if (size > sizeof(val))
-		return -EINVAL;
-
-	r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val);
+	r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, id, val);
 	if (r == -EINVAL) {
 		r = 0;
-		switch (reg->id) {
+		switch (id) {
 		case KVM_REG_PPC_DAR:
-			val = get_reg_val(reg->id, kvmppc_get_dar(vcpu));
+			*val = get_reg_val(id, kvmppc_get_dar(vcpu));
 			break;
 		case KVM_REG_PPC_DSISR:
-			val = get_reg_val(reg->id, kvmppc_get_dsisr(vcpu));
+			*val = get_reg_val(id, kvmppc_get_dsisr(vcpu));
 			break;
 		case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
-			i = reg->id - KVM_REG_PPC_FPR0;
-			val = get_reg_val(reg->id, VCPU_FPR(vcpu, i));
+			i = id - KVM_REG_PPC_FPR0;
+			*val = get_reg_val(id, VCPU_FPR(vcpu, i));
 			break;
 		case KVM_REG_PPC_FPSCR:
-			val = get_reg_val(reg->id, vcpu->arch.fp.fpscr);
+			*val = get_reg_val(id, vcpu->arch.fp.fpscr);
 			break;
 #ifdef CONFIG_ALTIVEC
 		case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
@@ -569,110 +564,94 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 				r = -ENXIO;
 				break;
 			}
-			val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
+			val->vval = vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0];
 			break;
 		case KVM_REG_PPC_VSCR:
 			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
 				r = -ENXIO;
 				break;
 			}
-			val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
+			*val = get_reg_val(id, vcpu->arch.vr.vscr.u[3]);
 			break;
 		case KVM_REG_PPC_VRSAVE:
-			val = get_reg_val(reg->id, vcpu->arch.vrsave);
+			*val = get_reg_val(id, vcpu->arch.vrsave);
 			break;
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
 		case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
 			if (cpu_has_feature(CPU_FTR_VSX)) {
-				long int i = reg->id - KVM_REG_PPC_VSR0;
-				val.vsxval[0] = vcpu->arch.fp.fpr[i][0];
-				val.vsxval[1] = vcpu->arch.fp.fpr[i][1];
+				i = id - KVM_REG_PPC_VSR0;
+				val->vsxval[0] = vcpu->arch.fp.fpr[i][0];
+				val->vsxval[1] = vcpu->arch.fp.fpr[i][1];
 			} else {
 				r = -ENXIO;
 			}
 			break;
 #endif /* CONFIG_VSX */
-		case KVM_REG_PPC_DEBUG_INST: {
-			u32 opcode = INS_TW;
-			r = copy_to_user((u32 __user *)(long)reg->addr,
-					 &opcode, sizeof(u32));
+		case KVM_REG_PPC_DEBUG_INST:
+			*val = get_reg_val(id, INS_TW);
 			break;
-		}
 #ifdef CONFIG_KVM_XICS
 		case KVM_REG_PPC_ICP_STATE:
 			if (!vcpu->arch.icp) {
 				r = -ENXIO;
 				break;
 			}
-			val = get_reg_val(reg->id, kvmppc_xics_get_icp(vcpu));
+			*val = get_reg_val(id, kvmppc_xics_get_icp(vcpu));
 			break;
 #endif /* CONFIG_KVM_XICS */
 		case KVM_REG_PPC_FSCR:
-			val = get_reg_val(reg->id, vcpu->arch.fscr);
+			*val = get_reg_val(id, vcpu->arch.fscr);
 			break;
 		case KVM_REG_PPC_TAR:
-			val = get_reg_val(reg->id, vcpu->arch.tar);
+			*val = get_reg_val(id, vcpu->arch.tar);
 			break;
 		case KVM_REG_PPC_EBBHR:
-			val = get_reg_val(reg->id, vcpu->arch.ebbhr);
+			*val = get_reg_val(id, vcpu->arch.ebbhr);
 			break;
 		case KVM_REG_PPC_EBBRR:
-			val = get_reg_val(reg->id, vcpu->arch.ebbrr);
+			*val = get_reg_val(id, vcpu->arch.ebbrr);
 			break;
 		case KVM_REG_PPC_BESCR:
-			val = get_reg_val(reg->id, vcpu->arch.bescr);
+			*val = get_reg_val(id, vcpu->arch.bescr);
 			break;
 		case KVM_REG_PPC_VTB:
-			val = get_reg_val(reg->id, vcpu->arch.vtb);
+			*val = get_reg_val(id, vcpu->arch.vtb);
 			break;
 		case KVM_REG_PPC_IC:
-			val = get_reg_val(reg->id, vcpu->arch.ic);
+			*val = get_reg_val(id, vcpu->arch.ic);
 			break;
 		default:
 			r = -EINVAL;
 			break;
 		}
 	}
-	if (r)
-		return r;
-
-	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
-		r = -EFAULT;
 
 	return r;
 }
 
-int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
 {
-	int r;
-	union kvmppc_one_reg val;
-	int size;
+	int r = 0;
 	long int i;
 
-	size = one_reg_size(reg->id);
-	if (size > sizeof(val))
-		return -EINVAL;
-
-	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
-		return -EFAULT;
-
-	r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val);
+	r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, id, val);
 	if (r == -EINVAL) {
 		r = 0;
-		switch (reg->id) {
+		switch (id) {
 		case KVM_REG_PPC_DAR:
-			kvmppc_set_dar(vcpu, set_reg_val(reg->id, val));
+			kvmppc_set_dar(vcpu, set_reg_val(id, *val));
 			break;
 		case KVM_REG_PPC_DSISR:
-			kvmppc_set_dsisr(vcpu, set_reg_val(reg->id, val));
+			kvmppc_set_dsisr(vcpu, set_reg_val(id, *val));
 			break;
 		case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
-			i = reg->id - KVM_REG_PPC_FPR0;
-			VCPU_FPR(vcpu, i) = set_reg_val(reg->id, val);
+			i = id - KVM_REG_PPC_FPR0;
+			VCPU_FPR(vcpu, i) = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_FPSCR:
-			vcpu->arch.fp.fpscr = set_reg_val(reg->id, val);
+			vcpu->arch.fp.fpscr = set_reg_val(id, *val);
 			break;
 #ifdef CONFIG_ALTIVEC
 		case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
@@ -680,29 +659,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 				r = -ENXIO;
 				break;
 			}
-			vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
+			vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0] = val->vval;
 			break;
 		case KVM_REG_PPC_VSCR:
 			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
 				r = -ENXIO;
 				break;
 			}
-			vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
+			vcpu->arch.vr.vscr.u[3] = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_VRSAVE:
 			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
 				r = -ENXIO;
 				break;
 			}
-			vcpu->arch.vrsave = set_reg_val(reg->id, val);
+			vcpu->arch.vrsave = set_reg_val(id, *val);
 			break;
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
 		case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
 			if (cpu_has_feature(CPU_FTR_VSX)) {
-				long int i = reg->id - KVM_REG_PPC_VSR0;
-				vcpu->arch.fp.fpr[i][0] = val.vsxval[0];
-				vcpu->arch.fp.fpr[i][1] = val.vsxval[1];
+				i = id - KVM_REG_PPC_VSR0;
+				vcpu->arch.fp.fpr[i][0] = val->vsxval[0];
+				vcpu->arch.fp.fpr[i][1] = val->vsxval[1];
 			} else {
 				r = -ENXIO;
 			}
@@ -715,29 +694,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 				break;
 			}
 			r = kvmppc_xics_set_icp(vcpu,
-						set_reg_val(reg->id, val));
+						set_reg_val(id, *val));
 			break;
 #endif /* CONFIG_KVM_XICS */
 		case KVM_REG_PPC_FSCR:
-			vcpu->arch.fscr = set_reg_val(reg->id, val);
+			vcpu->arch.fscr = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_TAR:
-			vcpu->arch.tar = set_reg_val(reg->id, val);
+			vcpu->arch.tar = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_EBBHR:
-			vcpu->arch.ebbhr = set_reg_val(reg->id, val);
+			vcpu->arch.ebbhr = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_EBBRR:
-			vcpu->arch.ebbrr = set_reg_val(reg->id, val);
+			vcpu->arch.ebbrr = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_BESCR:
-			vcpu->arch.bescr = set_reg_val(reg->id, val);
+			vcpu->arch.bescr = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_VTB:
-			vcpu->arch.vtb = set_reg_val(reg->id, val);
+			vcpu->arch.vtb = set_reg_val(id, *val);
 			break;
 		case KVM_REG_PPC_IC:
-			vcpu->arch.ic = set_reg_val(reg->id, val);
+			vcpu->arch.ic = set_reg_val(id, *val);
 			break;
 		default:
 			r = -EINVAL;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 8ace612..831c1b4 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1564,150 +1564,125 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 	return vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs);
 }
 
-int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
 {
 	int r = 0;
-	union kvmppc_one_reg val;
-	int size;
 
-	size = one_reg_size(reg->id);
-	if (size > sizeof(val))
-		return -EINVAL;
-
-	switch (reg->id) {
+	switch (id) {
 	case KVM_REG_PPC_IAC1:
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac1);
+		*val = get_reg_val(id, vcpu->arch.dbg_reg.iac1);
 		break;
 	case KVM_REG_PPC_IAC2:
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac2);
+		*val = get_reg_val(id, vcpu->arch.dbg_reg.iac2);
 		break;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
 	case KVM_REG_PPC_IAC3:
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac3);
+		*val = get_reg_val(id, vcpu->arch.dbg_reg.iac3);
 		break;
 	case KVM_REG_PPC_IAC4:
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac4);
+		*val = get_reg_val(id, vcpu->arch.dbg_reg.iac4);
 		break;
 #endif
 	case KVM_REG_PPC_DAC1:
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac1);
+		*val = get_reg_val(id, vcpu->arch.dbg_reg.dac1);
 		break;
 	case KVM_REG_PPC_DAC2:
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2);
-		break;
-	case KVM_REG_PPC_DBSR:
-		val = get_reg_val(reg->id, vcpu->arch.dbsr);
+		*val = get_reg_val(id, vcpu->arch.dbg_reg.dac2);
 		break;
 	case KVM_REG_PPC_EPR: {
 		u32 epr = kvmppc_get_epr(vcpu);
-		val = get_reg_val(reg->id, epr);
+		*val = get_reg_val(id, epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR:
-		val = get_reg_val(reg->id, vcpu->arch.epcr);
+		*val = get_reg_val(id, vcpu->arch.epcr);
 		break;
 #endif
 	case KVM_REG_PPC_TCR:
-		val = get_reg_val(reg->id, vcpu->arch.tcr);
+		*val = get_reg_val(id, vcpu->arch.tcr);
 		break;
 	case KVM_REG_PPC_TSR:
-		val = get_reg_val(reg->id, vcpu->arch.tsr);
+		*val = get_reg_val(id, vcpu->arch.tsr);
 		break;
 	case KVM_REG_PPC_DEBUG_INST:
-		val = get_reg_val(reg->id, KVMPPC_INST_EHPRIV_DEBUG);
+		*val = get_reg_val(id, KVMPPC_INST_EHPRIV_DEBUG);
 		break;
 	case KVM_REG_PPC_VRSAVE:
-		val = get_reg_val(reg->id, vcpu->arch.vrsave);
+		*val = get_reg_val(id, vcpu->arch.vrsave);
 		break;
 	default:
-		r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val);
+		r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, id, val);
 		break;
 	}
 
-	if (r)
-		return r;
-
-	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
-		r = -EFAULT;
-
 	return r;
 }
 
-int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
 {
 	int r = 0;
-	union kvmppc_one_reg val;
-	int size;
 
-	size = one_reg_size(reg->id);
-	if (size > sizeof(val))
-		return -EINVAL;
-
-	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
-		return -EFAULT;
-
-	switch (reg->id) {
+	switch (id) {
 	case KVM_REG_PPC_IAC1:
-		vcpu->arch.dbg_reg.iac1 = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.iac1 = set_reg_val(id, *val);
 		break;
 	case KVM_REG_PPC_IAC2:
-		vcpu->arch.dbg_reg.iac2 = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.iac2 = set_reg_val(id, *val);
 		break;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
 	case KVM_REG_PPC_IAC3:
-		vcpu->arch.dbg_reg.iac3 = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.iac3 = set_reg_val(id, *val);
 		break;
 	case KVM_REG_PPC_IAC4:
-		vcpu->arch.dbg_reg.iac4 = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.iac4 = set_reg_val(id, *val);
 		break;
 #endif
 	case KVM_REG_PPC_DAC1:
-		vcpu->arch.dbg_reg.dac1 = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.dac1 = set_reg_val(id, *val);
 		break;
 	case KVM_REG_PPC_DAC2:
-		vcpu->arch.dbg_reg.dac2 = set_reg_val(reg->id, val);
-		break;
-	case KVM_REG_PPC_DBSR:
-		vcpu->arch.dbsr = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.dac2 = set_reg_val(id, *val);
 		break;
 	case KVM_REG_PPC_EPR: {
-		u32 new_epr = set_reg_val(reg->id, val);
+		u32 new_epr = set_reg_val(id, *val);
 		kvmppc_set_epr(vcpu, new_epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR: {
-		u32 new_epcr = set_reg_val(reg->id, val);
+		u32 new_epcr = set_reg_val(id, *val);
 		kvmppc_set_epcr(vcpu, new_epcr);
 		break;
 	}
 #endif
 	case KVM_REG_PPC_OR_TSR: {
-		u32 tsr_bits = set_reg_val(reg->id, val);
+		u32 tsr_bits = set_reg_val(id, *val);
 		kvmppc_set_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_CLEAR_TSR: {
-		u32 tsr_bits = set_reg_val(reg->id, val);
+		u32 tsr_bits = set_reg_val(id, *val);
 		kvmppc_clr_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_TSR: {
-		u32 tsr = set_reg_val(reg->id, val);
+		u32 tsr = set_reg_val(id, *val);
 		kvmppc_set_tsr(vcpu, tsr);
 		break;
 	}
 	case KVM_REG_PPC_TCR: {
-		u32 tcr = set_reg_val(reg->id, val);
+		u32 tcr = set_reg_val(id, *val);
 		kvmppc_set_tcr(vcpu, tcr);
 		break;
 	}
 	case KVM_REG_PPC_VRSAVE:
-		vcpu->arch.vrsave = set_reg_val(reg->id, val);
+		vcpu->arch.vrsave = set_reg_val(id, *val);
 		break;
 	default:
-		r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val);
+		r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, id, val);
 		break;
 	}
 
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 4c79284..1326116 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -927,6 +927,61 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
 }
 EXPORT_SYMBOL_GPL(kvmppc_handle_store);
 
+int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
+{
+	int r = 0;
+	union kvmppc_one_reg val;
+	int size;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
+
+	r = kvmppc_get_one_reg(vcpu, reg->id, &val);
+	if (r == -EINVAL) {
+		r = 0;
+		switch (reg->id) {
+		default:
+			r = -EINVAL;
+			break;
+		}
+	}
+
+	if (r)
+		return r;
+
+	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
+		r = -EFAULT;
+
+	return r;
+}
+
+int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
+{
+	int r;
+	union kvmppc_one_reg val;
+	int size;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
+
+	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
+		return -EFAULT;
+
+	r = kvmppc_set_one_reg(vcpu, reg->id, &val);
+	if (r == -EINVAL) {
+		r = 0;
+		switch (reg->id) {
+		default:
+			r = -EINVAL;
+			break;
+		}
+	}
+
+	return r;
+}
+
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
 	int r;
-- 
1.7.11.7

^ permalink raw reply related

* Re: [PATCH v2 00/14] Add support for parameterized events from sysfs
From: Jiri Olsa @ 2014-08-20 14:15 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: ak, Michael Ellerman, peterz, linux-kernel, eranian, dev,
	Arnaldo Carvalho de Melo, linuxppc-dev, Anshuman Khandual
In-Reply-To: <1408087583-32239-1-git-send-email-sukadev@linux.vnet.ibm.com>

On Fri, Aug 15, 2014 at 12:26:09AM -0700, Sukadev Bhattiprolu wrote:
> From: Cody P Schafer <dev@codyps.com>
> 
> What this patchset does:
> 
>  - the first patch (override sysfs in tools/perf via SYSFS_PATH) was sent out
>    previously, but needed a resend anyhow. Having it is useful for testing the
>    later changes to tools/perf.
>  - the second patch is a bugfix to the powerpc hv-24x7 code which was
>    previously sent out, which is a good idea to have when testing these patches
>    on POWER8 hardware.
> 
>  - document perf sysfs and the changes to add parameterized events
>    - semi-notably: removes the growing list of specific POWER cpu events and
>      begins documenting them generically, much like the docs for
>      /sys/modules/MODULENAME do for modules.
>  - tools/perf changes to support parameterized events
>  - export some parameterized events from the powerpc pmus hv_24x7 and hv_gpci
> 
> Description of "event parameters" from the documentation patch:
> 
>     Event parameters are a basic way for partial events to be specified in
>     sysfs with per-event names given to the fields that need to be filled in
>     when using a particular event.
> 
>     It is intended for supporting cases where the single 'cpu' parameter is
>     insufficient. For example, POWER 8 has events for physical
>     sockets/cores/cpus that are accessible from with virtual machines. To
>     keep using the single 'cpu' parameter we'd need to perform a mapping
>     between Linux's cpus and the physical machine's cpus (in this case
>     Linux is running under a hypervisor). This isn't possible because
>     bindings between our cpus and physical cpus may not be fixed, and we
>     probably won't have a "cpu" on each physical cpu.
> 
> Description of the sysfs contents when events are parameterized (copied from an
> included patch):
> 
> 	Examples:
> 
> 		domain=0x1,offset=0x8,starting_index=phys_cpu
> 
> 	In the case of the last example, a value replacing "phys_cpu"
> 	would need to be provided by the user selecting the particular
> 	event. This is refered to as "event parameterization". All
> 	non-numerical values indicate an event parameter.
> 
> Notes on how perf-list displays parameterized events (and how to use them,
> again culled from an included patch):
> 
> 	PARAMETERIZED EVENTS
> 	--------------------
> 
> 	Some pmu events listed by 'perf-list' will be displayed with '?' in
> 	them. For example:
> 
> 	  hv_gpci/dtbp_ptitc,phys_processor_idx=?/
> 
> 	This means that when provided as an event, a value for
> 	phys_processor_idx must also be supplied. For example:
> 
> 	  perf stat -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ...

hi,
is the reason for this to document this field for event
in "events/<event>" file?

Because once you have the field (phys_processor_idx) defined in
"formats/phys_processor_idx" you should be able to use it as in
your example:

   perf stat -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/'

without any changes

thanks,
jirka

^ 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