aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/core.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-07-26 13:41:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-26 14:35:17 -0400
commitdde797899ac17ebb812b7566044124d785e98dc7 (patch)
tree531ae7fd415d267e49acfedbbf4f03cf86e5eac1 /drivers/lguest/core.c
parente2c9784325490c878b7f69aeec1bed98b288bd97 (diff)
lguest: documentation IV: Launcher
Documentation: The Launcher Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/lguest/core.c')
-rw-r--r--drivers/lguest/core.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 2cea0c80c992..1eb05f9a56b6 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -208,24 +208,39 @@ static int emulate_insn(struct lguest *lg)
208 return 1; 208 return 1;
209} 209}
210 210
211/*L:305
212 * Dealing With Guest Memory.
213 *
214 * When the Guest gives us (what it thinks is) a physical address, we can use
215 * the normal copy_from_user() & copy_to_user() on that address: remember,
216 * Guest physical == Launcher virtual.
217 *
218 * But we can't trust the Guest: it might be trying to access the Launcher
219 * code. We have to check that the range is below the pfn_limit the Launcher
220 * gave us. We have to make sure that addr + len doesn't give us a false
221 * positive by overflowing, too. */
211int lguest_address_ok(const struct lguest *lg, 222int lguest_address_ok(const struct lguest *lg,
212 unsigned long addr, unsigned long len) 223 unsigned long addr, unsigned long len)
213{ 224{
214 return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr); 225 return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
215} 226}
216 227
217/* Just like get_user, but don't let guest access lguest binary. */ 228/* This is a convenient routine to get a 32-bit value from the Guest (a very
229 * common operation). Here we can see how useful the kill_lguest() routine we
230 * met in the Launcher can be: we return a random value (0) instead of needing
231 * to return an error. */
218u32 lgread_u32(struct lguest *lg, unsigned long addr) 232u32 lgread_u32(struct lguest *lg, unsigned long addr)
219{ 233{
220 u32 val = 0; 234 u32 val = 0;
221 235
222 /* Don't let them access lguest binary */ 236 /* Don't let them access lguest binary. */
223 if (!lguest_address_ok(lg, addr, sizeof(val)) 237 if (!lguest_address_ok(lg, addr, sizeof(val))
224 || get_user(val, (u32 __user *)addr) != 0) 238 || get_user(val, (u32 __user *)addr) != 0)
225 kill_guest(lg, "bad read address %#lx", addr); 239 kill_guest(lg, "bad read address %#lx", addr);
226 return val; 240 return val;
227} 241}
228 242
243/* Same thing for writing a value. */
229void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val) 244void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val)
230{ 245{
231 if (!lguest_address_ok(lg, addr, sizeof(val)) 246 if (!lguest_address_ok(lg, addr, sizeof(val))
@@ -233,6 +248,9 @@ void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val)
233 kill_guest(lg, "bad write address %#lx", addr); 248 kill_guest(lg, "bad write address %#lx", addr);
234} 249}
235 250
251/* This routine is more generic, and copies a range of Guest bytes into a
252 * buffer. If the copy_from_user() fails, we fill the buffer with zeroes, so
253 * the caller doesn't end up using uninitialized kernel memory. */
236void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes) 254void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
237{ 255{
238 if (!lguest_address_ok(lg, addr, bytes) 256 if (!lguest_address_ok(lg, addr, bytes)
@@ -243,6 +261,7 @@ void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
243 } 261 }
244} 262}
245 263
264/* Similarly, our generic routine to copy into a range of Guest bytes. */
246void lgwrite(struct lguest *lg, unsigned long addr, const void *b, 265void lgwrite(struct lguest *lg, unsigned long addr, const void *b,
247 unsigned bytes) 266 unsigned bytes)
248{ 267{
@@ -250,6 +269,7 @@ void lgwrite(struct lguest *lg, unsigned long addr, const void *b,
250 || copy_to_user((void __user *)addr, b, bytes) != 0) 269 || copy_to_user((void __user *)addr, b, bytes) != 0)
251 kill_guest(lg, "bad write address %#lx len %u", addr, bytes); 270 kill_guest(lg, "bad write address %#lx len %u", addr, bytes);
252} 271}
272/* (end of memory access helper routines) :*/
253 273
254static void set_ts(void) 274static void set_ts(void)
255{ 275{