diff mbox

[kvm-unit-tests,v2,5/5] powerpc: Check lswx in little-endian mode.

Message ID 1458560014-28862-6-git-send-email-lvivier@redhat.com
State Accepted
Headers show

Commit Message

Laurent Vivier March 21, 2016, 11:33 a.m. UTC
For lswx in little-endian mode, an alignment interrupt occurs.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 powerpc/emulator.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Comments

David Gibson March 21, 2016, 11:56 p.m. UTC | #1
On Mon, 21 Mar 2016 12:33:34 +0100
Laurent Vivier <lvivier@redhat.com> wrote:

> For lswx in little-endian mode, an alignment interrupt occurs.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>

I'm not entirely clear here; will the test fail if the alignment
exception doesn't occur in little endian mode?

The general trend in Power has been for less and less things to trigger
alignment exceptions, so failing to cause an alignment exception
shouldn't cause a test failure (as long as the unaligned case is
correctly processed, of course).

> ---
>  powerpc/emulator.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/powerpc/emulator.c b/powerpc/emulator.c
> index 8d0dde2..87ef4a9 100644
> --- a/powerpc/emulator.c
> +++ b/powerpc/emulator.c
> @@ -7,6 +7,7 @@
>  
>  static int verbose;
>  static int volatile is_invalid;
> +static int volatile alignment;
>  
>  static void program_check_handler(struct pt_regs *regs, void *opaque)
>  {
> @@ -30,6 +31,18 @@ static void program_check_handler(struct pt_regs *regs, void *opaque)
>  	regs->nip += 4;
>  }
>  
> +static void alignment_handler(struct pt_regs *regs, void *opaque)
> +{
> +	int *data = opaque;
> +
> +	printf("Detected alignment exception 0x%016lx: %08x\n",
> +	       regs->nip, *(uint32_t*)regs->nip);
> +
> +	*data = 1;
> +
> +	regs->nip += 4;
> +}
> +
>  static void test_illegal(void)
>  {
>  	report_prefix_push("invalid");
> @@ -73,6 +86,8 @@ static void test_64bit(void)
>   * - RT <= RA or RB < RT + (n + 4) is invalid or result is undefined
>   * - RT == RA == 0 is invalid
>   *
> + * For lswx in little-endian mode, an alignment interrupt always occurs.
> + *
>   */
>  
>  static void test_lswx(void)
> @@ -90,6 +105,7 @@ static void test_lswx(void)
>  
>  	/* check incomplete register filling */
>  
> +	alignment = 0;
>  	asm volatile ("mtxer %[len];"
>  		      "li r12,-1;"
>  		      "mr r11, r12;"
> @@ -103,7 +119,12 @@ static void test_lswx(void)
>  		      :
>  		      "xer", "r11", "r12", "memory");
>  
> +#if  __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> +	report("alignment", alignment);
> +	return;
> +#else
>  	report("partial", regs[0] == 0x01020300 && regs[1] == (uint64_t)-1);
> +#endif
>  
>  	/* check an old know bug: the number of bytes is used as
>  	 * the number of registers, so try 32 bytes.
> @@ -200,6 +221,7 @@ int main(int argc, char **argv)
>  	int i;
>  
>  	handle_exception(0x700, program_check_handler, (void *)&is_invalid);
> +	handle_exception(0x600, alignment_handler, (void *)&alignment);
>  
>  	for (i = 0; i < argc; i++) {
>  		if (strcmp(argv[i], "-v") == 0) {
> -- 
> 2.5.0
>
Thomas Huth March 22, 2016, 8:12 a.m. UTC | #2
On 22.03.2016 00:56, David Gibson wrote:
> On Mon, 21 Mar 2016 12:33:34 +0100
> Laurent Vivier <lvivier@redhat.com> wrote:
> 
>> For lswx in little-endian mode, an alignment interrupt occurs.
>>
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> Reviewed-by: Thomas Huth <thuth@redhat.com>
> 
> I'm not entirely clear here; will the test fail if the alignment
> exception doesn't occur in little endian mode?

I think so, yes.

> The general trend in Power has been for less and less things to trigger
> alignment exceptions, so failing to cause an alignment exception
> shouldn't cause a test failure (as long as the unaligned case is
> correctly processed, of course).

According to the PowerISA 2.07, chapter 6.5.8, lswx should always
trigger an alignment exception in little endian mode. So that's
architected behavior and the test should be OK, as far as I can see...
In case this gets changed with a future CPU, I think the test could be
adapted later, too?

 Thomas
Laurent Vivier March 22, 2016, 8:25 a.m. UTC | #3
On 22/03/2016 09:12, Thomas Huth wrote:
> On 22.03.2016 00:56, David Gibson wrote:
>> On Mon, 21 Mar 2016 12:33:34 +0100
>> Laurent Vivier <lvivier@redhat.com> wrote:
>>
>>> For lswx in little-endian mode, an alignment interrupt occurs.
>>>
>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>> Reviewed-by: Thomas Huth <thuth@redhat.com>
>>
>> I'm not entirely clear here; will the test fail if the alignment
>> exception doesn't occur in little endian mode?
> 
> I think so, yes.
> 
>> The general trend in Power has been for less and less things to trigger
>> alignment exceptions, so failing to cause an alignment exception
>> shouldn't cause a test failure (as long as the unaligned case is
>> correctly processed, of course).
> 
> According to the PowerISA 2.07, chapter 6.5.8, lswx should always
> trigger an alignment exception in little endian mode. So that's
> architected behavior and the test should be OK, as far as I can see...
> In case this gets changed with a future CPU, I think the test could be
> adapted later, too?

Exactly.

Then in the kernel, the instruction is emulated. It's why I didn't
understand why this test case fails with kvm in little endian mode,
while is was working on a real host or in a guest.

Laurent
--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Gibson March 23, 2016, 12:14 a.m. UTC | #4
On Tue, 22 Mar 2016 09:25:58 +0100
Laurent Vivier <lvivier@redhat.com> wrote:

> On 22/03/2016 09:12, Thomas Huth wrote:
> > On 22.03.2016 00:56, David Gibson wrote:  
> >> On Mon, 21 Mar 2016 12:33:34 +0100
> >> Laurent Vivier <lvivier@redhat.com> wrote:
> >>  
> >>> For lswx in little-endian mode, an alignment interrupt occurs.
> >>>
> >>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> >>> Reviewed-by: Thomas Huth <thuth@redhat.com>  
> >>
> >> I'm not entirely clear here; will the test fail if the alignment
> >> exception doesn't occur in little endian mode?  
> > 
> > I think so, yes.
> >   
> >> The general trend in Power has been for less and less things to trigger
> >> alignment exceptions, so failing to cause an alignment exception
> >> shouldn't cause a test failure (as long as the unaligned case is
> >> correctly processed, of course).  
> > 
> > According to the PowerISA 2.07, chapter 6.5.8, lswx should always
> > trigger an alignment exception in little endian mode. So that's
> > architected behavior and the test should be OK, as far as I can see...
> > In case this gets changed with a future CPU, I think the test could be
> > adapted later, too?  
> 
> Exactly.
> 
> Then in the kernel, the instruction is emulated. It's why I didn't
> understand why this test case fails with kvm in little endian mode,
> while is was working on a real host or in a guest.

Ok, then.
diff mbox

Patch

diff --git a/powerpc/emulator.c b/powerpc/emulator.c
index 8d0dde2..87ef4a9 100644
--- a/powerpc/emulator.c
+++ b/powerpc/emulator.c
@@ -7,6 +7,7 @@ 
 
 static int verbose;
 static int volatile is_invalid;
+static int volatile alignment;
 
 static void program_check_handler(struct pt_regs *regs, void *opaque)
 {
@@ -30,6 +31,18 @@  static void program_check_handler(struct pt_regs *regs, void *opaque)
 	regs->nip += 4;
 }
 
+static void alignment_handler(struct pt_regs *regs, void *opaque)
+{
+	int *data = opaque;
+
+	printf("Detected alignment exception 0x%016lx: %08x\n",
+	       regs->nip, *(uint32_t*)regs->nip);
+
+	*data = 1;
+
+	regs->nip += 4;
+}
+
 static void test_illegal(void)
 {
 	report_prefix_push("invalid");
@@ -73,6 +86,8 @@  static void test_64bit(void)
  * - RT <= RA or RB < RT + (n + 4) is invalid or result is undefined
  * - RT == RA == 0 is invalid
  *
+ * For lswx in little-endian mode, an alignment interrupt always occurs.
+ *
  */
 
 static void test_lswx(void)
@@ -90,6 +105,7 @@  static void test_lswx(void)
 
 	/* check incomplete register filling */
 
+	alignment = 0;
 	asm volatile ("mtxer %[len];"
 		      "li r12,-1;"
 		      "mr r11, r12;"
@@ -103,7 +119,12 @@  static void test_lswx(void)
 		      :
 		      "xer", "r11", "r12", "memory");
 
+#if  __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+	report("alignment", alignment);
+	return;
+#else
 	report("partial", regs[0] == 0x01020300 && regs[1] == (uint64_t)-1);
+#endif
 
 	/* check an old know bug: the number of bytes is used as
 	 * the number of registers, so try 32 bytes.
@@ -200,6 +221,7 @@  int main(int argc, char **argv)
 	int i;
 
 	handle_exception(0x700, program_check_handler, (void *)&is_invalid);
+	handle_exception(0x600, alignment_handler, (void *)&alignment);
 
 	for (i = 0; i < argc; i++) {
 		if (strcmp(argv[i], "-v") == 0) {