x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays
In order to allow objtool to make sense of all the various paravirt functions, it needs to either parse whole pv_ops[] tables, or observe individual assignments in the form: bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip) bf92 <xen_init_spinlocks+0x5f> bf8a: R_X86_64_PC32 pv_ops+0x268 As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and xen_mmu_ops[] are not. Worse, both the latter two are compiled into the individual assignment for by current GCC, but that's not something one can rely on. Therefore, convert all three into full pv_ops[] tables. This has the benefit of not needing to teach objtool about the offsets and resulting in more conservative code-gen. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Juergen Gross <jgross@suse.com> Link: https://lore.kernel.org/r/20210624095149.057262522@infradead.org
This commit is contained in:
Родитель
847d9317b2
Коммит
1462eb381b
|
@ -1050,52 +1050,54 @@ static const struct pv_info xen_info __initconst = {
|
|||
.name = "Xen",
|
||||
};
|
||||
|
||||
static const struct pv_cpu_ops xen_cpu_ops __initconst = {
|
||||
.cpuid = xen_cpuid,
|
||||
static const typeof(pv_ops) xen_cpu_ops __initconst = {
|
||||
.cpu = {
|
||||
.cpuid = xen_cpuid,
|
||||
|
||||
.set_debugreg = xen_set_debugreg,
|
||||
.get_debugreg = xen_get_debugreg,
|
||||
.set_debugreg = xen_set_debugreg,
|
||||
.get_debugreg = xen_get_debugreg,
|
||||
|
||||
.read_cr0 = xen_read_cr0,
|
||||
.write_cr0 = xen_write_cr0,
|
||||
.read_cr0 = xen_read_cr0,
|
||||
.write_cr0 = xen_write_cr0,
|
||||
|
||||
.write_cr4 = xen_write_cr4,
|
||||
.write_cr4 = xen_write_cr4,
|
||||
|
||||
.wbinvd = native_wbinvd,
|
||||
.wbinvd = native_wbinvd,
|
||||
|
||||
.read_msr = xen_read_msr,
|
||||
.write_msr = xen_write_msr,
|
||||
.read_msr = xen_read_msr,
|
||||
.write_msr = xen_write_msr,
|
||||
|
||||
.read_msr_safe = xen_read_msr_safe,
|
||||
.write_msr_safe = xen_write_msr_safe,
|
||||
.read_msr_safe = xen_read_msr_safe,
|
||||
.write_msr_safe = xen_write_msr_safe,
|
||||
|
||||
.read_pmc = xen_read_pmc,
|
||||
.read_pmc = xen_read_pmc,
|
||||
|
||||
.load_tr_desc = paravirt_nop,
|
||||
.set_ldt = xen_set_ldt,
|
||||
.load_gdt = xen_load_gdt,
|
||||
.load_idt = xen_load_idt,
|
||||
.load_tls = xen_load_tls,
|
||||
.load_gs_index = xen_load_gs_index,
|
||||
.load_tr_desc = paravirt_nop,
|
||||
.set_ldt = xen_set_ldt,
|
||||
.load_gdt = xen_load_gdt,
|
||||
.load_idt = xen_load_idt,
|
||||
.load_tls = xen_load_tls,
|
||||
.load_gs_index = xen_load_gs_index,
|
||||
|
||||
.alloc_ldt = xen_alloc_ldt,
|
||||
.free_ldt = xen_free_ldt,
|
||||
.alloc_ldt = xen_alloc_ldt,
|
||||
.free_ldt = xen_free_ldt,
|
||||
|
||||
.store_tr = xen_store_tr,
|
||||
.store_tr = xen_store_tr,
|
||||
|
||||
.write_ldt_entry = xen_write_ldt_entry,
|
||||
.write_gdt_entry = xen_write_gdt_entry,
|
||||
.write_idt_entry = xen_write_idt_entry,
|
||||
.load_sp0 = xen_load_sp0,
|
||||
.write_ldt_entry = xen_write_ldt_entry,
|
||||
.write_gdt_entry = xen_write_gdt_entry,
|
||||
.write_idt_entry = xen_write_idt_entry,
|
||||
.load_sp0 = xen_load_sp0,
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
.invalidate_io_bitmap = xen_invalidate_io_bitmap,
|
||||
.update_io_bitmap = xen_update_io_bitmap,
|
||||
.invalidate_io_bitmap = xen_invalidate_io_bitmap,
|
||||
.update_io_bitmap = xen_update_io_bitmap,
|
||||
#endif
|
||||
.io_delay = xen_io_delay,
|
||||
.io_delay = xen_io_delay,
|
||||
|
||||
.start_context_switch = paravirt_start_context_switch,
|
||||
.end_context_switch = xen_end_context_switch,
|
||||
.start_context_switch = paravirt_start_context_switch,
|
||||
.end_context_switch = xen_end_context_switch,
|
||||
},
|
||||
};
|
||||
|
||||
static void xen_restart(char *msg)
|
||||
|
@ -1231,7 +1233,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
|
|||
|
||||
/* Install Xen paravirt ops */
|
||||
pv_info = xen_info;
|
||||
pv_ops.cpu = xen_cpu_ops;
|
||||
pv_ops.cpu = xen_cpu_ops.cpu;
|
||||
paravirt_iret = xen_iret;
|
||||
xen_init_irq_ops();
|
||||
|
||||
|
|
|
@ -94,17 +94,20 @@ static void xen_halt(void)
|
|||
xen_safe_halt();
|
||||
}
|
||||
|
||||
static const struct pv_irq_ops xen_irq_ops __initconst = {
|
||||
.save_fl = PV_CALLEE_SAVE(xen_save_fl),
|
||||
.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
|
||||
.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
|
||||
static const typeof(pv_ops) xen_irq_ops __initconst = {
|
||||
.irq = {
|
||||
|
||||
.safe_halt = xen_safe_halt,
|
||||
.halt = xen_halt,
|
||||
.save_fl = PV_CALLEE_SAVE(xen_save_fl),
|
||||
.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
|
||||
.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
|
||||
|
||||
.safe_halt = xen_safe_halt,
|
||||
.halt = xen_halt,
|
||||
},
|
||||
};
|
||||
|
||||
void __init xen_init_irq_ops(void)
|
||||
{
|
||||
pv_ops.irq = xen_irq_ops;
|
||||
pv_ops.irq = xen_irq_ops.irq;
|
||||
x86_init.irqs.intr_init = xen_init_IRQ;
|
||||
}
|
||||
|
|
|
@ -2076,67 +2076,69 @@ static void xen_leave_lazy_mmu(void)
|
|||
preempt_enable();
|
||||
}
|
||||
|
||||
static const struct pv_mmu_ops xen_mmu_ops __initconst = {
|
||||
.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
|
||||
.write_cr2 = xen_write_cr2,
|
||||
static const typeof(pv_ops) xen_mmu_ops __initconst = {
|
||||
.mmu = {
|
||||
.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
|
||||
.write_cr2 = xen_write_cr2,
|
||||
|
||||
.read_cr3 = xen_read_cr3,
|
||||
.write_cr3 = xen_write_cr3_init,
|
||||
.read_cr3 = xen_read_cr3,
|
||||
.write_cr3 = xen_write_cr3_init,
|
||||
|
||||
.flush_tlb_user = xen_flush_tlb,
|
||||
.flush_tlb_kernel = xen_flush_tlb,
|
||||
.flush_tlb_one_user = xen_flush_tlb_one_user,
|
||||
.flush_tlb_multi = xen_flush_tlb_multi,
|
||||
.tlb_remove_table = tlb_remove_table,
|
||||
.flush_tlb_user = xen_flush_tlb,
|
||||
.flush_tlb_kernel = xen_flush_tlb,
|
||||
.flush_tlb_one_user = xen_flush_tlb_one_user,
|
||||
.flush_tlb_multi = xen_flush_tlb_multi,
|
||||
.tlb_remove_table = tlb_remove_table,
|
||||
|
||||
.pgd_alloc = xen_pgd_alloc,
|
||||
.pgd_free = xen_pgd_free,
|
||||
.pgd_alloc = xen_pgd_alloc,
|
||||
.pgd_free = xen_pgd_free,
|
||||
|
||||
.alloc_pte = xen_alloc_pte_init,
|
||||
.release_pte = xen_release_pte_init,
|
||||
.alloc_pmd = xen_alloc_pmd_init,
|
||||
.release_pmd = xen_release_pmd_init,
|
||||
.alloc_pte = xen_alloc_pte_init,
|
||||
.release_pte = xen_release_pte_init,
|
||||
.alloc_pmd = xen_alloc_pmd_init,
|
||||
.release_pmd = xen_release_pmd_init,
|
||||
|
||||
.set_pte = xen_set_pte_init,
|
||||
.set_pmd = xen_set_pmd_hyper,
|
||||
.set_pte = xen_set_pte_init,
|
||||
.set_pmd = xen_set_pmd_hyper,
|
||||
|
||||
.ptep_modify_prot_start = xen_ptep_modify_prot_start,
|
||||
.ptep_modify_prot_commit = xen_ptep_modify_prot_commit,
|
||||
.ptep_modify_prot_start = xen_ptep_modify_prot_start,
|
||||
.ptep_modify_prot_commit = xen_ptep_modify_prot_commit,
|
||||
|
||||
.pte_val = PV_CALLEE_SAVE(xen_pte_val),
|
||||
.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
|
||||
.pte_val = PV_CALLEE_SAVE(xen_pte_val),
|
||||
.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
|
||||
|
||||
.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
|
||||
.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
|
||||
.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
|
||||
.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
|
||||
|
||||
.set_pud = xen_set_pud_hyper,
|
||||
.set_pud = xen_set_pud_hyper,
|
||||
|
||||
.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
|
||||
.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
|
||||
.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
|
||||
.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
|
||||
|
||||
.pud_val = PV_CALLEE_SAVE(xen_pud_val),
|
||||
.make_pud = PV_CALLEE_SAVE(xen_make_pud),
|
||||
.set_p4d = xen_set_p4d_hyper,
|
||||
.pud_val = PV_CALLEE_SAVE(xen_pud_val),
|
||||
.make_pud = PV_CALLEE_SAVE(xen_make_pud),
|
||||
.set_p4d = xen_set_p4d_hyper,
|
||||
|
||||
.alloc_pud = xen_alloc_pmd_init,
|
||||
.release_pud = xen_release_pmd_init,
|
||||
.alloc_pud = xen_alloc_pmd_init,
|
||||
.release_pud = xen_release_pmd_init,
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS >= 5
|
||||
.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
|
||||
.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
|
||||
.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
|
||||
.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
|
||||
#endif
|
||||
|
||||
.activate_mm = xen_activate_mm,
|
||||
.dup_mmap = xen_dup_mmap,
|
||||
.exit_mmap = xen_exit_mmap,
|
||||
.activate_mm = xen_activate_mm,
|
||||
.dup_mmap = xen_dup_mmap,
|
||||
.exit_mmap = xen_exit_mmap,
|
||||
|
||||
.lazy_mode = {
|
||||
.enter = paravirt_enter_lazy_mmu,
|
||||
.leave = xen_leave_lazy_mmu,
|
||||
.flush = paravirt_flush_lazy_mmu,
|
||||
.lazy_mode = {
|
||||
.enter = paravirt_enter_lazy_mmu,
|
||||
.leave = xen_leave_lazy_mmu,
|
||||
.flush = paravirt_flush_lazy_mmu,
|
||||
},
|
||||
|
||||
.set_fixmap = xen_set_fixmap,
|
||||
},
|
||||
|
||||
.set_fixmap = xen_set_fixmap,
|
||||
};
|
||||
|
||||
void __init xen_init_mmu_ops(void)
|
||||
|
@ -2144,7 +2146,7 @@ void __init xen_init_mmu_ops(void)
|
|||
x86_init.paging.pagetable_init = xen_pagetable_init;
|
||||
x86_init.hyper.init_after_bootmem = xen_after_bootmem;
|
||||
|
||||
pv_ops.mmu = xen_mmu_ops;
|
||||
pv_ops.mmu = xen_mmu_ops.mmu;
|
||||
|
||||
memset(dummy_mapping, 0xff, PAGE_SIZE);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче