All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] KQEMU Darwin port status?
@ 2007-03-17 19:30 Philip Boulain
  2007-03-19  8:49 ` Mike Kronenberg
  0 siblings, 1 reply; 11+ messages in thread
From: Philip Boulain @ 2007-03-17 19:30 UTC (permalink / raw)
  To: qemu-devel

Hi! I'll keep this succinct, because I'm sure they'd be FAQ-grade  
questions if this list had a FAQ:  :)

  1) Where's the version repository for KQEMU? It doesn't appear to  
be under/alongside QEMU itself.
  2) Has anyone made any progress with porting KQEMU to Darwin x86?  
I've had a look at the GPL release (hurrah) and it looked to me like  
the platform-specific parts would mostly involve writing an I/O Kit  
Device Driver which provided a device node with suitable ioctl support 
[1], as the FreeBSD version does. The mailing list archives show some  
activity in this area, but without 1) it's hard to get an overview.  
(There are also obvious-looking compilation problems with the  
distributed 1.3.0pre11 sources, but I'm guessing that someone who  
knows assembler better than now has fixed them by now.)

Thanks,
LionsPhil
1. http://developer.apple.com/documentation/Darwin/Conceptual/ 
KernelProgramming/boundaries/chapter_14_section_6.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-17 19:30 [Qemu-devel] KQEMU Darwin port status? Philip Boulain
@ 2007-03-19  8:49 ` Mike Kronenberg
  2007-03-19 18:54   ` Philip Boulain
  0 siblings, 1 reply; 11+ messages in thread
From: Mike Kronenberg @ 2007-03-19  8:49 UTC (permalink / raw)
  To: qemu-devel

Hi there,

On 17.03.2007, at 20:30, Philip Boulain wrote:

> Hi! I'll keep this succinct, because I'm sure they'd be FAQ-grade  
> questions if this list had a FAQ:  :)
>
>  1) Where's the version repository for KQEMU? It doesn't appear to  
> be under/alongside QEMU itself.
>  2) Has anyone made any progress with porting KQEMU to Darwin x86?  
> I've had a look at the GPL release (hurrah) and it looked to me  
> like the platform-specific parts would mostly involve writing an I/ 
> O Kit Device Driver which provided a device node with suitable  
> ioctl support[1], as the FreeBSD version does. The mailing list  
> archives show some activity in this area, but without 1) it's hard  
> to get an overview. (There are also obvious-looking compilation  
> problems with the distributed 1.3.0pre11 sources, but I'm guessing  
> that someone who knows assembler better than now has fixed them by  
> now.)

I have made a empty kext and a dummy client to do some tests on this  
topics. Boundary crossing is working well, so by now the kext part is  
ready.
http://www.kronenberg.org/files/kqemu_poc.zip

Unfortunately, Apple decided to remove/hide some of the vm_* API  
(especially vm_map_(un)wire in Tiger. (It was available on Panther.  
vm_map_user_pageable was never part of Darwin). So any suggestions on  
how to lock user pages in Darwin would be very welcome.

So right now, I'm reading thru lots of stuff to replace the  
unsupported kqemu-freebsd.c function calls. If someone is interested,  
I post snapshots or put it in the http://www.kju-app.org repository,  
until it's working and can be merged.

>
> Thanks,
> LionsPhil
> 1. http://developer.apple.com/documentation/Darwin/Conceptual/ 
> KernelProgramming/boundaries/chapter_14_section_6.html

Best Regards
Mike

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-19  8:49 ` Mike Kronenberg
@ 2007-03-19 18:54   ` Philip Boulain
  2007-03-19 20:23     ` Derek Fawcus
  0 siblings, 1 reply; 11+ messages in thread
From: Philip Boulain @ 2007-03-19 18:54 UTC (permalink / raw)
  To: qemu-devel

On 19 Mar 2007, at 08:49, Mike Kronenberg wrote:
> I have made a empty kext and a dummy client to do some tests on  
> this topics. Boundary crossing is working well, so by now the kext  
> part is ready.
> http://www.kronenberg.org/files/kqemu_poc.zip

Neat, thanks.

> Unfortunately, Apple decided to remove/hide some of the vm_* API  
> (especially vm_map_(un)wire in Tiger. (It was available on Panther.  
> vm_map_user_pageable was never part of Darwin). So any suggestions  
> on how to lock user pages in Darwin would be very welcome.

Mmm, that's rather unhelpful. From my own reading, it looks like the  
Apple-approved way of doing this would be to use an  
IOMemoryDescriptor: initWithAddress() would initialise one which  
represents the appropriate lump of application-space memory  
(vm_address_t, length, direction [1] and task_t [2]); prepare() and  
complete() wire and unwire it respectively; and presumably  
getPhysicalSegment() covers the 'get physical address' part. Using  
this probably requires making the extension a I/O Kit Device Driver,  
but that's just a few extra methods to implement AFAICT.

I'll see if I can make a trivial test for this approach.

Phil
1. kIODirectionOutIn (or InOut) appears suitable here---the kernel- 
side IOKit headers show both as equivilent to VM_PROT_READ |  
VM_PROT_WRITE
2. Looking at the FreeBSD version, that's just "current process", so  
literally current_task()

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-19 18:54   ` Philip Boulain
@ 2007-03-19 20:23     ` Derek Fawcus
  2007-03-19 22:16       ` Philip Boulain
  0 siblings, 1 reply; 11+ messages in thread
From: Derek Fawcus @ 2007-03-19 20:23 UTC (permalink / raw)
  To: qemu-devel

On Mon, Mar 19, 2007 at 06:54:35PM +0000, Philip Boulain wrote:
> 
> Mmm, that's rather unhelpful. From my own reading, it looks like the  
> Apple-approved way of doing this would be to use an  
> IOMemoryDescriptor: initWithAddress() would initialise one which  

There was just a discussion relating to this on the darwin-kernel list,
you may wish to review the archive.

(The thread starts at http://lists.apple.com/archives/Darwin-kernel/2007/Mar/msg00010.html).

DF

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-19 20:23     ` Derek Fawcus
@ 2007-03-19 22:16       ` Philip Boulain
  2007-03-20  2:18         ` Philip Boulain
  2007-03-21 15:39         ` Derek Fawcus
  0 siblings, 2 replies; 11+ messages in thread
From: Philip Boulain @ 2007-03-19 22:16 UTC (permalink / raw)
  To: qemu-devel

On 19 Mar 2007, at 20:23, Derek Fawcus wrote:
> There was just a discussion relating to this on the darwin-kernel  
> list,
> you may wish to review the archive.
>
> (The thread starts at http://lists.apple.com/archives/Darwin-kernel/ 
> 2007/Mar/msg00010.html).

Thanks; looking at this post, I'm probably barking up the right tree:

http://lists.apple.com/archives/Darwin-kernel/2007/Mar/msg00031.html

Unfortunately, rather than confirm or deny this path of reasoning,  
the others got unhelpfully uppity. =/

LionsPhil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-19 22:16       ` Philip Boulain
@ 2007-03-20  2:18         ` Philip Boulain
  2007-03-20  8:02           ` Mike Kronenberg
  2007-03-21 15:39         ` Derek Fawcus
  1 sibling, 1 reply; 11+ messages in thread
From: Philip Boulain @ 2007-03-20  2:18 UTC (permalink / raw)
  To: qemu-devel

Mike Kronenberg wrote:
 > So any suggestions on how to lock user pages in Darwin would be  
very welcome.

Philip Boulain wrote:
> Thanks; looking at this post, I'm probably barking up the right tree

Right. I've cobbled up the aformentioned prototype, and it working  
insofar that the modified and now-leaky version of Mike's test client  
is allocating sequential lumps of memory when you bash the EXEC  
button, and I'm getting plausible sequential physical addresses out;  
I can also read/write to the memory via the IOMemoryDescriptor (the  
client initialises the first uint8 of the 'lump' to 23, which will  
appear in the system log/console; the kext writes 42 to it, which  
will appear in the client).

http://www.ecs.soton.ac.uk/~prb/junk/qemu-devel-darwin- 
kqemu-19mar07.tar.bz2 (1934KB)

Summary of changes to Mike's earlier example:
  - 'transporter' struct now has a 'uint8_t* lump_of_ram;' member, to  
act as some application-allocated memory (it mallocs (and never  
frees, ahem) 2K each EXEC ioctl).
  - I dropped Mike's KEXT code into the HelloIOKit example, so that  
it does all the IO KEXT initialisation. I'm not convinced that this  
is actually necessary.
    A side effect is that 'kqemu.ext' is now called 'HelloIOKit.ext'.  
Please bear with the quick and nasty prototype. ;)
  - The KQEMU_EXEC ioctl handling case now:
    - Constructs a IOGeneralMemoryDescriptor and initialises it to  
point to the lump_of_ram in the transporter struct
    - 'Prepares' the Descriptor. I believe that this is performing  
the required locking:
      "This involves paging in the memory, if necessary, and wiring  
it down for the duration of the transfer." [1]
    - Prints the physical address to the system log, and does the  
aformentioned read/write
    - 'Completes' the Descriptor (unlocking)
    - Destructs (pedantically: unreferences) the  
IOGeneralMemoryDescriptor

[De]constructing a fresh IOGMD each time is rough-prototype-code  
garbage. One can be recycled by just calling initWithAddress() again  
on it---at a _glance_, it looks like the kqemu_instance struct would  
be a sensible place to put it.

Phil
1. http://developer.apple.com/documentation/Darwin/Reference/ 
KernelIOKitFramework/IOMemoryDescriptor/Classes/IOMemoryDescriptor/ 
index.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-20  2:18         ` Philip Boulain
@ 2007-03-20  8:02           ` Mike Kronenberg
  2007-03-20 11:58             ` Mike Kronenberg
  0 siblings, 1 reply; 11+ messages in thread
From: Mike Kronenberg @ 2007-03-20  8:02 UTC (permalink / raw)
  To: qemu-devel

Cool :)

just dlded your tarball, and things work well.

I'm about to add the code to the "genuine" kqemu environment. With  
kqemu Variables and function stubs.
I hope to post back soon.

Mike


On 20.03.2007, at 03:18, Philip Boulain wrote:

> Mike Kronenberg wrote:
> > So any suggestions on how to lock user pages in Darwin would be  
> very welcome.
>
> Philip Boulain wrote:
>> Thanks; looking at this post, I'm probably barking up the right tree
>
> Right. I've cobbled up the aformentioned prototype, and it working  
> insofar that the modified and now-leaky version of Mike's test  
> client is allocating sequential lumps of memory when you bash the  
> EXEC button, and I'm getting plausible sequential physical  
> addresses out; I can also read/write to the memory via the  
> IOMemoryDescriptor (the client initialises the first uint8 of the  
> 'lump' to 23, which will appear in the system log/console; the kext  
> writes 42 to it, which will appear in the client).
>
> http://www.ecs.soton.ac.uk/~prb/junk/qemu-devel-darwin- 
> kqemu-19mar07.tar.bz2 (1934KB)
>
> Summary of changes to Mike's earlier example:
>  - 'transporter' struct now has a 'uint8_t* lump_of_ram;' member,  
> to act as some application-allocated memory (it mallocs (and never  
> frees, ahem) 2K each EXEC ioctl).
>  - I dropped Mike's KEXT code into the HelloIOKit example, so that  
> it does all the IO KEXT initialisation. I'm not convinced that this  
> is actually necessary.
>    A side effect is that 'kqemu.ext' is now called  
> 'HelloIOKit.ext'. Please bear with the quick and nasty prototype. ;)
>  - The KQEMU_EXEC ioctl handling case now:
>    - Constructs a IOGeneralMemoryDescriptor and initialises it to  
> point to the lump_of_ram in the transporter struct
>    - 'Prepares' the Descriptor. I believe that this is performing  
> the required locking:
>      "This involves paging in the memory, if necessary, and wiring  
> it down for the duration of the transfer." [1]
>    - Prints the physical address to the system log, and does the  
> aformentioned read/write
>    - 'Completes' the Descriptor (unlocking)
>    - Destructs (pedantically: unreferences) the  
> IOGeneralMemoryDescriptor
>
> [De]constructing a fresh IOGMD each time is rough-prototype-code  
> garbage. One can be recycled by just calling initWithAddress()  
> again on it---at a _glance_, it looks like the kqemu_instance  
> struct would be a sensible place to put it.
>
> Phil
> 1. http://developer.apple.com/documentation/Darwin/Reference/ 
> KernelIOKitFramework/IOMemoryDescriptor/Classes/IOMemoryDescriptor/ 
> index.html
>
>
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-20  8:02           ` Mike Kronenberg
@ 2007-03-20 11:58             ` Mike Kronenberg
  2007-03-20 16:26               ` Mike Kronenberg
  0 siblings, 1 reply; 11+ messages in thread
From: Mike Kronenberg @ 2007-03-20 11:58 UTC (permalink / raw)
  To: qemu-devel

Here we go:
www.kronenberg.org/qemu/qemu-devel-darwin-kqemu-20mar07.tar.bz2

- Made a new IOKit kext proj to match all the kqemu name requirements
- moved kext header inside kqemu-darwin.cpp to lessen stray darwin  
related files
- added kqemu-kernel.h to the target
- added kqemu.h to the target
- added stubs from kqemu-kernel.h
- moved the test cases to the "playground"

The kqemuClient is updated to work with the kext and its playground.

Next I will start filling in the stubs and kqemu_open/close and  
kqemu_ioctl based on Phils prototype.
- Wondering how to convert a physical address to a page index on...

feel free to be faster :)
Mike


On 20.03.2007, at 09:02, Mike Kronenberg wrote:

> Cool :)
>
> just dlded your tarball, and things work well.
>
> I'm about to add the code to the "genuine" kqemu environment. With  
> kqemu Variables and function stubs.
> I hope to post back soon.
>
> Mike
>
>
> On 20.03.2007, at 03:18, Philip Boulain wrote:
>
>> Mike Kronenberg wrote:
>> > So any suggestions on how to lock user pages in Darwin would be  
>> very welcome.
>>
>> Philip Boulain wrote:
>>> Thanks; looking at this post, I'm probably barking up the right tree
>>
>> Right. I've cobbled up the aformentioned prototype, and it working  
>> insofar that the modified and now-leaky version of Mike's test  
>> client is allocating sequential lumps of memory when you bash the  
>> EXEC button, and I'm getting plausible sequential physical  
>> addresses out; I can also read/write to the memory via the  
>> IOMemoryDescriptor (the client initialises the first uint8 of the  
>> 'lump' to 23, which will appear in the system log/console; the  
>> kext writes 42 to it, which will appear in the client).
>>
>> http://www.ecs.soton.ac.uk/~prb/junk/qemu-devel-darwin- 
>> kqemu-19mar07.tar.bz2 (1934KB)
>>
>> Summary of changes to Mike's earlier example:
>>  - 'transporter' struct now has a 'uint8_t* lump_of_ram;' member,  
>> to act as some application-allocated memory (it mallocs (and never  
>> frees, ahem) 2K each EXEC ioctl).
>>  - I dropped Mike's KEXT code into the HelloIOKit example, so that  
>> it does all the IO KEXT initialisation. I'm not convinced that  
>> this is actually necessary.
>>    A side effect is that 'kqemu.ext' is now called  
>> 'HelloIOKit.ext'. Please bear with the quick and nasty prototype. ;)
>>  - The KQEMU_EXEC ioctl handling case now:
>>    - Constructs a IOGeneralMemoryDescriptor and initialises it to  
>> point to the lump_of_ram in the transporter struct
>>    - 'Prepares' the Descriptor. I believe that this is performing  
>> the required locking:
>>      "This involves paging in the memory, if necessary, and wiring  
>> it down for the duration of the transfer." [1]
>>    - Prints the physical address to the system log, and does the  
>> aformentioned read/write
>>    - 'Completes' the Descriptor (unlocking)
>>    - Destructs (pedantically: unreferences) the  
>> IOGeneralMemoryDescriptor
>>
>> [De]constructing a fresh IOGMD each time is rough-prototype-code  
>> garbage. One can be recycled by just calling initWithAddress()  
>> again on it---at a _glance_, it looks like the kqemu_instance  
>> struct would be a sensible place to put it.
>>
>> Phil
>> 1. http://developer.apple.com/documentation/Darwin/Reference/ 
>> KernelIOKitFramework/IOMemoryDescriptor/Classes/IOMemoryDescriptor/ 
>> index.html
>>
>>
>>
>> _______________________________________________
>> Qemu-devel mailing list
>> Qemu-devel@nongnu.org
>> http://lists.nongnu.org/mailman/listinfo/qemu-devel
>
>
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-20 11:58             ` Mike Kronenberg
@ 2007-03-20 16:26               ` Mike Kronenberg
  0 siblings, 0 replies; 11+ messages in thread
From: Mike Kronenberg @ 2007-03-20 16:26 UTC (permalink / raw)
  To: qemu-devel

You may want to hit me with a brick :)

here is a draft not thested or whatever of kqemu-darwin.cpp before I  
have to leave...
...just for some ideads.

/note to self
  -open a folder in kju svn tonight, so that we don't have to spam  
the list to much.

Mike

On 20.03.2007, at 12:58, Mike Kronenberg wrote:

> Here we go:
> www.kronenberg.org/qemu/qemu-devel-darwin-kqemu-20mar07.tar.bz2
>
> - Made a new IOKit kext proj to match all the kqemu name requirements
> - moved kext header inside kqemu-darwin.cpp to lessen stray darwin  
> related files
> - added kqemu-kernel.h to the target
> - added kqemu.h to the target
> - added stubs from kqemu-kernel.h
> - moved the test cases to the "playground"
>
> The kqemuClient is updated to work with the kext and its playground.
>
> Next I will start filling in the stubs and kqemu_open/close and  
> kqemu_ioctl based on Phils prototype.
> - Wondering how to convert a physical address to a page index on...
>
> feel free to be faster :)
> Mike
>
>
> On 20.03.2007, at 09:02, Mike Kronenberg wrote:
>
>> Cool :)
>>
>> just dlded your tarball, and things work well.
>>
>> I'm about to add the code to the "genuine" kqemu environment. With  
>> kqemu Variables and function stubs.
>> I hope to post back soon.
>>
>> Mike
>>
>>
>> On 20.03.2007, at 03:18, Philip Boulain wrote:
>>
>>> Mike Kronenberg wrote:
>>> > So any suggestions on how to lock user pages in Darwin would be  
>>> very welcome.
>>>
>>> Philip Boulain wrote:
>>>> Thanks; looking at this post, I'm probably barking up the right  
>>>> tree
>>>
>>> Right. I've cobbled up the aformentioned prototype, and it  
>>> working insofar that the modified and now-leaky version of Mike's  
>>> test client is allocating sequential lumps of memory when you  
>>> bash the EXEC button, and I'm getting plausible sequential  
>>> physical addresses out; I can also read/write to the memory via  
>>> the IOMemoryDescriptor (the client initialises the first uint8 of  
>>> the 'lump' to 23, which will appear in the system log/console;  
>>> the kext writes 42 to it, which will appear in the client).
>>>
>>> http://www.ecs.soton.ac.uk/~prb/junk/qemu-devel-darwin- 
>>> kqemu-19mar07.tar.bz2 (1934KB)
>>>
>>> Summary of changes to Mike's earlier example:
>>>  - 'transporter' struct now has a 'uint8_t* lump_of_ram;' member,  
>>> to act as some application-allocated memory (it mallocs (and  
>>> never frees, ahem) 2K each EXEC ioctl).
>>>  - I dropped Mike's KEXT code into the HelloIOKit example, so  
>>> that it does all the IO KEXT initialisation. I'm not convinced  
>>> that this is actually necessary.
>>>    A side effect is that 'kqemu.ext' is now called  
>>> 'HelloIOKit.ext'. Please bear with the quick and nasty prototype. ;)
>>>  - The KQEMU_EXEC ioctl handling case now:
>>>    - Constructs a IOGeneralMemoryDescriptor and initialises it to  
>>> point to the lump_of_ram in the transporter struct
>>>    - 'Prepares' the Descriptor. I believe that this is performing  
>>> the required locking:
>>>      "This involves paging in the memory, if necessary, and  
>>> wiring it down for the duration of the transfer." [1]
>>>    - Prints the physical address to the system log, and does the  
>>> aformentioned read/write
>>>    - 'Completes' the Descriptor (unlocking)
>>>    - Destructs (pedantically: unreferences) the  
>>> IOGeneralMemoryDescriptor
>>>
>>> [De]constructing a fresh IOGMD each time is rough-prototype-code  
>>> garbage. One can be recycled by just calling initWithAddress()  
>>> again on it---at a _glance_, it looks like the kqemu_instance  
>>> struct would be a sensible place to put it.
>>>
>>> Phil
>>> 1. http://developer.apple.com/documentation/Darwin/Reference/ 
>>> KernelIOKitFramework/IOMemoryDescriptor/Classes/ 
>>> IOMemoryDescriptor/index.html
>>>
>>>
>>>
>>> _______________________________________________
>>> Qemu-devel mailing list
>>> Qemu-devel@nongnu.org
>>> http://lists.nongnu.org/mailman/listinfo/qemu-devel
>>
>>
>>
>> _______________________________________________
>> Qemu-devel mailing list
>> Qemu-devel@nongnu.org
>> http://lists.nongnu.org/mailman/listinfo/qemu-devel
>
>
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel



//header start - included to generate less clutter in the kqemu  
repository :)
#include <IOKit/IOService.h>

class org_qemu_driver_kqemu : public IOService {
	OSDeclareDefaultStructors(org_qemu_driver_kqemu)
public:
	virtual bool init(OSDictionary* dictionary = 0);
	virtual void free(void);
	virtual IOService* probe(IOService* provider, SInt32* score);
	virtual bool start(IOService* provider);
	virtual void stop(IOService* provider);
};
//header end



#include <IOKit/IOLib.h>

#include <mach/mach_types.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/conf.h>
#include <miscfs/devfs/devfs.h>
#include <sys/ioctl.h>

#import <libkern/OSMalloc.h>

//#include "kqemu-darwin.h" //we included the kext header

extern "C" {
	#include <pexpert/pexpert.h> /* Tutorial says for debug only */
}

#define super IOService

// Second argument must be literal (preprocessor limitation?)
OSDefineMetaClassAndStructors(org_qemu_driver_kqemu, IOService)



/*
  *    kqemu stuff below  
***********************************************************
  */

//#include <sys/proc.h>

#import "kqemu-kernel.h" //this is the kqemu project header
int kqemu_debug;

static struct kqemu_global_state *kqemu_gs = NULL;

struct kqemu_global_state * CDECL kqemu_global_init(int  
max_locked_pages)
{
     return NULL;
}

void CDECL kqemu_global_delete(struct kqemu_global_state *g)
{
}

struct kqemu_state * CDECL kqemu_init(struct kqemu_init *d,
                                       struct kqemu_global_state *g)
{
     return NULL;
}

struct kqemu_cpu_state * CDECL kqemu_get_cpu_state(struct kqemu_state  
*s)
{
     return NULL;
}

long CDECL kqemu_exec(struct kqemu_state *s)
{
     return NULL;
}

void CDECL kqemu_delete(struct kqemu_state *s)
{
}


/* Lock the page at virtual address 'user_addr' and return its
    physical address (page index). Return a host OS private user page
    identifier or NULL if error */
struct kqemu_user_page *CDECL kqemu_lock_user_page(unsigned long  
*ppage_index,
                                                    unsigned long  
user_addr)
{
     return NULL;
}

void CDECL kqemu_unlock_user_page(struct kqemu_user_page *page)
{
}


/* Allocate a new page and return its physical address (page
    index). Return a host OS private page identifier or NULL if
    error */
struct kqemu_page *CDECL kqemu_alloc_zeroed_page(unsigned long  
*ppage_index)
{
     return NULL;
}

void CDECL kqemu_free_page(struct kqemu_page *page)
{
}


/* Return a host kernel address of the physical page whose private
    identifier is 'page1' */
void * CDECL kqemu_page_kaddr(struct kqemu_page *page)
{
     return NULL;
}


/* Allocate 'size' bytes of memory in host kernel address space (size
    is a multiple of 4 KB) and return the address or NULL if error. The
    allocated memory must be marked as executable by the host kernel
    and must be page aligned. On i386 with PAE (but not on x86_64), it
    must be allocated in the first 4 GB of physical memory. */
void * CDECL kqemu_vmalloc(unsigned int size)
{
     return NULL;
}

void CDECL kqemu_vfree(void *ptr)
{
}


/* Convert a page aligned address inside a memory area allocated by
    kqemu_vmalloc() to a physical address (page index) */
unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr)
{
     vm_offset_t pa = ml_vtophys((vm_offset_t)vaddr); //vm_paddr_t pa  
= vtophys(vaddr);
     if (pa == 0) {
         kqemu_log("kqemu_vmalloc_to_phys(%p)->error\n", vaddr);
         return -1;
     }
     if (kqemu_debug > 0)
         kqemu_log("kqemu_vmalloc_to_phys(%p)->%08x\n", vaddr, pa);
     return pa >> PAGE_SHIFT;
}


/* Map a IO area in the kernel address space and return its
    address. Return NULL if error or not implemented. This function is
    only used if an APIC is detected on the host CPU. */
void * CDECL kqemu_io_map(unsigned long page_index, unsigned int size)
{

// from machine_routines.h:
///* Map memory map IO space */
//vm_offset_t ml_io_map(
//	vm_offset_t phys_addr,
//	vm_size_t size);

     return NULL;
}

void CDECL kqemu_io_unmap(void *ptr, unsigned int size)
{
}


/* return TRUE if a signal is pending (i.e. the guest must stop
    execution) */
int CDECL kqemu_schedule(void)
{
	return proc_issignal(proc_selfpid(), (sigset_t)-1);
}

static char log_buf[4096];

void CDECL kqemu_log(const char *fmt, ...)
{
     va_list ap;
     va_start(ap, fmt);
     vsnprintf(log_buf, sizeof(log_buf), fmt, ap);
     printf("kqemu: %s", log_buf);
     va_end(ap);
}

/*
  *   darwin specific stuff  
*******************************************************
  */
struct kqemu_instance {
//#if __FreeBSD_version >= 500000
//    TAILQ_ENTRY(kqemu_instance) kqemu_ent;
//    struct cdev *kqemu_dev;
//#endif
     /*    struct semaphore sem;  */
     struct kqemu_state *state;
};


/*
    workaround for darwin not having dev->si_drv1
    found in qvm86-osx.c by Sandro Tolaini, txs */
#define MAX_MAP_ENTRIES 8
struct proc *procs[MAX_MAP_ENTRIES];
kqemu_instance *instances[MAX_MAP_ENTRIES];

void instance_map_init()
{
	int i;

	for (i = 0; i < MAX_MAP_ENTRIES; ++i) {
		procs[i] = NULL;
		instances[i] = NULL;
	}
}

kqemu_instance *instance_map_find(struct proc *p)
{
	int i;
	
	for (i = 0; i < MAX_MAP_ENTRIES; ++i) {
		if (procs[i] == p)
			return instances[i];
	}
	
	return NULL;
}

int instance_map_add(struct proc *p, kqemu_instance *ks)
{
	int i;
	
	for (i = 0; i < MAX_MAP_ENTRIES; ++i) {
		if (procs[i] == NULL) {
			procs[i] = p;
			instances[i] = ks;
			return 0;
		}
	}
	
	return -1;
}

void instance_map_remove(struct proc *p)
{
	int i;
	
	for (i = 0; i < MAX_MAP_ENTRIES; ++i) {
		if (procs[i] == p) {
			procs[i] = NULL;
			instances[i] = NULL;
		}
	}
}


/*
  *    kext stuff below  
***********************************************************
  */
OSMallocTag kqemu_malloc_tag;
static int major = -1;
static void *devfshandle = 0;

static int kqemu_open(dev_t dev, int flags, int devtype, struct proc  
*p) {
	struct kqemu_instance *ks;

     ks = (kqemu_instance *)OSMalloc(sizeof(struct kqemu_instance),  
kqemu_malloc_tag);
     if (ks == NULL) {
         kqemu_log("malloc failed\n");
         return ENOMEM;
     }
//    init_MUTEX(&ks->sem); do we need this semaphore?
     memset(ks, 0, sizeof *ks);
     instance_map_add(p, ks);
     if (kqemu_debug > 0)
         kqemu_log("opened by pid=%d\n", proc_pid(p));

     return 0;
}

static int kqemu_close(dev_t dev, int flags, int devtype, struct proc  
*p) {
	kqemu_instance *ks = (kqemu_instance *)instance_map_find(p);

//    down(&ks->sem);
     if (ks->state) {
         kqemu_delete(ks->state);
         ks->state = NULL;
     }
//    up(&ks->sem);
     OSFree(ks, sizeof(struct kqemu_instance), kqemu_malloc_tag);
     instance_map_remove(p);

     return 0;
}

/* playground start - this is for debigging/testing only */
#define KQEMU_TEST_1          _IOWR('q', 5, u_int32_t)
#define KQEMU_TEST_2          _IOWR('q', 6, transporter)
#define KQEMU_TEST_3          _IOWR('q', 7, int)

typedef struct transporter {
	uint8_t* lump_of_ram;
} transporter;
/* playground end */

static int kqemu_ioctl(dev_t dev, u_long cmd, caddr_t addr, int  
fflag, struct proc *p) {
     int error = 0;
     kqemu_instance *ks = (kqemu_instance *)instance_map_find(p);
     struct kqemu_state *s = ks->state;

     switch(cmd) {
         case KQEMU_INIT: {
             if (addr) {

                 struct kqemu_init d1, *d = &d1;
                 if (s != NULL) {
                     error = EIO;
                     break;
                 }
                 d1 = *(struct kqemu_init *)addr;
                 if (kqemu_debug > 0)
                     kqemu_log("ram_base=%p ram_size=%ld\n",  
d1.ram_base, d1.ram_size);
                 s = kqemu_init(d, kqemu_gs);
                 if (s == NULL) {
                     error = ENOMEM;
                     break;
                 }
                 ks->state = s;

                 break;
             } else {
                 printf("kqemu KEXT: KQEMU_INIT: no addr\n");
                 error = EINVAL;
                 break;
             }
         }
			
         case KQEMU_EXEC: {
             if (addr) {
                 struct kqemu_cpu_state *ctx;
                 if (s != NULL) {
                     error = EIO;
                     break;
                 }
                 ctx = kqemu_get_cpu_state(s);
                 *ctx = *(struct kqemu_cpu_state *)addr;
                 //do we need a lock here?
                 error = kqemu_exec(s);
                 //do we need a unlock here?
                 *(struct kqemu_cpu_state *)addr = *ctx;
                 break;
             } else {
                 printf("kqemu KEXT: KQEMU_EXEC no addr\n");
             }
             break;
         }
			
         case KQEMU_GET_VERSION: {
             if (addr) {
				*(int *)addr = KQEMU_VERSION;
				printf("kqemu KEXT: KQEMU_VERSION: %08x\n", *(int *)addr);
             } else {
                 printf("kqemu KEXT: KQEMU_VERSION: no addr\n");
             }
             break;
         }

         /* playground start - this is for debigging/testing only */
         case KQEMU_TEST_1: {
             if (addr) {
                 *(u_int32_t *)addr = 102;
                 printf("kqemu KEXT: KQEMU_TEST_1: %d\n", *addr);
                 break;
             } else {
                 printf("kqemu KEXT: KQEMU_TEST_1: no addr\n");
             }
         }
			
         case KQEMU_TEST_2: { // Actually just a test case
             if (addr) {
				IOGeneralMemoryDescriptor* iomd = new IOGeneralMemoryDescriptor();
				
                 transporter *tTr = (transporter *)addr;
                 printf("kqemu KEXT: KQEMU_TEST_2: Ooh, a lump of  
RAM, with user address %p!\n", tTr->lump_of_ram);
				
				if(!iomd->initWithAddress((vm_address_t) tTr->lump_of_ram, 256,  
kIODirectionOutIn, current_task())) {
					// Initialisation failed---drop the instance and bail.
					printf("kqemu KEXT: KQEMU_TEST_2: initWithAddress failed!\n");
					iomd->release();
					break;
				} else {
					printf("kqemu KEXT: KQEMU_TEST_2: initWithAddress succeeded,  
hurrah.\n");
				}
				if(iomd->prepare() == kIOReturnSuccess) {
					uint8_t value;
					uint8_t* ram_ptr = (uint8_t*) iomd->getPhysicalAddress();
					printf("kqemu KEXT: KQEMU_TEST_2: It's physical address is %p. 
\n", (void*) ram_ptr);
					
					// Unsuprisingly, poking with random physical addresses in a  
kernel context causes explosions.
					// Uncommenting these lines will almost certainly panic OS X  
beautifully. YHBW.
					//printf("kqemu KEXT: KQEMU_TEST_2: And the first value there is  
%u.\n", (unsigned int) *ram_ptr);
					//*ram_ptr = 42;
					
					// For the sake of testing, let's do this with the accessors/ 
mutators
					iomd->readBytes(0, &value, sizeof(uint8_t));
					printf("kqemu KEXT: KQEMU_TEST_2: And the first value there is % 
u.\n", (unsigned int) value);
					value = 42;
					iomd->writeBytes(0, &value, sizeof(uint8_t));
						
					iomd->complete();
				} else {
					printf("kqemu KEXT: KQEMU_TEST_2: prepare failed!\n");
				}
				
				iomd->release();
             } else {
                 printf("kqemu KEXT: KQEMU_TEST_2 no addr\n");
             }
             break;
         }
			
         case KQEMU_TEST_3: {
             if (addr) {
				*(int *)addr = KQEMU_VERSION;
				printf("kqemu KEXT: KQEMU_TEST_3: %08x\n", *(int *)addr);
             } else {
                 printf("kqemu KEXT: KQEMU_TEST_3: no addr\n");
             }
             break;
         }
         /* playground end */
			
         default:
             error = EINVAL;
     }

     return error;
}

// Character device switch table
static struct cdevsw chardev = {
	kqemu_open, /* open */
	kqemu_close, /* close */
	eno_rdwrt, /* read */
	eno_rdwrt, /* write */
	kqemu_ioctl, /* ioctl */
	eno_stop, /* stop*/
	eno_reset, /* reset */
	0, /* ttys */
	eno_select, /* select */
	eno_mmap, /* mmap */
	eno_strat, /* strategy */
	eno_getc, /* getc */
	eno_putc, /* putc */
	0 /* type */
};

// Object initialiser
bool org_qemu_driver_kqemu::init(OSDictionary* dict) {
	bool result = super::init(dict);
	IOLog("kqemu KEXT: initializing...\n");
	return result;
}

// Object destructor
void org_qemu_driver_kqemu::free(void) {
	IOLog("kqemu KEXT: freeing...\n");
	super::free();
}

// Hardware compatability test
IOService* org_qemu_driver_kqemu::probe(IOService* provider, SInt32*  
score) {
	IOService* result = super::probe(provider, score);
	IOLog("kqemu KEXT: probing...\n");
	return result;
}

// Class initialiser
bool org_qemu_driver_kqemu::start(IOService* provider) {
	bool result = super::start(provider);

	instance_map_init();
     kqemu_malloc_tag = OSMalloc_Tagalloc("kqemu", OSMT_DEFAULT);
	
	// Register device in /dev
     major = cdevsw_add(major, &chardev);
     if (major == -1) {
         printf("kqemu KEXT: error registering cdevsw\n");
     }
	devfshandle = devfs_make_node(makedev(major, 0), DEVFS_CHAR,  
UID_ROOT, GID_WHEEL, 0666, "kqemu");
     if (!devfshandle) {
         printf("kqemu KEXT: error creating device node\n");
     }
	
	IOLog("kqemu KEXT: starting...\n");
	return result;
}

// Class destructor
void org_qemu_driver_kqemu::stop(IOService* provider) {
     // remove device from /dev
	devfs_remove(devfshandle);
	cdevsw_remove(major, &chardev);
	
	IOLog("kqemu KEXT: stopping...\n");
	super::stop(provider);
     OSMalloc_Tagfree(kqemu_malloc_tag);
}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-19 22:16       ` Philip Boulain
  2007-03-20  2:18         ` Philip Boulain
@ 2007-03-21 15:39         ` Derek Fawcus
  2007-03-21 16:07           ` Philip Boulain
  1 sibling, 1 reply; 11+ messages in thread
From: Derek Fawcus @ 2007-03-21 15:39 UTC (permalink / raw)
  To: qemu-devel

On Mon, Mar 19, 2007 at 10:16:13PM +0000, Philip Boulain wrote:
> On 19 Mar 2007, at 20:23, Derek Fawcus wrote:
> > There was just a discussion relating to this on the darwin-kernel  
> > list,
> > you may wish to review the archive.
> >
> > (The thread starts at http://lists.apple.com/archives/Darwin-kernel/ 
> > 2007/Mar/msg00010.html).
> 
> Thanks; looking at this post, I'm probably barking up the right tree:
> 
> http://lists.apple.com/archives/Darwin-kernel/2007/Mar/msg00031.html

Well,  they seemed to be suggesting that the kernel importing and locking
the user space memory was a bit dodgy,  and that the kernel should export
memory to user space.   Or maybe that only really applies inthe case of
devices...

DF

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] KQEMU Darwin port status?
  2007-03-21 15:39         ` Derek Fawcus
