1) Example code: old libc headers don't have SIOCBRADDIF, and old zlibs
don't have gzdirect() -- it's a sanity check anyway.
2) Some people don't build in their source directories, so .config
isn't there (thanks to Tony Breeds <tony@bakeyournoodle.com>).
3) Point out that guest and host kernel are usually the same.
4) Set the "no checksum" option on the tun device as a minor
optimization.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
Documentation/lguest/Makefile | 9 ++++++++-
Documentation/lguest/lguest.c | 6 ++++--
Documentation/lguest/lguest.txt | 8 ++++++--
3 files changed, 18 insertions(+), 5 deletions(-)
==================================================================---
a/Documentation/lguest/Makefile
+++ b/Documentation/lguest/Makefile
@@ -1,7 +1,14 @@
# This creates the demonstration utility "lguest" which runs a Linux
guest.
+# For those people that have a separate object dir, look there for .config
+KBUILD_OUTPUT := ../..
+ifdef O
+ ifeq ("$(origin O)", "command line")
+ KBUILD_OUTPUT := $(O)
+ endif
+endif
# We rely on CONFIG_PAGE_OFFSET to know where to put lguest binary.
-include ../../.config
+include $(KBUILD_OUTPUT)/.config
LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000)
CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 \
==================================================================---
a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -40,6 +40,9 @@ typedef uint8_t u8;
#define PAGE_PRESENT 0x7 /* Present, RW, Execute */
#define NET_PEERNUM 1
#define BRIDGE_PFX "bridge:"
+#ifndef SIOCBRADDIF
+#define SIOCBRADDIF 0x89a2 /* add interface to bridge */
+#endif
static bool verbose;
#define verbose(args...) \
@@ -166,8 +169,6 @@ static unsigned long unpack_bzimage(int
void *img = (void *)0x100000;
f = gzdopen(fd, "rb");
- if (gzdirect(f))
- errx(1, "did not find correct gzip header");
while ((ret = gzread(f, img + len, 65536)) > 0)
len += ret;
if (ret < 0)
@@ -820,6 +821,7 @@ static void setup_tun_net(const char *ar
strcpy(ifr.ifr_name, "tap%d");
if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
err(1, "configuring /dev/net/tun");
+ ioctl(netfd, TUNSETNOCSUM, 1);
/* You will be peer 1: we should create enough jitter to randomize */
dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
==================================================================---
a/Documentation/lguest/lguest.txt
+++ b/Documentation/lguest/lguest.txt
@@ -23,7 +23,10 @@ Developer features:
Running Lguest:
-- You will need to configure your kernel with the following options:
+- Lguest runs the same kernel as guest and host. You can configure
+ them differently, but usually it's easiest not to.
+
+ You will need to configure your kernel with the following options:
CONFIG_HIGHMEM64G=n ("High Memory Support" "64GB")[1]
CONFIG_TUN=y/m ("Universal TUN/TAP device driver support")
@@ -35,7 +38,8 @@ Running Lguest:
CONFIG_HZ=100 ("Timer frequency")[2]
- A tool called "lguest" is available in this directory: type
"make"
- to build it.
+ to build it. If you didn't build your kernel in-tree, use "make
+ O=<builddir>".
- Create or find a root disk image. There are several useful ones
around, such as the xm-test tiny root image at
Rusty Russell
2007-May-04 08:00 UTC
[PATCH 2/3] lguest: remove put_user etc warnings, add bloat
I've long disliked Linux's user access functions. Nonetheless,
let's
stop the warnings.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
drivers/lguest/core.c | 8 +++++---
drivers/lguest/hypercalls.c | 33 ++++++++++++++++++++++-----------
drivers/lguest/interrupts_and_traps.c | 17 ++++++++++++-----
3 files changed, 39 insertions(+), 19 deletions(-)
==================================================================---
a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -303,8 +303,9 @@ int run_guest(struct lguest *lg, char *_
/* Hypercalls first: we might have been out to userspace */
do_hypercalls(lg);
if (lg->dma_is_pending) {
- put_user(lg->pending_dma, (unsigned long *)user);
- put_user(lg->pending_key, (unsigned long *)user+1);
+ if (put_user(lg->pending_dma, (unsigned long *)user) ||
+ put_user(lg->pending_key, (unsigned long *)user+1))
+ return -EFAULT;
return sizeof(unsigned long)*2;
}
@@ -350,7 +351,8 @@ int run_guest(struct lguest *lg, char *_
continue;
/* If lguest_data is NULL, this won't hurt. */
- put_user(cr2, &lg->lguest_data->cr2);
+ if (put_user(cr2, &lg->lguest_data->cr2))
+ kill_guest(lg, "Writing cr2");
break;
case 7: /* We've intercepted a Device Not Available fault. */
/* If they don't want to know, just absorb it. */
==================================================================---
a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -102,7 +102,9 @@ static void do_async_hcalls(struct lgues
unsigned int i;
u8 st[LHCALL_RING_SIZE];
- copy_from_user(&st, &lg->lguest_data->hcall_status, sizeof(st));
+ if (copy_from_user(&st, &lg->lguest_data->hcall_status,
sizeof(st)))
+ return;
+
for (i = 0; i < ARRAY_SIZE(st); i++) {
struct lguest_regs regs;
unsigned int n = lg->next_hcall;
@@ -113,12 +115,20 @@ static void do_async_hcalls(struct lgues
if (++lg->next_hcall == LHCALL_RING_SIZE)
lg->next_hcall = 0;
- get_user(regs.eax, &lg->lguest_data->hcalls[n].eax);
- get_user(regs.edx, &lg->lguest_data->hcalls[n].edx);
- get_user(regs.ecx, &lg->lguest_data->hcalls[n].ecx);
- get_user(regs.ebx, &lg->lguest_data->hcalls[n].ebx);
+ if (get_user(regs.eax, &lg->lguest_data->hcalls[n].eax)
+ || get_user(regs.edx, &lg->lguest_data->hcalls[n].edx)
+ || get_user(regs.ecx, &lg->lguest_data->hcalls[n].ecx)
+ || get_user(regs.ebx, &lg->lguest_data->hcalls[n].ebx)) {
+ kill_guest(lg, "Fetching async hypercalls");
+ break;
+ }
+
do_hcall(lg, ®s);
- put_user(0xFF, &lg->lguest_data->hcall_status[n]);
+ if (put_user(0xFF, &lg->lguest_data->hcall_status[n])) {
+ kill_guest(lg, "Writing result for async hypercall");
+ break;
+ }
+
if (lg->dma_is_pending)
break;
}
@@ -139,11 +149,12 @@ static void initialize(struct lguest *lg
kill_guest(lg, "bad guest page %p", lg->lguest_data);
return;
}
- get_user(lg->noirq_start, &lg->lguest_data->noirq_start);
- get_user(lg->noirq_end, &lg->lguest_data->noirq_end);
- /* We reserve the top pgd entry. */
- put_user(4U*1024*1024, &lg->lguest_data->reserve_mem);
- put_user(lg->guestid, &lg->lguest_data->guestid);
+ if (get_user(lg->noirq_start, &lg->lguest_data->noirq_start)
+ || get_user(lg->noirq_end, &lg->lguest_data->noirq_end)
+ /* We reserve the top pgd entry. */
+ || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
+ || put_user(lg->guestid, &lg->lguest_data->guestid))
+ kill_guest(lg, "bad guest page %p", lg->lguest_data);
/* This is the one case where the above accesses might have
* been the first write to a Guest page. This may have caused
==================================================================---
a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -40,7 +40,8 @@ static void set_guest_interrupt(struct l
/* We use IF bit in eflags to indicate whether irqs were disabled
(it's always 0, since irqs are enabled when guest is running). */
eflags = lg->regs->eflags;
- get_user(irq_enable, &lg->lguest_data->irq_enabled);
+ if (get_user(irq_enable, &lg->lguest_data->irq_enabled))
+ irq_enable = 0;
eflags |= (irq_enable & X86_EFLAGS_IF);
push_guest_stack(lg, &gstack, eflags);
@@ -58,7 +59,8 @@ static void set_guest_interrupt(struct l
/* Disable interrupts for an interrupt gate. */
if (idt_type(lo, hi) == 0xE)
- put_user(0, &lg->lguest_data->irq_enabled);
+ if (put_user(0, &lg->lguest_data->irq_enabled))
+ kill_guest(lg, "Disabling interrupts");
}
void maybe_do_interrupt(struct lguest *lg)
@@ -75,7 +77,10 @@ void maybe_do_interrupt(struct lguest *l
set_bit(0, lg->irqs_pending);
/* Mask out any interrupts they have blocked. */
- copy_from_user(&blk, lg->lguest_data->blocked_interrupts,
sizeof(blk));
+ if (copy_from_user(&blk, lg->lguest_data->blocked_interrupts,
+ sizeof(blk)))
+ return;
+
bitmap_andnot(blk, lg->irqs_pending, blk, LGUEST_IRQS);
irq = find_first_bit(blk, LGUEST_IRQS);
@@ -88,12 +93,14 @@ void maybe_do_interrupt(struct lguest *l
/* If they're halted, we re-enable interrupts. */
if (lg->halted) {
/* Re-enable interrupts. */
- put_user(X86_EFLAGS_IF, &lg->lguest_data->irq_enabled);
+ if (put_user(X86_EFLAGS_IF, &lg->lguest_data->irq_enabled))
+ kill_guest(lg, "Re-enabling interrupts");
lg->halted = 0;
} else {
/* Maybe they have interrupts disabled? */
u32 irq_enabled;
- get_user(irq_enabled, &lg->lguest_data->irq_enabled);
+ if (get_user(irq_enabled, &lg->lguest_data->irq_enabled))
+ irq_enabled = 0;
if (!irq_enabled)
return;
}
Maybe Matching Threads
- [PATCH 1/3] Documentation and example updates
- [PATCH 0/7] Modify lguest32 to make room for lguest64
- [PATCH 0/7] Modify lguest32 to make room for lguest64
- [PATCH 0/5 -v2] Modify lguest32 to make room for lguest64 (version 2)
- [PATCH 0/5 -v2] Modify lguest32 to make room for lguest64 (version 2)