diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-22 11:24:24 +1000 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-23 15:49:56 +1000 |
commit | 2d37f94a28170ca656438758fca577acb49a7932 (patch) | |
tree | 21049219a98d314a2c442293e512b74d879e6270 /drivers/lguest/lg.h | |
parent | 56ae43dfe233323683248a5c553bad7160db2fa5 (diff) | |
download | lwn-2d37f94a28170ca656438758fca577acb49a7932.tar.gz lwn-2d37f94a28170ca656438758fca577acb49a7932.zip |
generalize lgread_u32/lgwrite_u32.
Jes complains that page table code still uses lgread_u32 even though
it now uses general kernel pte types. The best thing to do is to
generalize lgread_u32 and lgwrite_u32.
This means we lose the efficiency of getuser(). We could potentially
regain it if we used __copy_from_user instead of copy_from_user, but
I'm not certain that our range check is equivalent to access_ok() on
all platforms.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Acked-by: Jes Sorensen <jes@sgi.com>
Diffstat (limited to 'drivers/lguest/lg.h')
-rw-r--r-- | drivers/lguest/lg.h | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index 4d45b7036e82..d9144beca82c 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h @@ -98,12 +98,27 @@ struct lguest extern struct mutex lguest_lock; /* core.c: */ -u32 lgread_u32(struct lguest *lg, unsigned long addr); -void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val); -void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len); -void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len); int lguest_address_ok(const struct lguest *lg, unsigned long addr, unsigned long len); +void __lgread(struct lguest *, void *, unsigned long, unsigned); +void __lgwrite(struct lguest *, unsigned long, const void *, unsigned); + +/*L:306 Using memory-copy operations like that is usually inconvient, so we + * have the following helper macros which read and write a specific type (often + * an unsigned long). + * + * This reads into a variable of the given type then returns that. */ +#define lgread(lg, addr, type) \ + ({ type _v; __lgread((lg), &_v, (addr), sizeof(_v)); _v; }) + +/* This checks that the variable is of the given type, then writes it out. */ +#define lgwrite(lg, addr, type, val) \ + do { \ + typecheck(type, val); \ + __lgwrite((lg), (addr), &(val), sizeof(val)); \ + } while(0) +/* (end of memory access helper routines) :*/ + int run_guest(struct lguest *lg, unsigned long __user *user); /* Helper macros to obtain the first 12 or the last 20 bits, this is only the |