[RFC] First (incomplete) cut of Xen paravirt binding

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Rusty Russell <rusty at rustcorp.com.au> writes:

> On Sun, 2006-07-30 at 19:05 +0200, Andi Kleen wrote:
>>  > (1) We can make startup_32 work for every known and future reasonable
>> > hypervisor as well as native, by testing if ring isn't 0 and paging is
>> > enabled and jumping to the paravirt entry path.
>> 
>> Somehow the right Hypervisor still needs to be discovered though
>> so that the right paravirt ops can be installed.
>> 
>> We would need a standard interface for this.
>
> Yes, that's %ebx here (0 == Xen): we call paravirts[%ebx]->init().
>
> Of course if you do full virtualization and then later want to insert
> paravirt_ops, you can just use the normal boot path (Zach has indicated
> that VMWare will do this in the short to medium term anyway).
>
> FYI, here's the actual patch.
>
> Thanks!
> Rusty.
>
> First cut (compiles, untested) of generic startup_paravirt entry point.

Well I can tell to some extent it doesn't work as you got the
x86 calling conventions wrong.

>
> 1) Each hypervisor type creates a paravirt_ops struct and puts an
>    agreed-on entry in the paravirts[] array.  Strictly, this need
>    only have the init function populated.
>
> 2) The hypervisor type is handed through %ebx to the startup_paravirt
>    function at boot.  Currently 0 = Xen 3.0, 1 = VMI.
>
> 3) The init function (called with all regs except for %ebx and %esp
>    intact), with first arg pointing to the paravirt_ops structure
>    we're using.  This is responsible for overwriting the paravirt_ops:
>    a helper called initialize_ops_struct is provided.

I like the concept of passing as much through as possible to
the init function, but in practice I'm not certain it make sense.
Especially where the C calling conventions pass everything on
the stack.

Anyway here is roughly what I was thinking...

> Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index eb79aa2..a1c21b3 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -54,6 +54,13 @@ #define INIT_MAP_BEYOND_END	(128*1024)
  * can.
  */
 ENTRY(startup_32)
+/*
+ * See if we need to run paravirtualized
+ */	
+	xorl %ebx, %ebx	
+	movw 0x226(%esi), %bx
+	testl %ebx, %ebx
+	jnz startup_paravirt
 
 /*
  * Set segments to known values.
@@ -411,6 +418,19 @@ #endif
 #endif
 	iret
 
+startup_paravirt:
+#ifdef CONFIG_PARAVIRT
+	cld
+	movl $(init_thread_union+THREAD_SIZE), %esp
+
+	/* ebx contains index into paravirt to copy.  Hand to init as a ptr */
+	movl paravirts(,%ebx,4), %ebx
+	pushl %ebx
+	call *PARAVIRT_init_offset(%ebx)
+#endif
+1:	jmp 1b
+
 /*
  * Real beginning of normal "text" segment
  */


[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux