Re: [PATCH] fill in missing pv_mmu_ops entries for PAGETABLE_LEVELS >= 3

2008-01-28 Thread Glauber de Oliveira Costa

Ingo Molnar wrote:

* Marcelo Tosatti <[EMAIL PROTECTED]> wrote:

  
The first fix is not even specific for PARAVIRT, and it's actually 
preventing the whole tree from booting.


  

And the following allows PARAVIRT kernels to boot on x86_64.



  
Fill in missing pagetable manipulation entries in pv_mmu_ops 
for PAGETABLE_LEVELS >= 3.



thanks Marcelo - picked this up and the other changes as well. I guess 
the only thing missing at the moment is the proper Kconfig changes to 
allow the building of a 64-bit PARAVIRT kernel?

Ingo
  

For normal hardware yes. But I still have a vsmp patch in the queue.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] fill in missing pv_mmu_ops entries for PAGETABLE_LEVELS = 3

2008-01-28 Thread Glauber de Oliveira Costa

Ingo Molnar wrote:

* Marcelo Tosatti [EMAIL PROTECTED] wrote:

  
The first fix is not even specific for PARAVIRT, and it's actually 
preventing the whole tree from booting.


  

And the following allows PARAVIRT kernels to boot on x86_64.



  
Fill in missing pagetable manipulation entries in pv_mmu_ops 
for PAGETABLE_LEVELS = 3.



thanks Marcelo - picked this up and the other changes as well. I guess 
the only thing missing at the moment is the proper Kconfig changes to 
allow the building of a 64-bit PARAVIRT kernel?

Ingo
  

For normal hardware yes. But I still have a vsmp patch in the queue.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 6/6] export __supported_pte_mask

2008-01-18 Thread Glauber de Oliveira Costa
export __supported_pte_mask variable as GPL symbol.
lguest is a user of it.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/setup64.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
index 8fa0de8..5cc1339 100644
--- a/arch/x86/kernel/setup64.c
+++ b/arch/x86/kernel/setup64.c
@@ -41,6 +41,8 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) 
idt_table };
 char boot_cpu_stack[IRQSTACKSIZE] 
__attribute__((section(".bss.page_aligned")));
 
 unsigned long __supported_pte_mask __read_mostly = ~0UL;
+EXPORT_SYMBOL_GPL(__supported_pte_mask);
+
 static int do_not_nx __cpuinitdata = 0;
 
 /* noexec=on|off
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 5/6] export check_tsc_unstable

2008-01-18 Thread Glauber de Oliveira Costa
Exporrt check_tsc_unstable function as GPL symbol. lguest is
a user of it.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/tsc_64.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index c62f3b6..947554d 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -92,10 +92,12 @@ sched_clock(void) 
__attribute__((alias("native_sched_clock")));
 
 static int tsc_unstable;
 
-inline int check_tsc_unstable(void)
+int check_tsc_unstable(void)
 {
return tsc_unstable;
 }
+EXPORT_SYMBOL_GPL(check_tsc_unstable);
+
 #ifdef CONFIG_CPU_FREQ
 
 /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/6] use __PAGE_KERNEL instead of _PAGE_KERNEL

2008-01-18 Thread Glauber de Oliveira Costa
x86_64 don't expose the intermediate representation with one underline,
_PAGE_KERNEL, just the double-underlined one.

Use it, to get a common ground between 32 and 64-bit

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/page_tables.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 399c05d..fb5ebd0 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -645,7 +645,7 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 
/* Make the last PGD entry for this Guest point to the Switcher's PTE
 * page for this CPU (with appropriate flags). */
-   switcher_pgd = __pgd(__pa(switcher_pte_page) | _PAGE_KERNEL);
+   switcher_pgd = __pgd(__pa(switcher_pte_page) | __PAGE_KERNEL);
 
cpu->lg->pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX] = switcher_pgd;
 
@@ -657,7 +657,7 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 * page is already mapped there, we don't have to copy them out
 * again. */
pfn = __pa(cpu->regs_page) >> PAGE_SHIFT;
-   regs_pte = pfn_pte(pfn, __pgprot(_PAGE_KERNEL));
+   regs_pte = pfn_pte(pfn, __pgprot(__PAGE_KERNEL));
switcher_pte_page[(unsigned long)pages/PAGE_SIZE%PTRS_PER_PTE] = 
regs_pte;
 }
 /*:*/
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/6] explicitly use sched.h include

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the sched.h header explicitly to lguest_user file,
and avoid depending on it being included somewhere else.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/lguest_user.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index a87fca6..85d42d3 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "lg.h"
 
 /*L:055 When something happens, the Waker process needs a way to stop the
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/6] explicitly use hrtimer.h include

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the hrtimer.h header explicitly to lg.h file,
and avoid depending on it being included somewhere else.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/lg.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index f9707cf..eb51fc2 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/6] explicitly use ktime.h include

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the ktime.h header explicitly to hypercalls file,
and avoid depending on it being included somewhere else.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/hypercalls.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 32666d0..0f2cb4f 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "lg.h"
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/6] lguest patches for compiling x86_64

2008-01-18 Thread Glauber de Oliveira Costa
Right now, I have lguest in-tree module compiling on x86_64.
It's not yet on a sendable state, since the module itself isn't loading.

However, this subset of the series is pretty straightforward, and I'm sending it
now aiming at reducing the delta size in the future ;-)

Have fun,


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/10] Tree fixes for PARAVIRT

2008-01-18 Thread Glauber de Oliveira Costa
On Jan 18, 2008 8:02 PM, Ingo Molnar <[EMAIL PROTECTED]> wrote:
>
> * Zachary Amsden <[EMAIL PROTECTED]> wrote:
>
> > > but in exchange you broke all of 32-bit with CONFIG_PARAVIRT=y.
> > > Which means you did not even build-test it on 32-bit, let alone boot
> > > test it...
> >
> > Why are we rushing so much to do 64-bit paravirt that we are breaking
> > working configurations?  If the developement is going to be this
> > chaotic, it should be done and tested out of tree until it can
> > stabilize.
>
> what you see is a open feedback cycle conducted on lkml. People send
> patches for arch/x86, and we tell them if it breaks something. The bug
> was found before i pushed out the x86.git devel tree (and the fix is
> below - but this shouldnt matter to you because the bug never hit a
> public x86.git tree).
>
>         Ingo
>
Other than this, it seems to build and boot fine.

Do you want me to resend ?
-- 
Glauber de Oliveira Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 9/10] provide __parainstructions section

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the __parainstructions section to vmlinux.lds.S.
It's needed for the patching system.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/vmlinux_64.lds.S |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index 5ae8aa8..5e0300f 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -175,6 +175,14 @@ SECTIONS
   }
   __con_initcall_end = .;
   SECURITY_INIT
+
+  . = ALIGN(8);
+  .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
+  __parainstructions = .;
+   *(.parainstructions)
+  __parainstructions_end = .;
+  }
+
   . = ALIGN(8);
   __alt_instructions = .;
   .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/10] change function orders in paravirt.h

2008-01-18 Thread Glauber de Oliveira Costa
__pmd, pmd_val and set_pud are used before they are defined (as static)
We move them a little up in the file, so it doesn't happen.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 include/asm-x86/paravirt.h |   84 ++--
 1 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 3e7ca42..12caaf1 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -1023,6 +1023,48 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, val);
 }
 
+#if PAGETABLE_LEVELS >= 3
+static inline pmd_t __pmd(pmdval_t val)
+{
+   pmdval_t ret;
+
+   if (sizeof(pmdval_t) > sizeof(long))
+   ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd,
+val, (u64)val >> 32);
+   else
+   ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd,
+val);
+
+   return (pmd_t) { ret };
+}
+
+static inline pmdval_t pmd_val(pmd_t pmd)
+{
+   pmdval_t ret;
+
+   if (sizeof(pmdval_t) > sizeof(long))
+   ret =  PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val,
+ pmd.pmd, (u64)pmd.pmd >> 32);
+   else
+   ret =  PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val,
+ pmd.pmd);
+
+   return ret;
+}
+
+static inline void set_pud(pud_t *pudp, pud_t pud)
+{
+   pudval_t val = native_pud_val(pud);
+
+   if (sizeof(pudval_t) > sizeof(long))
+   PVOP_VCALL3(pv_mmu_ops.set_pud, pudp,
+   val, (u64)val >> 32);
+   else
+   PVOP_VCALL2(pv_mmu_ops.set_pud, pudp,
+   val);
+}
+#endif /* PAGETABLE_LEVELS >= 3 */
+
 #ifdef CONFIG_X86_PAE
 /* Special-case pte-setting operations for PAE, which can't update a
64-bit pte atomically */
@@ -1073,48 +1115,6 @@ static inline void pmd_clear(pmd_t *pmdp)
 }
 #endif /* CONFIG_X86_PAE */
 
-#if PAGETABLE_LEVELS >= 3
-static inline pmd_t __pmd(pmdval_t val)
-{
-   pmdval_t ret;
-
-   if (sizeof(pmdval_t) > sizeof(long))
-   ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd,
-val, (u64)val >> 32);
-   else
-   ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd,
-val);
-
-   return (pmd_t) { ret };
-}
-
-static inline pmdval_t pmd_val(pmd_t pmd)
-{
-   pmdval_t ret;
-
-   if (sizeof(pmdval_t) > sizeof(long))
-   ret =  PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val,
- pmd.pmd, (u64)pmd.pmd >> 32);
-   else
-   ret =  PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val,
- pmd.pmd);
-
-   return ret;
-}
-
-static inline void set_pud(pud_t *pudp, pud_t pud)
-{
-   pudval_t val = native_pud_val(pud);
-
-   if (sizeof(pudval_t) > sizeof(long))
-   PVOP_VCALL3(pv_mmu_ops.set_pud, pudp,
-   val, (u64)val >> 32);
-   else
-   PVOP_VCALL2(pv_mmu_ops.set_pud, pudp,
-   val);
-}
-#endif /* PAGETABLE_LEVELS >= 3 */
-
 /* Lazy mode for batching updates / context switch */
 enum paravirt_lazy_mode {
PARAVIRT_LAZY_NONE,
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 6/10] provide read and write cr8 paravirt hooks

2008-01-18 Thread Glauber de Oliveira Costa
Since the cr8 manipulation functions ended up staying in the tree,
they can't be defined just when PARAVIRT is off: In this patch,
those functions are defined for the PARAVIRT case too.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 include/asm-x86/system.h |   30 --
 1 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h
index 692c28c..a33c3f4 100644
--- a/include/asm-x86/system.h
+++ b/include/asm-x86/system.h
@@ -236,6 +236,20 @@ static inline void native_write_cr4(unsigned long val)
asm volatile("mov %0,%%cr4": :"r" (val), "m" (__force_order));
 }
 
+#ifdef CONFIG_X86_64
+static inline unsigned long native_read_cr8(void)
+{
+   unsigned long cr8;
+   asm volatile("movq %%cr8,%0" : "=r" (cr8));
+   return cr8;
+}
+
+static inline void native_write_cr8(unsigned long val)
+{
+   asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
+}
+#endif
+
 static inline void native_wbinvd(void)
 {
asm volatile("wbinvd": : :"memory");
@@ -253,21 +267,9 @@ static inline void native_wbinvd(void)
 #define read_cr4_safe()(native_read_cr4_safe())
 #define write_cr4(x)   (native_write_cr4(x))
 #define wbinvd()   (native_wbinvd())
-
 #ifdef CONFIG_X86_64
-
-static inline unsigned long read_cr8(void)
-{
-   unsigned long cr8;
-   asm volatile("movq %%cr8,%0" : "=r" (cr8));
-   return cr8;
-}
-
-static inline void write_cr8(unsigned long val)
-{
-   asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
-}
-
+#define read_cr8() (native_read_cr8())
+#define write_cr8(x)   (native_write_cr8(x))
 #endif
 
 /* Clear the 'TS' bit */
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 7/10] fill pv_cpu_ops structure with cr8 fields

2008-01-18 Thread Glauber de Oliveira Costa
This patch fills in the read and write cr8 fields with their
native version

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/paravirt.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index c20b4f8..c67d331 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -319,6 +319,10 @@ struct pv_cpu_ops pv_cpu_ops = {
.read_cr4 = native_read_cr4,
.read_cr4_safe = native_read_cr4_safe,
.write_cr4 = native_write_cr4,
+#ifdef CONFIG_X86_64
+   .read_cr8 = native_read_cr8,
+   .write_cr8 = native_write_cr8,
+#endif
.wbinvd = native_wbinvd,
.read_msr = native_read_msr_safe,
.write_msr = native_write_msr_safe,
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 8/10] add asm_offset PARAVIRT constants

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the constant PARAVIRT needs in asm_offsets_64.c

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/asm-offsets_64.c |   14 ++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 2b32719..494e1e0 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -61,6 +61,20 @@ int main(void)
ENTRY(data_offset);
BLANK();
 #undef ENTRY
+#ifdef CONFIG_PARAVIRT
+   BLANK();
+   OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
+   OFFSET(PARAVIRT_PATCH_pv_cpu_ops, paravirt_patch_template, pv_cpu_ops);
+   OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops);
+   OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
+   OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
+   OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
+   OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, 
irq_enable_syscall_ret);
+   OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
+   OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
+#endif
+
+
 #ifdef CONFIG_IA32_EMULATION
 #define ENTRY(entry) DEFINE(IA32_SIGCONTEXT_ ## entry, offsetof(struct 
sigcontext_ia32, entry))
ENTRY(ax);
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 5/10] puts read and write cr8 into pv_cpu_ops

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds room for read and write_cr8 functions back in
pv_cpu_ops struct

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 include/asm-x86/paravirt.h |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 7ff25c2..3e7ca42 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -101,6 +101,11 @@ struct pv_cpu_ops {
unsigned long (*read_cr4)(void);
void (*write_cr4)(unsigned long);
 
+#ifdef CONFIG_X86_64
+   unsigned long (*read_cr8)(void);
+   void (*write_cr8)(unsigned long);
+#endif
+
/* Segment descriptor handling */
void (*load_tr_desc)(void);
void (*load_gdt)(const struct desc_ptr *);
@@ -614,6 +619,16 @@ static inline void write_cr4(unsigned long x)
PVOP_VCALL1(pv_cpu_ops.write_cr4, x);
 }
 
+static inline unsigned long read_cr8(void)
+{
+   return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr8);
+}
+
+static inline void write_cr8(unsigned long x)
+{
+   PVOP_VCALL1(pv_cpu_ops.write_cr8, x);
+}
+
 static inline void raw_safe_halt(void)
 {
PVOP_VCALL0(pv_irq_ops.safe_halt);
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/10] add missing parameter for lookup_address

2008-01-18 Thread Glauber de Oliveira Costa
lookup_address() receives two parameters, but efi_64.c call
is passing only one. It's actually preventing the tree from compiling

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/efi_64.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c
index f420819..1f8bbd9 100644
--- a/arch/x86/kernel/efi_64.c
+++ b/arch/x86/kernel/efi_64.c
@@ -45,9 +45,10 @@ static void __init early_mapping_set_exec(unsigned long 
start,
  int executable)
 {
pte_t *kpte;
+   int level;
 
while (start < end) {
-   kpte = lookup_address((unsigned long)__va(start));
+   kpte = lookup_address((unsigned long)__va(start), );
BUG_ON(!kpte);
if (executable)
set_pte(kpte, pte_mkexec(*kpte));
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/10] put generic mm_hooks include into PARAVIRT

2008-01-18 Thread Glauber de Oliveira Costa
With PARAVIRT, we actually have arch_{dup,exit}_mmap functions,
so we can't include the generic header

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 include/asm-x86/mmu_context_64.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h
index 7e2aa23..ad6dc82 100644
--- a/include/asm-x86/mmu_context_64.h
+++ b/include/asm-x86/mmu_context_64.h
@@ -7,7 +7,9 @@
 #include 
 #include 
 #include 
+#ifndef CONFIG_PARAVIRT
 #include 
+#endif
 
 /*
  * possibly do the LDT unload here?
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/10] provide a native_init_IRQ function to x86_64

2008-01-18 Thread Glauber de Oliveira Costa
x86_64 lacks a native_init_IRQ() function, so we turn the arch's
init_IRQ() function into a native construct

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/i8259_64.c  |4 +++-
 include/asm-x86/hw_irq_64.h |1 +
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/i8259_64.c b/arch/x86/kernel/i8259_64.c
index cba13e0..738517e 100644
--- a/arch/x86/kernel/i8259_64.c
+++ b/arch/x86/kernel/i8259_64.c
@@ -456,7 +456,9 @@ void __init init_ISA_irqs (void)
}
 }
 
-void __init init_IRQ(void)
+void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
+
+void __init native_init_IRQ(void)
 {
int i;
 
diff --git a/include/asm-x86/hw_irq_64.h b/include/asm-x86/hw_irq_64.h
index a346159..312a58d 100644
--- a/include/asm-x86/hw_irq_64.h
+++ b/include/asm-x86/hw_irq_64.h
@@ -141,6 +141,7 @@ extern void print_IO_APIC(void);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
 extern void send_IPI(int dest, int vector);
 extern void setup_ioapic_dest(void);
+extern void native_init_IRQ(void);
 
 extern unsigned long io_apic_irqs;
 
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/10] Tree fixes for PARAVIRT

2008-01-18 Thread Glauber de Oliveira Costa
Hi,

This small series provides some more fixes towards the goal
to have the PARAVIRT selectable for x86_64. After that, just
some more small steps are needed.

The first fix is not even specific for PARAVIRT, and it's actually
preventing the whole tree from booting.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/10] add stringify header

2008-01-18 Thread Glauber de Oliveira Costa
We use a __stringify construction at paravirt_patch_64.c.
It's better practice to include the stringify header directly

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/paravirt_patch_64.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/paravirt_patch_64.c 
b/arch/x86/kernel/paravirt_patch_64.c
index cbfc4f3..7d904e1 100644
--- a/arch/x86/kernel/paravirt_patch_64.c
+++ b/arch/x86/kernel/paravirt_patch_64.c
@@ -1,5 +1,6 @@
 #include 
 #include 
+#include 
 
 DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
 DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
-- 
1.4.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 6/6] export __supported_pte_mask

2008-01-18 Thread Glauber de Oliveira Costa
export __supported_pte_mask variable as GPL symbol.
lguest is a user of it.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/setup64.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
index 8fa0de8..5cc1339 100644
--- a/arch/x86/kernel/setup64.c
+++ b/arch/x86/kernel/setup64.c
@@ -41,6 +41,8 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) 
idt_table };
 char boot_cpu_stack[IRQSTACKSIZE] 
__attribute__((section(.bss.page_aligned)));
 
 unsigned long __supported_pte_mask __read_mostly = ~0UL;
+EXPORT_SYMBOL_GPL(__supported_pte_mask);
+
 static int do_not_nx __cpuinitdata = 0;
 
 /* noexec=on|off
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 5/6] export check_tsc_unstable

2008-01-18 Thread Glauber de Oliveira Costa
Exporrt check_tsc_unstable function as GPL symbol. lguest is
a user of it.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/tsc_64.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index c62f3b6..947554d 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -92,10 +92,12 @@ sched_clock(void) 
__attribute__((alias(native_sched_clock)));
 
 static int tsc_unstable;
 
-inline int check_tsc_unstable(void)
+int check_tsc_unstable(void)
 {
return tsc_unstable;
 }
+EXPORT_SYMBOL_GPL(check_tsc_unstable);
+
 #ifdef CONFIG_CPU_FREQ
 
 /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/6] use __PAGE_KERNEL instead of _PAGE_KERNEL

2008-01-18 Thread Glauber de Oliveira Costa
x86_64 don't expose the intermediate representation with one underline,
_PAGE_KERNEL, just the double-underlined one.

Use it, to get a common ground between 32 and 64-bit

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/page_tables.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 399c05d..fb5ebd0 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -645,7 +645,7 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 
/* Make the last PGD entry for this Guest point to the Switcher's PTE
 * page for this CPU (with appropriate flags). */
-   switcher_pgd = __pgd(__pa(switcher_pte_page) | _PAGE_KERNEL);
+   switcher_pgd = __pgd(__pa(switcher_pte_page) | __PAGE_KERNEL);
 
cpu-lg-pgdirs[cpu-cpu_pgd].pgdir[SWITCHER_PGD_INDEX] = switcher_pgd;
 
@@ -657,7 +657,7 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 * page is already mapped there, we don't have to copy them out
 * again. */
pfn = __pa(cpu-regs_page)  PAGE_SHIFT;
-   regs_pte = pfn_pte(pfn, __pgprot(_PAGE_KERNEL));
+   regs_pte = pfn_pte(pfn, __pgprot(__PAGE_KERNEL));
switcher_pte_page[(unsigned long)pages/PAGE_SIZE%PTRS_PER_PTE] = 
regs_pte;
 }
 /*:*/
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/6] explicitly use hrtimer.h include

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the hrtimer.h header explicitly to lg.h file,
and avoid depending on it being included somewhere else.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/lg.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index f9707cf..eb51fc2 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -8,6 +8,7 @@
 #include linux/lguest.h
 #include linux/lguest_launcher.h
 #include linux/wait.h
+#include linux/hrtimer.h
 #include linux/err.h
 #include asm/semaphore.h
 
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/6] explicitly use ktime.h include

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the ktime.h header explicitly to hypercalls file,
and avoid depending on it being included somewhere else.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/hypercalls.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 32666d0..0f2cb4f 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -23,6 +23,7 @@
 #include linux/uaccess.h
 #include linux/syscalls.h
 #include linux/mm.h
+#include linux/ktime.h
 #include asm/page.h
 #include asm/pgtable.h
 #include lg.h
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/10] Tree fixes for PARAVIRT

2008-01-18 Thread Glauber de Oliveira Costa
On Jan 18, 2008 8:02 PM, Ingo Molnar [EMAIL PROTECTED] wrote:

 * Zachary Amsden [EMAIL PROTECTED] wrote:

   but in exchange you broke all of 32-bit with CONFIG_PARAVIRT=y.
   Which means you did not even build-test it on 32-bit, let alone boot
   test it...
 
  Why are we rushing so much to do 64-bit paravirt that we are breaking
  working configurations?  If the developement is going to be this
  chaotic, it should be done and tested out of tree until it can
  stabilize.

 what you see is a open feedback cycle conducted on lkml. People send
 patches for arch/x86, and we tell them if it breaks something. The bug
 was found before i pushed out the x86.git devel tree (and the fix is
 below - but this shouldnt matter to you because the bug never hit a
 public x86.git tree).

 Ingo

Other than this, it seems to build and boot fine.

Do you want me to resend ?
-- 
Glauber de Oliveira Costa.
Free as in Freedom
http://glommer.net

The less confident you are, the more serious you have to act.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 9/10] provide __parainstructions section

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the __parainstructions section to vmlinux.lds.S.
It's needed for the patching system.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/vmlinux_64.lds.S |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index 5ae8aa8..5e0300f 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -175,6 +175,14 @@ SECTIONS
   }
   __con_initcall_end = .;
   SECURITY_INIT
+
+  . = ALIGN(8);
+  .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
+  __parainstructions = .;
+   *(.parainstructions)
+  __parainstructions_end = .;
+  }
+
   . = ALIGN(8);
   __alt_instructions = .;
   .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/10] change function orders in paravirt.h

2008-01-18 Thread Glauber de Oliveira Costa
__pmd, pmd_val and set_pud are used before they are defined (as static)
We move them a little up in the file, so it doesn't happen.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 include/asm-x86/paravirt.h |   84 ++--
 1 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 3e7ca42..12caaf1 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -1023,6 +1023,48 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, val);
 }
 
+#if PAGETABLE_LEVELS = 3
+static inline pmd_t __pmd(pmdval_t val)
+{
+   pmdval_t ret;
+
+   if (sizeof(pmdval_t)  sizeof(long))
+   ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd,
+val, (u64)val  32);
+   else
+   ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd,
+val);
+
+   return (pmd_t) { ret };
+}
+
+static inline pmdval_t pmd_val(pmd_t pmd)
+{
+   pmdval_t ret;
+
+   if (sizeof(pmdval_t)  sizeof(long))
+   ret =  PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val,
+ pmd.pmd, (u64)pmd.pmd  32);
+   else
+   ret =  PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val,
+ pmd.pmd);
+
+   return ret;
+}
+
+static inline void set_pud(pud_t *pudp, pud_t pud)
+{
+   pudval_t val = native_pud_val(pud);
+
+   if (sizeof(pudval_t)  sizeof(long))
+   PVOP_VCALL3(pv_mmu_ops.set_pud, pudp,
+   val, (u64)val  32);
+   else
+   PVOP_VCALL2(pv_mmu_ops.set_pud, pudp,
+   val);
+}
+#endif /* PAGETABLE_LEVELS = 3 */
+
 #ifdef CONFIG_X86_PAE
 /* Special-case pte-setting operations for PAE, which can't update a
64-bit pte atomically */
@@ -1073,48 +1115,6 @@ static inline void pmd_clear(pmd_t *pmdp)
 }
 #endif /* CONFIG_X86_PAE */
 
-#if PAGETABLE_LEVELS = 3
-static inline pmd_t __pmd(pmdval_t val)
-{
-   pmdval_t ret;
-
-   if (sizeof(pmdval_t)  sizeof(long))
-   ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd,
-val, (u64)val  32);
-   else
-   ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd,
-val);
-
-   return (pmd_t) { ret };
-}
-
-static inline pmdval_t pmd_val(pmd_t pmd)
-{
-   pmdval_t ret;
-
-   if (sizeof(pmdval_t)  sizeof(long))
-   ret =  PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val,
- pmd.pmd, (u64)pmd.pmd  32);
-   else
-   ret =  PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val,
- pmd.pmd);
-
-   return ret;
-}
-
-static inline void set_pud(pud_t *pudp, pud_t pud)
-{
-   pudval_t val = native_pud_val(pud);
-
-   if (sizeof(pudval_t)  sizeof(long))
-   PVOP_VCALL3(pv_mmu_ops.set_pud, pudp,
-   val, (u64)val  32);
-   else
-   PVOP_VCALL2(pv_mmu_ops.set_pud, pudp,
-   val);
-}
-#endif /* PAGETABLE_LEVELS = 3 */
-
 /* Lazy mode for batching updates / context switch */
 enum paravirt_lazy_mode {
PARAVIRT_LAZY_NONE,
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 8/10] add asm_offset PARAVIRT constants

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds the constant PARAVIRT needs in asm_offsets_64.c

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/asm-offsets_64.c |   14 ++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 2b32719..494e1e0 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -61,6 +61,20 @@ int main(void)
ENTRY(data_offset);
BLANK();
 #undef ENTRY
+#ifdef CONFIG_PARAVIRT
+   BLANK();
+   OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
+   OFFSET(PARAVIRT_PATCH_pv_cpu_ops, paravirt_patch_template, pv_cpu_ops);
+   OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops);
+   OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
+   OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
+   OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
+   OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, 
irq_enable_syscall_ret);
+   OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
+   OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
+#endif
+
+
 #ifdef CONFIG_IA32_EMULATION
 #define ENTRY(entry) DEFINE(IA32_SIGCONTEXT_ ## entry, offsetof(struct 
sigcontext_ia32, entry))
ENTRY(ax);
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 5/10] puts read and write cr8 into pv_cpu_ops

2008-01-18 Thread Glauber de Oliveira Costa
This patch adds room for read and write_cr8 functions back in
pv_cpu_ops struct

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 include/asm-x86/paravirt.h |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 7ff25c2..3e7ca42 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -101,6 +101,11 @@ struct pv_cpu_ops {
unsigned long (*read_cr4)(void);
void (*write_cr4)(unsigned long);
 
+#ifdef CONFIG_X86_64
+   unsigned long (*read_cr8)(void);
+   void (*write_cr8)(unsigned long);
+#endif
+
/* Segment descriptor handling */
void (*load_tr_desc)(void);
void (*load_gdt)(const struct desc_ptr *);
@@ -614,6 +619,16 @@ static inline void write_cr4(unsigned long x)
PVOP_VCALL1(pv_cpu_ops.write_cr4, x);
 }
 
+static inline unsigned long read_cr8(void)
+{
+   return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr8);
+}
+
+static inline void write_cr8(unsigned long x)
+{
+   PVOP_VCALL1(pv_cpu_ops.write_cr8, x);
+}
+
 static inline void raw_safe_halt(void)
 {
PVOP_VCALL0(pv_irq_ops.safe_halt);
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/6] lguest patches for compiling x86_64

2008-01-18 Thread Glauber de Oliveira Costa
Right now, I have lguest in-tree module compiling on x86_64.
It's not yet on a sendable state, since the module itself isn't loading.

However, this subset of the series is pretty straightforward, and I'm sending it
now aiming at reducing the delta size in the future ;-)

Have fun,


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 6/10] provide read and write cr8 paravirt hooks

2008-01-18 Thread Glauber de Oliveira Costa
Since the cr8 manipulation functions ended up staying in the tree,
they can't be defined just when PARAVIRT is off: In this patch,
those functions are defined for the PARAVIRT case too.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 include/asm-x86/system.h |   30 --
 1 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h
index 692c28c..a33c3f4 100644
--- a/include/asm-x86/system.h
+++ b/include/asm-x86/system.h
@@ -236,6 +236,20 @@ static inline void native_write_cr4(unsigned long val)
asm volatile(mov %0,%%cr4: :r (val), m (__force_order));
 }
 
+#ifdef CONFIG_X86_64
+static inline unsigned long native_read_cr8(void)
+{
+   unsigned long cr8;
+   asm volatile(movq %%cr8,%0 : =r (cr8));
+   return cr8;
+}
+
+static inline void native_write_cr8(unsigned long val)
+{
+   asm volatile(movq %0,%%cr8 :: r (val) : memory);
+}
+#endif
+
 static inline void native_wbinvd(void)
 {
asm volatile(wbinvd: : :memory);
@@ -253,21 +267,9 @@ static inline void native_wbinvd(void)
 #define read_cr4_safe()(native_read_cr4_safe())
 #define write_cr4(x)   (native_write_cr4(x))
 #define wbinvd()   (native_wbinvd())
-
 #ifdef CONFIG_X86_64
-
-static inline unsigned long read_cr8(void)
-{
-   unsigned long cr8;
-   asm volatile(movq %%cr8,%0 : =r (cr8));
-   return cr8;
-}
-
-static inline void write_cr8(unsigned long val)
-{
-   asm volatile(movq %0,%%cr8 :: r (val) : memory);
-}
-
+#define read_cr8() (native_read_cr8())
+#define write_cr8(x)   (native_write_cr8(x))
 #endif
 
 /* Clear the 'TS' bit */
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/10] put generic mm_hooks include into PARAVIRT

2008-01-18 Thread Glauber de Oliveira Costa
With PARAVIRT, we actually have arch_{dup,exit}_mmap functions,
so we can't include the generic header

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 include/asm-x86/mmu_context_64.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h
index 7e2aa23..ad6dc82 100644
--- a/include/asm-x86/mmu_context_64.h
+++ b/include/asm-x86/mmu_context_64.h
@@ -7,7 +7,9 @@
 #include asm/pda.h
 #include asm/pgtable.h
 #include asm/tlbflush.h
+#ifndef CONFIG_PARAVIRT
 #include asm-generic/mm_hooks.h
+#endif
 
 /*
  * possibly do the LDT unload here?
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/10] add stringify header

2008-01-18 Thread Glauber de Oliveira Costa
We use a __stringify construction at paravirt_patch_64.c.
It's better practice to include the stringify header directly

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/paravirt_patch_64.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/paravirt_patch_64.c 
b/arch/x86/kernel/paravirt_patch_64.c
index cbfc4f3..7d904e1 100644
--- a/arch/x86/kernel/paravirt_patch_64.c
+++ b/arch/x86/kernel/paravirt_patch_64.c
@@ -1,5 +1,6 @@
 #include asm/paravirt.h
 #include asm/asm-offsets.h
+#include linux/stringify.h
 
 DEF_NATIVE(pv_irq_ops, irq_disable, cli);
 DEF_NATIVE(pv_irq_ops, irq_enable, sti);
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/10] Tree fixes for PARAVIRT

2008-01-18 Thread Glauber de Oliveira Costa
Hi,

This small series provides some more fixes towards the goal
to have the PARAVIRT selectable for x86_64. After that, just
some more small steps are needed.

The first fix is not even specific for PARAVIRT, and it's actually
preventing the whole tree from booting.


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/10] provide a native_init_IRQ function to x86_64

2008-01-18 Thread Glauber de Oliveira Costa
x86_64 lacks a native_init_IRQ() function, so we turn the arch's
init_IRQ() function into a native construct

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/i8259_64.c  |4 +++-
 include/asm-x86/hw_irq_64.h |1 +
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/i8259_64.c b/arch/x86/kernel/i8259_64.c
index cba13e0..738517e 100644
--- a/arch/x86/kernel/i8259_64.c
+++ b/arch/x86/kernel/i8259_64.c
@@ -456,7 +456,9 @@ void __init init_ISA_irqs (void)
}
 }
 
-void __init init_IRQ(void)
+void init_IRQ(void) __attribute__((weak, alias(native_init_IRQ)));
+
+void __init native_init_IRQ(void)
 {
int i;
 
diff --git a/include/asm-x86/hw_irq_64.h b/include/asm-x86/hw_irq_64.h
index a346159..312a58d 100644
--- a/include/asm-x86/hw_irq_64.h
+++ b/include/asm-x86/hw_irq_64.h
@@ -141,6 +141,7 @@ extern void print_IO_APIC(void);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
 extern void send_IPI(int dest, int vector);
 extern void setup_ioapic_dest(void);
+extern void native_init_IRQ(void);
 
 extern unsigned long io_apic_irqs;
 
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/10] add missing parameter for lookup_address

2008-01-18 Thread Glauber de Oliveira Costa
lookup_address() receives two parameters, but efi_64.c call
is passing only one. It's actually preventing the tree from compiling

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/efi_64.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c
index f420819..1f8bbd9 100644
--- a/arch/x86/kernel/efi_64.c
+++ b/arch/x86/kernel/efi_64.c
@@ -45,9 +45,10 @@ static void __init early_mapping_set_exec(unsigned long 
start,
  int executable)
 {
pte_t *kpte;
+   int level;
 
while (start  end) {
-   kpte = lookup_address((unsigned long)__va(start));
+   kpte = lookup_address((unsigned long)__va(start), level);
BUG_ON(!kpte);
if (executable)
set_pte(kpte, pte_mkexec(*kpte));
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 7/10] fill pv_cpu_ops structure with cr8 fields

2008-01-18 Thread Glauber de Oliveira Costa
This patch fills in the read and write cr8 fields with their
native version

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 arch/x86/kernel/paravirt.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index c20b4f8..c67d331 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -319,6 +319,10 @@ struct pv_cpu_ops pv_cpu_ops = {
.read_cr4 = native_read_cr4,
.read_cr4_safe = native_read_cr4_safe,
.write_cr4 = native_write_cr4,
+#ifdef CONFIG_X86_64
+   .read_cr8 = native_read_cr8,
+   .write_cr8 = native_write_cr8,
+#endif
.wbinvd = native_wbinvd,
.read_msr = native_read_msr_safe,
.write_msr = native_write_msr_safe,
-- 
1.4.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] fix drivers/lguest Makefile entry

2008-01-17 Thread Glauber de Oliveira Costa
It should depend on CONFIG_LGUEST, not CONFIG_LGUEST_GUEST

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/Makefile |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/Makefile b/drivers/Makefile
index ee1b6a5..58a17e9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -73,7 +73,7 @@ obj-$(CONFIG_ISDN)+= isdn/
 obj-$(CONFIG_EDAC) += edac/
 obj-$(CONFIG_MCA)  += mca/
 obj-$(CONFIG_EISA) += eisa/
-obj-$(CONFIG_LGUEST_GUEST) += lguest/
+obj-$(CONFIG_LGUEST)   += lguest/
 obj-$(CONFIG_CPU_FREQ) += cpufreq/
 obj-$(CONFIG_CPU_IDLE) += cpuidle/
 obj-$(CONFIG_MMC)  += mmc/
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
I don't have _any_ idea about what happened to those patches. They
were sent through the normal git-send-email script, but for
some reason, all got the same subject. They might be okay for the
review, but anyone willing to try it more seriously, please grab it
at http://glommer.net/patches-lguest.tar.gz

On Jan 17, 2008 10:35 PM, Glauber de Oliveira Costa <[EMAIL PROTECTED]> wrote:
> urrently, lguest module can't be compiled without the PARAVIRT flag being
> on.This is a fake dependency, since the module itself shouldn't need any
> paravirtoverride. Reason for that is the reference to pv_info structure
> ininitial loading tests.
>
> his patch removes it in favour of a more generic error message.
>
> Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
> ---
> drivers/lguest/core.c |2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff--git a/drivers/lguest/core.c b/drivers/lguest/core.c
> indexbb42fd0..97b76d6 100644
> ---a/drivers/lguest/core.c
> +++b/drivers/lguest/core.c
> @@-255,7 +255,7 @@ static int __init init(void)
>
> /* Lguest can't run under Xen, VMI or itself.  It does Tricky Stuff. 
> */
> if (paravirt_enabled()) {
> -   printk("lguestis afraid of %s\n", pv_info.name);
> +   printk("lguestcan't run under another hypervisor");
> return -EPERM;
> }
>
> --
> 1.5.0.6
>
>



-- 
Glauber de Oliveira Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
Wecan save some lines of code by getting rid of
*lg= cpu... lines of code spread everywhere by now.

he new macro lg_data(cpu) is used anywhere we'd otherwise use the
cpu->lg->lguest_dataconstruction, to prevent lines getting to big.

Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
drivers/lguest/core.c |   24 +++
drivers/lguest/hypercalls.c   |   49 +++
drivers/lguest/interrupts_and_traps.c |   54 
drivers/lguest/lg.h   |   30 +
drivers/lguest/page_tables.c  |  114 
drivers/lguest/segments.c |8 +--
drivers/lguest/x86/core.c |   30 -
7 files changed, 149 insertions(+), 160 deletions(-)

diff--git a/drivers/lguest/core.c b/drivers/lguest/core.c
index4c26ba7..bb42fd0 100644
---a/drivers/lguest/core.c
+++b/drivers/lguest/core.c
@@-151,23 +151,23 @@ int lguest_address_ok(const struct lguest *lg,
/* 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)
+void__lgread(struct lg_cpu *cpu, void *b, unsigned long addr, unsigned bytes)
{
-   if(!lguest_address_ok(lg, addr, bytes)
-  || copy_from_user(b, lg->mem_base + addr, bytes) != 0) {
+   if(!lguest_address_ok(cpu->lg, addr, bytes)
+  || copy_from_user(b, cpu->lg->mem_base + addr, bytes) != 0) {
/* copy_from_user should do this, but as we rely on it... */
memset(b, 0, bytes);
-   kill_guest(lg,"bad read address %#lx len %u", addr, bytes);
+   kill_guest(cpu,"bad read address %#lx len %u", addr, bytes);
}
}

/* This is the write (copy into guest) version. */
-void__lgwrite(struct lguest *lg, unsigned long addr, const void *b,
+void__lgwrite(struct lg_cpu *cpu, 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);
+   if(!lguest_address_ok(cpu->lg, addr, bytes)
+  || copy_to_user(cpu->lg->mem_base + addr, b, bytes) != 0)
+   kill_guest(cpu,"bad write address %#lx len %u", addr, bytes);
}
/*:*/

@@-176,10 +176,8 @@ void __lgwrite(struct lguest *lg, unsigned long addr, const 
void *b,
 * going around and around until something interesting happens. */
int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
{
-   structlguest *lg = cpu->lg;
-
/* We stop running once the Guest is dead. */
-   while(!lg->dead) {
+   while(!cpu->lg->dead) {
/* First we run any hypercalls the Guest wants done. */
if (cpu->hcall)
do_hypercalls(cpu);
@@-212,7 +210,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)

/* Just make absolutely sure the Guest is still alive.  One of
 * those hypercalls could have been fatal, for example. */
-   if(lg->dead)
+   if(cpu->lg->dead)
break;

/* If the Guest asked to be stopped, we sleep.  The Guest's
@@-237,7 +235,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
lguest_arch_handle_trap(cpu);
}

-   if(lg->dead == ERR_PTR(-ERESTART))
+   if(cpu->lg->dead == ERR_PTR(-ERESTART))
return -ERESTART;
/* The Guest is dead => "No such file or directory" */
return -ENOENT;
diff--git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index0471018..32666d0 100644
---a/drivers/lguest/hypercalls.c
+++b/drivers/lguest/hypercalls.c
@@-31,8 +31,6 @@
 * Or gets killed.  Or, in the case of LHCALL_CRASH, both. */
static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
{
-   structlguest *lg = cpu->lg;
-
switch (args->arg0) {
case LHCALL_FLUSH_ASYNC:
/* This call does nothing, except by breaking out of the Guest
@@-41,7 +39,7 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args 
*args)
case LHCALL_LGUEST_INIT:
/* You can't get here unless you're already initialized.  Don't
 * do that. */
-   kill_guest(lg,"already have lguest_data");
+   kill_guest(cpu,"already have lguest_data");
break;
case LHCALL_SHUTDOWN: {
/* Shutdown is such a trivial hypercall that we do it in four
@@-49,11 +47,11 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args 
*args)
char msg[128];
/* If the lgread fails, it will call kill_guest() itself; the
 * kill_guest() with the message will be 

[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
urrently, lguest module can't be compiled without the PARAVIRT flag being
on.This is a fake dependency, since the module itself shouldn't need any
paravirtoverride. Reason for that is the reference to pv_info structure
ininitial loading tests.

his patch removes it in favour of a more generic error message.

Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
drivers/lguest/core.c |2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff--git a/drivers/lguest/core.c b/drivers/lguest/core.c
indexbb42fd0..97b76d6 100644
---a/drivers/lguest/core.c
+++b/drivers/lguest/core.c
@@-255,7 +255,7 @@ static int __init init(void)

/* Lguest can't run under Xen, VMI or itself.  It does Tricky Stuff. */
if (paravirt_enabled()) {
-   printk("lguestis afraid of %s\n", pv_info.name);
+   printk("lguestcan't run under another hypervisor");
return -EPERM;
}

--
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
eventsrepresented in the 'changed' bitmap are per-cpu, not per-guest.
moveit to the lg_cpu structure

Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
drivers/lguest/interrupts_and_traps.c |2 +-
drivers/lguest/lg.h   |6 +++---
drivers/lguest/segments.c |4 ++--
drivers/lguest/x86/core.c |   11 +--
4 files changed, 11 insertions(+), 12 deletions(-)

diff--git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index6bbfce4..9ac7455 100644
---a/drivers/lguest/interrupts_and_traps.c
+++b/drivers/lguest/interrupts_and_traps.c
@@-395,7 +395,7 @@ void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int 
num, u32 lo, u32 hi)

/* Mark the IDT as changed: next time the Guest runs we'll know we have
 * to copy this again. */
-   cpu->lg->changed|= CHANGED_IDT;
+   cpu->changed|= CHANGED_IDT;

/* Check that the Guest doesn't try to step outside the bounds. */
if (num >= ARRAY_SIZE(cpu->arch.idt))
diff--git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
indexeb473a5..5458af8 100644
---a/drivers/lguest/lg.h
+++b/drivers/lguest/lg.h
@@-51,6 +51,9 @@ struct lg_cpu {
u32 esp1;
u8 ss1;

+   /*Bitmap of what has changed: see CHANGED_* above. */
+   intchanged;
+
unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */

/* At end of a page shared mapped over lguest_pages in guest.  */
@@-92,9 +95,6 @@ struct lguest
void __user *mem_base;
unsigned long kernel_address;

-   /*Bitmap of what has changed: see CHANGED_* above. */
-   intchanged;
-
struct pgdir pgdirs[4];

unsigned long noirq_start, noirq_end;
diff--git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index0213845..635f54c 100644
---a/drivers/lguest/segments.c
+++b/drivers/lguest/segments.c
@@-159,7 +159,7 @@ void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, 
u32 num)
fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu->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. */
-   lg->changed|= CHANGED_GDT;
+   cpu->changed|= CHANGED_GDT;
}

/* This is the fast-track version for just changing the three TLS entries.
@@-174,7 +174,7 @@ void guest_load_tls(struct lg_cpu *cpu, unsigned long gtls)
__lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
fixup_gdt_table(cpu, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
/* Note that just the TLS entries have changed. */
-   lg->changed|= CHANGED_GDT_TLS;
+   cpu->changed|= CHANGED_GDT_TLS;
}
/*:*/

diff--git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index3e457f2..dea52d5 100644
---a/drivers/lguest/x86/core.c
+++b/drivers/lguest/x86/core.c
@@-75,7 +75,6 @@ static DEFINE_PER_CPU(struct lg_cpu *, last_cpu);
 */
static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
{
-   structlguest *lg = cpu->lg;
/* Copying all this data can be quite expensive.  We usually run the
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
@@-83,7 +82,7 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
if (__get_cpu_var(last_cpu) != cpu || cpu->last_pages != pages) {
__get_cpu_var(last_cpu) = cpu;
cpu->last_pages = pages;
-   lg->changed= CHANGED_ALL;
+   cpu->changed= CHANGED_ALL;
}

/* These copies are pretty cheap, so we do them unconditionally: */
@@-99,18 +98,18 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
pages->state.guest_tss.ss1 = cpu->ss1;

/* Copy direct-to-Guest trap entries. */
-   if(lg->changed & CHANGED_IDT)
+   if(cpu->changed & CHANGED_IDT)
copy_traps(cpu, pages->state.guest_idt, default_idt_entries);

/* Copy all GDT entries which the Guest can change. */
-   if(lg->changed & CHANGED_GDT)
+   if(cpu->changed & CHANGED_GDT)
copy_gdt(cpu, pages->state.guest_gdt);
/* If only the TLS entries have changed, copy them. */
-   elseif (lg->changed & CHANGED_GDT_TLS)
+   elseif (cpu->changed & CHANGED_GDT_TLS)
copy_gdt_tls(cpu, pages->state.guest_gdt);

/* Mark the Guest as unchanged for next time. */
-   lg->changed= 0;
+   cpu->changed= 0;
}

/* Finally: the code to actually call into the Switcher to run the Guest. */
--
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
spte_addrdoes not depend on any guest information, so we
wipeout the lg parameter completely.

Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
drivers/lguest/page_tables.c |8 
1 files changed, 4 insertions(+), 4 deletions(-)

diff--git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
indexfb66561..c4b8eaf 100644
---a/drivers/lguest/page_tables.c
+++b/drivers/lguest/page_tables.c
@@-84,7 +84,7 @@ static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned 
long vaddr)
/* This routine then takes the page directory entry returned above, which
 * contains the address of the page table entry (PTE) page.  It then returns a
 * pointer to the PTE entry for the given address. */
-staticpte_t *spte_addr(struct lguest *lg, pgd_t spgd, unsigned long vaddr)
+staticpte_t *spte_addr(pgd_t spgd, unsigned long vaddr)
{
pte_t *page = __va(pgd_pfn(spgd) << PAGE_SHIFT);
/* You should never call this if the PGD entry wasn't valid */
@@-261,7 +261,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int 
errcode)
gpte = pte_mkdirty(gpte);

/* Get the pointer to the shadow PTE entry we're going to set. */
-   spte= spte_addr(lg, *spgd, vaddr);
+   spte= spte_addr(*spgd, vaddr);
/* If there was a valid shadow PTE entry here before, we release it.
 * This can happen with a write to a previously read-only entry. */
release_pte(*spte);
@@-310,7 +310,7 @@ static int page_writable(struct lg_cpu *cpu, unsigned long 
vaddr)

/* Check the flags on the pte entry itself: it must be present and
 * writable. */
-   flags= pte_flags(*(spte_addr(cpu->lg, *spgd, vaddr)));
+   flags= pte_flags(*(spte_addr(*spgd, vaddr)));

return (flags & (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW);
}
@@-509,7 +509,7 @@ static void do_set_pte(struct lguest *lg, int idx,
/* If the top level isn't present, there's no entry to update. */
if (pgd_flags(*spgd) & _PAGE_PRESENT) {
/* Otherwise, we start by releasing the existing entry. */
-   pte_t*spte = spte_addr(lg, *spgd, vaddr);
+   pte_t*spte = spte_addr(*spgd, vaddr);
release_pte(*spte);

/* If they're setting this entry as dirty or accessed, we might
--
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
inour new model, pages are assigned to a virtual cpu, not to a guest.
Wemove it to the lg_cpu structure.

Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
drivers/lguest/lg.h  |3 ++-
drivers/lguest/lguest_user.c |8 
drivers/lguest/x86/core.c|4 ++--
3 files changed, 8 insertions(+), 7 deletions(-)

diff--git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index11a3ae2..eb473a5 100644
---a/drivers/lguest/lg.h
+++b/drivers/lguest/lg.h
@@-57,6 +57,8 @@ struct lg_cpu {
unsigned long regs_page;
struct lguest_regs *regs;

+   structlguest_pages *last_pages;
+
int cpu_pgd; /* which pgd this cpu is currently using */

/* If a hypercall was asked for, this points to the arguments. */
@@-92,7 +94,6 @@ struct lguest

/* Bitmap of what has changed: see CHANGED_* above. */
int changed;
-   structlguest_pages *last_pages;

struct pgdir pgdirs[4];

diff--git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
indexf4f6df8..a87fca6 100644
---a/drivers/lguest/lguest_user.c
+++b/drivers/lguest/lguest_user.c
@@-131,6 +131,10 @@ static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, 
unsigned long start_ip)
 * reference, it is destroyed before close() is called. */
cpu->mm = get_task_mm(cpu->tsk);

+   /*We remember which CPU's pages this Guest used last, for optimization
+   * when the same Guest runs on the same CPU twice. */
+   cpu->last_pages= NULL;
+
return 0;
}

@@-192,10 +196,6 @@ static int initialize(struct file *file, const unsigned 
long __user *input)
if (err)
goto free_regs;

-   /*We remember which CPU's pages this Guest used last, for optimization
-   * when the same Guest runs on the same CPU twice. */
-   lg->last_pages= NULL;
-
/* We keep our "struct lguest" in the file's private_data. */
file->private_data = lg;

diff--git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index25f48fd..3e457f2 100644
---a/drivers/lguest/x86/core.c
+++b/drivers/lguest/x86/core.c
@@-80,9 +80,9 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
 * Guest has changed. */
-   if(__get_cpu_var(last_cpu) != cpu || lg->last_pages != pages) {
+   if(__get_cpu_var(last_cpu) != cpu || cpu->last_pages != pages) {
__get_cpu_var(last_cpu) = cpu;
-   lg->last_pages= pages;
+   cpu->last_pages= pages;
lg->changed = CHANGED_ALL;
}

--
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
gpte_addr()does not depend on any guest information. So we wipe out
thelg parameter from it completely.

Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
drivers/lguest/page_tables.c |7 +++
1 files changed, 3 insertions(+), 4 deletions(-)

diff--git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
indexc4b8eaf..c9acafc 100644
---a/drivers/lguest/page_tables.c
+++b/drivers/lguest/page_tables.c
@@-100,8 +100,7 @@ static unsigned long gpgd_addr(struct lg_cpu *cpu, unsigned 
long vaddr)
return cpu->lg->pgdirs[cpu->cpu_pgd].gpgdir + index * sizeof(pgd_t);
}

-staticunsigned long gpte_addr(struct lguest *lg,
- pgd_t gpgd, unsigned long vaddr)
+staticunsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
{
unsigned long gpage = pgd_pfn(gpgd) << PAGE_SHIFT;
BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
@@-235,7 +234,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int 
errcode)

/* 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_ptr= gpte_addr(gpgd, vaddr);
gpte = lgread(lg, gpte_ptr, pte_t);

/* If this page isn't in the Guest page tables, we can't page it in. */
@@-378,7 +377,7 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long 
vaddr)
if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
kill_guest(cpu->lg, "Bad address %#lx", vaddr);

-   gpte= lgread(cpu->lg, gpte_addr(cpu->lg, gpgd, vaddr), pte_t);
+   gpte= lgread(cpu->lg, gpte_addr(gpgd, vaddr), pte_t);
if (!(pte_flags(gpte) & _PAGE_PRESENT))
kill_guest(cpu->lg, "Bad address %#lx", vaddr);

--
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
This series takes one more step towards cpu-ification of lguest.
As for rusty's last suggestion, I get rid of the whole bunch
of "struct lguest *lg = cpu->lg" statements around by using
lg_cpu as our base structure wherever it matters. (this saves us
11 lines)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
inour model, a guest does not run in a cpu anymore: a virtual cpu
does.So we change last_guest to last_cpu

Signed-off-by:Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
drivers/lguest/x86/core.c |6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff--git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index2859447..25f48fd 100644
---a/drivers/lguest/x86/core.c
+++b/drivers/lguest/x86/core.c
@@-60,7 +60,7 @@ static struct lguest_pages *lguest_pages(unsigned int cpu)
  (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
}

-staticDEFINE_PER_CPU(struct lguest *, last_guest);
+staticDEFINE_PER_CPU(struct lg_cpu *, last_cpu);

/*S:010
 * We approach the Switcher.
@@-80,8 +80,8 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
 * Guest has changed. */
-   if(__get_cpu_var(last_guest) != lg || lg->last_pages != pages) {
-   __get_cpu_var(last_guest)= lg;
+   if(__get_cpu_var(last_cpu) != cpu || lg->last_pages != pages) {
+   __get_cpu_var(last_cpu)= cpu;
lg->last_pages = pages;
lg->changed = CHANGED_ALL;
}
--
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
This series takes one more step towards cpu-ification of lguest.
As for rusty's last suggestion, I get rid of the whole bunch
of struct lguest *lg = cpu-lg statements around by using
lg_cpu as our base structure wherever it matters. (this saves us
11 lines)


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
inour model, a guest does not run in a cpu anymore: a virtual cpu
does.So we change last_guest to last_cpu

Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
---
drivers/lguest/x86/core.c |6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff--git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index2859447..25f48fd 100644
---a/drivers/lguest/x86/core.c
+++b/drivers/lguest/x86/core.c
@@-60,7 +60,7 @@ static struct lguest_pages *lguest_pages(unsigned int cpu)
  (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
}

-staticDEFINE_PER_CPU(struct lguest *, last_guest);
+staticDEFINE_PER_CPU(struct lg_cpu *, last_cpu);

/*S:010
 * We approach the Switcher.
@@-80,8 +80,8 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
 * Guest has changed. */
-   if(__get_cpu_var(last_guest) != lg || lg-last_pages != pages) {
-   __get_cpu_var(last_guest)= lg;
+   if(__get_cpu_var(last_cpu) != cpu || lg-last_pages != pages) {
+   __get_cpu_var(last_cpu)= cpu;
lg-last_pages = pages;
lg-changed = CHANGED_ALL;
}
--
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
spte_addrdoes not depend on any guest information, so we
wipeout the lg parameter completely.

Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
---
drivers/lguest/page_tables.c |8 
1 files changed, 4 insertions(+), 4 deletions(-)

diff--git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
indexfb66561..c4b8eaf 100644
---a/drivers/lguest/page_tables.c
+++b/drivers/lguest/page_tables.c
@@-84,7 +84,7 @@ static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned 
long vaddr)
/* This routine then takes the page directory entry returned above, which
 * contains the address of the page table entry (PTE) page.  It then returns a
 * pointer to the PTE entry for the given address. */
-staticpte_t *spte_addr(struct lguest *lg, pgd_t spgd, unsigned long vaddr)
+staticpte_t *spte_addr(pgd_t spgd, unsigned long vaddr)
{
pte_t *page = __va(pgd_pfn(spgd)  PAGE_SHIFT);
/* You should never call this if the PGD entry wasn't valid */
@@-261,7 +261,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int 
errcode)
gpte = pte_mkdirty(gpte);

/* Get the pointer to the shadow PTE entry we're going to set. */
-   spte= spte_addr(lg, *spgd, vaddr);
+   spte= spte_addr(*spgd, vaddr);
/* If there was a valid shadow PTE entry here before, we release it.
 * This can happen with a write to a previously read-only entry. */
release_pte(*spte);
@@-310,7 +310,7 @@ static int page_writable(struct lg_cpu *cpu, unsigned long 
vaddr)

/* Check the flags on the pte entry itself: it must be present and
 * writable. */
-   flags= pte_flags(*(spte_addr(cpu-lg, *spgd, vaddr)));
+   flags= pte_flags(*(spte_addr(*spgd, vaddr)));

return (flags  (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW);
}
@@-509,7 +509,7 @@ static void do_set_pte(struct lguest *lg, int idx,
/* If the top level isn't present, there's no entry to update. */
if (pgd_flags(*spgd)  _PAGE_PRESENT) {
/* Otherwise, we start by releasing the existing entry. */
-   pte_t*spte = spte_addr(lg, *spgd, vaddr);
+   pte_t*spte = spte_addr(*spgd, vaddr);
release_pte(*spte);

/* If they're setting this entry as dirty or accessed, we might
--
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
inour new model, pages are assigned to a virtual cpu, not to a guest.
Wemove it to the lg_cpu structure.

Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
---
drivers/lguest/lg.h  |3 ++-
drivers/lguest/lguest_user.c |8 
drivers/lguest/x86/core.c|4 ++--
3 files changed, 8 insertions(+), 7 deletions(-)

diff--git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index11a3ae2..eb473a5 100644
---a/drivers/lguest/lg.h
+++b/drivers/lguest/lg.h
@@-57,6 +57,8 @@ struct lg_cpu {
unsigned long regs_page;
struct lguest_regs *regs;

+   structlguest_pages *last_pages;
+
int cpu_pgd; /* which pgd this cpu is currently using */

/* If a hypercall was asked for, this points to the arguments. */
@@-92,7 +94,6 @@ struct lguest

/* Bitmap of what has changed: see CHANGED_* above. */
int changed;
-   structlguest_pages *last_pages;

struct pgdir pgdirs[4];

diff--git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
indexf4f6df8..a87fca6 100644
---a/drivers/lguest/lguest_user.c
+++b/drivers/lguest/lguest_user.c
@@-131,6 +131,10 @@ static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, 
unsigned long start_ip)
 * reference, it is destroyed before close() is called. */
cpu-mm = get_task_mm(cpu-tsk);

+   /*We remember which CPU's pages this Guest used last, for optimization
+   * when the same Guest runs on the same CPU twice. */
+   cpu-last_pages= NULL;
+
return 0;
}

@@-192,10 +196,6 @@ static int initialize(struct file *file, const unsigned 
long __user *input)
if (err)
goto free_regs;

-   /*We remember which CPU's pages this Guest used last, for optimization
-   * when the same Guest runs on the same CPU twice. */
-   lg-last_pages= NULL;
-
/* We keep our struct lguest in the file's private_data. */
file-private_data = lg;

diff--git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index25f48fd..3e457f2 100644
---a/drivers/lguest/x86/core.c
+++b/drivers/lguest/x86/core.c
@@-80,9 +80,9 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
 * Guest has changed. */
-   if(__get_cpu_var(last_cpu) != cpu || lg-last_pages != pages) {
+   if(__get_cpu_var(last_cpu) != cpu || cpu-last_pages != pages) {
__get_cpu_var(last_cpu) = cpu;
-   lg-last_pages= pages;
+   cpu-last_pages= pages;
lg-changed = CHANGED_ALL;
}

--
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
gpte_addr()does not depend on any guest information. So we wipe out
thelg parameter from it completely.

Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
---
drivers/lguest/page_tables.c |7 +++
1 files changed, 3 insertions(+), 4 deletions(-)

diff--git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
indexc4b8eaf..c9acafc 100644
---a/drivers/lguest/page_tables.c
+++b/drivers/lguest/page_tables.c
@@-100,8 +100,7 @@ static unsigned long gpgd_addr(struct lg_cpu *cpu, unsigned 
long vaddr)
return cpu-lg-pgdirs[cpu-cpu_pgd].gpgdir + index * sizeof(pgd_t);
}

-staticunsigned long gpte_addr(struct lguest *lg,
- pgd_t gpgd, unsigned long vaddr)
+staticunsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
{
unsigned long gpage = pgd_pfn(gpgd)  PAGE_SHIFT;
BUG_ON(!(pgd_flags(gpgd)  _PAGE_PRESENT));
@@-235,7 +234,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int 
errcode)

/* 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_ptr= gpte_addr(gpgd, vaddr);
gpte = lgread(lg, gpte_ptr, pte_t);

/* If this page isn't in the Guest page tables, we can't page it in. */
@@-378,7 +377,7 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long 
vaddr)
if (!(pgd_flags(gpgd)  _PAGE_PRESENT))
kill_guest(cpu-lg, Bad address %#lx, vaddr);

-   gpte= lgread(cpu-lg, gpte_addr(cpu-lg, gpgd, vaddr), pte_t);
+   gpte= lgread(cpu-lg, gpte_addr(gpgd, vaddr), pte_t);
if (!(pte_flags(gpte)  _PAGE_PRESENT))
kill_guest(cpu-lg, Bad address %#lx, vaddr);

--
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
eventsrepresented in the 'changed' bitmap are per-cpu, not per-guest.
moveit to the lg_cpu structure

Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
---
drivers/lguest/interrupts_and_traps.c |2 +-
drivers/lguest/lg.h   |6 +++---
drivers/lguest/segments.c |4 ++--
drivers/lguest/x86/core.c |   11 +--
4 files changed, 11 insertions(+), 12 deletions(-)

diff--git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index6bbfce4..9ac7455 100644
---a/drivers/lguest/interrupts_and_traps.c
+++b/drivers/lguest/interrupts_and_traps.c
@@-395,7 +395,7 @@ void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int 
num, u32 lo, u32 hi)

/* Mark the IDT as changed: next time the Guest runs we'll know we have
 * to copy this again. */
-   cpu-lg-changed|= CHANGED_IDT;
+   cpu-changed|= CHANGED_IDT;

/* Check that the Guest doesn't try to step outside the bounds. */
if (num = ARRAY_SIZE(cpu-arch.idt))
diff--git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
indexeb473a5..5458af8 100644
---a/drivers/lguest/lg.h
+++b/drivers/lguest/lg.h
@@-51,6 +51,9 @@ struct lg_cpu {
u32 esp1;
u8 ss1;

+   /*Bitmap of what has changed: see CHANGED_* above. */
+   intchanged;
+
unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */

/* At end of a page shared mapped over lguest_pages in guest.  */
@@-92,9 +95,6 @@ struct lguest
void __user *mem_base;
unsigned long kernel_address;

-   /*Bitmap of what has changed: see CHANGED_* above. */
-   intchanged;
-
struct pgdir pgdirs[4];

unsigned long noirq_start, noirq_end;
diff--git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index0213845..635f54c 100644
---a/drivers/lguest/segments.c
+++b/drivers/lguest/segments.c
@@-159,7 +159,7 @@ void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, 
u32 num)
fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu-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. */
-   lg-changed|= CHANGED_GDT;
+   cpu-changed|= CHANGED_GDT;
}

/* This is the fast-track version for just changing the three TLS entries.
@@-174,7 +174,7 @@ void guest_load_tls(struct lg_cpu *cpu, unsigned long gtls)
__lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
fixup_gdt_table(cpu, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
/* Note that just the TLS entries have changed. */
-   lg-changed|= CHANGED_GDT_TLS;
+   cpu-changed|= CHANGED_GDT_TLS;
}
/*:*/

diff--git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index3e457f2..dea52d5 100644
---a/drivers/lguest/x86/core.c
+++b/drivers/lguest/x86/core.c
@@-75,7 +75,6 @@ static DEFINE_PER_CPU(struct lg_cpu *, last_cpu);
 */
static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
{
-   structlguest *lg = cpu-lg;
/* Copying all this data can be quite expensive.  We usually run the
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
@@-83,7 +82,7 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
if (__get_cpu_var(last_cpu) != cpu || cpu-last_pages != pages) {
__get_cpu_var(last_cpu) = cpu;
cpu-last_pages = pages;
-   lg-changed= CHANGED_ALL;
+   cpu-changed= CHANGED_ALL;
}

/* These copies are pretty cheap, so we do them unconditionally: */
@@-99,18 +98,18 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct 
lguest_pages *pages)
pages-state.guest_tss.ss1 = cpu-ss1;

/* Copy direct-to-Guest trap entries. */
-   if(lg-changed  CHANGED_IDT)
+   if(cpu-changed  CHANGED_IDT)
copy_traps(cpu, pages-state.guest_idt, default_idt_entries);

/* Copy all GDT entries which the Guest can change. */
-   if(lg-changed  CHANGED_GDT)
+   if(cpu-changed  CHANGED_GDT)
copy_gdt(cpu, pages-state.guest_gdt);
/* If only the TLS entries have changed, copy them. */
-   elseif (lg-changed  CHANGED_GDT_TLS)
+   elseif (cpu-changed  CHANGED_GDT_TLS)
copy_gdt_tls(cpu, pages-state.guest_gdt);

/* Mark the Guest as unchanged for next time. */
-   lg-changed= 0;
+   cpu-changed= 0;
}

/* Finally: the code to actually call into the Switcher to run the Guest. */
--
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
Wecan save some lines of code by getting rid of
*lg= cpu... lines of code spread everywhere by now.

he new macro lg_data(cpu) is used anywhere we'd otherwise use the
cpu-lg-lguest_dataconstruction, to prevent lines getting to big.

Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
---
drivers/lguest/core.c |   24 +++
drivers/lguest/hypercalls.c   |   49 +++
drivers/lguest/interrupts_and_traps.c |   54 
drivers/lguest/lg.h   |   30 +
drivers/lguest/page_tables.c  |  114 
drivers/lguest/segments.c |8 +--
drivers/lguest/x86/core.c |   30 -
7 files changed, 149 insertions(+), 160 deletions(-)

diff--git a/drivers/lguest/core.c b/drivers/lguest/core.c
index4c26ba7..bb42fd0 100644
---a/drivers/lguest/core.c
+++b/drivers/lguest/core.c
@@-151,23 +151,23 @@ int lguest_address_ok(const struct lguest *lg,
/* 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)
+void__lgread(struct lg_cpu *cpu, void *b, unsigned long addr, unsigned bytes)
{
-   if(!lguest_address_ok(lg, addr, bytes)
-  || copy_from_user(b, lg-mem_base + addr, bytes) != 0) {
+   if(!lguest_address_ok(cpu-lg, addr, bytes)
+  || copy_from_user(b, cpu-lg-mem_base + addr, bytes) != 0) {
/* copy_from_user should do this, but as we rely on it... */
memset(b, 0, bytes);
-   kill_guest(lg,bad read address %#lx len %u, addr, bytes);
+   kill_guest(cpu,bad read address %#lx len %u, addr, bytes);
}
}

/* This is the write (copy into guest) version. */
-void__lgwrite(struct lguest *lg, unsigned long addr, const void *b,
+void__lgwrite(struct lg_cpu *cpu, 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);
+   if(!lguest_address_ok(cpu-lg, addr, bytes)
+  || copy_to_user(cpu-lg-mem_base + addr, b, bytes) != 0)
+   kill_guest(cpu,bad write address %#lx len %u, addr, bytes);
}
/*:*/

@@-176,10 +176,8 @@ void __lgwrite(struct lguest *lg, unsigned long addr, const 
void *b,
 * going around and around until something interesting happens. */
int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
{
-   structlguest *lg = cpu-lg;
-
/* We stop running once the Guest is dead. */
-   while(!lg-dead) {
+   while(!cpu-lg-dead) {
/* First we run any hypercalls the Guest wants done. */
if (cpu-hcall)
do_hypercalls(cpu);
@@-212,7 +210,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)

/* Just make absolutely sure the Guest is still alive.  One of
 * those hypercalls could have been fatal, for example. */
-   if(lg-dead)
+   if(cpu-lg-dead)
break;

/* If the Guest asked to be stopped, we sleep.  The Guest's
@@-237,7 +235,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
lguest_arch_handle_trap(cpu);
}

-   if(lg-dead == ERR_PTR(-ERESTART))
+   if(cpu-lg-dead == ERR_PTR(-ERESTART))
return -ERESTART;
/* The Guest is dead = No such file or directory */
return -ENOENT;
diff--git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index0471018..32666d0 100644
---a/drivers/lguest/hypercalls.c
+++b/drivers/lguest/hypercalls.c
@@-31,8 +31,6 @@
 * Or gets killed.  Or, in the case of LHCALL_CRASH, both. */
static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
{
-   structlguest *lg = cpu-lg;
-
switch (args-arg0) {
case LHCALL_FLUSH_ASYNC:
/* This call does nothing, except by breaking out of the Guest
@@-41,7 +39,7 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args 
*args)
case LHCALL_LGUEST_INIT:
/* You can't get here unless you're already initialized.  Don't
 * do that. */
-   kill_guest(lg,already have lguest_data);
+   kill_guest(cpu,already have lguest_data);
break;
case LHCALL_SHUTDOWN: {
/* Shutdown is such a trivial hypercall that we do it in four
@@-49,11 +47,11 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args 
*args)
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, 

[PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
urrently, lguest module can't be compiled without the PARAVIRT flag being
on.This is a fake dependency, since the module itself shouldn't need any
paravirtoverride. Reason for that is the reference to pv_info structure
ininitial loading tests.

his patch removes it in favour of a more generic error message.

Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
---
drivers/lguest/core.c |2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff--git a/drivers/lguest/core.c b/drivers/lguest/core.c
indexbb42fd0..97b76d6 100644
---a/drivers/lguest/core.c
+++b/drivers/lguest/core.c
@@-255,7 +255,7 @@ static int __init init(void)

/* Lguest can't run under Xen, VMI or itself.  It does Tricky Stuff. */
if (paravirt_enabled()) {
-   printk(lguestis afraid of %s\n, pv_info.name);
+   printk(lguestcan't run under another hypervisor);
return -EPERM;
}

--
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/7] More lguest massage.

2008-01-17 Thread Glauber de Oliveira Costa
I don't have _any_ idea about what happened to those patches. They
were sent through the normal git-send-email script, but for
some reason, all got the same subject. They might be okay for the
review, but anyone willing to try it more seriously, please grab it
at http://glommer.net/patches-lguest.tar.gz

On Jan 17, 2008 10:35 PM, Glauber de Oliveira Costa [EMAIL PROTECTED] wrote:
 urrently, lguest module can't be compiled without the PARAVIRT flag being
 on.This is a fake dependency, since the module itself shouldn't need any
 paravirtoverride. Reason for that is the reference to pv_info structure
 ininitial loading tests.

 his patch removes it in favour of a more generic error message.

 Signed-off-by:Glauber de Oliveira Costa [EMAIL PROTECTED]
 ---
 drivers/lguest/core.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

 diff--git a/drivers/lguest/core.c b/drivers/lguest/core.c
 indexbb42fd0..97b76d6 100644
 ---a/drivers/lguest/core.c
 +++b/drivers/lguest/core.c
 @@-255,7 +255,7 @@ static int __init init(void)

 /* Lguest can't run under Xen, VMI or itself.  It does Tricky Stuff. 
 */
 if (paravirt_enabled()) {
 -   printk(lguestis afraid of %s\n, pv_info.name);
 +   printk(lguestcan't run under another hypervisor);
 return -EPERM;
 }

 --
 1.5.0.6





-- 
Glauber de Oliveira Costa.
Free as in Freedom
http://glommer.net

The less confident you are, the more serious you have to act.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] fix drivers/lguest Makefile entry

2008-01-17 Thread Glauber de Oliveira Costa
It should depend on CONFIG_LGUEST, not CONFIG_LGUEST_GUEST

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/Makefile |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/Makefile b/drivers/Makefile
index ee1b6a5..58a17e9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -73,7 +73,7 @@ obj-$(CONFIG_ISDN)+= isdn/
 obj-$(CONFIG_EDAC) += edac/
 obj-$(CONFIG_MCA)  += mca/
 obj-$(CONFIG_EISA) += eisa/
-obj-$(CONFIG_LGUEST_GUEST) += lguest/
+obj-$(CONFIG_LGUEST)   += lguest/
 obj-$(CONFIG_CPU_FREQ) += cpufreq/
 obj-$(CONFIG_CPU_IDLE) += cpuidle/
 obj-$(CONFIG_MMC)  += mmc/
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 16/16] per-vcpu lguest pgdir management

2008-01-07 Thread Glauber de Oliveira Costa
this patch makes the pgdir management per-vcpu. The pgdirs pool
is still guest-wide (although it'll probably need to grow when we
are really executing more vcpus), but the pgdidx index is gone,
since it makes no sense anymore. Instead, we use a per-vcpu
index.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |6 ++--
 drivers/lguest/lg.h   |   12 +++---
 drivers/lguest/page_tables.c  |   60 +
 drivers/lguest/x86/core.c |6 ++--
 5 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index ae8c0b4..b3a1942 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -60,7 +60,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
if (args->arg1)
guest_pagetable_clear_all(vcpu);
else
-   guest_pagetable_flush_user(lg);
+   guest_pagetable_flush_user(vcpu);
break;
 
/* All these calls simply pass the arguments through to the right
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 745f3ae..68b403f 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -77,7 +77,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
virtstack = vcpu->esp1;
ss = vcpu->ss1;
 
-   origstack = gstack = guest_pa(lg, virtstack);
+   origstack = gstack = guest_pa(vcpu, virtstack);
/* We push the old stack segment and pointer onto the new
 * stack: when the Guest does an "iret" back from the interrupt
 * handler the CPU will notice they're dropping privilege
@@ -89,7 +89,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
virtstack = vcpu->regs->esp;
ss = vcpu->regs->ss;
 
-   origstack = gstack = guest_pa(lg, virtstack);
+   origstack = gstack = guest_pa(vcpu, virtstack);
}
 
/* Remember that we never let the Guest actually disable interrupts, so
@@ -325,7 +325,7 @@ void pin_stack_pages(struct lg_vcpu *vcpu)
 * start of the page after the kernel stack.  Subtract one to
 * get back onto the first stack page, and keep subtracting to
 * get to the rest of the stack pages. */
-   pin_page(lg, vcpu->esp1 - 1 - i * PAGE_SIZE);
+   pin_page(vcpu, vcpu->esp1 - 1 - i * PAGE_SIZE);
 }
 
 /* Direct traps also mean that we need to know whenever the Guest wants to use
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index d33445f..6e6a69e 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -57,6 +57,8 @@ struct lg_vcpu {
unsigned long regs_page;
struct lguest_regs *regs;
 
+   int vcpu_pgd; /* which pgd this vcpu is currently using */
+
/* If a hypercall was asked for, this points to the arguments. */
struct hcall_args *hcall;
u32 next_hcall;
@@ -92,8 +94,6 @@ struct lguest
int changed;
struct lguest_pages *last_pages;
 
-   /* We keep a small number of these. */
-   u32 pgdidx;
struct pgdir pgdirs[4];
 
unsigned long noirq_start, noirq_end;
@@ -170,14 +170,14 @@ void free_guest_pagetable(struct lguest *lg);
 void guest_new_pagetable(struct lg_vcpu *vcpu, unsigned long pgtable);
 void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i);
 void guest_pagetable_clear_all(struct lg_vcpu *vcpu);
-void guest_pagetable_flush_user(struct lguest *lg);
+void guest_pagetable_flush_user(struct lg_vcpu *vcpu);
 void guest_set_pte(struct lguest *lg, unsigned long gpgdir,
   unsigned long vaddr, pte_t val);
 void map_switcher_in_guest(struct lg_vcpu *vcpu,
   struct lguest_pages *pages);
-int demand_page(struct lguest *info, unsigned long cr2, int errcode);
-void pin_page(struct lguest *lg, unsigned long vaddr);
-unsigned long guest_pa(struct lguest *lg, unsigned long vaddr);
+int demand_page(struct lg_vcpu *vcpu, unsigned long cr2, int errcode);
+void pin_page(struct lg_vcpu *vcpu, unsigned long vaddr);
+unsigned long guest_pa(struct lg_vcpu *vcpu, unsigned long vaddr);
 void page_table_guest_data_init(struct lguest *lg);
 
 /* /core.c: */
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 1a7ac3a..839ea27 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -94,10 +94,10 @@ static pte_t *spte_addr(struct lguest *lg, pgd_t spgd, 
unsigned long vaddr)
 
 /* These two functions just like the above two, except they access the Guest
  * page

[PATCH 14/16] makes special fields be per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
lguest struct have room for some fields, namely, cr2, ts, esp1
and ss1, that are not really guest-wide, but rather, vcpu-wide.

This patch puts it in the vcpu struct

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/hypercalls.c   |   10 +-
 drivers/lguest/interrupts_and_traps.c |   24 +---
 drivers/lguest/lg.h   |   18 ++
 drivers/lguest/page_tables.c  |   11 ++-
 drivers/lguest/x86/core.c |   10 --
 5 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index edc8cb4..4a4133b 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -58,7 +58,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
/* FLUSH_TLB comes in two flavors, depending on the
 * argument: */
if (args->arg1)
-   guest_pagetable_clear_all(lg);
+   guest_pagetable_clear_all(vcpu);
else
guest_pagetable_flush_user(lg);
break;
@@ -66,10 +66,10 @@ static void do_hcall(struct lg_vcpu *vcpu, struct 
hcall_args *args)
/* All these calls simply pass the arguments through to the right
 * routines. */
case LHCALL_NEW_PGTABLE:
-   guest_new_pagetable(lg, args->arg1);
+   guest_new_pagetable(vcpu, args->arg1);
break;
case LHCALL_SET_STACK:
-   guest_set_stack(lg, args->arg1, args->arg2, args->arg3);
+   guest_set_stack(vcpu, args->arg1, args->arg2, args->arg3);
break;
case LHCALL_SET_PTE:
guest_set_pte(lg, args->arg1, args->arg2, __pte(args->arg3));
@@ -82,7 +82,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
break;
case LHCALL_TS:
/* This sets the TS flag, as we saw used in run_guest(). */
-   lg->ts = args->arg1;
+   vcpu->ts = args->arg1;
break;
case LHCALL_HALT:
/* Similarly, this sets the halted flag for run_guest(). */
@@ -189,7 +189,7 @@ static void initialize(struct lg_vcpu *vcpu)
 * first write to a Guest page.  This may have caused a copy-on-write
 * fault, but the old page might be (read-only) in the Guest
 * pagetable. */
-   guest_pagetable_clear_all(lg);
+   guest_pagetable_clear_all(vcpu);
 }
 
 /*H:100
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index c1ca198..745f3ae 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -74,8 +74,8 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
if ((vcpu->regs->ss&0x3) != GUEST_PL) {
/* The Guest told us their kernel stack with the SET_STACK
 * hypercall: both the virtual address and the segment */
-   virtstack = lg->esp1;
-   ss = lg->ss1;
+   virtstack = vcpu->esp1;
+   ss = vcpu->ss1;
 
origstack = gstack = guest_pa(lg, virtstack);
/* We push the old stack segment and pointer onto the new
@@ -313,10 +313,11 @@ static int direct_trap(unsigned int num)
  * the Guest.
  *
  * Which is deeply unfair, because (literally!) it wasn't the Guests' fault. */
-void pin_stack_pages(struct lguest *lg)
+void pin_stack_pages(struct lg_vcpu *vcpu)
 {
unsigned int i;
 
+   struct lguest *lg = vcpu->lg;
/* Depending on the CONFIG_4KSTACKS option, the Guest can have one or
 * two pages of stack space. */
for (i = 0; i < lg->stack_pages; i++)
@@ -324,7 +325,7 @@ void pin_stack_pages(struct lguest *lg)
 * start of the page after the kernel stack.  Subtract one to
 * get back onto the first stack page, and keep subtracting to
 * get to the rest of the stack pages. */
-   pin_page(lg, lg->esp1 - 1 - i * PAGE_SIZE);
+   pin_page(lg, vcpu->esp1 - 1 - i * PAGE_SIZE);
 }
 
 /* Direct traps also mean that we need to know whenever the Guest wants to use
@@ -335,21 +336,22 @@ void pin_stack_pages(struct lguest *lg)
  *
  * In Linux each process has its own kernel stack, so this happens a lot: we
  * change stacks on each context switch. */
-void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages)
+void guest_set_stack(struct lg_vcpu *vcpu, u32 seg, u32 esp,
+unsigned int pages)
 {
/* You are not allowed have a stack segment with privilege level 0: bad
 * Guest! */
if ((seg & 0x3) != GUEST_PL)
-   kill_guest(lg, "bad stack segment %i&

[PATCH 15/16] make pending notifications per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
this patch makes the pending_notify field, used to control
pending notifications, per-vcpu, instead of per-guest

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/core.c|6 +++---
 drivers/lguest/hypercalls.c  |6 +++---
 drivers/lguest/lg.h  |3 ++-
 drivers/lguest/lguest_user.c |4 ++--
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 847f2df..eae5149 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -186,10 +186,10 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
 
/* It's possible the Guest did a NOTIFY hypercall to the
 * Launcher, in which case we return from the read() now. */
-   if (lg->pending_notify) {
-   if (put_user(lg->pending_notify, user))
+   if (vcpu->pending_notify) {
+   if (put_user(vcpu->pending_notify, user))
return -EFAULT;
-   return sizeof(lg->pending_notify);
+   return sizeof(vcpu->pending_notify);
}
 
/* Check for signals */
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 4a4133b..ae8c0b4 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -89,7 +89,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
vcpu->halted = 1;
break;
case LHCALL_NOTIFY:
-   lg->pending_notify = args->arg1;
+   vcpu->pending_notify = args->arg1;
break;
default:
/* It should be an architecture-specific hypercall. */
@@ -152,7 +152,7 @@ static void do_async_hcalls(struct lg_vcpu *vcpu)
 
/* Stop doing hypercalls if they want to notify the Launcher:
 * it needs to service this first. */
-   if (lg->pending_notify)
+   if (vcpu->pending_notify)
break;
}
 }
@@ -217,7 +217,7 @@ void do_hypercalls(struct lg_vcpu *vcpu)
/* If we stopped reading the hypercall ring because the Guest did a
 * NOTIFY to the Launcher, we want to return now.  Otherwise we do
 * the hypercall. */
-   if (!vcpu->lg->pending_notify) {
+   if (!vcpu->pending_notify) {
do_hcall(vcpu, vcpu->hcall);
/* Tricky point: we reset the hcall pointer to mark the
 * hypercall as "done".  We use the hcall pointer rather than
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 1b3c933..d33445f 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -51,6 +51,8 @@ struct lg_vcpu {
u32 esp1;
u8 ss1;
 
+   unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
+
/* At end of a page shared mapped over lguest_pages in guest.  */
unsigned long regs_page;
struct lguest_regs *regs;
@@ -95,7 +97,6 @@ struct lguest
struct pgdir pgdirs[4];
 
unsigned long noirq_start, noirq_end;
-   unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
 
unsigned int stack_pages;
u32 tsc_khz;
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index acc1616..8ac6d2b 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -92,8 +92,8 @@ static ssize_t read(struct file *file, char __user *user, 
size_t size,loff_t*o)
 
/* If we returned from read() last time because the Guest notified,
 * clear the flag. */
-   if (lg->pending_notify)
-   lg->pending_notify = 0;
+   if (vcpu->pending_notify)
+   vcpu->pending_notify = 0;
 
/* Run the Guest until something interesting happens. */
return run_guest(vcpu, (unsigned long __user *)user);
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 13/16] per-vcpu lguest task management

2008-01-07 Thread Glauber de Oliveira Costa
lguest uses tasks to control its running behaviour (like sending
breaks, controlling halted state, etc). In a per-vcpu environment,
each vcpu will have its own underlying task. So this patch
makes the infrastructure for that possible

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/core.c |4 +-
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |8 ++--
 drivers/lguest/lg.h   |   14 
 drivers/lguest/lguest_user.c  |   55 ++---
 5 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index bc3b32d..847f2df 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -197,7 +197,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
return -ERESTARTSYS;
 
/* If Waker set break_out, return to Launcher. */
-   if (lg->break_out)
+   if (vcpu->break_out)
return -EAGAIN;
 
/* Check if there are any interrupts which can be delivered
@@ -217,7 +217,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
 
/* If the Guest asked to be stopped, we sleep.  The Guest's
 * clock timer or LHCALL_BREAK from the Waker will wake us. */
-   if (lg->halted) {
+   if (vcpu->halted) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
continue;
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 1bf133e..edc8cb4 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -86,7 +86,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
break;
case LHCALL_HALT:
/* Similarly, this sets the halted flag for run_guest(). */
-   lg->halted = 1;
+   vcpu->halted = 1;
break;
case LHCALL_NOTIFY:
lg->pending_notify = args->arg1;
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index f8f7efe..c1ca198 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -163,11 +163,11 @@ void maybe_do_interrupt(struct lg_vcpu *vcpu)
return;
 
/* If they're halted, interrupts restart them. */
-   if (lg->halted) {
+   if (vcpu->halted) {
/* Re-enable interrupts. */
if (put_user(X86_EFLAGS_IF, >lguest_data->irq_enabled))
kill_guest(lg, "Re-enabling interrupts");
-   lg->halted = 0;
+   vcpu->halted = 0;
} else {
/* Otherwise we check if they have interrupts disabled. */
u32 irq_enabled;
@@ -500,8 +500,8 @@ static enum hrtimer_restart clockdev_fn(struct hrtimer 
*timer)
/* Remember the first interrupt is the timer interrupt. */
set_bit(0, vcpu->irqs_pending);
/* If the Guest is actually stopped, we need to wake it up. */
-   if (vcpu->lg->halted)
-   wake_up_process(vcpu->lg->tsk);
+   if (vcpu->halted)
+   wake_up_process(vcpu->tsk);
return HRTIMER_NORESTART;
 }
 
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 5165172..8c9c8df 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -43,6 +43,8 @@ struct lguest;
 struct lg_vcpu {
int vcpu_id;
struct lguest *lg;
+   struct task_struct *tsk;
+   struct mm_struct *mm;   /* == tsk->mm, but that becomes NULL on exit */
 
/* At end of a page shared mapped over lguest_pages in guest.  */
unsigned long regs_page;
@@ -55,6 +57,11 @@ struct lg_vcpu {
/* Virtual clock device */
struct hrtimer hrt;
 
+   /* Do we need to stop what we're doing and return to userspace? */
+   int break_out;
+   wait_queue_head_t break_wq;
+   int halted;
+
/* Pending virtual interrupts */
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 
@@ -65,8 +72,6 @@ struct lg_vcpu {
 struct lguest
 {
struct lguest_data __user *lguest_data;
-   struct task_struct *tsk;
-   struct mm_struct *mm;   /* == tsk->mm, but that becomes NULL on exit */
struct lg_vcpu vcpus[NR_CPUS];
unsigned int nr_vcpus;
 
@@ -76,15 +81,10 @@ struct lguest
void __user *mem_base;
unsigned long kernel_address;
u32 cr2;
-   int halted;
int ts;
u32 esp1;
u8 ss1;
 
-   /* Do we need to stop what we're doing and return to userspace? */
-   int break_out;
-   wait_queue_head_t break_wq;
-
/* Bitmap of what has changed: see CHANGED_* above. */
int changed;

[PATCH 11/16] make registers per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
This is the most obvious per-vcpu field: registers.

So this patch moves it from struct lguest to struct vcpu,
and patch the places in which they are used, accordingly

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/interrupts_and_traps.c |   29 ---
 drivers/lguest/lg.h   |9 ---
 drivers/lguest/lguest_user.c  |   36 +++---
 drivers/lguest/page_tables.c  |4 ++-
 drivers/lguest/x86/core.c |   39 +
 5 files changed, 61 insertions(+), 56 deletions(-)

diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index d28671b..4cc7404 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -71,7 +71,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
/* There are two cases for interrupts: one where the Guest is already
 * in the kernel, and a more complex one where the Guest is in
 * userspace.  We check the privilege level to find out. */
-   if ((lg->regs->ss&0x3) != GUEST_PL) {
+   if ((vcpu->regs->ss&0x3) != GUEST_PL) {
/* The Guest told us their kernel stack with the SET_STACK
 * hypercall: both the virtual address and the segment */
virtstack = lg->esp1;
@@ -82,12 +82,12 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 
lo, u32 hi,
 * stack: when the Guest does an "iret" back from the interrupt
 * handler the CPU will notice they're dropping privilege
 * levels and expect these here. */
-   push_guest_stack(lg, , lg->regs->ss);
-   push_guest_stack(lg, , lg->regs->esp);
+   push_guest_stack(lg, , vcpu->regs->ss);
+   push_guest_stack(lg, , vcpu->regs->esp);
} else {
/* We're staying on the same Guest (kernel) stack. */
-   virtstack = lg->regs->esp;
-   ss = lg->regs->ss;
+   virtstack = vcpu->regs->esp;
+   ss = vcpu->regs->ss;
 
origstack = gstack = guest_pa(lg, virtstack);
}
@@ -96,7 +96,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
 * the "Interrupt Flag" bit is always set.  We copy that bit from the
 * Guest's "irq_enabled" field into the eflags word: we saw the Guest
 * copy it back in "lguest_iret". */
-   eflags = lg->regs->eflags;
+   eflags = vcpu->regs->eflags;
if (get_user(irq_enable, >lguest_data->irq_enabled) == 0
&& !(irq_enable & X86_EFLAGS_IF))
eflags &= ~X86_EFLAGS_IF;
@@ -105,19 +105,19 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 
lo, u32 hi,
 * "eflags" word, the old code segment, and the old instruction
 * pointer. */
push_guest_stack(lg, , eflags);
-   push_guest_stack(lg, , lg->regs->cs);
-   push_guest_stack(lg, , lg->regs->eip);
+   push_guest_stack(lg, , vcpu->regs->cs);
+   push_guest_stack(lg, , vcpu->regs->eip);
 
/* For the six traps which supply an error code, we push that, too. */
if (has_err)
-   push_guest_stack(lg, , lg->regs->errcode);
+   push_guest_stack(lg, , vcpu->regs->errcode);
 
/* Now we've pushed all the old state, we change the stack, the code
 * segment and the address to execute. */
-   lg->regs->ss = ss;
-   lg->regs->esp = virtstack + (gstack - origstack);
-   lg->regs->cs = (__KERNEL_CS|GUEST_PL);
-   lg->regs->eip = idt_address(lo, hi);
+   vcpu->regs->ss = ss;
+   vcpu->regs->esp = virtstack + (gstack - origstack);
+   vcpu->regs->cs = (__KERNEL_CS|GUEST_PL);
+   vcpu->regs->eip = idt_address(lo, hi);
 
/* There are two kinds of interrupt handlers: 0xE is an "interrupt
 * gate" which expects interrupts to be disabled on entry. */
@@ -158,7 +158,8 @@ void maybe_do_interrupt(struct lg_vcpu *vcpu)
 
/* They may be in the middle of an iret, where they asked us never to
 * deliver interrupts. */
-   if (lg->regs->eip >= lg->noirq_start && lg->regs->eip < lg->noirq_end)
+   if ((vcpu->regs->eip >= lg->noirq_start) &&
+   (vcpu->regs->eip < lg->noirq_end))
return;
 
/* If they're halted, interrupts restart them. */
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index f871737..d8429a0 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -44,6 +44,10 @@ struct lg_vcpu {
int vc

[PATCH 10/16] make emulate_insn receive a vcpu struct.

2008-01-07 Thread Glauber de Oliveira Costa
emulate_insn() needs to know about current eip, which will be,
in the future, a per-vcpu thing. So in this patch, the function
prototype is modified to receive a vcpu struct

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/x86/core.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 125a14b..b336fff 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -220,8 +220,9 @@ void lguest_arch_run_guest(struct lg_vcpu *vcpu)
  * When the Guest uses one of these instructions, we get a trap (General
  * Protection Fault) and come here.  We see if it's one of those troublesome
  * instructions and skip over it.  We return true if we did. */
-static int emulate_insn(struct lguest *lg)
+static int emulate_insn(struct lg_vcpu *vcpu)
 {
+   struct lguest *lg = vcpu->lg;
u8 insn;
unsigned int insnlen = 0, in = 0, shift = 0;
/* The eip contains the *virtual* address of the Guest's instruction:
@@ -294,7 +295,7 @@ void lguest_arch_handle_trap(struct lg_vcpu *vcpu)
 * instructions which we need to emulate.  If so, we just go
 * back into the Guest after we've done it. */
if (lg->regs->errcode == 0) {
-   if (emulate_insn(lg))
+   if (emulate_insn(vcpu))
return;
}
break;
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 12/16] replace lguest_arch with lg_vcpu_arch.

2008-01-07 Thread Glauber de Oliveira Costa
The fields found in lguest_arch are not really per-guest,
but per-cpu (gdt, idt, etc). So this patch turns lguest_arch
into lg_vcpu_arch.

It makes sense to have a per-guest per-arch struct, but this
can be addressed later, when the need arrives.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/interrupts_and_traps.c |   29 +++--
 drivers/lguest/lg.h   |   19 +++---
 drivers/lguest/segments.c |   43 +---
 drivers/lguest/x86/core.c |   24 --
 include/asm-x86/lguest.h  |2 +-
 5 files changed, 60 insertions(+), 57 deletions(-)

diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 4cc7404..f8f7efe 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -180,7 +180,7 @@ void maybe_do_interrupt(struct lg_vcpu *vcpu)
/* Look at the IDT entry the Guest gave us for this interrupt.  The
 * first 32 (FIRST_EXTERNAL_VECTOR) entries are for traps, so we skip
 * over them. */
-   idt = >arch.idt[FIRST_EXTERNAL_VECTOR+irq];
+   idt = >arch.idt[FIRST_EXTERNAL_VECTOR+irq];
/* If they don't have a handler (yet?), we just ignore it */
if (idt_present(idt->a, idt->b)) {
/* OK, mark it no longer pending and deliver it. */
@@ -253,15 +253,15 @@ int deliver_trap(struct lg_vcpu *vcpu, unsigned int num)
 {
/* Trap numbers are always 8 bit, but we set an impossible trap number
 * for traps inside the Switcher, so check that here. */
-   if (num >= ARRAY_SIZE(vcpu->lg->arch.idt))
+   if (num >= ARRAY_SIZE(vcpu->arch.idt))
return 0;
 
/* Early on the Guest hasn't set the IDT entries (or maybe it put a
 * bogus one in): if we fail here, the Guest will be killed. */
-   if (!idt_present(vcpu->lg->arch.idt[num].a, vcpu->lg->arch.idt[num].b))
+   if (!idt_present(vcpu->arch.idt[num].a, vcpu->arch.idt[num].b))
return 0;
-   set_guest_interrupt(vcpu, vcpu->lg->arch.idt[num].a,
-   vcpu->lg->arch.idt[num].b, has_err(num));
+   set_guest_interrupt(vcpu, vcpu->arch.idt[num].a,
+   vcpu->arch.idt[num].b, has_err(num));
return 1;
 }
 
@@ -387,7 +387,8 @@ static void set_trap(struct lguest *lg, struct desc_struct 
*trap,
  *
  * We saw the Guest setting Interrupt Descriptor Table (IDT) entries with the
  * LHCALL_LOAD_IDT_ENTRY hypercall before: that comes here. */
-void load_guest_idt_entry(struct lguest *lg, unsigned int num, u32 lo, u32 hi)
+void load_guest_idt_entry(struct lg_vcpu *vcpu,
+ unsigned int num, u32 lo, u32 hi)
 {
/* Guest never handles: NMI, doublefault, spurious interrupt or
 * hypercall.  We ignore when it tries to set them. */
@@ -396,13 +397,13 @@ void load_guest_idt_entry(struct lguest *lg, unsigned int 
num, u32 lo, u32 hi)
 
/* Mark the IDT as changed: next time the Guest runs we'll know we have
 * to copy this again. */
-   lg->changed |= CHANGED_IDT;
+   vcpu->lg->changed |= CHANGED_IDT;
 
/* Check that the Guest doesn't try to step outside the bounds. */
-   if (num >= ARRAY_SIZE(lg->arch.idt))
-   kill_guest(lg, "Setting idt entry %u", num);
+   if (num >= ARRAY_SIZE(vcpu->arch.idt))
+   kill_guest(vcpu->lg, "Setting idt entry %u", num);
else
-   set_trap(lg, >arch.idt[num], num, lo, hi);
+   set_trap(vcpu->lg, >arch.idt[num], num, lo, hi);
 }
 
 /* The default entry for each interrupt points into the Switcher routines which
@@ -438,14 +439,14 @@ void setup_default_idt_entries(struct lguest_ro_state 
*state,
 /*H:240 We don't use the IDT entries in the "struct lguest" directly, instead
  * we copy them into the IDT which we've set up for Guests on this CPU, just
  * before we run the Guest.  This routine does that copy. */
-void copy_traps(const struct lguest *lg, struct desc_struct *idt,
+void copy_traps(const struct lg_vcpu *vcpu, struct desc_struct *idt,
const unsigned long *def)
 {
unsigned int i;
 
/* We can simply copy the direct traps, otherwise we use the default
 * ones in the Switcher: they will return to the Host. */
-   for (i = 0; i < ARRAY_SIZE(lg->arch.idt); i++) {
+   for (i = 0; i < ARRAY_SIZE(vcpu->arch.idt); i++) {
/* If no Guest can ever override this trap, leave it alone. */
if (!direct_trap(i))
continue;
@@ -454,8 +455,8 @@ void copy_traps(const struct lguest *lg, struct desc_struct 
*idt,
 * Interrupt gates (type 14) disable interrupts as they are

[PATCH 08/16] per-vcpu interrupt processing.

2008-01-07 Thread Glauber de Oliveira Costa
This patch adapts interrupt processing for using the vcpu struct.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/core.c |2 +-
 drivers/lguest/interrupts_and_traps.c |   25 ++---
 drivers/lguest/lg.h   |   10 +-
 drivers/lguest/lguest_user.c  |7 ---
 drivers/lguest/x86/core.c |2 +-
 5 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 99f65f9..bc3b32d 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -203,7 +203,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
/* Check if there are any interrupts which can be delivered
 * now: if so, this sets up the hander to be executed when we
 * next run the Guest. */
-   maybe_do_interrupt(lg);
+   maybe_do_interrupt(vcpu);
 
/* All long-lived kernel loops need to check with this horrible
 * thing called the freezer.  If the Host is trying to suspend,
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 3be18a6..d28671b 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -60,11 +60,13 @@ static void push_guest_stack(struct lguest *lg, unsigned 
long *gstack, u32 val)
  * We set up the stack just like the CPU does for a real interrupt, so it's
  * identical for the Guest (and the standard "iret" instruction will undo
  * it). */
-static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
+static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, u32 hi,
+   int has_err)
 {
unsigned long gstack, origstack;
u32 eflags, ss, irq_enable;
unsigned long virtstack;
+   struct lguest *lg = vcpu->lg;
 
/* There are two cases for interrupts: one where the Guest is already
 * in the kernel, and a more complex one where the Guest is in
@@ -129,9 +131,10 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, 
u32 hi, int has_err)
  *
  * maybe_do_interrupt() gets called before every entry to the Guest, to see if
  * we should divert the Guest to running an interrupt handler. */
-void maybe_do_interrupt(struct lguest *lg)
+void maybe_do_interrupt(struct lg_vcpu *vcpu)
 {
unsigned int irq;
+   struct lguest *lg = vcpu->lg;
DECLARE_BITMAP(blk, LGUEST_IRQS);
struct desc_struct *idt;
 
@@ -145,7 +148,7 @@ void maybe_do_interrupt(struct lguest *lg)
   sizeof(blk)))
return;
 
-   bitmap_andnot(blk, lg->irqs_pending, blk, LGUEST_IRQS);
+   bitmap_andnot(blk, vcpu->irqs_pending, blk, LGUEST_IRQS);
 
/* Find the first interrupt. */
irq = find_first_bit(blk, LGUEST_IRQS);
@@ -180,11 +183,11 @@ void maybe_do_interrupt(struct lguest *lg)
/* If they don't have a handler (yet?), we just ignore it */
if (idt_present(idt->a, idt->b)) {
/* OK, mark it no longer pending and deliver it. */
-   clear_bit(irq, lg->irqs_pending);
+   clear_bit(irq, vcpu->irqs_pending);
/* set_guest_interrupt() takes the interrupt descriptor and a
 * flag to say whether this interrupt pushes an error code onto
 * the stack as well: virtual interrupts never do. */
-   set_guest_interrupt(lg, idt->a, idt->b, 0);
+   set_guest_interrupt(vcpu, idt->a, idt->b, 0);
}
 
/* Every time we deliver an interrupt, we update the timestamp in the
@@ -245,19 +248,19 @@ static int has_err(unsigned int trap)
 }
 
 /* deliver_trap() returns true if it could deliver the trap. */
-int deliver_trap(struct lguest *lg, unsigned int num)
+int deliver_trap(struct lg_vcpu *vcpu, unsigned int num)
 {
/* Trap numbers are always 8 bit, but we set an impossible trap number
 * for traps inside the Switcher, so check that here. */
-   if (num >= ARRAY_SIZE(lg->arch.idt))
+   if (num >= ARRAY_SIZE(vcpu->lg->arch.idt))
return 0;
 
/* Early on the Guest hasn't set the IDT entries (or maybe it put a
 * bogus one in): if we fail here, the Guest will be killed. */
-   if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b))
+   if (!idt_present(vcpu->lg->arch.idt[num].a, vcpu->lg->arch.idt[num].b))
return 0;
-   set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b,
-   has_err(num));
+   set_guest_interrupt(vcpu, vcpu->lg->arch.idt[num].a,
+   vcpu->lg->arch.idt[num].b, has_err(num));
return 1;
 }
 
@@ -493,7 +496,7 @@ static enum hrtimer_restart clo

[PATCH 09/16] map_switcher_in_guest() per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
The switcher needs to be mapped per-vcpu, because different vcpus
will potentially have different page tables (they don't have to,
because threads will share the same).

So our first step is the make the function receive a vcpu struct

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/lg.h  |3 ++-
 drivers/lguest/page_tables.c |4 +++-
 drivers/lguest/x86/core.c|2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 6c794cd..f871737 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -168,7 +168,8 @@ void guest_pagetable_clear_all(struct lguest *lg);
 void guest_pagetable_flush_user(struct lguest *lg);
 void guest_set_pte(struct lguest *lg, unsigned long gpgdir,
   unsigned long vaddr, pte_t val);
-void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages);
+void map_switcher_in_guest(struct lg_vcpu *vcpu,
+  struct lguest_pages *pages);
 int demand_page(struct lguest *info, unsigned long cr2, int errcode);
 void pin_page(struct lguest *lg, unsigned long vaddr);
 unsigned long guest_pa(struct lguest *lg, unsigned long vaddr);
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index fffabb3..c79fac2 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -634,8 +634,10 @@ void free_guest_pagetable(struct lguest *lg)
  * Guest (and not the pages for other CPUs).  We have the appropriate PTE pages
  * for each CPU already set up, we just need to hook them in now we know which
  * Guest is about to run on this CPU. */
-void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages)
+void map_switcher_in_guest(struct lg_vcpu *vcpu,
+  struct lguest_pages *pages)
 {
+   struct lguest *lg = vcpu->lg;
pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
pgd_t switcher_pgd;
pte_t regs_pte;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 8fbb373..125a14b 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -92,7 +92,7 @@ static void copy_in_guest_info(struct lg_vcpu *vcpu,
pages->state.host_cr3 = __pa(current->mm->pgd);
/* Set up the Guest's page tables to see this CPU's pages (and no
 * other CPU's pages). */
-   map_switcher_in_guest(lg, pages);
+   map_switcher_in_guest(vcpu, pages);
/* Set up the two "TSS" members which tell the CPU what stack to use
 * for traps which do directly into the Guest (ie. traps at privilege
 * level 1). */
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 07/16] per-vcpu lguest timers

2008-01-07 Thread Glauber de Oliveira Costa
Here, I introduce per-vcpu timers. With this, we can have
local expiries, needed for accounting time in smp guests

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |   20 ++--
 drivers/lguest/lg.h   |   10 +-
 drivers/lguest/lguest_user.c  |   12 +++-
 4 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 9417601..1bf133e 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -78,7 +78,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
guest_set_pmd(lg, args->arg1, args->arg2);
break;
case LHCALL_SET_CLOCKEVENT:
-   guest_set_clockevent(lg, args->arg1);
+   guest_set_clockevent(vcpu, args->arg1);
break;
case LHCALL_TS:
/* This sets the TS flag, as we saw used in run_guest(). */
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 2b66f79..3be18a6 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -470,13 +470,13 @@ void copy_traps(const struct lguest *lg, struct 
desc_struct *idt,
  * infrastructure to set a callback at that time.
  *
  * 0 means "turn off the clock". */
-void guest_set_clockevent(struct lguest *lg, unsigned long delta)
+void guest_set_clockevent(struct lg_vcpu *vcpu, unsigned long delta)
 {
ktime_t expires;
 
if (unlikely(delta == 0)) {
/* Clock event device is shutting down. */
-   hrtimer_cancel(>hrt);
+   hrtimer_cancel(>hrt);
return;
}
 
@@ -484,25 +484,25 @@ void guest_set_clockevent(struct lguest *lg, unsigned 
long delta)
 * all the time between now and the timer interrupt it asked for.  This
 * is almost always the right thing to do. */
expires = ktime_add_ns(ktime_get_real(), delta);
-   hrtimer_start(>hrt, expires, HRTIMER_MODE_ABS);
+   hrtimer_start(>hrt, expires, HRTIMER_MODE_ABS);
 }
 
 /* This is the function called when the Guest's timer expires. */
 static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
 {
-   struct lguest *lg = container_of(timer, struct lguest, hrt);
+   struct lg_vcpu *vcpu = container_of(timer, struct lg_vcpu, hrt);
 
/* Remember the first interrupt is the timer interrupt. */
-   set_bit(0, lg->irqs_pending);
+   set_bit(0, vcpu->lg->irqs_pending);
/* If the Guest is actually stopped, we need to wake it up. */
-   if (lg->halted)
-   wake_up_process(lg->tsk);
+   if (vcpu->lg->halted)
+   wake_up_process(vcpu->lg->tsk);
return HRTIMER_NORESTART;
 }
 
 /* This sets up the timer for this Guest. */
-void init_clockdev(struct lguest *lg)
+void init_clockdev(struct lg_vcpu *vcpu)
 {
-   hrtimer_init(>hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
-   lg->hrt.function = clockdev_fn;
+   hrtimer_init(>hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+   vcpu->hrt.function = clockdev_fn;
 }
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 13a991a..9c90fd3 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -47,6 +47,9 @@ struct lg_vcpu {
/* If a hypercall was asked for, this points to the arguments. */
struct hcall_args *hcall;
u32 next_hcall;
+
+   /* Virtual clock device */
+   struct hrtimer hrt;
 };
 
 /* The private info the thread maintains about the guest. */
@@ -95,9 +98,6 @@ struct lguest
 
struct lguest_arch arch;
 
-   /* Virtual clock device */
-   struct hrtimer hrt;
-
/* Pending virtual interrupts */
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
@@ -145,8 +145,8 @@ void setup_default_idt_entries(struct lguest_ro_state 
*state,
   const unsigned long *def);
 void copy_traps(const struct lguest *lg, struct desc_struct *idt,
const unsigned long *def);
-void guest_set_clockevent(struct lguest *lg, unsigned long delta);
-void init_clockdev(struct lguest *lg);
+void guest_set_clockevent(struct lg_vcpu *vcpu, unsigned long delta);
+void init_clockdev(struct lg_vcpu *vcpu);
 bool check_syscall_vector(struct lguest *lg);
 int init_interrupts(void);
 void free_interrupts(void);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index d176004..cd2b0bf 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -104,6 +104,9 @@ static int vcpu_start(struct lg_vcpu *vcpu, int vcpu_id,
 
vcpu->vcpu_id = vcpu_id;
 
+   /* The timer for lguest's clock needs initialization. */
+   init_clockdev(vcpu);
+
vcpu->lg 

[PATCH 06/16] make hypercalls use the vcpu struct

2008-01-07 Thread Glauber de Oliveira Costa
this patch changes do_hcall() and do_async_hcall() interfaces (and obviously 
their
callers) to get a vcpu struct. Again, a vcpu services the hypercall, not the 
whole
guest

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/core.c   |6 +++---
 drivers/lguest/hypercalls.c |   42 +++---
 drivers/lguest/lg.h |   16 
 drivers/lguest/x86/core.c   |   16 ++--
 4 files changed, 44 insertions(+), 36 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 07a4c22..99f65f9 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -181,8 +181,8 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
/* We stop running once the Guest is dead. */
while (!lg->dead) {
/* First we run any hypercalls the Guest wants done. */
-   if (lg->hcall)
-   do_hypercalls(lg);
+   if (vcpu->hcall)
+   do_hypercalls(vcpu);
 
/* It's possible the Guest did a NOTIFY hypercall to the
 * Launcher, in which case we return from the read() now. */
@@ -234,7 +234,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
local_irq_enable();
 
/* Now we deal with whatever happened to the Guest. */
-   lguest_arch_handle_trap(lg);
+   lguest_arch_handle_trap(vcpu);
}
 
/* The Guest is dead => "No such file or directory" */
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index b478aff..9417601 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -29,8 +29,10 @@
 
 /*H:120 This is the core hypercall routine: where the Guest gets what it wants.
  * Or gets killed.  Or, in the case of LHCALL_CRASH, both. */
-static void do_hcall(struct lguest *lg, struct hcall_args *args)
+static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args *args)
 {
+   struct lguest *lg = vcpu->lg;
+
switch (args->arg0) {
case LHCALL_FLUSH_ASYNC:
/* This call does nothing, except by breaking out of the Guest
@@ -91,7 +93,7 @@ static void do_hcall(struct lguest *lg, struct hcall_args 
*args)
break;
default:
/* It should be an architecture-specific hypercall. */
-   if (lguest_arch_do_hcall(lg, args))
+   if (lguest_arch_do_hcall(vcpu, args))
kill_guest(lg, "Bad hypercall %li\n", args->arg0);
}
 }
@@ -104,10 +106,11 @@ static void do_hcall(struct lguest *lg, struct hcall_args 
*args)
  * Guest put them in the ring, but we also promise the Guest that they will
  * happen before any normal hypercall (which is why we check this before
  * checking for a normal hcall). */
-static void do_async_hcalls(struct lguest *lg)
+static void do_async_hcalls(struct lg_vcpu *vcpu)
 {
unsigned int i;
u8 st[LHCALL_RING_SIZE];
+   struct lguest *lg = vcpu->lg;
 
/* For simplicity, we copy the entire call status array in at once. */
if (copy_from_user(, >lguest_data->hcall_status, sizeof(st)))
@@ -119,7 +122,7 @@ static void do_async_hcalls(struct lguest *lg)
/* We remember where we were up to from last time.  This makes
 * sure that the hypercalls are done in the order the Guest
 * places them in the ring. */
-   unsigned int n = lg->next_hcall;
+   unsigned int n = vcpu->next_hcall;
 
/* 0xFF means there's no call here (yet). */
if (st[n] == 0xFF)
@@ -127,8 +130,8 @@ static void do_async_hcalls(struct lguest *lg)
 
/* OK, we have hypercall.  Increment the "next_hcall" cursor,
 * and wrap back to 0 if we reach the end. */
-   if (++lg->next_hcall == LHCALL_RING_SIZE)
-   lg->next_hcall = 0;
+   if (++vcpu->next_hcall == LHCALL_RING_SIZE)
+   vcpu->next_hcall = 0;
 
/* Copy the hypercall arguments into a local copy of
 * the hcall_args struct. */
@@ -139,7 +142,7 @@ static void do_async_hcalls(struct lguest *lg)
}
 
/* Do the hypercall, same as a normal one. */
-   do_hcall(lg, );
+   do_hcall(vcpu, );
 
/* Mark the hypercall done. */
if (put_user(0xFF, >lguest_data->hcall_status[n])) {
@@ -156,16 +159,17 @@ static void do_async_hcalls(struct lguest *lg)
 
 /* Last of all, we look at what happens first of all.  The very first time the
  * Guest makes a hypercall, we end up here to set things up: */
-static void initialize(struct lguest *lg)
+static void initialize(struct lg_vcpu *vcpu)
 {
+   struct lguest *

[PATCH 02/16] adapt lguest launcher to per-cpuness

2008-01-07 Thread Glauber de Oliveira Costa
This patch makes uses of pread() and pwrite() in lguest launcher
to communicate the vcpu id to the lguest driver. The id is kept in
a thread variable, which means we'll span in the future, vcpus as
threads. But right now, only the infrastructure is out there.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 Documentation/lguest/lguest.c |   23 ---
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 9b0e322..4745f7e 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -79,6 +79,9 @@ static void *guest_base;
 /* The maximum guest physical address allowed, and maximum possible. */
 static unsigned long guest_limit, guest_max;
 
+/* a per-cpu variable indicating whose vcpu is currently running */
+static unsigned int __thread vcpu_id;
+
 /* This is our list of devices. */
 struct device_list
 {
@@ -554,7 +557,7 @@ static void wake_parent(int pipefd, int lguest_fd)
else
FD_CLR(-fd - 1, );
} else /* Send LHREQ_BREAK command. */
-   write(lguest_fd, args, sizeof(args));
+   pwrite(lguest_fd, args, sizeof(args), 0);
}
 }
 
@@ -1511,7 +1514,8 @@ static void __attribute__((noreturn)) run_guest(int 
lguest_fd)
int readval;
 
/* We read from the /dev/lguest device to run the Guest. */
-   readval = read(lguest_fd, _addr, sizeof(notify_addr));
+   readval = pread(lguest_fd, _addr,
+   sizeof(notify_addr), vcpu_id);
 
/* One unsigned long means the Guest did HCALL_NOTIFY */
if (readval == sizeof(notify_addr)) {
@@ -1521,17 +1525,21 @@ static void __attribute__((noreturn)) run_guest(int 
lguest_fd)
/* ENOENT means the Guest died.  Reading tells us why. */
} else if (errno == ENOENT) {
char reason[1024] = { 0 };
-   read(lguest_fd, reason, sizeof(reason)-1);
+   pread(lguest_fd, reason, sizeof(reason)-1, vcpu_id);
errx(1, "%s", reason);
/* EAGAIN means the Waker wanted us to look at some input.
 * Anything else means a bug or incompatible change. */
} else if (errno != EAGAIN)
err(1, "Running guest failed");
 
-   /* Service input, then unset the BREAK to release the Waker. */
-   handle_input(lguest_fd);
-   if (write(lguest_fd, args, sizeof(args)) < 0)
-   err(1, "Resetting break");
+   if (!vcpu_id) {
+   /* Service input, then unset the BREAK to
+* release the Waker. Right now, simple mecahnism
+* to issue it all to first vcpu */
+   handle_input(lguest_fd);
+   if (pwrite(lguest_fd, args, sizeof(args), 0) < 0)
+   err(1, "Resetting break");
+   }
}
 }
 /*
@@ -1582,6 +1590,7 @@ int main(int argc, char *argv[])
devices.lastdev = 
devices.next_irq = 1;
 
+   vcpu_id = 0;
/* We need to know how much memory so we can set up the device
 * descriptor and memory pages for the devices as we parse the command
 * line.  So we quickly look through the arguments to find the amount
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 05/16] make write() operation smp aware

2008-01-07 Thread Glauber de Oliveira Costa
This patch makes the write() file operation smp aware. Which means, receiving
the vcpu_id value through the offset parameter, and being well aware to which
vcpu we're talking to.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/lguest_user.c |   11 +--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 216514b..d176004 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -230,14 +230,21 @@ static ssize_t write(struct file *file, const char __user 
*in,
struct lguest *lg = file->private_data;
const unsigned long __user *input = (const unsigned long __user *)in;
unsigned long req;
+   struct lg_vcpu *vcpu = NULL;
+   int vcpu_id = *off;
 
if (get_user(req, input) != 0)
return -EFAULT;
input++;
 
/* If you haven't initialized, you must do that first. */
-   if (req != LHREQ_INITIALIZE && !lg)
-   return -EINVAL;
+   if (req != LHREQ_INITIALIZE) {
+   if (!lg || (vcpu_id > lg->nr_vcpus))
+   return -EINVAL;
+   vcpu = >vcpus[vcpu_id];
+   if (!vcpu)
+   return -EINVAL;
+   }
 
/* Once the Guest is dead, all you can do is read() why it died. */
if (lg && lg->dead)
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/16] initialize vcpu

2008-01-07 Thread Glauber de Oliveira Costa
this patch initializes the first vcpu in the initialize() routing,
which is responsible for starting the process of putting the guest up.
right now, as much of the fields are still not per-vcpu, it does not
do much.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/lguest_user.c |   20 
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 3b92a61..34be8e7 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -88,6 +88,20 @@ static ssize_t read(struct file *file, char __user *user, 
size_t size,loff_t*o)
return run_guest(lg, (unsigned long __user *)user);
 }
 
+static int vcpu_start(struct lg_vcpu *vcpu, int vcpu_id,
+ unsigned long start_ip)
+{
+   if (vcpu_id > NR_CPUS)
+   return -EINVAL;
+
+   vcpu->vcpu_id = vcpu_id;
+
+   vcpu->lg = container_of((vcpu - vcpu_id), struct lguest, vcpus[0]);
+   vcpu->lg->nr_vcpus++;
+
+   return 0;
+}
+
 /*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit)
  * values (in addition to the LHREQ_INITIALIZE value).  These are:
  *
@@ -134,6 +148,12 @@ static int initialize(struct file *file, const unsigned 
long __user *input)
lg->mem_base = (void __user *)(long)args[0];
lg->pfn_limit = args[1];
 
+   /* This is the first cpu */
+   lg->nr_vcpus = 0;
+   err = vcpu_start(>vcpus[0], 0, args[3]);
+   if (err)
+   goto release_guest;
+
/* We need a complete page for the Guest registers: they are accessible
 * to the Guest and we can only grant it access to whole pages. */
lg->regs_page = get_zeroed_page(GFP_KERNEL);
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 04/16] per-cpu run guest

2008-01-07 Thread Glauber de Oliveira Costa
This patch makes the run_guest() routine use the vcpu struct.
This is required since in a smp guest environment, there's no
more the notion of "running the guest", but rather, it is "running the vcpu"

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/core.c|6 --
 drivers/lguest/lg.h  |4 ++--
 drivers/lguest/lguest_user.c |   10 +-
 drivers/lguest/x86/core.c|   16 +++-
 4 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index cb4c670..07a4c22 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -174,8 +174,10 @@ void __lgwrite(struct lguest *lg, unsigned long addr, 
const void *b,
 /*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
  * going around and around until something interesting happens. */
-int run_guest(struct lguest *lg, unsigned long __user *user)
+int run_guest(struct lg_vcpu *vcpu, unsigned long __user *user)
 {
+   struct lguest *lg = vcpu->lg;
+
/* We stop running once the Guest is dead. */
while (!lg->dead) {
/* First we run any hypercalls the Guest wants done. */
@@ -226,7 +228,7 @@ int run_guest(struct lguest *lg, unsigned long __user *user)
local_irq_disable();
 
/* Actually run the Guest until something happens. */
-   lguest_arch_run_guest(lg);
+   lguest_arch_run_guest(vcpu);
 
/* Now we're ready to be interrupted or moved to other CPUs */
local_irq_enable();
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 8fc1c29..271d214 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -126,7 +126,7 @@ void __lgwrite(struct lguest *, unsigned long, const void 
*, unsigned);
} while(0)
 /* (end of memory access helper routines) :*/
 
-int run_guest(struct lguest *lg, unsigned long __user *user);
+int run_guest(struct lg_vcpu *vcpu, unsigned long __user *user);
 
 /* Helper macros to obtain the first 12 or the last 20 bits, this is only the
  * first step in the migration to the kernel types.  pte_pfn is already defined
@@ -177,7 +177,7 @@ void page_table_guest_data_init(struct lguest *lg);
 /* /core.c: */
 void lguest_arch_host_init(void);
 void lguest_arch_host_fini(void);
-void lguest_arch_run_guest(struct lguest *lg);
+void lguest_arch_run_guest(struct lg_vcpu *vcpu);
 void lguest_arch_handle_trap(struct lguest *lg);
 int lguest_arch_init_hypercalls(struct lguest *lg);
 int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 34be8e7..216514b 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -55,11 +55,19 @@ static int user_send_irq(struct lguest *lg, const unsigned 
long __user *input)
 static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
 {
struct lguest *lg = file->private_data;
+   struct lg_vcpu *vcpu = NULL;
+   unsigned int vcpu_id = *o;
 
/* You must write LHREQ_INITIALIZE first! */
if (!lg)
return -EINVAL;
 
+   /* Watch out for arbitrary vcpu indexes! */
+   if (vcpu_id > lg->nr_vcpus)
+   return -EINVAL;
+
+   vcpu = >vcpus[vcpu_id];
+
/* If you're not the task which owns the Guest, go away. */
if (current != lg->tsk)
return -EPERM;
@@ -85,7 +93,7 @@ static ssize_t read(struct file *file, char __user *user, 
size_t size,loff_t*o)
lg->pending_notify = 0;
 
/* Run the Guest until something interesting happens. */
-   return run_guest(lg, (unsigned long __user *)user);
+   return run_guest(vcpu, (unsigned long __user *)user);
 }
 
 static int vcpu_start(struct lg_vcpu *vcpu, int vcpu_id,
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 482aec2..3496cd9 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -73,8 +73,10 @@ static DEFINE_PER_CPU(struct lguest *, last_guest);
  * since it last ran.  We saw this set in interrupts_and_traps.c and
  * segments.c.
  */
-static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages)
+static void copy_in_guest_info(struct lg_vcpu *vcpu,
+  struct lguest_pages *pages)
 {
+   struct lguest *lg = vcpu->lg;
/* Copying all this data can be quite expensive.  We usually run the
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
@@ -113,14 +115,16 @@ static void copy_in_guest_info(struct lguest *lg, struct 
lguest_pages *pages)
 }
 
 /* Finally: the code to actually call into the Switcher to run the Guest. */

[PATCH 0/16 -v2] lguest smp infrastructure

2008-01-07 Thread Glauber de Oliveira Costa
Folks,

This new series is not at all fundamentally different from the old one
I sent. Only difference is that I address the comments received, mainly
from Rusty.

enjoy!


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 01/16] introduce vcpu struct

2008-01-07 Thread Glauber de Oliveira Costa
this patch introduces a vcpu struct for lguest. In upcoming patches,
more and more fields will be moved from the lguest struct to the vcpu

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/lg.h |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 8692489..8fc1c29 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -38,6 +38,13 @@ struct lguest_pages
 #define CHANGED_GDT_TLS4 /* Actually a subset of CHANGED_GDT */
 #define CHANGED_ALL3
 
+struct lguest;
+
+struct lg_vcpu {
+   int vcpu_id;
+   struct lguest *lg;
+};
+
 /* The private info the thread maintains about the guest. */
 struct lguest
 {
@@ -47,6 +54,9 @@ struct lguest
struct lguest_data __user *lguest_data;
struct task_struct *tsk;
struct mm_struct *mm;   /* == tsk->mm, but that becomes NULL on exit */
+   struct lg_vcpu vcpus[NR_CPUS];
+   unsigned int nr_vcpus;
+
u32 pfn_limit;
/* This provides the offset to the base of guest-physical
 * memory in the Launcher. */
-- 
1.5.0.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/16 -v2] lguest smp infrastructure

2008-01-07 Thread Glauber de Oliveira Costa
Folks,

This new series is not at all fundamentally different from the old one
I sent. Only difference is that I address the comments received, mainly
from Rusty.

enjoy!


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 01/16] introduce vcpu struct

2008-01-07 Thread Glauber de Oliveira Costa
this patch introduces a vcpu struct for lguest. In upcoming patches,
more and more fields will be moved from the lguest struct to the vcpu

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/lg.h |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 8692489..8fc1c29 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -38,6 +38,13 @@ struct lguest_pages
 #define CHANGED_GDT_TLS4 /* Actually a subset of CHANGED_GDT */
 #define CHANGED_ALL3
 
+struct lguest;
+
+struct lg_vcpu {
+   int vcpu_id;
+   struct lguest *lg;
+};
+
 /* The private info the thread maintains about the guest. */
 struct lguest
 {
@@ -47,6 +54,9 @@ struct lguest
struct lguest_data __user *lguest_data;
struct task_struct *tsk;
struct mm_struct *mm;   /* == tsk-mm, but that becomes NULL on exit */
+   struct lg_vcpu vcpus[NR_CPUS];
+   unsigned int nr_vcpus;
+
u32 pfn_limit;
/* This provides the offset to the base of guest-physical
 * memory in the Launcher. */
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/16] initialize vcpu

2008-01-07 Thread Glauber de Oliveira Costa
this patch initializes the first vcpu in the initialize() routing,
which is responsible for starting the process of putting the guest up.
right now, as much of the fields are still not per-vcpu, it does not
do much.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/lguest_user.c |   20 
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 3b92a61..34be8e7 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -88,6 +88,20 @@ static ssize_t read(struct file *file, char __user *user, 
size_t size,loff_t*o)
return run_guest(lg, (unsigned long __user *)user);
 }
 
+static int vcpu_start(struct lg_vcpu *vcpu, int vcpu_id,
+ unsigned long start_ip)
+{
+   if (vcpu_id  NR_CPUS)
+   return -EINVAL;
+
+   vcpu-vcpu_id = vcpu_id;
+
+   vcpu-lg = container_of((vcpu - vcpu_id), struct lguest, vcpus[0]);
+   vcpu-lg-nr_vcpus++;
+
+   return 0;
+}
+
 /*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit)
  * values (in addition to the LHREQ_INITIALIZE value).  These are:
  *
@@ -134,6 +148,12 @@ static int initialize(struct file *file, const unsigned 
long __user *input)
lg-mem_base = (void __user *)(long)args[0];
lg-pfn_limit = args[1];
 
+   /* This is the first cpu */
+   lg-nr_vcpus = 0;
+   err = vcpu_start(lg-vcpus[0], 0, args[3]);
+   if (err)
+   goto release_guest;
+
/* We need a complete page for the Guest registers: they are accessible
 * to the Guest and we can only grant it access to whole pages. */
lg-regs_page = get_zeroed_page(GFP_KERNEL);
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 04/16] per-cpu run guest

2008-01-07 Thread Glauber de Oliveira Costa
This patch makes the run_guest() routine use the vcpu struct.
This is required since in a smp guest environment, there's no
more the notion of running the guest, but rather, it is running the vcpu

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/core.c|6 --
 drivers/lguest/lg.h  |4 ++--
 drivers/lguest/lguest_user.c |   10 +-
 drivers/lguest/x86/core.c|   16 +++-
 4 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index cb4c670..07a4c22 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -174,8 +174,10 @@ void __lgwrite(struct lguest *lg, unsigned long addr, 
const void *b,
 /*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
  * going around and around until something interesting happens. */
-int run_guest(struct lguest *lg, unsigned long __user *user)
+int run_guest(struct lg_vcpu *vcpu, unsigned long __user *user)
 {
+   struct lguest *lg = vcpu-lg;
+
/* We stop running once the Guest is dead. */
while (!lg-dead) {
/* First we run any hypercalls the Guest wants done. */
@@ -226,7 +228,7 @@ int run_guest(struct lguest *lg, unsigned long __user *user)
local_irq_disable();
 
/* Actually run the Guest until something happens. */
-   lguest_arch_run_guest(lg);
+   lguest_arch_run_guest(vcpu);
 
/* Now we're ready to be interrupted or moved to other CPUs */
local_irq_enable();
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 8fc1c29..271d214 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -126,7 +126,7 @@ void __lgwrite(struct lguest *, unsigned long, const void 
*, unsigned);
} while(0)
 /* (end of memory access helper routines) :*/
 
-int run_guest(struct lguest *lg, unsigned long __user *user);
+int run_guest(struct lg_vcpu *vcpu, unsigned long __user *user);
 
 /* Helper macros to obtain the first 12 or the last 20 bits, this is only the
  * first step in the migration to the kernel types.  pte_pfn is already defined
@@ -177,7 +177,7 @@ void page_table_guest_data_init(struct lguest *lg);
 /* arch/core.c: */
 void lguest_arch_host_init(void);
 void lguest_arch_host_fini(void);
-void lguest_arch_run_guest(struct lguest *lg);
+void lguest_arch_run_guest(struct lg_vcpu *vcpu);
 void lguest_arch_handle_trap(struct lguest *lg);
 int lguest_arch_init_hypercalls(struct lguest *lg);
 int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 34be8e7..216514b 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -55,11 +55,19 @@ static int user_send_irq(struct lguest *lg, const unsigned 
long __user *input)
 static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
 {
struct lguest *lg = file-private_data;
+   struct lg_vcpu *vcpu = NULL;
+   unsigned int vcpu_id = *o;
 
/* You must write LHREQ_INITIALIZE first! */
if (!lg)
return -EINVAL;
 
+   /* Watch out for arbitrary vcpu indexes! */
+   if (vcpu_id  lg-nr_vcpus)
+   return -EINVAL;
+
+   vcpu = lg-vcpus[vcpu_id];
+
/* If you're not the task which owns the Guest, go away. */
if (current != lg-tsk)
return -EPERM;
@@ -85,7 +93,7 @@ static ssize_t read(struct file *file, char __user *user, 
size_t size,loff_t*o)
lg-pending_notify = 0;
 
/* Run the Guest until something interesting happens. */
-   return run_guest(lg, (unsigned long __user *)user);
+   return run_guest(vcpu, (unsigned long __user *)user);
 }
 
 static int vcpu_start(struct lg_vcpu *vcpu, int vcpu_id,
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 482aec2..3496cd9 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -73,8 +73,10 @@ static DEFINE_PER_CPU(struct lguest *, last_guest);
  * since it last ran.  We saw this set in interrupts_and_traps.c and
  * segments.c.
  */
-static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages)
+static void copy_in_guest_info(struct lg_vcpu *vcpu,
+  struct lguest_pages *pages)
 {
+   struct lguest *lg = vcpu-lg;
/* Copying all this data can be quite expensive.  We usually run the
 * same Guest we ran last time (and that Guest hasn't run anywhere else
 * meanwhile).  If that's not the case, we pretend everything in the
@@ -113,14 +115,16 @@ static void copy_in_guest_info(struct lguest *lg, struct 
lguest_pages *pages)
 }
 
 /* Finally: the code to actually call into the Switcher to run the Guest. */
-static void run_guest_once(struct lguest *lg, struct lguest_pages

[PATCH 02/16] adapt lguest launcher to per-cpuness

2008-01-07 Thread Glauber de Oliveira Costa
This patch makes uses of pread() and pwrite() in lguest launcher
to communicate the vcpu id to the lguest driver. The id is kept in
a thread variable, which means we'll span in the future, vcpus as
threads. But right now, only the infrastructure is out there.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 Documentation/lguest/lguest.c |   23 ---
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 9b0e322..4745f7e 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -79,6 +79,9 @@ static void *guest_base;
 /* The maximum guest physical address allowed, and maximum possible. */
 static unsigned long guest_limit, guest_max;
 
+/* a per-cpu variable indicating whose vcpu is currently running */
+static unsigned int __thread vcpu_id;
+
 /* This is our list of devices. */
 struct device_list
 {
@@ -554,7 +557,7 @@ static void wake_parent(int pipefd, int lguest_fd)
else
FD_CLR(-fd - 1, devices.infds);
} else /* Send LHREQ_BREAK command. */
-   write(lguest_fd, args, sizeof(args));
+   pwrite(lguest_fd, args, sizeof(args), 0);
}
 }
 
@@ -1511,7 +1514,8 @@ static void __attribute__((noreturn)) run_guest(int 
lguest_fd)
int readval;
 
/* We read from the /dev/lguest device to run the Guest. */
-   readval = read(lguest_fd, notify_addr, sizeof(notify_addr));
+   readval = pread(lguest_fd, notify_addr,
+   sizeof(notify_addr), vcpu_id);
 
/* One unsigned long means the Guest did HCALL_NOTIFY */
if (readval == sizeof(notify_addr)) {
@@ -1521,17 +1525,21 @@ static void __attribute__((noreturn)) run_guest(int 
lguest_fd)
/* ENOENT means the Guest died.  Reading tells us why. */
} else if (errno == ENOENT) {
char reason[1024] = { 0 };
-   read(lguest_fd, reason, sizeof(reason)-1);
+   pread(lguest_fd, reason, sizeof(reason)-1, vcpu_id);
errx(1, %s, reason);
/* EAGAIN means the Waker wanted us to look at some input.
 * Anything else means a bug or incompatible change. */
} else if (errno != EAGAIN)
err(1, Running guest failed);
 
-   /* Service input, then unset the BREAK to release the Waker. */
-   handle_input(lguest_fd);
-   if (write(lguest_fd, args, sizeof(args))  0)
-   err(1, Resetting break);
+   if (!vcpu_id) {
+   /* Service input, then unset the BREAK to
+* release the Waker. Right now, simple mecahnism
+* to issue it all to first vcpu */
+   handle_input(lguest_fd);
+   if (pwrite(lguest_fd, args, sizeof(args), 0)  0)
+   err(1, Resetting break);
+   }
}
 }
 /*
@@ -1582,6 +1590,7 @@ int main(int argc, char *argv[])
devices.lastdev = devices.dev;
devices.next_irq = 1;
 
+   vcpu_id = 0;
/* We need to know how much memory so we can set up the device
 * descriptor and memory pages for the devices as we parse the command
 * line.  So we quickly look through the arguments to find the amount
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 05/16] make write() operation smp aware

2008-01-07 Thread Glauber de Oliveira Costa
This patch makes the write() file operation smp aware. Which means, receiving
the vcpu_id value through the offset parameter, and being well aware to which
vcpu we're talking to.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/lguest_user.c |   11 +--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 216514b..d176004 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -230,14 +230,21 @@ static ssize_t write(struct file *file, const char __user 
*in,
struct lguest *lg = file-private_data;
const unsigned long __user *input = (const unsigned long __user *)in;
unsigned long req;
+   struct lg_vcpu *vcpu = NULL;
+   int vcpu_id = *off;
 
if (get_user(req, input) != 0)
return -EFAULT;
input++;
 
/* If you haven't initialized, you must do that first. */
-   if (req != LHREQ_INITIALIZE  !lg)
-   return -EINVAL;
+   if (req != LHREQ_INITIALIZE) {
+   if (!lg || (vcpu_id  lg-nr_vcpus))
+   return -EINVAL;
+   vcpu = lg-vcpus[vcpu_id];
+   if (!vcpu)
+   return -EINVAL;
+   }
 
/* Once the Guest is dead, all you can do is read() why it died. */
if (lg  lg-dead)
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 07/16] per-vcpu lguest timers

2008-01-07 Thread Glauber de Oliveira Costa
Here, I introduce per-vcpu timers. With this, we can have
local expiries, needed for accounting time in smp guests

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |   20 ++--
 drivers/lguest/lg.h   |   10 +-
 drivers/lguest/lguest_user.c  |   12 +++-
 4 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 9417601..1bf133e 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -78,7 +78,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
guest_set_pmd(lg, args-arg1, args-arg2);
break;
case LHCALL_SET_CLOCKEVENT:
-   guest_set_clockevent(lg, args-arg1);
+   guest_set_clockevent(vcpu, args-arg1);
break;
case LHCALL_TS:
/* This sets the TS flag, as we saw used in run_guest(). */
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 2b66f79..3be18a6 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -470,13 +470,13 @@ void copy_traps(const struct lguest *lg, struct 
desc_struct *idt,
  * infrastructure to set a callback at that time.
  *
  * 0 means turn off the clock. */
-void guest_set_clockevent(struct lguest *lg, unsigned long delta)
+void guest_set_clockevent(struct lg_vcpu *vcpu, unsigned long delta)
 {
ktime_t expires;
 
if (unlikely(delta == 0)) {
/* Clock event device is shutting down. */
-   hrtimer_cancel(lg-hrt);
+   hrtimer_cancel(vcpu-hrt);
return;
}
 
@@ -484,25 +484,25 @@ void guest_set_clockevent(struct lguest *lg, unsigned 
long delta)
 * all the time between now and the timer interrupt it asked for.  This
 * is almost always the right thing to do. */
expires = ktime_add_ns(ktime_get_real(), delta);
-   hrtimer_start(lg-hrt, expires, HRTIMER_MODE_ABS);
+   hrtimer_start(vcpu-hrt, expires, HRTIMER_MODE_ABS);
 }
 
 /* This is the function called when the Guest's timer expires. */
 static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
 {
-   struct lguest *lg = container_of(timer, struct lguest, hrt);
+   struct lg_vcpu *vcpu = container_of(timer, struct lg_vcpu, hrt);
 
/* Remember the first interrupt is the timer interrupt. */
-   set_bit(0, lg-irqs_pending);
+   set_bit(0, vcpu-lg-irqs_pending);
/* If the Guest is actually stopped, we need to wake it up. */
-   if (lg-halted)
-   wake_up_process(lg-tsk);
+   if (vcpu-lg-halted)
+   wake_up_process(vcpu-lg-tsk);
return HRTIMER_NORESTART;
 }
 
 /* This sets up the timer for this Guest. */
-void init_clockdev(struct lguest *lg)
+void init_clockdev(struct lg_vcpu *vcpu)
 {
-   hrtimer_init(lg-hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
-   lg-hrt.function = clockdev_fn;
+   hrtimer_init(vcpu-hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+   vcpu-hrt.function = clockdev_fn;
 }
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 13a991a..9c90fd3 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -47,6 +47,9 @@ struct lg_vcpu {
/* If a hypercall was asked for, this points to the arguments. */
struct hcall_args *hcall;
u32 next_hcall;
+
+   /* Virtual clock device */
+   struct hrtimer hrt;
 };
 
 /* The private info the thread maintains about the guest. */
@@ -95,9 +98,6 @@ struct lguest
 
struct lguest_arch arch;
 
-   /* Virtual clock device */
-   struct hrtimer hrt;
-
/* Pending virtual interrupts */
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
@@ -145,8 +145,8 @@ void setup_default_idt_entries(struct lguest_ro_state 
*state,
   const unsigned long *def);
 void copy_traps(const struct lguest *lg, struct desc_struct *idt,
const unsigned long *def);
-void guest_set_clockevent(struct lguest *lg, unsigned long delta);
-void init_clockdev(struct lguest *lg);
+void guest_set_clockevent(struct lg_vcpu *vcpu, unsigned long delta);
+void init_clockdev(struct lg_vcpu *vcpu);
 bool check_syscall_vector(struct lguest *lg);
 int init_interrupts(void);
 void free_interrupts(void);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index d176004..cd2b0bf 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -104,6 +104,9 @@ static int vcpu_start(struct lg_vcpu *vcpu, int vcpu_id,
 
vcpu-vcpu_id = vcpu_id;
 
+   /* The timer for lguest's clock needs initialization. */
+   init_clockdev(vcpu);
+
vcpu-lg = container_of((vcpu - vcpu_id), struct lguest, vcpus[0]);
vcpu-lg-nr_vcpus++;
 
@@ -183,9

[PATCH 06/16] make hypercalls use the vcpu struct

2008-01-07 Thread Glauber de Oliveira Costa
this patch changes do_hcall() and do_async_hcall() interfaces (and obviously 
their
callers) to get a vcpu struct. Again, a vcpu services the hypercall, not the 
whole
guest

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/core.c   |6 +++---
 drivers/lguest/hypercalls.c |   42 +++---
 drivers/lguest/lg.h |   16 
 drivers/lguest/x86/core.c   |   16 ++--
 4 files changed, 44 insertions(+), 36 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 07a4c22..99f65f9 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -181,8 +181,8 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
/* We stop running once the Guest is dead. */
while (!lg-dead) {
/* First we run any hypercalls the Guest wants done. */
-   if (lg-hcall)
-   do_hypercalls(lg);
+   if (vcpu-hcall)
+   do_hypercalls(vcpu);
 
/* It's possible the Guest did a NOTIFY hypercall to the
 * Launcher, in which case we return from the read() now. */
@@ -234,7 +234,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
local_irq_enable();
 
/* Now we deal with whatever happened to the Guest. */
-   lguest_arch_handle_trap(lg);
+   lguest_arch_handle_trap(vcpu);
}
 
/* The Guest is dead = No such file or directory */
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index b478aff..9417601 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -29,8 +29,10 @@
 
 /*H:120 This is the core hypercall routine: where the Guest gets what it wants.
  * Or gets killed.  Or, in the case of LHCALL_CRASH, both. */
-static void do_hcall(struct lguest *lg, struct hcall_args *args)
+static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args *args)
 {
+   struct lguest *lg = vcpu-lg;
+
switch (args-arg0) {
case LHCALL_FLUSH_ASYNC:
/* This call does nothing, except by breaking out of the Guest
@@ -91,7 +93,7 @@ static void do_hcall(struct lguest *lg, struct hcall_args 
*args)
break;
default:
/* It should be an architecture-specific hypercall. */
-   if (lguest_arch_do_hcall(lg, args))
+   if (lguest_arch_do_hcall(vcpu, args))
kill_guest(lg, Bad hypercall %li\n, args-arg0);
}
 }
@@ -104,10 +106,11 @@ static void do_hcall(struct lguest *lg, struct hcall_args 
*args)
  * Guest put them in the ring, but we also promise the Guest that they will
  * happen before any normal hypercall (which is why we check this before
  * checking for a normal hcall). */
-static void do_async_hcalls(struct lguest *lg)
+static void do_async_hcalls(struct lg_vcpu *vcpu)
 {
unsigned int i;
u8 st[LHCALL_RING_SIZE];
+   struct lguest *lg = vcpu-lg;
 
/* For simplicity, we copy the entire call status array in at once. */
if (copy_from_user(st, lg-lguest_data-hcall_status, sizeof(st)))
@@ -119,7 +122,7 @@ static void do_async_hcalls(struct lguest *lg)
/* We remember where we were up to from last time.  This makes
 * sure that the hypercalls are done in the order the Guest
 * places them in the ring. */
-   unsigned int n = lg-next_hcall;
+   unsigned int n = vcpu-next_hcall;
 
/* 0xFF means there's no call here (yet). */
if (st[n] == 0xFF)
@@ -127,8 +130,8 @@ static void do_async_hcalls(struct lguest *lg)
 
/* OK, we have hypercall.  Increment the next_hcall cursor,
 * and wrap back to 0 if we reach the end. */
-   if (++lg-next_hcall == LHCALL_RING_SIZE)
-   lg-next_hcall = 0;
+   if (++vcpu-next_hcall == LHCALL_RING_SIZE)
+   vcpu-next_hcall = 0;
 
/* Copy the hypercall arguments into a local copy of
 * the hcall_args struct. */
@@ -139,7 +142,7 @@ static void do_async_hcalls(struct lguest *lg)
}
 
/* Do the hypercall, same as a normal one. */
-   do_hcall(lg, args);
+   do_hcall(vcpu, args);
 
/* Mark the hypercall done. */
if (put_user(0xFF, lg-lguest_data-hcall_status[n])) {
@@ -156,16 +159,17 @@ static void do_async_hcalls(struct lguest *lg)
 
 /* Last of all, we look at what happens first of all.  The very first time the
  * Guest makes a hypercall, we end up here to set things up: */
-static void initialize(struct lguest *lg)
+static void initialize(struct lg_vcpu *vcpu)
 {
+   struct lguest *lg = vcpu-lg;
/* You can't do anything until you're initialized.  The Guest knows

[PATCH 08/16] per-vcpu interrupt processing.

2008-01-07 Thread Glauber de Oliveira Costa
This patch adapts interrupt processing for using the vcpu struct.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/core.c |2 +-
 drivers/lguest/interrupts_and_traps.c |   25 ++---
 drivers/lguest/lg.h   |   10 +-
 drivers/lguest/lguest_user.c  |7 ---
 drivers/lguest/x86/core.c |2 +-
 5 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 99f65f9..bc3b32d 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -203,7 +203,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
/* Check if there are any interrupts which can be delivered
 * now: if so, this sets up the hander to be executed when we
 * next run the Guest. */
-   maybe_do_interrupt(lg);
+   maybe_do_interrupt(vcpu);
 
/* All long-lived kernel loops need to check with this horrible
 * thing called the freezer.  If the Host is trying to suspend,
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 3be18a6..d28671b 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -60,11 +60,13 @@ static void push_guest_stack(struct lguest *lg, unsigned 
long *gstack, u32 val)
  * We set up the stack just like the CPU does for a real interrupt, so it's
  * identical for the Guest (and the standard iret instruction will undo
  * it). */
-static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
+static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, u32 hi,
+   int has_err)
 {
unsigned long gstack, origstack;
u32 eflags, ss, irq_enable;
unsigned long virtstack;
+   struct lguest *lg = vcpu-lg;
 
/* There are two cases for interrupts: one where the Guest is already
 * in the kernel, and a more complex one where the Guest is in
@@ -129,9 +131,10 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, 
u32 hi, int has_err)
  *
  * maybe_do_interrupt() gets called before every entry to the Guest, to see if
  * we should divert the Guest to running an interrupt handler. */
-void maybe_do_interrupt(struct lguest *lg)
+void maybe_do_interrupt(struct lg_vcpu *vcpu)
 {
unsigned int irq;
+   struct lguest *lg = vcpu-lg;
DECLARE_BITMAP(blk, LGUEST_IRQS);
struct desc_struct *idt;
 
@@ -145,7 +148,7 @@ void maybe_do_interrupt(struct lguest *lg)
   sizeof(blk)))
return;
 
-   bitmap_andnot(blk, lg-irqs_pending, blk, LGUEST_IRQS);
+   bitmap_andnot(blk, vcpu-irqs_pending, blk, LGUEST_IRQS);
 
/* Find the first interrupt. */
irq = find_first_bit(blk, LGUEST_IRQS);
@@ -180,11 +183,11 @@ void maybe_do_interrupt(struct lguest *lg)
/* If they don't have a handler (yet?), we just ignore it */
if (idt_present(idt-a, idt-b)) {
/* OK, mark it no longer pending and deliver it. */
-   clear_bit(irq, lg-irqs_pending);
+   clear_bit(irq, vcpu-irqs_pending);
/* set_guest_interrupt() takes the interrupt descriptor and a
 * flag to say whether this interrupt pushes an error code onto
 * the stack as well: virtual interrupts never do. */
-   set_guest_interrupt(lg, idt-a, idt-b, 0);
+   set_guest_interrupt(vcpu, idt-a, idt-b, 0);
}
 
/* Every time we deliver an interrupt, we update the timestamp in the
@@ -245,19 +248,19 @@ static int has_err(unsigned int trap)
 }
 
 /* deliver_trap() returns true if it could deliver the trap. */
-int deliver_trap(struct lguest *lg, unsigned int num)
+int deliver_trap(struct lg_vcpu *vcpu, unsigned int num)
 {
/* Trap numbers are always 8 bit, but we set an impossible trap number
 * for traps inside the Switcher, so check that here. */
-   if (num = ARRAY_SIZE(lg-arch.idt))
+   if (num = ARRAY_SIZE(vcpu-lg-arch.idt))
return 0;
 
/* Early on the Guest hasn't set the IDT entries (or maybe it put a
 * bogus one in): if we fail here, the Guest will be killed. */
-   if (!idt_present(lg-arch.idt[num].a, lg-arch.idt[num].b))
+   if (!idt_present(vcpu-lg-arch.idt[num].a, vcpu-lg-arch.idt[num].b))
return 0;
-   set_guest_interrupt(lg, lg-arch.idt[num].a, lg-arch.idt[num].b,
-   has_err(num));
+   set_guest_interrupt(vcpu, vcpu-lg-arch.idt[num].a,
+   vcpu-lg-arch.idt[num].b, has_err(num));
return 1;
 }
 
@@ -493,7 +496,7 @@ static enum hrtimer_restart clockdev_fn(struct hrtimer 
*timer)
struct lg_vcpu *vcpu = container_of(timer, struct lg_vcpu, hrt);
 
/* Remember the first

[PATCH 09/16] map_switcher_in_guest() per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
The switcher needs to be mapped per-vcpu, because different vcpus
will potentially have different page tables (they don't have to,
because threads will share the same).

So our first step is the make the function receive a vcpu struct

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/lg.h  |3 ++-
 drivers/lguest/page_tables.c |4 +++-
 drivers/lguest/x86/core.c|2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 6c794cd..f871737 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -168,7 +168,8 @@ void guest_pagetable_clear_all(struct lguest *lg);
 void guest_pagetable_flush_user(struct lguest *lg);
 void guest_set_pte(struct lguest *lg, unsigned long gpgdir,
   unsigned long vaddr, pte_t val);
-void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages);
+void map_switcher_in_guest(struct lg_vcpu *vcpu,
+  struct lguest_pages *pages);
 int demand_page(struct lguest *info, unsigned long cr2, int errcode);
 void pin_page(struct lguest *lg, unsigned long vaddr);
 unsigned long guest_pa(struct lguest *lg, unsigned long vaddr);
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index fffabb3..c79fac2 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -634,8 +634,10 @@ void free_guest_pagetable(struct lguest *lg)
  * Guest (and not the pages for other CPUs).  We have the appropriate PTE pages
  * for each CPU already set up, we just need to hook them in now we know which
  * Guest is about to run on this CPU. */
-void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages)
+void map_switcher_in_guest(struct lg_vcpu *vcpu,
+  struct lguest_pages *pages)
 {
+   struct lguest *lg = vcpu-lg;
pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
pgd_t switcher_pgd;
pte_t regs_pte;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 8fbb373..125a14b 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -92,7 +92,7 @@ static void copy_in_guest_info(struct lg_vcpu *vcpu,
pages-state.host_cr3 = __pa(current-mm-pgd);
/* Set up the Guest's page tables to see this CPU's pages (and no
 * other CPU's pages). */
-   map_switcher_in_guest(lg, pages);
+   map_switcher_in_guest(vcpu, pages);
/* Set up the two TSS members which tell the CPU what stack to use
 * for traps which do directly into the Guest (ie. traps at privilege
 * level 1). */
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/16] make emulate_insn receive a vcpu struct.

2008-01-07 Thread Glauber de Oliveira Costa
emulate_insn() needs to know about current eip, which will be,
in the future, a per-vcpu thing. So in this patch, the function
prototype is modified to receive a vcpu struct

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/x86/core.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 125a14b..b336fff 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -220,8 +220,9 @@ void lguest_arch_run_guest(struct lg_vcpu *vcpu)
  * When the Guest uses one of these instructions, we get a trap (General
  * Protection Fault) and come here.  We see if it's one of those troublesome
  * instructions and skip over it.  We return true if we did. */
-static int emulate_insn(struct lguest *lg)
+static int emulate_insn(struct lg_vcpu *vcpu)
 {
+   struct lguest *lg = vcpu-lg;
u8 insn;
unsigned int insnlen = 0, in = 0, shift = 0;
/* The eip contains the *virtual* address of the Guest's instruction:
@@ -294,7 +295,7 @@ void lguest_arch_handle_trap(struct lg_vcpu *vcpu)
 * instructions which we need to emulate.  If so, we just go
 * back into the Guest after we've done it. */
if (lg-regs-errcode == 0) {
-   if (emulate_insn(lg))
+   if (emulate_insn(vcpu))
return;
}
break;
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 12/16] replace lguest_arch with lg_vcpu_arch.

2008-01-07 Thread Glauber de Oliveira Costa
The fields found in lguest_arch are not really per-guest,
but per-cpu (gdt, idt, etc). So this patch turns lguest_arch
into lg_vcpu_arch.

It makes sense to have a per-guest per-arch struct, but this
can be addressed later, when the need arrives.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/interrupts_and_traps.c |   29 +++--
 drivers/lguest/lg.h   |   19 +++---
 drivers/lguest/segments.c |   43 +---
 drivers/lguest/x86/core.c |   24 --
 include/asm-x86/lguest.h  |2 +-
 5 files changed, 60 insertions(+), 57 deletions(-)

diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 4cc7404..f8f7efe 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -180,7 +180,7 @@ void maybe_do_interrupt(struct lg_vcpu *vcpu)
/* Look at the IDT entry the Guest gave us for this interrupt.  The
 * first 32 (FIRST_EXTERNAL_VECTOR) entries are for traps, so we skip
 * over them. */
-   idt = lg-arch.idt[FIRST_EXTERNAL_VECTOR+irq];
+   idt = vcpu-arch.idt[FIRST_EXTERNAL_VECTOR+irq];
/* If they don't have a handler (yet?), we just ignore it */
if (idt_present(idt-a, idt-b)) {
/* OK, mark it no longer pending and deliver it. */
@@ -253,15 +253,15 @@ int deliver_trap(struct lg_vcpu *vcpu, unsigned int num)
 {
/* Trap numbers are always 8 bit, but we set an impossible trap number
 * for traps inside the Switcher, so check that here. */
-   if (num = ARRAY_SIZE(vcpu-lg-arch.idt))
+   if (num = ARRAY_SIZE(vcpu-arch.idt))
return 0;
 
/* Early on the Guest hasn't set the IDT entries (or maybe it put a
 * bogus one in): if we fail here, the Guest will be killed. */
-   if (!idt_present(vcpu-lg-arch.idt[num].a, vcpu-lg-arch.idt[num].b))
+   if (!idt_present(vcpu-arch.idt[num].a, vcpu-arch.idt[num].b))
return 0;
-   set_guest_interrupt(vcpu, vcpu-lg-arch.idt[num].a,
-   vcpu-lg-arch.idt[num].b, has_err(num));
+   set_guest_interrupt(vcpu, vcpu-arch.idt[num].a,
+   vcpu-arch.idt[num].b, has_err(num));
return 1;
 }
 
@@ -387,7 +387,8 @@ static void set_trap(struct lguest *lg, struct desc_struct 
*trap,
  *
  * We saw the Guest setting Interrupt Descriptor Table (IDT) entries with the
  * LHCALL_LOAD_IDT_ENTRY hypercall before: that comes here. */
-void load_guest_idt_entry(struct lguest *lg, unsigned int num, u32 lo, u32 hi)
+void load_guest_idt_entry(struct lg_vcpu *vcpu,
+ unsigned int num, u32 lo, u32 hi)
 {
/* Guest never handles: NMI, doublefault, spurious interrupt or
 * hypercall.  We ignore when it tries to set them. */
@@ -396,13 +397,13 @@ void load_guest_idt_entry(struct lguest *lg, unsigned int 
num, u32 lo, u32 hi)
 
/* Mark the IDT as changed: next time the Guest runs we'll know we have
 * to copy this again. */
-   lg-changed |= CHANGED_IDT;
+   vcpu-lg-changed |= CHANGED_IDT;
 
/* Check that the Guest doesn't try to step outside the bounds. */
-   if (num = ARRAY_SIZE(lg-arch.idt))
-   kill_guest(lg, Setting idt entry %u, num);
+   if (num = ARRAY_SIZE(vcpu-arch.idt))
+   kill_guest(vcpu-lg, Setting idt entry %u, num);
else
-   set_trap(lg, lg-arch.idt[num], num, lo, hi);
+   set_trap(vcpu-lg, vcpu-arch.idt[num], num, lo, hi);
 }
 
 /* The default entry for each interrupt points into the Switcher routines which
@@ -438,14 +439,14 @@ void setup_default_idt_entries(struct lguest_ro_state 
*state,
 /*H:240 We don't use the IDT entries in the struct lguest directly, instead
  * we copy them into the IDT which we've set up for Guests on this CPU, just
  * before we run the Guest.  This routine does that copy. */
-void copy_traps(const struct lguest *lg, struct desc_struct *idt,
+void copy_traps(const struct lg_vcpu *vcpu, struct desc_struct *idt,
const unsigned long *def)
 {
unsigned int i;
 
/* We can simply copy the direct traps, otherwise we use the default
 * ones in the Switcher: they will return to the Host. */
-   for (i = 0; i  ARRAY_SIZE(lg-arch.idt); i++) {
+   for (i = 0; i  ARRAY_SIZE(vcpu-arch.idt); i++) {
/* If no Guest can ever override this trap, leave it alone. */
if (!direct_trap(i))
continue;
@@ -454,8 +455,8 @@ void copy_traps(const struct lguest *lg, struct desc_struct 
*idt,
 * Interrupt gates (type 14) disable interrupts as they are
 * entered, which we never let the Guest do.  Not present
 * entries (type 0x0) also can't go direct, of course. */
-   if (idt_type(lg

[PATCH 11/16] make registers per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
This is the most obvious per-vcpu field: registers.

So this patch moves it from struct lguest to struct vcpu,
and patch the places in which they are used, accordingly

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/interrupts_and_traps.c |   29 ---
 drivers/lguest/lg.h   |9 ---
 drivers/lguest/lguest_user.c  |   36 +++---
 drivers/lguest/page_tables.c  |4 ++-
 drivers/lguest/x86/core.c |   39 +
 5 files changed, 61 insertions(+), 56 deletions(-)

diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index d28671b..4cc7404 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -71,7 +71,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
/* There are two cases for interrupts: one where the Guest is already
 * in the kernel, and a more complex one where the Guest is in
 * userspace.  We check the privilege level to find out. */
-   if ((lg-regs-ss0x3) != GUEST_PL) {
+   if ((vcpu-regs-ss0x3) != GUEST_PL) {
/* The Guest told us their kernel stack with the SET_STACK
 * hypercall: both the virtual address and the segment */
virtstack = lg-esp1;
@@ -82,12 +82,12 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 
lo, u32 hi,
 * stack: when the Guest does an iret back from the interrupt
 * handler the CPU will notice they're dropping privilege
 * levels and expect these here. */
-   push_guest_stack(lg, gstack, lg-regs-ss);
-   push_guest_stack(lg, gstack, lg-regs-esp);
+   push_guest_stack(lg, gstack, vcpu-regs-ss);
+   push_guest_stack(lg, gstack, vcpu-regs-esp);
} else {
/* We're staying on the same Guest (kernel) stack. */
-   virtstack = lg-regs-esp;
-   ss = lg-regs-ss;
+   virtstack = vcpu-regs-esp;
+   ss = vcpu-regs-ss;
 
origstack = gstack = guest_pa(lg, virtstack);
}
@@ -96,7 +96,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
 * the Interrupt Flag bit is always set.  We copy that bit from the
 * Guest's irq_enabled field into the eflags word: we saw the Guest
 * copy it back in lguest_iret. */
-   eflags = lg-regs-eflags;
+   eflags = vcpu-regs-eflags;
if (get_user(irq_enable, lg-lguest_data-irq_enabled) == 0
 !(irq_enable  X86_EFLAGS_IF))
eflags = ~X86_EFLAGS_IF;
@@ -105,19 +105,19 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 
lo, u32 hi,
 * eflags word, the old code segment, and the old instruction
 * pointer. */
push_guest_stack(lg, gstack, eflags);
-   push_guest_stack(lg, gstack, lg-regs-cs);
-   push_guest_stack(lg, gstack, lg-regs-eip);
+   push_guest_stack(lg, gstack, vcpu-regs-cs);
+   push_guest_stack(lg, gstack, vcpu-regs-eip);
 
/* For the six traps which supply an error code, we push that, too. */
if (has_err)
-   push_guest_stack(lg, gstack, lg-regs-errcode);
+   push_guest_stack(lg, gstack, vcpu-regs-errcode);
 
/* Now we've pushed all the old state, we change the stack, the code
 * segment and the address to execute. */
-   lg-regs-ss = ss;
-   lg-regs-esp = virtstack + (gstack - origstack);
-   lg-regs-cs = (__KERNEL_CS|GUEST_PL);
-   lg-regs-eip = idt_address(lo, hi);
+   vcpu-regs-ss = ss;
+   vcpu-regs-esp = virtstack + (gstack - origstack);
+   vcpu-regs-cs = (__KERNEL_CS|GUEST_PL);
+   vcpu-regs-eip = idt_address(lo, hi);
 
/* There are two kinds of interrupt handlers: 0xE is an interrupt
 * gate which expects interrupts to be disabled on entry. */
@@ -158,7 +158,8 @@ void maybe_do_interrupt(struct lg_vcpu *vcpu)
 
/* They may be in the middle of an iret, where they asked us never to
 * deliver interrupts. */
-   if (lg-regs-eip = lg-noirq_start  lg-regs-eip  lg-noirq_end)
+   if ((vcpu-regs-eip = lg-noirq_start) 
+   (vcpu-regs-eip  lg-noirq_end))
return;
 
/* If they're halted, interrupts restart them. */
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index f871737..d8429a0 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -44,6 +44,10 @@ struct lg_vcpu {
int vcpu_id;
struct lguest *lg;
 
+   /* At end of a page shared mapped over lguest_pages in guest.  */
+   unsigned long regs_page;
+   struct lguest_regs *regs;
+
/* If a hypercall was asked for, this points to the arguments. */
struct hcall_args *hcall;
u32 next_hcall;
@@ -58,9 +62,6 @@ struct lg_vcpu

[PATCH 13/16] per-vcpu lguest task management

2008-01-07 Thread Glauber de Oliveira Costa
lguest uses tasks to control its running behaviour (like sending
breaks, controlling halted state, etc). In a per-vcpu environment,
each vcpu will have its own underlying task. So this patch
makes the infrastructure for that possible

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/core.c |4 +-
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |8 ++--
 drivers/lguest/lg.h   |   14 
 drivers/lguest/lguest_user.c  |   55 ++---
 5 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index bc3b32d..847f2df 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -197,7 +197,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
return -ERESTARTSYS;
 
/* If Waker set break_out, return to Launcher. */
-   if (lg-break_out)
+   if (vcpu-break_out)
return -EAGAIN;
 
/* Check if there are any interrupts which can be delivered
@@ -217,7 +217,7 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
 
/* If the Guest asked to be stopped, we sleep.  The Guest's
 * clock timer or LHCALL_BREAK from the Waker will wake us. */
-   if (lg-halted) {
+   if (vcpu-halted) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
continue;
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 1bf133e..edc8cb4 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -86,7 +86,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
break;
case LHCALL_HALT:
/* Similarly, this sets the halted flag for run_guest(). */
-   lg-halted = 1;
+   vcpu-halted = 1;
break;
case LHCALL_NOTIFY:
lg-pending_notify = args-arg1;
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index f8f7efe..c1ca198 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -163,11 +163,11 @@ void maybe_do_interrupt(struct lg_vcpu *vcpu)
return;
 
/* If they're halted, interrupts restart them. */
-   if (lg-halted) {
+   if (vcpu-halted) {
/* Re-enable interrupts. */
if (put_user(X86_EFLAGS_IF, lg-lguest_data-irq_enabled))
kill_guest(lg, Re-enabling interrupts);
-   lg-halted = 0;
+   vcpu-halted = 0;
} else {
/* Otherwise we check if they have interrupts disabled. */
u32 irq_enabled;
@@ -500,8 +500,8 @@ static enum hrtimer_restart clockdev_fn(struct hrtimer 
*timer)
/* Remember the first interrupt is the timer interrupt. */
set_bit(0, vcpu-irqs_pending);
/* If the Guest is actually stopped, we need to wake it up. */
-   if (vcpu-lg-halted)
-   wake_up_process(vcpu-lg-tsk);
+   if (vcpu-halted)
+   wake_up_process(vcpu-tsk);
return HRTIMER_NORESTART;
 }
 
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 5165172..8c9c8df 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -43,6 +43,8 @@ struct lguest;
 struct lg_vcpu {
int vcpu_id;
struct lguest *lg;
+   struct task_struct *tsk;
+   struct mm_struct *mm;   /* == tsk-mm, but that becomes NULL on exit */
 
/* At end of a page shared mapped over lguest_pages in guest.  */
unsigned long regs_page;
@@ -55,6 +57,11 @@ struct lg_vcpu {
/* Virtual clock device */
struct hrtimer hrt;
 
+   /* Do we need to stop what we're doing and return to userspace? */
+   int break_out;
+   wait_queue_head_t break_wq;
+   int halted;
+
/* Pending virtual interrupts */
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 
@@ -65,8 +72,6 @@ struct lg_vcpu {
 struct lguest
 {
struct lguest_data __user *lguest_data;
-   struct task_struct *tsk;
-   struct mm_struct *mm;   /* == tsk-mm, but that becomes NULL on exit */
struct lg_vcpu vcpus[NR_CPUS];
unsigned int nr_vcpus;
 
@@ -76,15 +81,10 @@ struct lguest
void __user *mem_base;
unsigned long kernel_address;
u32 cr2;
-   int halted;
int ts;
u32 esp1;
u8 ss1;
 
-   /* Do we need to stop what we're doing and return to userspace? */
-   int break_out;
-   wait_queue_head_t break_wq;
-
/* Bitmap of what has changed: see CHANGED_* above. */
int changed;
struct lguest_pages *last_pages;
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c

[PATCH 14/16] makes special fields be per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
lguest struct have room for some fields, namely, cr2, ts, esp1
and ss1, that are not really guest-wide, but rather, vcpu-wide.

This patch puts it in the vcpu struct

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/hypercalls.c   |   10 +-
 drivers/lguest/interrupts_and_traps.c |   24 +---
 drivers/lguest/lg.h   |   18 ++
 drivers/lguest/page_tables.c  |   11 ++-
 drivers/lguest/x86/core.c |   10 --
 5 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index edc8cb4..4a4133b 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -58,7 +58,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
/* FLUSH_TLB comes in two flavors, depending on the
 * argument: */
if (args-arg1)
-   guest_pagetable_clear_all(lg);
+   guest_pagetable_clear_all(vcpu);
else
guest_pagetable_flush_user(lg);
break;
@@ -66,10 +66,10 @@ static void do_hcall(struct lg_vcpu *vcpu, struct 
hcall_args *args)
/* All these calls simply pass the arguments through to the right
 * routines. */
case LHCALL_NEW_PGTABLE:
-   guest_new_pagetable(lg, args-arg1);
+   guest_new_pagetable(vcpu, args-arg1);
break;
case LHCALL_SET_STACK:
-   guest_set_stack(lg, args-arg1, args-arg2, args-arg3);
+   guest_set_stack(vcpu, args-arg1, args-arg2, args-arg3);
break;
case LHCALL_SET_PTE:
guest_set_pte(lg, args-arg1, args-arg2, __pte(args-arg3));
@@ -82,7 +82,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
break;
case LHCALL_TS:
/* This sets the TS flag, as we saw used in run_guest(). */
-   lg-ts = args-arg1;
+   vcpu-ts = args-arg1;
break;
case LHCALL_HALT:
/* Similarly, this sets the halted flag for run_guest(). */
@@ -189,7 +189,7 @@ static void initialize(struct lg_vcpu *vcpu)
 * first write to a Guest page.  This may have caused a copy-on-write
 * fault, but the old page might be (read-only) in the Guest
 * pagetable. */
-   guest_pagetable_clear_all(lg);
+   guest_pagetable_clear_all(vcpu);
 }
 
 /*H:100
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index c1ca198..745f3ae 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -74,8 +74,8 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
if ((vcpu-regs-ss0x3) != GUEST_PL) {
/* The Guest told us their kernel stack with the SET_STACK
 * hypercall: both the virtual address and the segment */
-   virtstack = lg-esp1;
-   ss = lg-ss1;
+   virtstack = vcpu-esp1;
+   ss = vcpu-ss1;
 
origstack = gstack = guest_pa(lg, virtstack);
/* We push the old stack segment and pointer onto the new
@@ -313,10 +313,11 @@ static int direct_trap(unsigned int num)
  * the Guest.
  *
  * Which is deeply unfair, because (literally!) it wasn't the Guests' fault. */
-void pin_stack_pages(struct lguest *lg)
+void pin_stack_pages(struct lg_vcpu *vcpu)
 {
unsigned int i;
 
+   struct lguest *lg = vcpu-lg;
/* Depending on the CONFIG_4KSTACKS option, the Guest can have one or
 * two pages of stack space. */
for (i = 0; i  lg-stack_pages; i++)
@@ -324,7 +325,7 @@ void pin_stack_pages(struct lguest *lg)
 * start of the page after the kernel stack.  Subtract one to
 * get back onto the first stack page, and keep subtracting to
 * get to the rest of the stack pages. */
-   pin_page(lg, lg-esp1 - 1 - i * PAGE_SIZE);
+   pin_page(lg, vcpu-esp1 - 1 - i * PAGE_SIZE);
 }
 
 /* Direct traps also mean that we need to know whenever the Guest wants to use
@@ -335,21 +336,22 @@ void pin_stack_pages(struct lguest *lg)
  *
  * In Linux each process has its own kernel stack, so this happens a lot: we
  * change stacks on each context switch. */
-void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages)
+void guest_set_stack(struct lg_vcpu *vcpu, u32 seg, u32 esp,
+unsigned int pages)
 {
/* You are not allowed have a stack segment with privilege level 0: bad
 * Guest! */
if ((seg  0x3) != GUEST_PL)
-   kill_guest(lg, bad stack segment %i, seg);
+   kill_guest(vcpu-lg, bad stack segment %i, seg);
/* We only expect one or two stack pages

[PATCH 15/16] make pending notifications per-vcpu

2008-01-07 Thread Glauber de Oliveira Costa
this patch makes the pending_notify field, used to control
pending notifications, per-vcpu, instead of per-guest

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/core.c|6 +++---
 drivers/lguest/hypercalls.c  |6 +++---
 drivers/lguest/lg.h  |3 ++-
 drivers/lguest/lguest_user.c |4 ++--
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 847f2df..eae5149 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -186,10 +186,10 @@ int run_guest(struct lg_vcpu *vcpu, unsigned long __user 
*user)
 
/* It's possible the Guest did a NOTIFY hypercall to the
 * Launcher, in which case we return from the read() now. */
-   if (lg-pending_notify) {
-   if (put_user(lg-pending_notify, user))
+   if (vcpu-pending_notify) {
+   if (put_user(vcpu-pending_notify, user))
return -EFAULT;
-   return sizeof(lg-pending_notify);
+   return sizeof(vcpu-pending_notify);
}
 
/* Check for signals */
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 4a4133b..ae8c0b4 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -89,7 +89,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
vcpu-halted = 1;
break;
case LHCALL_NOTIFY:
-   lg-pending_notify = args-arg1;
+   vcpu-pending_notify = args-arg1;
break;
default:
/* It should be an architecture-specific hypercall. */
@@ -152,7 +152,7 @@ static void do_async_hcalls(struct lg_vcpu *vcpu)
 
/* Stop doing hypercalls if they want to notify the Launcher:
 * it needs to service this first. */
-   if (lg-pending_notify)
+   if (vcpu-pending_notify)
break;
}
 }
@@ -217,7 +217,7 @@ void do_hypercalls(struct lg_vcpu *vcpu)
/* If we stopped reading the hypercall ring because the Guest did a
 * NOTIFY to the Launcher, we want to return now.  Otherwise we do
 * the hypercall. */
-   if (!vcpu-lg-pending_notify) {
+   if (!vcpu-pending_notify) {
do_hcall(vcpu, vcpu-hcall);
/* Tricky point: we reset the hcall pointer to mark the
 * hypercall as done.  We use the hcall pointer rather than
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 1b3c933..d33445f 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -51,6 +51,8 @@ struct lg_vcpu {
u32 esp1;
u8 ss1;
 
+   unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
+
/* At end of a page shared mapped over lguest_pages in guest.  */
unsigned long regs_page;
struct lguest_regs *regs;
@@ -95,7 +97,6 @@ struct lguest
struct pgdir pgdirs[4];
 
unsigned long noirq_start, noirq_end;
-   unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
 
unsigned int stack_pages;
u32 tsc_khz;
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index acc1616..8ac6d2b 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -92,8 +92,8 @@ static ssize_t read(struct file *file, char __user *user, 
size_t size,loff_t*o)
 
/* If we returned from read() last time because the Guest notified,
 * clear the flag. */
-   if (lg-pending_notify)
-   lg-pending_notify = 0;
+   if (vcpu-pending_notify)
+   vcpu-pending_notify = 0;
 
/* Run the Guest until something interesting happens. */
return run_guest(vcpu, (unsigned long __user *)user);
-- 
1.5.0.6

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 16/16] per-vcpu lguest pgdir management

2008-01-07 Thread Glauber de Oliveira Costa
this patch makes the pgdir management per-vcpu. The pgdirs pool
is still guest-wide (although it'll probably need to grow when we
are really executing more vcpus), but the pgdidx index is gone,
since it makes no sense anymore. Instead, we use a per-vcpu
index.

Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED]
---
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |6 ++--
 drivers/lguest/lg.h   |   12 +++---
 drivers/lguest/page_tables.c  |   60 +
 drivers/lguest/x86/core.c |6 ++--
 5 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index ae8c0b4..b3a1942 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -60,7 +60,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
if (args-arg1)
guest_pagetable_clear_all(vcpu);
else
-   guest_pagetable_flush_user(lg);
+   guest_pagetable_flush_user(vcpu);
break;
 
/* All these calls simply pass the arguments through to the right
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 745f3ae..68b403f 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -77,7 +77,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
virtstack = vcpu-esp1;
ss = vcpu-ss1;
 
-   origstack = gstack = guest_pa(lg, virtstack);
+   origstack = gstack = guest_pa(vcpu, virtstack);
/* We push the old stack segment and pointer onto the new
 * stack: when the Guest does an iret back from the interrupt
 * handler the CPU will notice they're dropping privilege
@@ -89,7 +89,7 @@ static void set_guest_interrupt(struct lg_vcpu *vcpu, u32 lo, 
u32 hi,
virtstack = vcpu-regs-esp;
ss = vcpu-regs-ss;
 
-   origstack = gstack = guest_pa(lg, virtstack);
+   origstack = gstack = guest_pa(vcpu, virtstack);
}
 
/* Remember that we never let the Guest actually disable interrupts, so
@@ -325,7 +325,7 @@ void pin_stack_pages(struct lg_vcpu *vcpu)
 * start of the page after the kernel stack.  Subtract one to
 * get back onto the first stack page, and keep subtracting to
 * get to the rest of the stack pages. */
-   pin_page(lg, vcpu-esp1 - 1 - i * PAGE_SIZE);
+   pin_page(vcpu, vcpu-esp1 - 1 - i * PAGE_SIZE);
 }
 
 /* Direct traps also mean that we need to know whenever the Guest wants to use
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index d33445f..6e6a69e 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -57,6 +57,8 @@ struct lg_vcpu {
unsigned long regs_page;
struct lguest_regs *regs;
 
+   int vcpu_pgd; /* which pgd this vcpu is currently using */
+
/* If a hypercall was asked for, this points to the arguments. */
struct hcall_args *hcall;
u32 next_hcall;
@@ -92,8 +94,6 @@ struct lguest
int changed;
struct lguest_pages *last_pages;
 
-   /* We keep a small number of these. */
-   u32 pgdidx;
struct pgdir pgdirs[4];
 
unsigned long noirq_start, noirq_end;
@@ -170,14 +170,14 @@ void free_guest_pagetable(struct lguest *lg);
 void guest_new_pagetable(struct lg_vcpu *vcpu, unsigned long pgtable);
 void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i);
 void guest_pagetable_clear_all(struct lg_vcpu *vcpu);
-void guest_pagetable_flush_user(struct lguest *lg);
+void guest_pagetable_flush_user(struct lg_vcpu *vcpu);
 void guest_set_pte(struct lguest *lg, unsigned long gpgdir,
   unsigned long vaddr, pte_t val);
 void map_switcher_in_guest(struct lg_vcpu *vcpu,
   struct lguest_pages *pages);
-int demand_page(struct lguest *info, unsigned long cr2, int errcode);
-void pin_page(struct lguest *lg, unsigned long vaddr);
-unsigned long guest_pa(struct lguest *lg, unsigned long vaddr);
+int demand_page(struct lg_vcpu *vcpu, unsigned long cr2, int errcode);
+void pin_page(struct lg_vcpu *vcpu, unsigned long vaddr);
+unsigned long guest_pa(struct lg_vcpu *vcpu, unsigned long vaddr);
 void page_table_guest_data_init(struct lguest *lg);
 
 /* arch/core.c: */
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 1a7ac3a..839ea27 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -94,10 +94,10 @@ static pte_t *spte_addr(struct lguest *lg, pgd_t spgd, 
unsigned long vaddr)
 
 /* These two functions just like the above two, except they access the Guest
  * page tables.  Hence they return a Guest address. */
-static

Re: [PATCH 0/16] lguest: introduce vcpu structure

2008-01-06 Thread Glauber de Oliveira Costa
On Dec 25, 2007 9:54 PM, Rusty Russell <[EMAIL PROTECTED]> wrote:
> On Friday 21 December 2007 00:33:40 Glauber de Oliveira Costa wrote:
> > this patch makes room for the vcpu structure in lguest, already used in
> > this very same way at lguest64. It's the first part of our plan to
> > have lguest and lguest64 unified too.
>
> Hi Glauber!
>
> These patches look really solid, thanks!  A few minor things, then I'll
> apply them and push them for 2.6.25.

Thanks for all comments. I was in vacations until today, and I'll
repost a new version that address all your comments
soon (that's why I'm not answering each of them individually now, have
to look carefully)

> My only question is whether we should go further and vpu-ify routines like
> lgread and kill_guest, so that we can avoid more "lg" temporary variables...
Essentially, they don't need it, because they only touch
globally-visible variables (visible to the guest).
So it's more of an stylish thing. Using the vcpu in the signature can
have only one harm:
It needs the caller to also have a pointer to a vcpu, so we may end up
using it everywhere, like a domino fall.

Alternatively, in such functions that don't currently receive a vcpu
(nor they need to), we can convention to always pass
lg->vcpus[0] to lgread, kill_guest, etc. Which one do you prefer?

> > When two dogs hang out, you don't have new puppies right in the other day.
> > Some time has to be elapsed. They have to grow first. In this same spirit,
> > having these patches _do not_ mean smp guests can be launched (yet)
> > Much more work is to come, but this is the basic infrastructure.
>
> OK, that made me laugh...
\o/
> Thanks!
> Rusty.
>
>



-- 
Glauber de Oliveira Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/16] lguest: introduce vcpu structure

2008-01-06 Thread Glauber de Oliveira Costa
On Dec 25, 2007 9:54 PM, Rusty Russell [EMAIL PROTECTED] wrote:
 On Friday 21 December 2007 00:33:40 Glauber de Oliveira Costa wrote:
  this patch makes room for the vcpu structure in lguest, already used in
  this very same way at lguest64. It's the first part of our plan to
  have lguest and lguest64 unified too.

 Hi Glauber!

 These patches look really solid, thanks!  A few minor things, then I'll
 apply them and push them for 2.6.25.

Thanks for all comments. I was in vacations until today, and I'll
repost a new version that address all your comments
soon (that's why I'm not answering each of them individually now, have
to look carefully)

 My only question is whether we should go further and vpu-ify routines like
 lgread and kill_guest, so that we can avoid more lg temporary variables...
Essentially, they don't need it, because they only touch
globally-visible variables (visible to the guest).
So it's more of an stylish thing. Using the vcpu in the signature can
have only one harm:
It needs the caller to also have a pointer to a vcpu, so we may end up
using it everywhere, like a domino fall.

Alternatively, in such functions that don't currently receive a vcpu
(nor they need to), we can convention to always pass
lg-vcpus[0] to lgread, kill_guest, etc. Which one do you prefer?

  When two dogs hang out, you don't have new puppies right in the other day.
  Some time has to be elapsed. They have to grow first. In this same spirit,
  having these patches _do not_ mean smp guests can be launched (yet)
  Much more work is to come, but this is the basic infrastructure.

 OK, that made me laugh...
\o/
 Thanks!
 Rusty.





-- 
Glauber de Oliveira Costa.
Free as in Freedom
http://glommer.net

The less confident you are, the more serious you have to act.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/5] x86: another attempt at x86 pagetable unification

2007-12-20 Thread Glauber de Oliveira Costa
On Dec 20, 2007 10:58 PM, Ingo Molnar <[EMAIL PROTECTED]> wrote:
>
> * Jeremy Fitzhardinge <[EMAIL PROTECTED]> wrote:
>
> > Well, testing for bisectability requires compiling each patch as its
> > applied, which gets painful for something like this where any change
> > will rebuild the world.  And dealing with patch conflicts caused by
> > changing early patches in the series is never fun.
>
> that's true. The 'rej' tool helps alot though. ( Plus a distcc cluster
> that builds a distro kernel in 45-50 seconds from scratch ;)


So that's your secret!


-- 
Glauber de Oliveira Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 13/15] move patching code to arch-specific file.

2007-12-20 Thread Glauber de Oliveira Costa
On Dec 20, 2007 6:33 PM, Ingo Molnar <[EMAIL PROTECTED]> wrote:
>
> * Ingo Molnar <[EMAIL PROTECTED]> wrote:
>
> > this patch adds the paravirt_patch_32.o:
> >
> > > -obj-$(CONFIG_PARAVIRT) += paravirt.o
> > > +obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_32.o
> >
> > but does not add that file nor any other rule to build that target, so
> > it fails to build with the attached config:
> >
> > make[1]: *** No rule to make target
> >  `arch/x86/kernel/paravirt_patch_32.o', needed by
> >  `arch/x86/kernel/built-in.o'.  Stop.
>
> if it's just that single missing file then please send me a patch that
> adds that file and i'll add it to this patch. (instead of resending the
> whole series)

Yeah, I must have forgotten to git-add it.
It was building here fine, because I clearly have the file locally ;-)

I'm attaching a new patch that replaces just this one.

-- 
Glauber de Oliveira Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."
From 9a9307e976391776c0d63e3640d90738e20e9ee9 Mon Sep 17 00:00:00 2001
From: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
Date: Tue, 18 Dec 2007 16:47:35 -0200
Subject: [PATCH] [PATCH] move patching code to arch-specific file.

The core patching code for paravirt is sufficiently different
among i386 and x86_64, and we move them to specific files.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/Makefile_32 |2 +-
 arch/x86/kernel/paravirt.c  |   50 ---
 arch/x86/kernel/paravirt_patch_32.c |   49 ++
 include/asm-x86/paravirt.h  |8 +
 4 files changed, 58 insertions(+), 51 deletions(-)
 create mode 100644 arch/x86/kernel/paravirt_patch_32.c

diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index cfb71a5..86c6327 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -48,7 +48,7 @@ obj-$(CONFIG_K8_NB)		+= k8.o
 obj-$(CONFIG_MGEODE_LX)		+= geode_32.o mfgpt_32.o
 
 obj-$(CONFIG_VMI)		+= vmi_32.o vmiclock_32.o
-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
+obj-$(CONFIG_PARAVIRT)		+= paravirt.o paravirt_patch_32.o
 obj-y+= pcspeaker.o
 
 obj-$(CONFIG_SCx200)		+= scx200_32.o
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index e7c17cc..864be04 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -58,59 +58,9 @@ char *memory_setup(void)
 	extern const char start_##ops##_##name[], end_##ops##_##name[];	\
 	asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
 
-DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
-DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
-DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
-DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax");
-DEF_NATIVE(pv_cpu_ops, iret, "iret");
-DEF_NATIVE(pv_cpu_ops, irq_enable_syscall_ret, "sti; sysexit");
-DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax");
-DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3");
-DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax");
-DEF_NATIVE(pv_cpu_ops, clts, "clts");
-DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc");
-
 /* Undefined instruction for dealing with missing ops pointers. */
 static const unsigned char ud2a[] = { 0x0f, 0x0b };
 
-static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
-			 unsigned long addr, unsigned len)
-{
-	const unsigned char *start, *end;
-	unsigned ret;
-
-	switch(type) {
-#define SITE(ops, x)		\
-	case PARAVIRT_PATCH(ops.x):\
-		start = start_##ops##_##x;			\
-		end = end_##ops##_##x;\
-		goto patch_site
-
-	SITE(pv_irq_ops, irq_disable);
-	SITE(pv_irq_ops, irq_enable);
-	SITE(pv_irq_ops, restore_fl);
-	SITE(pv_irq_ops, save_fl);
-	SITE(pv_cpu_ops, iret);
-	SITE(pv_cpu_ops, irq_enable_syscall_ret);
-	SITE(pv_mmu_ops, read_cr2);
-	SITE(pv_mmu_ops, read_cr3);
-	SITE(pv_mmu_ops, write_cr3);
-	SITE(pv_cpu_ops, clts);
-	SITE(pv_cpu_ops, read_tsc);
-#undef SITE
-
-	patch_site:
-		ret = paravirt_patch_insns(ibuf, len, start, end);
-		break;
-
-	default:
-		ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
-		break;
-	}
-
-	return ret;
-}
-
 unsigned paravirt_patch_nop(void)
 {
 	return 0;
diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c
new file mode 100644
index 000..82fc5fc
--- /dev/null
+++ b/arch/x86/kernel/paravirt_patch_32.c
@@ -0,0 +1,49 @@
+#include 
+
+DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
+DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
+DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
+DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %

[PATCH 15/15] replace x86_read/write_per_cpu with a common function.

2007-12-20 Thread Glauber de Oliveira Costa
x86_read_per_cpu() and its writeish sister are not present in x86_64. So in
this patch, we replace them with __get_cpu_var(), which is present in both

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/paravirt.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

Index: linux-2.6-x86/arch/x86/kernel/paravirt.c
===
--- linux-2.6-x86.orig/arch/x86/kernel/paravirt.c   2007-12-20 
19:08:11.0 -0800
+++ linux-2.6-x86/arch/x86/kernel/paravirt.c2007-12-20 19:08:18.0 
-0800
@@ -238,18 +238,18 @@
 
 static inline void enter_lazy(enum paravirt_lazy_mode mode)
 {
-   BUG_ON(x86_read_percpu(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
+   BUG_ON(__get_cpu_var(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
BUG_ON(preemptible());
 
-   x86_write_percpu(paravirt_lazy_mode, mode);
+   __get_cpu_var(paravirt_lazy_mode) = mode;
 }
 
 void paravirt_leave_lazy(enum paravirt_lazy_mode mode)
 {
-   BUG_ON(x86_read_percpu(paravirt_lazy_mode) != mode);
+   BUG_ON(__get_cpu_var(paravirt_lazy_mode) != mode);
BUG_ON(preemptible());
 
-   x86_write_percpu(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
+   __get_cpu_var(paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;
 }
 
 void paravirt_enter_lazy_mmu(void)
@@ -274,7 +274,7 @@
 
 enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
 {
-   return x86_read_percpu(paravirt_lazy_mode);
+   return __get_cpu_var(paravirt_lazy_mode);
 }
 
 struct pv_info pv_info = {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 13/15] move patching code to arch-specific file.

2007-12-20 Thread Glauber de Oliveira Costa
The core patching code for paravirt is sufficiently different
among i386 and x86_64, and we move them to specific files.

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/Makefile_32 |2 +-
 arch/x86/kernel/paravirt.c  |   50 ---
 include/asm-x86/paravirt.h  |8 +++
 3 files changed, 9 insertions(+), 51 deletions(-)

Index: linux-2.6-x86/arch/x86/kernel/Makefile_32
===
--- linux-2.6-x86.orig/arch/x86/kernel/Makefile_32  2007-12-20 
19:07:15.0 -0800
+++ linux-2.6-x86/arch/x86/kernel/Makefile_32   2007-12-20 19:08:11.0 
-0800
@@ -48,7 +48,7 @@
 obj-$(CONFIG_MGEODE_LX)+= geode_32.o mfgpt_32.o
 
 obj-$(CONFIG_VMI)  += vmi_32.o vmiclock_32.o
-obj-$(CONFIG_PARAVIRT) += paravirt.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_32.o
 obj-y  += pcspeaker.o
 
 obj-$(CONFIG_SCx200)   += scx200_32.o
Index: linux-2.6-x86/arch/x86/kernel/paravirt.c
===
--- linux-2.6-x86.orig/arch/x86/kernel/paravirt.c   2007-12-20 
19:08:06.0 -0800
+++ linux-2.6-x86/arch/x86/kernel/paravirt.c2007-12-20 19:08:11.0 
-0800
@@ -58,59 +58,9 @@
extern const char start_##ops##_##name[], end_##ops##_##name[]; \
asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
 
-DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
-DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
-DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
-DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax");
-DEF_NATIVE(pv_cpu_ops, iret, "iret");
-DEF_NATIVE(pv_cpu_ops, irq_enable_syscall_ret, "sti; sysexit");
-DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax");
-DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3");
-DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax");
-DEF_NATIVE(pv_cpu_ops, clts, "clts");
-DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc");
-
 /* Undefined instruction for dealing with missing ops pointers. */
 static const unsigned char ud2a[] = { 0x0f, 0x0b };
 
-static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
-unsigned long addr, unsigned len)
-{
-   const unsigned char *start, *end;
-   unsigned ret;
-
-   switch(type) {
-#define SITE(ops, x)   \
-   case PARAVIRT_PATCH(ops.x): \
-   start = start_##ops##_##x;  \
-   end = end_##ops##_##x;  \
-   goto patch_site
-
-   SITE(pv_irq_ops, irq_disable);
-   SITE(pv_irq_ops, irq_enable);
-   SITE(pv_irq_ops, restore_fl);
-   SITE(pv_irq_ops, save_fl);
-   SITE(pv_cpu_ops, iret);
-   SITE(pv_cpu_ops, irq_enable_syscall_ret);
-   SITE(pv_mmu_ops, read_cr2);
-   SITE(pv_mmu_ops, read_cr3);
-   SITE(pv_mmu_ops, write_cr3);
-   SITE(pv_cpu_ops, clts);
-   SITE(pv_cpu_ops, read_tsc);
-#undef SITE
-
-   patch_site:
-   ret = paravirt_patch_insns(ibuf, len, start, end);
-   break;
-
-   default:
-   ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
-   break;
-   }
-
-   return ret;
-}
-
 unsigned paravirt_patch_nop(void)
 {
return 0;
Index: linux-2.6-x86/include/asm-x86/paravirt.h
===
--- linux-2.6-x86.orig/include/asm-x86/paravirt.h   2007-12-20 
19:08:10.0 -0800
+++ linux-2.6-x86/include/asm-x86/paravirt.h2007-12-20 19:08:11.0 
-0800
@@ -308,6 +308,11 @@
 #define paravirt_alt(insn_string)  \
_paravirt_alt(insn_string, "%c[paravirt_typenum]", 
"%c[paravirt_clobber]")
 
+/* Simple instruction patching code. */
+#define DEF_NATIVE(ops, name, code)\
+   extern const char start_##ops##_##name[], end_##ops##_##name[]; \
+   asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
+
 unsigned paravirt_patch_nop(void);
 unsigned paravirt_patch_ignore(unsigned len);
 unsigned paravirt_patch_call(void *insnbuf,
@@ -322,6 +327,9 @@
 unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
  const char *start, const char *end);
 
+unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
+ unsigned long addr, unsigned len);
+
 int paravirt_disable_iospace(void);
 
 /*
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 14/15] x86_64 patching functions

2007-12-20 Thread Glauber de Oliveira Costa
Like i386, x86_64 also need to include its own patching function.
(Well, if you're not in a hurry, and don't care about speed, you don't
really _need_ ;-)) 

So here they are. Not much different in essence from i386

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/Makefile_64 |1 +
 arch/x86/kernel/paravirt_patch_64.c |   56 +++
 2 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/kernel/paravirt_patch_64.c

Index: linux-2.6-x86/arch/x86/kernel/Makefile_64
===
--- linux-2.6-x86.orig/arch/x86/kernel/Makefile_64  2007-12-20 
19:05:52.0 -0800
+++ linux-2.6-x86/arch/x86/kernel/Makefile_64   2007-12-20 19:08:14.0 
-0800
@@ -41,6 +41,7 @@
 obj-$(CONFIG_K8_NB)+= k8.o
 obj-$(CONFIG_AUDIT)+= audit_64.o
 obj-$(CONFIG_EFI)  += efi.o efi_64.o efi_stub_64.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_64.o
 
 obj-$(CONFIG_MODULES)  += module_64.o
 obj-$(CONFIG_PCI)  += early-quirks.o
Index: linux-2.6-x86/arch/x86/kernel/paravirt_patch_64.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6-x86/arch/x86/kernel/paravirt_patch_64.c   2007-12-20 
19:08:14.0 -0800
@@ -0,0 +1,56 @@
+#include 
+#include 
+
+DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
+DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
+DEF_NATIVE(pv_irq_ops, restore_fl, "pushq %rdi; popfq");
+DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax");
+DEF_NATIVE(pv_cpu_ops, iret, "iretq");
+DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax");
+DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax");
+DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3");
+DEF_NATIVE(pv_mmu_ops, flush_tlb_single, "invlpg (%rdi)");
+DEF_NATIVE(pv_cpu_ops, clts, "clts");
+DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd");
+
+/* the three commands give us more control to how to return from a syscall */
+DEF_NATIVE(pv_cpu_ops, irq_enable_syscall_ret, "movq %gs:" 
__stringify(pda_oldrsp) ", %rsp; swapgs; sysretq;");
+DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs");
+
+unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
+ unsigned long addr, unsigned len)
+{
+   const unsigned char *start, *end;
+   unsigned ret;
+
+#define PATCH_SITE(ops, x) \
+   case PARAVIRT_PATCH(ops.x): \
+   start = start_##ops##_##x;  \
+   end = end_##ops##_##x;  \
+   goto patch_site
+   switch(type) {
+   PATCH_SITE(pv_irq_ops, restore_fl);
+   PATCH_SITE(pv_irq_ops, save_fl);
+   PATCH_SITE(pv_irq_ops, irq_enable);
+   PATCH_SITE(pv_irq_ops, irq_disable);
+   PATCH_SITE(pv_cpu_ops, iret);
+   PATCH_SITE(pv_cpu_ops, irq_enable_syscall_ret);
+   PATCH_SITE(pv_cpu_ops, swapgs);
+   PATCH_SITE(pv_mmu_ops, read_cr2);
+   PATCH_SITE(pv_mmu_ops, read_cr3);
+   PATCH_SITE(pv_mmu_ops, write_cr3);
+   PATCH_SITE(pv_cpu_ops, clts);
+   PATCH_SITE(pv_mmu_ops, flush_tlb_single);
+   PATCH_SITE(pv_cpu_ops, wbinvd);
+
+   patch_site:
+   ret = paravirt_patch_insns(ibuf, len, start, end);
+   break;
+
+   default:
+   ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
+   break;
+   }
+#undef PATCH_SITE
+   return ret;
+}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   3   4   5   6   7   8   9   10   >