aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorMukesh Rathor <mukesh.rathor@oracle.com>2013-12-13 13:03:37 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2014-01-06 10:44:10 -0500
commit8d656bbe43aee6d1be6b49fcf8acbc04588472bc (patch)
treefd4e39fe2758a0c6b9542c84152c3041bed1df0e /arch/x86
parent4dd322bc3b25be40dfa91e8ac483b846f3e8dffc (diff)
xen/pvh: Load GDT/GS in early PV bootup code for BSP.
During early bootup we start life using the Xen provided GDT, which means that we are running with %cs segment set to FLAT_KERNEL_CS (FLAT_RING3_CS64 0xe033, GDT index 261). But for PVH we want to be use HVM type mechanism for segment operations. As such we need to switch to the HVM one and also reload ourselves with the __KERNEL_CS:eip to run in the proper GDT and segment. For HVM this is usually done in 'secondary_startup_64' in (head_64.S) but since we are not taking that bootup path (we start in PV - xen_start_kernel) we need to do that in the early PV bootup paths. For good measure we also zero out the %fs, %ds, and %es (not strictly needed as Xen has already cleared them for us). The %gs is loaded by 'switch_to_new_gdt'. Signed-off-by: Mukesh Rathor <mukesh.rathor@oracle.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Reviewed-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/xen/enlighten.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 23ead298edbd..1170d00879d5 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1410,8 +1410,43 @@ static void __init xen_boot_params_init_edd(void)
1410 * we do this, we have to be careful not to call any stack-protected 1410 * we do this, we have to be careful not to call any stack-protected
1411 * function, which is most of the kernel. 1411 * function, which is most of the kernel.
1412 */ 1412 */
1413static void __init xen_setup_stackprotector(void) 1413static void __init xen_setup_gdt(void)
1414{ 1414{
1415 if (xen_feature(XENFEAT_auto_translated_physmap)) {
1416#ifdef CONFIG_X86_64
1417 unsigned long dummy;
1418
1419 switch_to_new_gdt(0); /* GDT and GS set */
1420
1421 /* We are switching of the Xen provided GDT to our HVM mode
1422 * GDT. The new GDT has __KERNEL_CS with CS.L = 1
1423 * and we are jumping to reload it.
1424 */
1425 asm volatile ("pushq %0\n"
1426 "leaq 1f(%%rip),%0\n"
1427 "pushq %0\n"
1428 "lretq\n"
1429 "1:\n"
1430 : "=&r" (dummy) : "0" (__KERNEL_CS));
1431
1432 /*
1433 * While not needed, we also set the %es, %ds, and %fs
1434 * to zero. We don't care about %ss as it is NULL.
1435 * Strictly speaking this is not needed as Xen zeros those
1436 * out (and also MSR_FS_BASE, MSR_GS_BASE, MSR_KERNEL_GS_BASE)
1437 *
1438 * Linux zeros them in cpu_init() and in secondary_startup_64
1439 * (for BSP).
1440 */
1441 loadsegment(es, 0);
1442 loadsegment(ds, 0);
1443 loadsegment(fs, 0);
1444#else
1445 /* PVH: TODO Implement. */
1446 BUG();
1447#endif
1448 return; /* PVH does not need any PV GDT ops. */
1449 }
1415 pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot; 1450 pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot;
1416 pv_cpu_ops.load_gdt = xen_load_gdt_boot; 1451 pv_cpu_ops.load_gdt = xen_load_gdt_boot;
1417 1452
@@ -1494,7 +1529,7 @@ asmlinkage void __init xen_start_kernel(void)
1494 * Set up kernel GDT and segment registers, mainly so that 1529 * Set up kernel GDT and segment registers, mainly so that
1495 * -fstack-protector code can be executed. 1530 * -fstack-protector code can be executed.
1496 */ 1531 */
1497 xen_setup_stackprotector(); 1532 xen_setup_gdt();
1498 1533
1499 xen_init_irq_ops(); 1534 xen_init_irq_ops();
1500 xen_init_cpuid_mask(); 1535 xen_init_cpuid_mask();