ChangeSet 1.1733, 2005/06/23 10:35:57+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
The 32-bit x86 LTP exposed bugs with LDT handling with x86_64 Xen and
XenLinux:
- fill the code for arbitrary_virt_to_machine(XenLinux)
- set 64-bit value for the base address for LDT (Xen)
- fix a bug (64-bit cleanup) in map_ldt_shadow_page (Xen)
Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx>
linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/ldt.c | 22 ++++-------
linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h | 16 +++++++-
xen/arch/x86/mm.c | 2 -
xen/include/asm-x86/ldt.h | 4 --
4 files changed, 26 insertions(+), 18 deletions(-)
diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/ldt.c
b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/ldt.c
--- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/ldt.c 2005-06-23
07:05:45 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/ldt.c 2005-06-23
07:05:45 -04:00
@@ -62,7 +62,6 @@
if (reload) {
#ifdef CONFIG_SMP
cpumask_t mask;
-
preempt_disable();
#endif
make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
@@ -73,8 +72,6 @@
if (!cpus_equal(current->mm->cpu_vm_mask, mask))
smp_call_function(flush_ldt, NULL, 1, 1);
preempt_enable();
-#else
- load_LDT(pc);
#endif
}
if (oldsize) {
@@ -188,13 +185,12 @@
{
struct task_struct *me = current;
struct mm_struct * mm = me->mm;
- unsigned long entry = 0, *lp;
+ __u32 entry_1, entry_2, *lp;
unsigned long mach_lp;
int error;
struct user_desc ldt_info;
error = -EINVAL;
-
if (bytecount != sizeof(ldt_info))
goto out;
error = -EFAULT;
@@ -218,26 +214,26 @@
goto out_unlock;
}
- lp = (unsigned long *)((ldt_info.entry_number << 3) + (char *)
mm->context.ldt);
- mach_lp = arbitrary_virt_to_machine(lp);
+ lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *)
mm->context.ldt);
+ mach_lp = arbitrary_virt_to_machine(lp);
/* Allow LDTs to be cleared by the user. */
if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
if (oldmode || LDT_empty(&ldt_info)) {
- entry = 0;
+ entry_1 = 0;
+ entry_2 = 0;
goto install;
}
}
-#if 0
- entry = LDT_entry(&ldt_info);
-#endif
+ entry_1 = LDT_entry_a(&ldt_info);
+ entry_2 = LDT_entry_b(&ldt_info);
if (oldmode)
- entry &= ~(1 << 20);
+ entry_2 &= ~(1 << 20);
/* Install the new entry ... */
install:
- error = HYPERVISOR_update_descriptor(mach_lp, entry);
+ error = HYPERVISOR_update_descriptor(mach_lp, (unsigned long)((entry_1
| (unsigned long) entry_2 << 32)));
out_unlock:
up(&mm->context.sem);
diff -Nru a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
2005-06-23 07:05:45 -04:00
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
2005-06-23 07:05:45 -04:00
@@ -30,7 +30,20 @@
extern unsigned long pgkern_mask;
-#define arbitrary_virt_to_machine(__va) ({0;})
+#define virt_to_ptep(__va) \
+({ \
+ pgd_t *__pgd = pgd_offset_k((unsigned long)(__va)); \
+ pud_t *__pud = pud_offset(__pgd, (unsigned long)(__va)); \
+ pmd_t *__pmd = pmd_offset(__pud, (unsigned long)(__va)); \
+ pte_offset_kernel(__pmd, (unsigned long)(__va)); \
+})
+
+#define arbitrary_virt_to_machine(__va)
\
+({ \
+ pte_t *__pte = virt_to_ptep(__va); \
+ unsigned long __pa = (*(unsigned long *)__pte) & PAGE_MASK; \
+ __pa | ((unsigned long)(__va) & (PAGE_SIZE-1)); \
+})
/*
* ZERO_PAGE is a global shared page that is always zero: used
@@ -210,6 +223,7 @@
#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+#define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
#define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
#define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
#define PAGE_KERNEL_VSYSCALL_NOCACHE
MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
diff -Nru a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c 2005-06-23 07:05:45 -04:00
+++ b/xen/arch/x86/mm.c 2005-06-23 07:05:45 -04:00
@@ -288,7 +288,7 @@
struct domain *d = v->domain;
unsigned long gpfn, gmfn;
l1_pgentry_t l1e, nl1e;
- unsigned gva = v->arch.guest_context.ldt_base + (off << PAGE_SHIFT);
+ unsigned long gva = v->arch.guest_context.ldt_base + (off << PAGE_SHIFT);
int res;
#if defined(__x86_64__)
diff -Nru a/xen/include/asm-x86/ldt.h b/xen/include/asm-x86/ldt.h
--- a/xen/include/asm-x86/ldt.h 2005-06-23 07:05:45 -04:00
+++ b/xen/include/asm-x86/ldt.h 2005-06-23 07:05:45 -04:00
@@ -18,9 +18,7 @@
{
cpu = smp_processor_id();
desc = gdt_table + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY;
- desc->a = ((LDT_VIRT_START(v)&0xffff)<<16) | (ents*8-1);
- desc->b = (LDT_VIRT_START(v)&(0xff<<24)) | 0x8200 |
- ((LDT_VIRT_START(v)&0xff0000)>>16);
+ _set_tssldt_desc(desc, LDT_VIRT_START(v), ents*8-1, 2);
__asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) );
}
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|