[Lguest] [patch] u32 pointer nightmare .....

Rusty Russell rusty at rustcorp.com.au
Thu Sep 13 21:07:36 EST 2007


On Thu, 2007-08-30 at 15:28 +0200, Jes Sorensen wrote:
> Apply Clue 2x4 to lguest userland<->kernel handling code and the
> lguest launcher. Pointers are not to be passed in u32's!

OK, I fixed this up.  Some minor breakages:

> @@ -505,7 +505,7 @@ static unsigned long setup_pagetables(un
>  	 * continue from there. */
>  	for (i = 0; i < mapped_pages; i += ptes_per_page) {
>  		pgdir[(i + page_offset/getpagesize())/ptes_per_page]
> -			= ((to_guest_phys(linear) + i*sizeof(u32))
> +			= ((to_guest_phys(linear) + i*sizeof(void *))
>  			   | PAGE_PRESENT);
>  	}

Well, this is actually sizeof(pte), but we can cross that later...

>  /* The Guest has given us the address of a "struct lguest_dma".  We check it's
>   * OK and convert it to an iovec (which is a simple array of ptr/size
>   * pairs). */
> -static u32 *dma2iov(unsigned long dma, struct iovec iov[], unsigned *num)
> +static unsigned long *
> +dma2iov(unsigned long dma, struct iovec iov[], unsigned *num)
>  {

This one really is a u32*, even on 64-bit platforms (it's where we put
the length written/read).

>  /* This routine gets a DMA buffer from the Guest for a given key, and converts
>   * it to an iovec array.  It returns the interrupt the Guest wants when we're
>   * finished, and a pointer to the "used_len" field to fill in. */
> -static u32 *get_dma_buffer(int fd, void *key,
> -			   struct iovec iov[], unsigned int *num, u32 *irq)
> +static unsigned long *get_dma_buffer(int fd, void *key, struct iovec iov[],
> +				     unsigned int *num, unsigned long *irq)
>  {

IRQ is also handed as a 32 bit, even on 64 bit platforms.

>  		= ((struct e820entry) { 0, mem, E820_RAM });
>  	/* The boot header contains a command line pointer: we put the command
>  	 * line after the boot header (at address 4096) */
> -	*(u32 *)(boot + 0x228) = 4096;
> +	*(unsigned long *)(boot + 0x228) = 4096;
>  	concat(boot + 4096, argv+optind+2);

I think the boot header is i386 specific anyway, but it's definitely
defined to be a 32 bit field.

>   * start with a 32 bit number: for the first write this must be
>   * LHREQ_INITIALIZE to set up the Guest.  After that the Launcher can use
>   * writes of other values to get DMA buffers and send interrupts. */
> -static ssize_t write(struct file *file, const char __user *input,
> +static ssize_t write(struct file *file, const char __user *__input,
>  		     size_t size, loff_t *off)
>  {
>  	/* Once the guest is initialized, we hold the "struct lguest" in the
>  	 * file private data. */
>  	struct lguest *lg = file->private_data;
> -	u32 req;
> +	const unsigned long __user *input  =
> +		(const unsigned long __user *)__input;
> +	unsigned long req;

This is a nice change, but we do an "input += sizeof(req)" later, and
that needed changing too.

Thanks!
Rusty.





More information about the Lguest mailing list