|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.5] xen: arm: correctly handle continuations for 64-bit guests
commit 1dcdf90a9f37e598e3f6c20ad96a551602777802
Author: Ian Campbell <ian.campbell@xxxxxxxxxx>
AuthorDate: Thu Mar 26 10:54:04 2015 +0000
Commit: Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Thu Apr 2 11:45:19 2015 +0100
xen: arm: correctly handle continuations for 64-bit guests
The 64-bit ABI is different to 32-bit:
- uses x16 as the op register rather than r12.
- arguments in x0..x5 and not r0..r5. Using rN here potentially
truncates.
- return value goes in x0, not r0.
Hypercalls can only be made directly from kernel space, so checking
the domain's size is sufficient.
Spotted due to spurious -EFAULT when destroying a domain, due to the
hypercall's pointer argument being truncated. I'm unclear why I am
only seeing this now.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Reviewed-by: Julien Grall <julien.grall@xxxxxxxxxx>
(cherry picked from commit 7466b88ec2c59b1769da358bdc843bcabbee522c)
---
xen/arch/arm/domain.c | 54 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 7221bc8..47431bf 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -357,29 +357,57 @@ unsigned long hypercall_create_continuation(
}
else
{
- regs = guest_cpu_user_regs();
- regs->r12 = op;
+ regs = guest_cpu_user_regs();
/* Ensure the hypercall trap instruction is re-executed. */
regs->pc -= 4; /* re-execute 'hvc #XEN_HYPERCALL_TAG' */
- for ( i = 0; *p != '\0'; i++ )
+#ifdef CONFIG_ARM_64
+ if ( !is_32bit_domain(current->domain) )
{
- arg = next_arg(p, args);
+ regs->x16 = op;
- switch ( i )
+ for ( i = 0; *p != '\0'; i++ )
{
- case 0: regs->r0 = arg; break;
- case 1: regs->r1 = arg; break;
- case 2: regs->r2 = arg; break;
- case 3: regs->r3 = arg; break;
- case 4: regs->r4 = arg; break;
- case 5: regs->r5 = arg; break;
+ arg = next_arg(p, args);
+
+ switch ( i )
+ {
+ case 0: regs->x0 = arg; break;
+ case 1: regs->x1 = arg; break;
+ case 2: regs->x2 = arg; break;
+ case 3: regs->x3 = arg; break;
+ case 4: regs->x4 = arg; break;
+ case 5: regs->x5 = arg; break;
+ }
}
+
+ /* Return value gets written back to x0 */
+ rc = regs->x0;
}
+ else
+#endif
+ {
+ regs->r12 = op;
- /* Return value gets written back to r0 */
- rc = regs->r0;
+ for ( i = 0; *p != '\0'; i++ )
+ {
+ arg = next_arg(p, args);
+
+ switch ( i )
+ {
+ case 0: regs->r0 = arg; break;
+ case 1: regs->r1 = arg; break;
+ case 2: regs->r2 = arg; break;
+ case 3: regs->r3 = arg; break;
+ case 4: regs->r4 = arg; break;
+ case 5: regs->r5 = arg; break;
+ }
+ }
+
+ /* Return value gets written back to r0 */
+ rc = regs->r0;
+ }
}
va_end(args);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.5
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |