#include <arch/segment.h>
#include <arch/symbolic-const.h>
-user_desc gdt[NR_GDT_ENTRIES] =
+#ifdef CONFIG_HVM
+#define gdt_section __page_aligned_data
+#else
+#define gdt_section __page_aligned_bss
+#endif
+
+user_desc gdt[NR_GDT_ENTRIES] gdt_section =
{
+#ifdef CONFIG_HVM
[GDTE_CS64_DPL0] = INIT_GDTE_SYM(0, 0xfffff, COMMON, CODE, DPL0, R, L),
[GDTE_CS32_DPL0] = INIT_GDTE_SYM(0, 0xfffff, COMMON, CODE, DPL0, R, D),
[GDTE_DS32_DPL0] = INIT_GDTE_SYM(0, 0xfffff, COMMON, DATA, DPL0, B, W),
/* [GDTE_TSS] */
/* [GDTE_TSS + 1] */
+#endif
};
+#if defined(CONFIG_HVM)
+
desc_ptr gdt_ptr =
{
.limit = sizeof(gdt) - 1,
.base = _u(&gdt),
};
-#if defined(CONFIG_HVM)
-
env_gate idt[256];
desc_ptr idt_ptr =
};
uint8_t base2;
};
+ /* Full width backing integer. */
+ uint64_t raw;
};
};
ASSERT(IS_ALIGNED(pse_l1_identmap, PAGE_SIZE), "pse_l1_identmap misaligned");
ASSERT(IS_ALIGNED(pse_l2_identmap, PAGE_SIZE), "pse_l2_identmap misaligned");
+#else
+
+ASSERT(IS_ALIGNED(gdt, PAGE_SIZE), "gdt misaligned");
+
#endif
/*
* Local variables:
if ( rc )
panic("Failed to set trap table: %d\n", rc);
+ /* Register gdt[] with Xen. Need to map it read-only first. */
+ if ( hypercall_update_va_mapping(
+ _u(gdt), pte_from_virt(gdt, PF_SYM(AD, P)), UVMF_INVLPG) )
+ panic("Unable to remap gdt[] as read-only\n");
+
+ unsigned long gdt_frames[] = {
+ virt_to_mfn(gdt),
+ };
+ BUILD_BUG_ON(NR_GDT_ENTRIES > (PAGE_SIZE / sizeof(user_desc)));
+
+ rc = hypercall_set_gdt(gdt_frames, NR_GDT_ENTRIES);
+ if ( rc )
+ panic("Failed to set gdt: %d\n", rc);
+
/* PV equivalent of setting tss.{esp0,ss0}. */
rc = hypercall_stack_switch(__KERN_DS, &boot_stack[2 * PAGE_SIZE]);
if ( rc )
#include <xtf/compiler.h>
#include <xtf/types.h>
+#include <arch/desc.h>
#include <arch/page.h>
#if defined(__x86_64__)
reqs, count, done, foreigndom);
}
+static inline long hypercall_set_gdt(const unsigned long *mfns,
+ unsigned int entries)
+{
+ return HYPERCALL2(long, __HYPERVISOR_set_gdt, mfns, entries);
+}
+
static inline long hypercall_stack_switch(const unsigned int ss, const void *sp)
{
return HYPERCALL2(long, __HYPERVISOR_stack_switch, ss, sp);
}
+static inline long hypercall_update_descriptor(uint64_t maddr, user_desc desc)
+{
+#ifdef __x86_64__
+ return HYPERCALL2(long, __HYPERVISOR_update_descriptor, maddr, desc.raw);
+#else
+ return HYPERCALL4(long, __HYPERVISOR_update_descriptor,
+ maddr, maddr >> 32, desc.lo, desc.hi);
+#endif
+}
+
static inline long hypercall_memory_op(unsigned int cmd, void *arg)
{
return HYPERCALL2(long, __HYPERVISOR_memory_op, cmd, arg);