xen: set IO permission early (before early_cpu_init())
This patch is based off "xen dom0: Set up basic IO permissions for dom0." by Juan Quintela <quintela@redhat.com>. On AMD machines when we boot the kernel as Domain 0 we get this nasty: mapping kernel into physical memory Xen: setup ISA identity maps about to get started... (XEN) traps.c:475:d0 Unhandled general protection fault fault/trap [#13] on VCPU 0 [ec=0000] (XEN) domain_crash_sync called from entry.S (XEN) Domain 0 (vcpu#0) crashed on cpu#0: (XEN) ----[ Xen-4.1-101116 x86_64 debug=y Not tainted ]---- (XEN) CPU: 0 (XEN) RIP: e033:[<ffffffff8130271b>] (XEN) RFLAGS: 0000000000000282 EM: 1 CONTEXT: pv guest (XEN) rax: 000000008000c068 rbx: ffffffff8186c680 rcx: 0000000000000068 (XEN) rdx: 0000000000000cf8 rsi: 000000000000c000 rdi: 0000000000000000 (XEN) rbp: ffffffff81801e98 rsp: ffffffff81801e50 r8: ffffffff81801eac (XEN) r9: ffffffff81801ea8 r10: ffffffff81801eb4 r11: 00000000ffffffff (XEN) r12: ffffffff8186c694 r13: ffffffff81801f90 r14: ffffffffffffffff (XEN) r15: 0000000000000000 cr0: 000000008005003b cr4: 00000000000006f0 (XEN) cr3: 0000000221803000 cr2: 0000000000000000 (XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: e02b cs: e033 (XEN) Guest stack trace from rsp=ffffffff81801e50: RIP points to read_pci_config() function. The issue is that we don't set IO permissions for the Linux kernel early enough. The call sequence used to be: xen_start_kernel() x86_init.oem.arch_setup = xen_setup_arch; setup_arch: - early_cpu_init - early_init_amd - read_pci_config - x86_init.oem.arch_setup [ xen_arch_setup ] - set IO permissions. We need to set the IO permissions earlier on, which this patch does. Acked-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This commit is contained in:
Родитель
d2a817130c
Коммит
ec35a69c46
|
@ -1095,6 +1095,8 @@ static void __init xen_setup_stackprotector(void)
|
||||||
/* First C function to be called on Xen boot */
|
/* First C function to be called on Xen boot */
|
||||||
asmlinkage void __init xen_start_kernel(void)
|
asmlinkage void __init xen_start_kernel(void)
|
||||||
{
|
{
|
||||||
|
struct physdev_set_iopl set_iopl;
|
||||||
|
int rc;
|
||||||
pgd_t *pgd;
|
pgd_t *pgd;
|
||||||
|
|
||||||
if (!xen_start_info)
|
if (!xen_start_info)
|
||||||
|
@ -1209,10 +1211,18 @@ asmlinkage void __init xen_start_kernel(void)
|
||||||
#else
|
#else
|
||||||
pv_info.kernel_rpl = 0;
|
pv_info.kernel_rpl = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* set the limit of our address space */
|
/* set the limit of our address space */
|
||||||
xen_reserve_top();
|
xen_reserve_top();
|
||||||
|
|
||||||
|
/* We used to do this in xen_arch_setup, but that is too late on AMD
|
||||||
|
* were early_cpu_init (run before ->arch_setup()) calls early_amd_init
|
||||||
|
* which pokes 0xcf8 port.
|
||||||
|
*/
|
||||||
|
set_iopl.iopl = 1;
|
||||||
|
rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
|
||||||
|
if (rc != 0)
|
||||||
|
xen_raw_printk("physdev_op failed %d\n", rc);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
/* set up basic CPUID stuff */
|
/* set up basic CPUID stuff */
|
||||||
cpu_detect(&new_cpu_data);
|
cpu_detect(&new_cpu_data);
|
||||||
|
|
|
@ -336,9 +336,6 @@ void __cpuinit xen_enable_syscall(void)
|
||||||
|
|
||||||
void __init xen_arch_setup(void)
|
void __init xen_arch_setup(void)
|
||||||
{
|
{
|
||||||
struct physdev_set_iopl set_iopl;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
xen_panic_handler_init();
|
xen_panic_handler_init();
|
||||||
|
|
||||||
HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
|
HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
|
||||||
|
@ -355,11 +352,6 @@ void __init xen_arch_setup(void)
|
||||||
xen_enable_sysenter();
|
xen_enable_sysenter();
|
||||||
xen_enable_syscall();
|
xen_enable_syscall();
|
||||||
|
|
||||||
set_iopl.iopl = 1;
|
|
||||||
rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
|
|
||||||
if (rc != 0)
|
|
||||||
printk(KERN_INFO "physdev_op failed %d\n", rc);
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
|
if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
|
||||||
printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
|
printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче