* lhype progress...
@ 2006-11-16 10:36 Rusty Russell
2006-11-17 0:45 ` James Morris
0 siblings, 1 reply; 6+ messages in thread
From: Rusty Russell @ 2006-11-16 10:36 UTC (permalink / raw)
To: James Morris, Don Mullis, Tony Breeds, Stephen Rothwell; +Cc: virtualization
Hi all,
Some of you know I've been working on a trivial in-kernel hypervisor to
demonstrate paravirt_ops. The good news is that it works! (And not
just for me!) The bad news is that I haven't written any documentation
and now I'm going to be offline (moving to a farm) for several weeks.
Nonetheless, if you're the kind of person who wants to poke around with
hypervisors, no doubt you can figure it out. Tony Breeds might even
write a HOWTO. There's certainly a lot to be done (see FIXMEs in the
code for example). Console device, block device and inter-domain
networking all work. From here it should be easy 8)
So, you can download the patch "lhype.patch" from the paravirt
mercurial patch queue. It should apply by itself to a recent -mm tree.
http://ozlabs.org/~rusty/paravirt
Thanks, and have fun playing!
Rusty.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: lhype progress...
2006-11-16 10:36 lhype progress Rusty Russell
@ 2006-11-17 0:45 ` James Morris
2006-11-27 23:37 ` [PATCH] lhype: Add TLS support James Morris
0 siblings, 1 reply; 6+ messages in thread
From: James Morris @ 2006-11-17 0:45 UTC (permalink / raw)
To: Rusty Russell; +Cc: Stephen Rothwell, virtualization, James Morris
On Thu, 16 Nov 2006, Rusty Russell wrote:
> Nonetheless, if you're the kind of person who wants to poke around with
> hypervisors, no doubt you can figure it out. Tony Breeds might even
> write a HOWTO.
Any patches I have queued for Rusty will be available here:
http://people.redhat.com/jmorris/lhype/patches/
(Currently just a couple of very minor things).
- James
--
James Morris
<jmorris@redhat.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] lhype: Add TLS support
2006-11-17 0:45 ` James Morris
@ 2006-11-27 23:37 ` James Morris
2006-11-29 5:37 ` Rusty Russell
0 siblings, 1 reply; 6+ messages in thread
From: James Morris @ 2006-11-27 23:37 UTC (permalink / raw)
To: Rusty Russell; +Cc: virtualization, Stephen Rothwell
This is queued for when Rusty returns, but may be generally useful now to
people playing with lhype.
TLS support is required for some binaries (notably, Fedora & co), and also
any binary which explicitly uses __thread variables (which all segfault
without this patch).
It works well enough to bring FC6 up as far as it goes without an initrd,
although there may be some further work required. e.g.
o Need to ensure fixup_gdt() doesn't stomp on TLS segement descriptors.
o In some cases, a binary may fall back to calling modify_ldt(2) instead
of get_thread_area(2), and this needs to be handled.
---
Virtualize thread local storage for guests. A new hypercall,
LHCALL_LOAD_TLS, is implemented, mapping to the load_tls()
paravirt op. The virtualized GDT is now updated correctly
from the guest's per-thread TLS array.
Signed-off-by: James Morris <jmorris@namei.org>
---
arch/i386/kernel/lhype.c | 6 ++++++
drivers/lhype/hypercalls.c | 22 +++++++++++++++++++++-
include/asm-i386/lhype.h | 1 +
3 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/arch/i386/kernel/lhype.c b/arch/i386/kernel/lhype.c
index d4376c5..35c4616 100644
--- a/arch/i386/kernel/lhype.c
+++ b/arch/i386/kernel/lhype.c
@@ -221,6 +221,11 @@ static fastcall void lhype_set_ldt(const
BUG_ON(entries);
}
+static fastcall void lhype_load_tls(struct thread_struct *t, unsigned int cpu)
+{
+ hcall(LHCALL_LOAD_TLS, __pa(t), cpu, 0);
+}
+
static fastcall void lhype_set_debugreg(int regno, unsigned long value)
{
/* FIXME: Implement */
@@ -385,6 +390,7 @@ #endif
paravirt_ops.load_esp0 = lhype_load_esp0;
paravirt_ops.load_tr_desc = lhype_load_tr_desc;
paravirt_ops.set_ldt = lhype_set_ldt;
+ paravirt_ops.load_tls = lhype_load_tls;
paravirt_ops.set_debugreg = lhype_set_debugreg;
paravirt_ops.clts = lhype_clts;
paravirt_ops.read_cr0 = lhype_read_cr0;
diff --git a/drivers/lhype/hypercalls.c b/drivers/lhype/hypercalls.c
index bc8639c..f3ff693 100644
--- a/drivers/lhype/hypercalls.c
+++ b/drivers/lhype/hypercalls.c
@@ -178,13 +178,29 @@ static int guest_set_stack(struct lhype_
return 1;
}
+static void guest_load_tls(struct lhype_dom_info *info,
+ const struct thread_struct __user *t)
+{
+ int i;
+ struct desc_struct *gdt = info->domain->gdt_table;
+
+ for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++) {
+ struct desc_struct d;
+
+ lhread(info, &d, (u32)&t->tls_array[i - GDT_ENTRY_TLS_MIN],
+ sizeof(d));
+ gdt[i] = d;
+ }
+}
+
void hypercall(struct lhype_dom_info *linfo, struct lhype_regs *regs)
{
static unsigned long last_jifs;
/* These three happen regularly, so we limit them... */
if ((regs->eax != LHCALL_IRET
&& regs->eax != LHCALL_HALT
- && regs->eax != LHCALL_TIMER_READ)
+ && regs->eax != LHCALL_TIMER_READ
+ && regs->eax != LHCALL_LOAD_TLS)
|| printk_timed_ratelimit(&last_jifs, 10000)) {
printk(KERN_DEBUG "%i: %s\n", linfo->domid,
regs->eax == LHCALL_LHYPE_PAGE ? "LHYPE_PAGE" :
@@ -208,6 +224,7 @@ void hypercall(struct lhype_dom_info *li
regs->eax == LHCALL_SET_PTE ? "SET_PTE" :
regs->eax == LHCALL_SET_SOME_PTE ? "SET_SOME_PTE" :
regs->eax == LHCALL_SET_PUD ? "SET_PUD" :
+ regs->eax == LHCALL_LOAD_TLS ? "LOAD_TLS" :
"UNKNOWN");
}
@@ -325,6 +342,9 @@ void hypercall(struct lhype_dom_info *li
case LHCALL_SET_PUD:
guest_set_pud(linfo, regs->edx);
break;
+ case LHCALL_LOAD_TLS:
+ guest_load_tls(linfo, (struct thread_struct __user*)regs->edx);
+ break;
}
return;
}
diff --git a/include/asm-i386/lhype.h b/include/asm-i386/lhype.h
index df86d97..af0c03b 100644
--- a/include/asm-i386/lhype.h
+++ b/include/asm-i386/lhype.h
@@ -26,6 +26,7 @@ #define LHCALL_SEND_DMA 18
#define LHCALL_SET_PTE 19
#define LHCALL_SET_SOME_PTE 20
#define LHCALL_SET_PUD 21
+#define LHCALL_LOAD_TLS 22
#define LHYPE_TRAP_ENTRY 0x81
--
1.4.2.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] lhype: Add TLS support
2006-11-27 23:37 ` [PATCH] lhype: Add TLS support James Morris
@ 2006-11-29 5:37 ` Rusty Russell
2006-11-30 0:50 ` Rusty Russell
0 siblings, 1 reply; 6+ messages in thread
From: Rusty Russell @ 2006-11-29 5:37 UTC (permalink / raw)
To: James Morris; +Cc: virtualization, Stephen Rothwell
On Mon, 2006-11-27 at 18:37 -0500, James Morris wrote:
> This is queued for when Rusty returns, but may be generally useful now to
> people playing with lhype.
>
> TLS support is required for some binaries (notably, Fedora & co), and also
> any binary which explicitly uses __thread variables (which all segfault
> without this patch).
Right...
This unfortunately brings a security issue; GLIBC uses huge positive
offsets (4G minus a smidge) against these segments to access some
variables. This means that the segments must cover the entire address
space, which would give them access to the hypervisor.
There are two simple solutions to this. The first is to trim the
segments, and use a modified libc (a-la Xen). The second is to only
allow those TLS mappings in usermode: the U/S bit on the pagetables will
prevent usermode from accessing the hypervisor anyway. This becomes a
little harder later, when we allow syscall traps directly into guest,
but I have another trick for that...
Untested, but based on your patch. Does it work?
Thanks!
Rusty.
diff -r d4fb2c676c1c arch/i386/kernel/lhype.c
--- a/arch/i386/kernel/lhype.c Thu Nov 16 08:34:46 2006 +1100
+++ b/arch/i386/kernel/lhype.c Wed Nov 29 16:23:43 2006 +1100
@@ -221,6 +221,11 @@ static fastcall void lhype_set_ldt(const
BUG_ON(entries);
}
+static fastcall void lhype_load_tls(struct thread_struct *t, unsigned int cpu)
+{
+ hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0);
+}
+
static fastcall void lhype_set_debugreg(int regno, unsigned long value)
{
/* FIXME: Implement */
@@ -385,6 +390,7 @@ static __attribute_used__ __init void lh
paravirt_ops.load_esp0 = lhype_load_esp0;
paravirt_ops.load_tr_desc = lhype_load_tr_desc;
paravirt_ops.set_ldt = lhype_set_ldt;
+ paravirt_ops.load_tls = lhype_load_tls;
paravirt_ops.set_debugreg = lhype_set_debugreg;
paravirt_ops.clts = lhype_clts;
paravirt_ops.read_cr0 = lhype_read_cr0;
diff -r d4fb2c676c1c drivers/lhype/hypercalls.c
--- a/drivers/lhype/hypercalls.c Thu Nov 16 08:34:46 2006 +1100
+++ b/drivers/lhype/hypercalls.c Wed Nov 29 16:32:56 2006 +1100
@@ -178,13 +178,20 @@ static int guest_set_stack(struct lhype_
return 1;
}
+static void guest_load_tls(struct lhype_dom_info *linfo,
+ const struct desc_struct __user *tls_array)
+{
+ lhread(linfo, &linfo->tls, (u32)tls_array, sizeof(linfo->tls));
+}
+
void hypercall(struct lhype_dom_info *linfo, struct lhype_regs *regs)
{
static unsigned long last_jifs;
/* These three happen regularly, so we limit them... */
if ((regs->eax != LHCALL_IRET
&& regs->eax != LHCALL_HALT
- && regs->eax != LHCALL_TIMER_READ)
+ && regs->eax != LHCALL_TIMER_READ
+ && regs->eax != LHCALL_LOAD_TLS)
|| printk_timed_ratelimit(&last_jifs, 10000)) {
printk(KERN_DEBUG "%i: %s\n", linfo->domid,
regs->eax == LHCALL_LHYPE_PAGE ? "LHYPE_PAGE" :
@@ -208,6 +215,7 @@ void hypercall(struct lhype_dom_info *li
regs->eax == LHCALL_SET_PTE ? "SET_PTE" :
regs->eax == LHCALL_SET_SOME_PTE ? "SET_SOME_PTE" :
regs->eax == LHCALL_SET_PUD ? "SET_PUD" :
+ regs->eax == LHCALL_LOAD_TLS ? "LOAD_TLS" :
"UNKNOWN");
}
@@ -325,6 +333,9 @@ void hypercall(struct lhype_dom_info *li
case LHCALL_SET_PUD:
guest_set_pud(linfo, regs->edx);
break;
+ case LHCALL_LOAD_TLS:
+ guest_load_tls(linfo, (struct desc_struct __user*)regs->edx);
+ break;
}
return;
}
diff -r d4fb2c676c1c drivers/lhype/init.c
--- a/drivers/lhype/init.c Thu Nov 16 08:34:46 2006 +1100
+++ b/drivers/lhype/init.c Wed Nov 29 16:32:14 2006 +1100
@@ -340,6 +340,17 @@ static int run_thread(struct lhype_dom_i
} else
cond_resched();
+ /* We can let them used the TLS 4G segments iff in
+ * userspace: the U/S bit on the pagetables protects
+ * hypervisor */
+ if ((linfo->domain->regs.cs & 3) == 3) {
+ memcpy(linfo->domain->gdt_table + GDT_ENTRY_TLS_MIN,
+ linfo->tls, sizeof(linfo->tls));
+ } else {
+ memset(linfo->domain->gdt_table + GDT_ENTRY_TLS_MIN,
+ 0, sizeof(linfo->tls));
+ }
+
local_irq_disable();
/* FIXME: We should be able to be smart here. */
math_state_restore();
diff -r d4fb2c676c1c drivers/lhype/lhype.h
--- a/drivers/lhype/lhype.h Thu Nov 16 08:34:46 2006 +1100
+++ b/drivers/lhype/lhype.h Wed Nov 29 16:32:00 2006 +1100
@@ -108,6 +108,7 @@ struct lhype_dom_info
int halted;
u32 last_timer;
struct file *input;
+ struct desc_struct tls[GDT_ENTRY_TLS_ENTRIES];
u32 *pgdir;
diff -r d4fb2c676c1c include/asm-i386/lhype.h
--- a/include/asm-i386/lhype.h Thu Nov 16 08:34:46 2006 +1100
+++ b/include/asm-i386/lhype.h Wed Nov 29 16:18:38 2006 +1100
@@ -26,6 +26,7 @@
#define LHCALL_SET_PTE 19
#define LHCALL_SET_SOME_PTE 20
#define LHCALL_SET_PUD 21
+#define LHCALL_LOAD_TLS 22
#define LHYPE_TRAP_ENTRY 0x81
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] lhype: Add TLS support
2006-11-29 5:37 ` Rusty Russell
@ 2006-11-30 0:50 ` Rusty Russell
2006-12-07 16:37 ` James Morris
0 siblings, 1 reply; 6+ messages in thread
From: Rusty Russell @ 2006-11-30 0:50 UTC (permalink / raw)
To: James Morris; +Cc: virtualization, Stephen Rothwell
On Wed, 2006-11-29 at 16:37 +1100, Rusty Russell wrote:
> Untested, but based on your patch. Does it work?
Actually, I suspect it won't. Instead of memset'ing to 0, the TLS
segment descriptors should be set to a valid value, such as copying
USER_DS.
Cheers,
Rusty.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] lhype: Add TLS support
2006-11-30 0:50 ` Rusty Russell
@ 2006-12-07 16:37 ` James Morris
0 siblings, 0 replies; 6+ messages in thread
From: James Morris @ 2006-12-07 16:37 UTC (permalink / raw)
To: Rusty Russell; +Cc: virtualization, Stephen Rothwell
On Thu, 30 Nov 2006, Rusty Russell wrote:
> On Wed, 2006-11-29 at 16:37 +1100, Rusty Russell wrote:
> > Untested, but based on your patch. Does it work?
FYI, I've resynced with your latest fix (from the paravirt queue), and it
seems to be working ok.
Some updated docs here:
http://virt.kernelnewbies.org/RustyvisorQuickstart
- James
--
James Morris
<jmorris@redhat.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-12-07 16:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-16 10:36 lhype progress Rusty Russell
2006-11-17 0:45 ` James Morris
2006-11-27 23:37 ` [PATCH] lhype: Add TLS support James Morris
2006-11-29 5:37 ` Rusty Russell
2006-11-30 0:50 ` Rusty Russell
2006-12-07 16:37 ` James Morris
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).