diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-21 21:24:24 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-23 01:49:56 -0400 |
commit | 2d37f94a28170ca656438758fca577acb49a7932 (patch) | |
tree | 21049219a98d314a2c442293e512b74d879e6270 /drivers/lguest/core.c | |
parent | 56ae43dfe233323683248a5c553bad7160db2fa5 (diff) |
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/core.c')
-rw-r--r-- | drivers/lguest/core.c | 39 |
1 files changed, 8 insertions, 31 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 3aec29ec7715..35d19ae58de7 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c | |||
@@ -145,33 +145,10 @@ int lguest_address_ok(const struct lguest *lg, | |||
145 | return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr); | 145 | return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr); |
146 | } | 146 | } |
147 | 147 | ||
148 | /* This is a convenient routine to get a 32-bit value from the Guest (a very | 148 | /* This routine copies memory from the Guest. Here we can see how useful the |
149 | * common operation). Here we can see how useful the kill_lguest() routine we | 149 | * kill_lguest() routine we met in the Launcher can be: we return a random |
150 | * met in the Launcher can be: we return a random value (0) instead of needing | 150 | * value (all zeroes) instead of needing to return an error. */ |
151 | * to return an error. */ | 151 | void __lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes) |
152 | u32 lgread_u32(struct lguest *lg, unsigned long addr) | ||
153 | { | ||
154 | u32 val = 0; | ||
155 | |||
156 | /* Don't let them access lguest binary. */ | ||
157 | if (!lguest_address_ok(lg, addr, sizeof(val)) | ||
158 | || get_user(val, (u32 *)(lg->mem_base + addr)) != 0) | ||
159 | kill_guest(lg, "bad read address %#lx: pfn_limit=%u membase=%p", addr, lg->pfn_limit, lg->mem_base); | ||
160 | return val; | ||
161 | } | ||
162 | |||
163 | /* Same thing for writing a value. */ | ||
164 | void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val) | ||
165 | { | ||
166 | if (!lguest_address_ok(lg, addr, sizeof(val)) | ||
167 | || put_user(val, (u32 *)(lg->mem_base + addr)) != 0) | ||
168 | kill_guest(lg, "bad write address %#lx", addr); | ||
169 | } | ||
170 | |||
171 | /* This routine is more generic, and copies a range of Guest bytes into a | ||
172 | * buffer. If the copy_from_user() fails, we fill the buffer with zeroes, so | ||
173 | * the caller doesn't end up using uninitialized kernel memory. */ | ||
174 | void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes) | ||
175 | { | 152 | { |
176 | if (!lguest_address_ok(lg, addr, bytes) | 153 | if (!lguest_address_ok(lg, addr, bytes) |
177 | || copy_from_user(b, lg->mem_base + addr, bytes) != 0) { | 154 | || copy_from_user(b, lg->mem_base + addr, bytes) != 0) { |
@@ -181,15 +158,15 @@ void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes) | |||
181 | } | 158 | } |
182 | } | 159 | } |
183 | 160 | ||
184 | /* Similarly, our generic routine to copy into a range of Guest bytes. */ | 161 | /* This is the write (copy into guest) version. */ |
185 | void lgwrite(struct lguest *lg, unsigned long addr, const void *b, | 162 | void __lgwrite(struct lguest *lg, unsigned long addr, const void *b, |
186 | unsigned bytes) | 163 | unsigned bytes) |
187 | { | 164 | { |
188 | if (!lguest_address_ok(lg, addr, bytes) | 165 | if (!lguest_address_ok(lg, addr, bytes) |
189 | || copy_to_user(lg->mem_base + addr, b, bytes) != 0) | 166 | || copy_to_user(lg->mem_base + addr, b, bytes) != 0) |
190 | kill_guest(lg, "bad write address %#lx len %u", addr, bytes); | 167 | kill_guest(lg, "bad write address %#lx len %u", addr, bytes); |
191 | } | 168 | } |
192 | /* (end of memory access helper routines) :*/ | 169 | /*:*/ |
193 | 170 | ||
194 | /*H:030 Let's jump straight to the the main loop which runs the Guest. | 171 | /*H:030 Let's jump straight to the the main loop which runs the Guest. |
195 | * Remember, this is called by the Launcher reading /dev/lguest, and we keep | 172 | * Remember, this is called by the Launcher reading /dev/lguest, and we keep |