All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Malley <mail@chrismalley.co.uk>
To: rusty@rustcorp.com.au
Cc: lguest@ozlabs.org, Jes Sorensen <jes@sgi.com>,
	virtualization@lists.linux-foundation.org
Subject: Re: [Lguest] [patch 43/43] lguest: generalize lgread_u32/lgwrite_u32.
Date: Thu, 27 Sep 2007 14:04:24 +0100	[thread overview]
Message-ID: <1190898264.6648.12.camel@feisty> (raw)
In-Reply-To: <20070926063652.917809564@rustcorp.com.au>

Hi Rusty, Jes et al

This last patch causes page_tables.c to fail compilation on my system thus:

....
  CC [M]  drivers/kvm/vmx.o
  CC [M]  drivers/kvm/kvm_main.o
  CC [M]  drivers/kvm/mmu.o
  CC [M]  drivers/kvm/x86_emulate.o
  LD [M]  drivers/kvm/kvm.o
  LD [M]  drivers/kvm/kvm-intel.o
  CC      drivers/leds/led-core.o
  LD      drivers/leds/built-in.o
  CC [M]  drivers/leds/led-class.o
  CC      drivers/lguest/lguest_device.o
  LD      drivers/lguest/built-in.o
  CC [M]  drivers/lguest/core.o
  CC [M]  drivers/lguest/hypercalls.o
  CC [M]  drivers/lguest/page_tables.o