@ 2007-03-21 16:07           ` Philip Boulain
  0 siblings, 0 replies; 11+ messages in thread
From: Philip Boulain @ 2007-03-21 16:07 UTC (permalink / raw)
  To: qemu-devel

On 21 Mar 2007, at 15:39, Derek Fawcus wrote:
> Well,  they seemed to be suggesting that the kernel importing and  
> locking
> the user space memory was a bit dodgy,  and that the kernel should  
> export
> memory to user space.   Or maybe that only really applies in the  
> case of
> devices...

Yes. It's perfectly valid to point out that this is usually a bad  
thing to do, but to refuse to help on those grounds is---well,  
unhelpful. Sometimes, you have no choice but to do something which is  
normally bizzare. (What I /don't/ get is why Bhavesh didn't explain  
the 'bizzare' circumstances, given that that thread appears to be  
post-GPL-KQEMU.)

I can see why this appears to be a bad thing, but it's also how KQEMU  
works, and I'm guessing that /that/ is for good reasons, even if  
they're good reasons on some other platform it supports. (One that  
comes to mind is that you /probably/ don't want to ask for 4GB of  
kernel-allocated memory in order to run a VM with 4GB of RAM.)  
AFAICT, the worst /effect/ of this is that a userland application  
could cause the kernel to either wire down so much memory that it  
can't swap things in, or run out of kernel address space, and I would  
expect those risks to affect other platforms too---in other words,  
you could probably crash the system from a userland application with  
access to the /dev/kqemu device. I /don't/ see any reason why it  
should be "dodgy" in the unpleasant-to-debug--side-effects sense;  
hopefully because no such reason exists. :)

Phil

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2007-03-21 16:09 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-17 19:30 [Qemu-devel] KQEMU Darwin port status? Philip Boulain
2007-03-19  8:49 ` Mike Kronenberg
2007-03-19 18:54   ` Philip Boulain
2007-03-19 20:23     ` Derek Fawcus
2007-03-19 22:16       ` Philip Boulain
2007-03-20  2:18         ` Philip Boulain
2007-03-20  8:02           ` Mike Kronenberg
2007-03-20 11:58             ` Mike Kronenberg
2007-03-20 16:26               ` Mike Kronenberg
2007-03-21 15:39         ` Derek Fawcus
2007-03-21 16:07           ` Philip Boulain

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.