I added a new inline function "invalid_endianness" for better readability.
An invalid address now returns -EINVAL and triggers a WARN_ON().
If a more sophisticated check is wanted later on like a additional >0x0C or something we can add this there on a central point.
If we will need it somewhere else in the future we can move it to a header.

This replaces the workaround patch sent with "libvirt status of bugt racking regarding bad paddr (patch)".

FYI I attached the libvirt patch too


--

Grüsse / regards, Christian Ehrhardt

IBM Linux Technology Center, Open Virtualization
+49 7031/16-3385
[EMAIL PROTECTED]
[EMAIL PROTECTED]

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen Geschäftsführung: Herbert Kircher Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

diff -r 1139ab948449 arch/powerpc/platforms/xen/hcall.c
--- a/arch/powerpc/platforms/xen/hcall.c	Sun Jul 15 15:33:56 2007 +0200
+++ b/arch/powerpc/platforms/xen/hcall.c	Sun Aug 05 03:50:28 2007 +0200
@@ -437,6 +437,16 @@ out:
 	return ret;
 }
 
+static inline int invalid_endianness(void *ptr)
+{
+	unsigned long p = (unsigned long)ptr;
+	if ( ((p & 0x00000000FFFFFFFFUL) == 0x0) 
+	  && ((p & 0xFFFFFFFF00000000UL) != 0x0) )
+		return 1;
+	else
+		return 0;
+}
+
 static int xenppc_privcmd_sysctl(privcmd_hypercall_t *hypercall)
 {
 	xen_sysctl_t kern_op;
@@ -481,6 +491,11 @@ static int xenppc_privcmd_sysctl(privcmd
 		printk(KERN_ERR "%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
 		return -ENOSYS;
 	case XEN_SYSCTL_getdomaininfolist:
+		if (invalid_endianness(kern_op.u.getdomaininfolist.buffer.p)) {
+			WARN_ON(1);
+			return -EINVAL;
+		}
+
 		desc = xencomm_map(
 			xen_guest_handle(kern_op.u.getdomaininfolist.buffer),
 			kern_op.u.getdomaininfolist.max_domains *
diff -r 57c3b9568ea6 src/xen_internal.c
--- a/src/xen_internal.c	Thu Jul 19 13:52:36 2007 +0200
+++ b/src/xen_internal.c	Sun Aug 05 04:04:51 2007 +0200
@@ -314,10 +314,17 @@ struct xen_v2s3_getdomaininfolistop {
 struct xen_v2s3_getdomaininfolistop {
     domid_t   first_domain;
     uint32_t  max_domains;
+#ifdef __BIG_ENDIAN__
+    struct {
+        int __pad[(sizeof (long long) - sizeof (struct xen_v2d5_getdomaininfo *)) / sizeof (int)];
+        struct xen_v2d5_getdomaininfo *v;
+    } buffer;
+#else
     union {
         struct xen_v2d5_getdomaininfo *v;
         uint64_t pad ALIGN_64;
     } buffer;
+#endif
     uint32_t  num_domains;
 };
 typedef struct xen_v2s3_getdomaininfolistop xen_v2s3_getdomaininfolistop;
@@ -422,10 +429,17 @@ typedef struct xen_v2_setvcpumap xen_v2_
 
 /* HV version 2, Dom version 5 requires 64-bit alignment */
 struct xen_v2d5_cpumap {
+#ifdef __BIG_ENDIAN__
+    struct {
+        int __pad[(sizeof (long long) - sizeof (uint8_t *)) / sizeof (int)];
+        uint8_t *v;
+    } bitmap;
+#else
     union {
         uint8_t    *v;
         uint64_t   pad ALIGN_64;
     } bitmap;
+#endif
     uint32_t    nr_cpus;
 };
 struct xen_v2d5_setvcpumap {
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to