drivers/lguest/page_tables.c: In function ‘demand_page’:
drivers/lguest/page_tables.c:212: error: expected expression before ‘{’ token
drivers/lguest/page_tables.c:238: error: expected expression before ‘{’ token
drivers/lguest/page_tables.c:284: error: ‘v’ undeclared (first use in this function)
drivers/lguest/page_tables.c:284: error: (Each undeclared identifier is reported only once
drivers/lguest/page_tables.c:284: error: for each function it appears in.)
drivers/lguest/page_tables.c:284: warning: type defaults to ‘int’ in declaration of ‘__dummy2’
drivers/lguest/page_tables.c:284: warning: comparison of distinct pointer types lacks a cast
drivers/lguest/page_tables.c:284: warning: passing argument 3 of ‘__lgwrite’ makes pointer from integer without a cast
drivers/lguest/page_tables.c: In function ‘guest_pa’:
drivers/lguest/page_tables.c:372: error: expected expression before ‘{’ token
drivers/lguest/page_tables.c:377: error: expected expression before ‘{’ token
make[2]: *** [drivers/lguest/page_tables.o] Error 1
make[1]: *** [drivers/lguest] Error 2
make: *** [drivers] Error 2


It compiles fine with all the previous patches applied, just doesn't
seem to like the new lgread/lgwrite macros.

(GCC 4.1.2 on i686 in case that makes any difference, patched against v2.6.23-rc8)

--
Chris


On Wed, 2007-09-26 at 16:37 +1000, rusty@rustcorp.com.au wrote:
> 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>
> Cc: Jes Sorensen <jes@sgi.com>
> ---
>  drivers/lguest/core.c                 |   39 ++++++---------------------------
>  drivers/lguest/hypercalls.c           |    2 -
>  drivers/lguest/i386_core.c            |    4 +--
>  drivers/lguest/interrupts_and_traps.c |    2 -
>  drivers/lguest/lg.h                   |   23 ++++++++++++++++---
>  drivers/lguest/page_tables.c          |   10 ++++----
>  drivers/lguest/segments.c             |    4 +--
>  7 files changed, 38 insertions(+), 46 deletions(-)
> 
> ===================================================================
> --- a/drivers/lguest/core.c
> +++ b/drivers/lguest/core.c
> @@ -145,33 +145,10 @@ int lguest_address_ok(const struct lgues
>  	return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
>  }
>  
> -/* This is a convenient routine to get a 32-bit value from the Guest (a very
> - * common operation).  Here we can see how useful the kill_lguest() routine we
> - * met in the Launcher can be: we return a random value (0) instead of needing
> - * to return an error. */
> -u32 lgread_u32(struct lguest *lg, unsigned long addr)
> -{
> -	u32 val = 0;
> -
> -	/* Don't let them access lguest binary. */
> -	if (!lguest_address_ok(lg, addr, sizeof(val))
> -	    || get_user(val, (u32 *)(lg->mem_base + addr)) != 0)
> -		kill_guest(lg, "bad read address %#lx: pfn_limit=%u membase=%p", addr, lg->pfn_limit, lg->mem_base);
> -	return val;
> -}
> -
> -/* Same thing for writing a value. */
> -void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val)
> -{
> -	if (!lguest_address_ok(lg, addr, sizeof(val))
> -	    || put_user(val, (u32 *)(lg->mem_base + addr)) != 0)
> -		kill_guest(lg, "bad write address %#lx", addr);
> -}
> -
> -/* This routine is more generic, and copies a range of Guest bytes into a
> - * buffer.  If the copy_from_user() fails, we fill the buffer with zeroes, so
> - * the caller doesn't end up using uninitialized kernel memory. */
> -void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
> +/* This routine copies memory from the Guest.  Here we can see how useful the
> + * kill_lguest() routine we met in the Launcher can be: we return a random
> + * value (all zeroes) instead of needing to return an error. */
> +void __lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
>  {
>  	if (!lguest_address_ok(lg, addr, bytes)
>  	    || copy_from_user(b, lg->mem_base + addr, bytes) != 0) {
> @@ -181,15 +158,15 @@ void lgread(struct lguest *lg, void *b, 
>  	}
>  }
>  
> -/* Similarly, our generic routine to copy into a range of Guest bytes. */
> -void lgwrite(struct lguest *lg, unsigned long addr, const void *b,
> -	     unsigned bytes)
> +/* This is the write (copy into guest) version. */
> +void __lgwrite(struct lguest *lg, unsigned long addr, const void *b,
> +	       unsigned bytes)
>  {
>  	if (!lguest_address_ok(lg, addr, bytes)
>  	    || copy_to_user(lg->mem_base + addr, b, bytes) != 0)
>  		kill_guest(lg, "bad write address %#lx len %u", addr, bytes);
>  }
> -/* (end of memory access helper routines) :*/
> +/*:*/
>  
>  /*H:030 Let's jump straight to the the main loop which runs the Guest.
>   * Remember, this is called by the Launcher reading /dev/lguest, and we keep
> ===================================================================
> --- a/drivers/lguest/hypercalls.c
> +++ b/drivers/lguest/hypercalls.c
> @@ -47,7 +47,7 @@ static void do_hcall(struct lguest *lg, 
>  		char msg[128];
>  		/* If the lgread fails, it will call kill_guest() itself; the
>  		 * kill_guest() with the message will be ignored. */
> -		lgread(lg, msg, args->arg1, sizeof(msg));
> +		__lgread(lg, msg, args->arg1, sizeof(msg));
>  		msg[sizeof(msg)-1] = '\0';
>  		kill_guest(lg, "CRASH: %s", msg);
>  		break;
> ===================================================================
> --- a/drivers/lguest/i386_core.c
> +++ b/drivers/lguest/i386_core.c
> @@ -222,7 +222,7 @@ static int emulate_insn(struct lguest *l
>  		return 0;
>  
>  	/* Decoding x86 instructions is icky. */
> -	lgread(lg, &insn, physaddr, 1);
> +	insn = lgread(lg, &insn, u8);
>  
>  	/* 0x66 is an "operand prefix".  It means it's using the upper 16 bits
>  	   of the eax register. */
> @@ -230,7 +230,7 @@ static int emulate_insn(struct lguest *l
>  		shift = 16;
>  		/* The instruction is 1 byte so far, read the next byte. */
>  		insnlen = 1;
> -		lgread(lg, &insn, physaddr + insnlen, 1);
> +		insn = lgread(lg, physaddr + insnlen, u8);
>  	}
>  
>  	/* We can ignore the lower bit for the moment and decode the 4 opcodes
> ===================================================================
> --- a/drivers/lguest/interrupts_and_traps.c
> +++ b/drivers/lguest/interrupts_and_traps.c
> @@ -45,7 +45,7 @@ static void push_guest_stack(struct lgue
>  {
>  	/* Stack grows upwards: move stack then write value. */
>  	*gstack -= 4;
> -	lgwrite_u32(lg, *gstack, val);
> +	lgwrite(lg, *gstack, u32, val);
>  }
>  
>  /*H:210 The set_guest_interrupt() routine actually delivers the interrupt or
> ===================================================================
> --- a/drivers/lguest/lg.h
> +++ b/drivers/lguest/lg.h
> @@ -99,12 +99,27 @@ extern struct mutex lguest_lock;
>  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, v);				\
> +		__lgwrite((lg), &(v), (addr), sizeof(v));	\
> +	} 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
> ===================================================================
> --- a/drivers/lguest/page_tables.c
> +++ b/drivers/lguest/page_tables.c
> @@ -209,7 +209,7 @@ int demand_page(struct lguest *lg, unsig
>  	pte_t *spte;
>  
>  	/* First step: get the top-level Guest page table entry. */
> -	gpgd = __pgd(lgread_u32(lg, gpgd_addr(lg, vaddr)));
> +	gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t);
>  	/* Toplevel not present?  We can't map it in. */
>  	if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
>  		return 0;
> @@ -235,7 +235,7 @@ int demand_page(struct lguest *lg, unsig
>  	/* OK, now we look at the lower level in the Guest page table: keep its
>  	 * address, because we might update it later. */
>  	gpte_ptr = gpte_addr(lg, gpgd, vaddr);
> -	gpte = __pte(lgread_u32(lg, gpte_ptr));
> +	gpte = lgread(lg, gpte_ptr, pte_t);
>  
>  	/* If this page isn't in the Guest page tables, we can't page it in. */
>  	if (!(pte_flags(gpte) & _PAGE_PRESENT))
> @@ -281,7 +281,7 @@ int demand_page(struct lguest *lg, unsig
>  
>  	/* Finally, we write the Guest PTE entry back: we've set the
>  	 * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */
> -	lgwrite_u32(lg, gpte_ptr, pte_val(gpte));
> +	lgwrite(lg, gpte_ptr, pte_t, gpte);
>  
>  	/* We succeeded in mapping the page! */
>  	return 1;
> @@ -369,12 +369,12 @@ unsigned long guest_pa(struct lguest *lg
>  	pte_t gpte;
>  
>  	/* First step: get the top-level Guest page table entry. */
> -	gpgd = __pgd(lgread_u32(lg, gpgd_addr(lg, vaddr)));
> +	gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t);
>  	/* Toplevel not present?  We can't map it in. */
>  	if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
>  		kill_guest(lg, "Bad address %#lx", vaddr);
>  
> -	gpte = __pte(lgread_u32(lg, gpte_addr(lg, gpgd, vaddr)));
> +	gpte = lgread(lg, gpte_addr(lg, gpgd, vaddr), pte_t);
>  	if (!(pte_flags(gpte) & _PAGE_PRESENT))
>  		kill_guest(lg, "Bad address %#lx", vaddr);
>  
> ===================================================================
> --- a/drivers/lguest/segments.c
> +++ b/drivers/lguest/segments.c
> @@ -150,7 +150,7 @@ void load_guest_gdt(struct lguest *lg, u
>  		kill_guest(lg, "too many gdt entries %i", num);
>  
>  	/* We read the whole thing in, then fix it up. */
> -	lgread(lg, lg->arch.gdt, table, num * sizeof(lg->arch.gdt[0]));
> +	__lgread(lg, lg->arch.gdt, table, num * sizeof(lg->arch.gdt[0]));
>  	fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->arch.gdt));
>  	/* Mark that the GDT changed so the core knows it has to copy it again,
>  	 * even if the Guest is run on the same CPU. */
> @@ -161,7 +161,7 @@ void guest_load_tls(struct lguest *lg, u
>  {
>  	struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN];
>  
> -	lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
> +	__lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
>  	fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
>  	lg->changed |= CHANGED_GDT_TLS;
>  }
> 
> --
>    there are those who do and those who hang on and you don't see too
>    many doers quoting their contemporaries.  -- Larry McVoy
> 
> _______________________________________________
> Lguest mailing list
> Lguest@ozlabs.org
> https://ozlabs.org/mailman/listinfo/lguest

  reply	other threads:[~2007-09-27 13:04 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-26  6:36 [patch 00/43] lguest: Patches for 2.6.24 (and patchbomb test) rusty
2007-09-26  6:36 ` [patch 01/43] lguest: lguest example launcher truncates block device file to 0 length on problems rusty
2007-09-26  6:36 ` [patch 02/43] lguest: fix modules oopsing in lguest guests rusty
2007-09-26  6:36 ` [patch 03/43] lguest: Normalize config options for guest support rusty
2007-09-26  6:36 ` [patch 04/43] lguest: Consolidate host virtualization support under Virtualization menu rusty
2007-09-26  6:36 ` [patch 05/43] lguest: Example launcher should include asm/e820.h instead of asm-i386/ rusty
2007-09-26  6:36 ` [patch 06/43] lguest: turn err into errx in lguest call sites rusty
2007-09-26  6:36 ` [patch 07/43] lguest: Use copy_to_user() not put_user for struct timespec rusty
2007-09-26  6:36 ` [patch 08/43] lguest: Lguest currently depends on 32-bit x86, not just x86 rusty
2007-09-26  6:36 ` [patch 09/43] lguest: lguest.txt update rusty
2007-09-26  6:36 ` [patch 10/43] lguest: Make lguest_launcher.h types userspace-friendly rusty
2007-09-26  6:36 ` [patch 11/43] lguest: lguest_devices belongs in lguest_bus.c: its not i386-specific rusty
2007-09-26  6:36 ` [patch 12/43] lguest: Only start khvcd when someone uses hvc_console driver rusty
2007-09-26  6:36 ` [patch 13/43] lguest: Move lguest hcalls to arch-specific header rusty
2007-09-26  6:36 ` [patch 14/43] lguest: Move lguest guest support to arch/i386 where it logically belongs rusty
2007-09-26  6:36 ` [patch 15/43] lguest: Rename switcher.S to i386_switcher.S, since its very i386-specific rusty
2007-09-26  6:36 ` [patch 16/43] lguest: Accept elf files that are valid but have sections that can not be mmaped for some reason rusty
2007-09-26  6:36 ` [patch 17/43] lguest: Introduce guest mem offset, static link example launcher rusty
2007-09-26  6:36 ` [patch 18/43] lguest: Remove fixed limit on number of guests, and lguests array rusty
2007-09-26  6:36 ` [patch 19/43] lguest: Make shadow IDT a complete IDT with 256 entries rusty
2007-09-26  6:36 ` [patch 20/43] lguest: Move i386 part of core.c to i386_core.c rusty
2007-09-26  6:36 ` [patch 21/43] lguest: Reorder guest saved regs to match hyperall order rusty
2007-09-26  6:36 ` [patch 22/43] lguest: Introduce "hcall" pointer to indicate pending hypercall rusty
2007-09-26  6:36 ` [patch 23/43] lguest: Make hypercalls arch-independent rusty
2007-09-26  6:36 ` [patch 24/43] lguest: Change example launcher to use unsigned long not u32 rusty
2007-09-26  6:36 ` [patch 25/43] lguest: Move register setup into i386_core.c rusty
2007-09-26  6:36 ` [patch 26/43] lguest: guest.h declares a struct timespec, make it include linux/time.h rusty
2007-09-26  6:36 ` [patch 27/43] lguest: Pagetables to use normal kernel types rusty
2007-09-26  6:36 ` [patch 28/43] lguest: Rename "cr3" to "gpgdir" to avoid x86-specific naming rusty
2007-09-26  6:36 ` [patch 29/43] lguest: Introduce "used_vectors" bitmap which can be used to reserve vectors rusty
2007-09-26  6:36 ` [patch 30/43] lguest: Allow guest to specify syscall vector to use rusty
2007-09-26  6:36 ` [patch 31/43] lguest: Boot with virtual == physical to get closer to native Linux rusty
2007-09-27  0:12   ` Jeremy Fitzhardinge
2007-09-27  0:53     ` [Lguest] " ron minnich
2007-09-29 13:02     ` Rusty Russell
2007-09-26  6:36 ` [patch 32/43] lguest: Virtio interface rusty
2007-10-02  9:03   ` Christian Borntraeger
2007-10-02 12:00     ` Rusty Russell
2007-10-10  8:50   ` Christian Borntraeger
2007-10-10 13:43     ` Glauber de Oliveira Costa
2007-10-10 14:24       ` Arnd Bergmann
2007-10-10 15:31         ` Eric Van Hensbergen
2007-10-10 16:00           ` Arnd Bergmann
2007-10-11 14:17     ` Rusty Russell
2007-09-26  6:36 ` [patch 33/43] lguest: Net driver using virtio rusty
2007-09-26  6:36 ` rusty
2007-09-26  6:36 ` [patch 34/43] lguest: Block " rusty
2007-09-28 11:32   ` [Lguest] " Chris Malley
2007-09-29 13:26     ` Rusty Russell
2007-09-26  6:36 ` [patch 35/43] lguest: Virtio console driver rusty
2007-09-26  6:36 ` [patch 36/43] lguest: Module autoprobing support for virtio drivers rusty
2007-09-26  6:36 ` [patch 37/43] lguest: Virtio helper routines for a descriptor ringbuffer implementation rusty
2007-09-30 17:03   ` Avi Kivity
2007-10-01 12:03     ` Rusty Russell
2007-10-01 12:13       ` Avi Kivity
2007-10-02  4:21         ` Rusty Russell
2007-10-02  6:02           ` Avi Kivity
2007-09-26  6:36 ` [patch 38/43] lguest: This gets rid of the lguest bus, drivers and DMA mechanism, to make way for a generic virtio mechanism rusty
2007-09-26  6:36 ` [patch 39/43] lguest: This patch gets rid of the old lguest host I/O infrastructure and replaces it with a single hypercall "LHCALL_NOTIFY" which takes an address rusty
2007-09-26  6:36 ` [patch 40/43] lguest: Lguest support for Virtio rusty
2007-09-26  6:36 ` [patch 41/43] lguest: Update example launcher for virtio rusty
2007-09-26  6:37 ` [patch 42/43] lguest: Example launcher handle guests not being ready for input rusty
2007-09-26  6:37 ` [patch 43/43] lguest: generalize lgread_u32/lgwrite_u32 rusty
2007-09-27 13:04   ` Chris Malley [this message]
2007-09-29 13:29     ` [Lguest] " Rusty Russell
2007-10-09 20:25 ` [Lguest] [patch 00/43] lguest: Patches for 2.6.24 (and patchbomb test) Eric Van Hensbergen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1190898264.6648.12.camel@feisty \
    --to=mail@chrismalley.co.uk \
    --cc=jes@sgi.com \
    --cc=lguest@ozlabs.org \
    --cc=rusty@rustcorp.com.au \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.