On Mon, 2006-02-13 at 23:45 +0000, Keir Fraser wrote:
>
> This opacity should probably be represented in the public header file
> definitions and in the prototypes of uaccess functions, instead of
> pretending the handles are really 'foo *' pointers. That would help
> clean up all uses of the uaccess functions in Xen.
One nice thing about leaving the types present is that some of the
macros can do some type-checking.
I'd be happy to help look at the uaccess users in general, but that's
not my immediate problem. This patch solves my immediate problem (though
obviously breaks x86* and ia64; I include it only for discussion). There
are other users of uaccess macros in common code, but due to other
problems (*ahem* grant_table.c) we don't build those right now anyways.
I am also attaching my new asm-ppc/uaccess.h so you can see the full API
presented. (I want to remove all get/put_user calls entirely so the
compiler will catch xencomm-incompatible users.)
I don't know what implications this could have for ia64, since they suck
in so much Linux code... but perhaps that Linux code isn't the stuff
that deals with userland, so might not have uaccess users.
While we're at it, I would like to rename *_user to *_domain, but that's
a cosmetic thing that can be done at any time.
Keir, would you accept this patch?
--- a/xen/common/memory.c Tue Feb 14 05:48:33 2006
+++ b/xen/common/memory.c Tue Feb 14 06:22:09 2006
@@ -60,7 +60,7 @@
/* Inform the domain of the new page's machine address. */
if ( (extent_list != NULL) &&
- (__put_user(page_to_pfn(page), &extent_list[i]) != 0) )
+ (__put_user_array(page_to_pfn(page), extent_list, i) != 0) )
return i;
}
@@ -90,7 +90,7 @@
return i;
}
- if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) )
+ if ( unlikely(__get_user_array(mpfn, extent_list, i) != 0) )
return i;
for ( j = 0; j < (1 << extent_order); j++ )
@@ -197,7 +197,7 @@
case XENMEM_current_reservation:
case XENMEM_maximum_reservation:
- if ( get_user(domid, (domid_t *)arg) )
+ if ( get_user_offset(domid, (domid_t *)arg, 0) )
return -EFAULT;
if ( likely((domid = (unsigned long)arg) == DOMID_SELF) )
--- a/xen/drivers/char/console.c Tue Feb 14 05:48:33 2006
+++ b/xen/drivers/char/console.c Tue Feb 14 06:22:09 2006
@@ -230,7 +230,7 @@
/* Start of buffer may get overwritten during copy. So copy backwards. */
for ( p = conringp, q = count; (p > conringc) && (q > 0); p--, q-- )
- if ( put_user(conring[CONRING_IDX_MASK(p-1)], (char *)str+q-1) )
+ if ( put_user_array(conring[CONRING_IDX_MASK(p-1)], (char *)str, q-1) )
return -EFAULT;
if ( clear )
@@ -362,8 +362,8 @@
rc = 0;
while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
{
- if ( put_user(serial_rx_ring[SERIAL_RX_MASK(serial_rx_cons)],
- &buffer[rc]) )
+ if ( put_user_array(serial_rx_ring[SERIAL_RX_MASK(serial_rx_cons)],
+ buffer, rc) )
{
rc = -EFAULT;
break;
/*
* Copyright (C) 2006 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __PPC_UACCESS_H__
#define __PPC_UACCESS_H__
#include <xen/errno.h>
#include <asm/page.h>
/* since we run in real mode, we can safely access all addresses.
* XXX well, except IO. should we check for that here? */
#define access_ok(addr,size) 1
#define array_access_ok(addr,count,size) 1
#define __copy_to_user copy_to_user
#define __copy_from_user copy_from_user
#define copy_to_user(to,from,len) xencomm_copy_to_user(to,from,len,0)
#define copy_from_user(to,from,len) xencomm_copy_from_user(to,from,len,0)
extern unsigned long xencomm_copy_to_user(void *to, const void *from,
unsigned len, unsigned int skip);
extern unsigned long xencomm_copy_from_user(void *to, const void *from,
unsigned len, unsigned int skip);
#define get_user_array(val,array,idx) __get_user_array(val,array,idx)
#define __get_user_array(val,array,idx) \
xencomm_get_user_offset((val), (array), (idx) * sizeof(*(array)))
#define get_user_offset(val,ptr,offset) __get_user_offset(val,ptr,offset)
#define __get_user_offset(val,ptr,offset) \
xencomm_get_user_offset((val), (ptr), (offset))
#define xencomm_get_user_offset(val,ptr,offset) \
({ \
long __gu_err; \
__typeof__(*(ptr)) __gu_tmp; \
__gu_err = xencomm_copy_from_user(&__gu_tmp, (ptr), \
sizeof(__gu_tmp), offset); \
if (__gu_err) \
__gu_err = -EFAULT; \
val = __gu_tmp; \
__gu_err; \
})
#define put_user_array(val,array,idx) __put_user_array(val,array,idx)
#define __put_user_array(val,array,idx) \
xencomm_put_user_offset((val), (array), (idx) * sizeof(*(array)))
#define put_user_offset(val,ptr,offset) __put_user_offset(val,ptr,offset)
#define __put_user_offset(val,ptr,offset) \
xencomm_put_user_offset((val), (ptr), (offset))
#define xencomm_put_user_offset(val,ptr,offset) \
({ \
long __pu_err; \
__typeof__(*(ptr)) __pu_tmp = val; \
__pu_err = xencomm_copy_to_user((ptr), &__pu_tmp, \
sizeof(__pu_tmp), offset); \
if (__pu_err) \
__pu_err = -EFAULT; \
__pu_err; \
})
#endif /* __PPC_UACCESS_H__ */
--
Hollis Blanchard
IBM Linux Technology Center
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|