aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/enlighten.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@xensource.com>2007-10-16 14:51:29 -0400
committerJeremy Fitzhardinge <jeremy@goop.org>2007-10-16 14:51:29 -0400
commit93b1eab3d29e7ea32ee583de3362da84db06ded8 (patch)
tree8dc7eb61d4c65a48f9ce21a49e392f4967185cfd /arch/x86/xen/enlighten.c
parentab9c232286c2b77be78441c2d8396500b045777e (diff)
paravirt: refactor struct paravirt_ops into smaller pv_*_ops
This patch refactors the paravirt_ops structure into groups of functionally related ops: pv_info - random info, rather than function entrypoints pv_init_ops - functions used at boot time (some for module_init too) pv_misc_ops - lazy mode, which didn't fit well anywhere else pv_time_ops - time-related functions pv_cpu_ops - various privileged instruction ops pv_irq_ops - operations for managing interrupt state pv_apic_ops - APIC operations pv_mmu_ops - operations for managing pagetables There are several motivations for this: 1. Some of these ops will be general to all x86, and some will be i386/x86-64 specific. This makes it easier to share common stuff while allowing separate implementations where needed. 2. At the moment we must export all of paravirt_ops, but modules only need selected parts of it. This allows us to export on a case by case basis (and also choose which export license we want to apply). 3. Functional groupings make things a bit more readable. Struct paravirt_ops is now only used as a template to generate patch-site identifiers, and to extract function pointers for inserting into jmp/calls when patching. It is only instantiated when needed. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Cc: Andi Kleen <ak@suse.de> Cc: Zach Amsden <zach@vmware.com> Cc: Avi Kivity <avi@qumranet.com> Cc: Anthony Liguory <aliguori@us.ibm.com> Cc: "Glauber de Oliveira Costa" <glommer@gmail.com> Cc: Jun Nakajima <jun.nakajima@intel.com>
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r--arch/x86/xen/enlighten.c98
1 files changed, 61 insertions, 37 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index f01bfcd4bdee..3d3bf05dec7f 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -124,7 +124,7 @@ static void __init xen_vcpu_setup(int cpu)
124static void __init xen_banner(void) 124static void __init xen_banner(void)
125{ 125{
126 printk(KERN_INFO "Booting paravirtualized kernel on %s\n", 126 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
127 paravirt_ops.name); 127 pv_info.name);
128 printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic); 128 printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic);
129} 129}
130 130
@@ -738,7 +738,7 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
738 pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base; 738 pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
739 739
740 /* special set_pte for pagetable initialization */ 740 /* special set_pte for pagetable initialization */
741 paravirt_ops.set_pte = xen_set_pte_init; 741 pv_mmu_ops.set_pte = xen_set_pte_init;
742 742
743 init_mm.pgd = base; 743 init_mm.pgd = base;
744 /* 744 /*
@@ -785,8 +785,8 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
785{ 785{
786 /* This will work as long as patching hasn't happened yet 786 /* This will work as long as patching hasn't happened yet
787 (which it hasn't) */ 787 (which it hasn't) */
788 paravirt_ops.alloc_pt = xen_alloc_pt; 788 pv_mmu_ops.alloc_pt = xen_alloc_pt;
789 paravirt_ops.set_pte = xen_set_pte; 789 pv_mmu_ops.set_pte = xen_set_pte;
790 790
791 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 791 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
792 /* 792 /*
@@ -833,12 +833,12 @@ void __init xen_setup_vcpu_info_placement(void)
833 if (have_vcpu_info_placement) { 833 if (have_vcpu_info_placement) {
834 printk(KERN_INFO "Xen: using vcpu_info placement\n"); 834 printk(KERN_INFO "Xen: using vcpu_info placement\n");
835 835
836 paravirt_ops.save_fl = xen_save_fl_direct; 836 pv_irq_ops.save_fl = xen_save_fl_direct;
837 paravirt_ops.restore_fl = xen_restore_fl_direct; 837 pv_irq_ops.restore_fl = xen_restore_fl_direct;
838 paravirt_ops.irq_disable = xen_irq_disable_direct; 838 pv_irq_ops.irq_disable = xen_irq_disable_direct;
839 paravirt_ops.irq_enable = xen_irq_enable_direct; 839 pv_irq_ops.irq_enable = xen_irq_enable_direct;
840 paravirt_ops.read_cr2 = xen_read_cr2_direct; 840 pv_mmu_ops.read_cr2 = xen_read_cr2_direct;
841 paravirt_ops.iret = xen_iret_direct; 841 pv_cpu_ops.iret = xen_iret_direct;
842 } 842 }
843} 843}
844 844
@@ -850,8 +850,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
850 850
851 start = end = reloc = NULL; 851 start = end = reloc = NULL;
852 852
853#define SITE(x) \ 853#define SITE(op, x) \
854 case PARAVIRT_PATCH(x): \ 854 case PARAVIRT_PATCH(op.x): \
855 if (have_vcpu_info_placement) { \ 855 if (have_vcpu_info_placement) { \
856 start = (char *)xen_##x##_direct; \ 856 start = (char *)xen_##x##_direct; \
857 end = xen_##x##_direct_end; \ 857 end = xen_##x##_direct_end; \
@@ -860,10 +860,10 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
860 goto patch_site 860 goto patch_site
861 861
862 switch (type) { 862 switch (type) {
863 SITE(irq_enable); 863 SITE(pv_irq_ops, irq_enable);
864 SITE(irq_disable); 864 SITE(pv_irq_ops, irq_disable);
865 SITE(save_fl); 865 SITE(pv_irq_ops, save_fl);
866 SITE(restore_fl); 866 SITE(pv_irq_ops, restore_fl);
867#undef SITE 867#undef SITE
868 868
869 patch_site: 869 patch_site:
@@ -895,26 +895,32 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
895 return ret; 895 return ret;
896} 896}
897 897
898static const struct paravirt_ops xen_paravirt_ops __initdata = { 898static const struct pv_info xen_info __initdata = {
899 .paravirt_enabled = 1, 899 .paravirt_enabled = 1,
900 .shared_kernel_pmd = 0, 900 .shared_kernel_pmd = 0,
901 901
902 .name = "Xen", 902 .name = "Xen",
903 .banner = xen_banner, 903};
904 904
905static const struct pv_init_ops xen_init_ops __initdata = {
905 .patch = xen_patch, 906 .patch = xen_patch,
906 907
908 .banner = xen_banner,
907 .memory_setup = xen_memory_setup, 909 .memory_setup = xen_memory_setup,
908 .arch_setup = xen_arch_setup, 910 .arch_setup = xen_arch_setup,
909 .init_IRQ = xen_init_IRQ,
910 .post_allocator_init = xen_mark_init_mm_pinned, 911 .post_allocator_init = xen_mark_init_mm_pinned,
912};
911 913
914static const struct pv_time_ops xen_time_ops __initdata = {
912 .time_init = xen_time_init, 915 .time_init = xen_time_init,
916
913 .set_wallclock = xen_set_wallclock, 917 .set_wallclock = xen_set_wallclock,
914 .get_wallclock = xen_get_wallclock, 918 .get_wallclock = xen_get_wallclock,
915 .get_cpu_khz = xen_cpu_khz, 919 .get_cpu_khz = xen_cpu_khz,
916 .sched_clock = xen_sched_clock, 920 .sched_clock = xen_sched_clock,
921};
917 922
923static const struct pv_cpu_ops xen_cpu_ops __initdata = {
918 .cpuid = xen_cpuid, 924 .cpuid = xen_cpuid,
919 925
920 .set_debugreg = xen_set_debugreg, 926 .set_debugreg = xen_set_debugreg,
@@ -925,22 +931,10 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
925 .read_cr0 = native_read_cr0, 931 .read_cr0 = native_read_cr0,
926 .write_cr0 = native_write_cr0, 932 .write_cr0 = native_write_cr0,
927 933
928 .read_cr2 = xen_read_cr2,
929 .write_cr2 = xen_write_cr2,
930
931 .read_cr3 = xen_read_cr3,
932 .write_cr3 = xen_write_cr3,
933
934 .read_cr4 = native_read_cr4, 934 .read_cr4 = native_read_cr4,
935 .read_cr4_safe = native_read_cr4_safe, 935 .read_cr4_safe = native_read_cr4_safe,
936 .write_cr4 = xen_write_cr4, 936 .write_cr4 = xen_write_cr4,
937 937
938 .save_fl = xen_save_fl,
939 .restore_fl = xen_restore_fl,
940 .irq_disable = xen_irq_disable,
941 .irq_enable = xen_irq_enable,
942 .safe_halt = xen_safe_halt,
943 .halt = xen_halt,
944 .wbinvd = native_wbinvd, 938 .wbinvd = native_wbinvd,
945 939
946 .read_msr = native_read_msr_safe, 940 .read_msr = native_read_msr_safe,
@@ -968,7 +962,19 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
968 962
969 .set_iopl_mask = xen_set_iopl_mask, 963 .set_iopl_mask = xen_set_iopl_mask,
970 .io_delay = xen_io_delay, 964 .io_delay = xen_io_delay,
965};
966
967static const struct pv_irq_ops xen_irq_ops __initdata = {
968 .init_IRQ = xen_init_IRQ,
969 .save_fl = xen_save_fl,
970 .restore_fl = xen_restore_fl,
971 .irq_disable = xen_irq_disable,
972 .irq_enable = xen_irq_enable,
973 .safe_halt = xen_safe_halt,
974 .halt = xen_halt,
975};
971 976
977static const struct pv_apic_ops xen_apic_ops __initdata = {
972#ifdef CONFIG_X86_LOCAL_APIC 978#ifdef CONFIG_X86_LOCAL_APIC
973 .apic_write = xen_apic_write, 979 .apic_write = xen_apic_write,
974 .apic_write_atomic = xen_apic_write, 980 .apic_write_atomic = xen_apic_write,
@@ -977,6 +983,17 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
977 .setup_secondary_clock = paravirt_nop, 983 .setup_secondary_clock = paravirt_nop,
978 .startup_ipi_hook = paravirt_nop, 984 .startup_ipi_hook = paravirt_nop,
979#endif 985#endif
986};
987
988static const struct pv_mmu_ops xen_mmu_ops __initdata = {
989 .pagetable_setup_start = xen_pagetable_setup_start,
990 .pagetable_setup_done = xen_pagetable_setup_done,
991
992 .read_cr2 = xen_read_cr2,
993 .write_cr2 = xen_write_cr2,
994
995 .read_cr3 = xen_read_cr3,
996 .write_cr3 = xen_write_cr3,
980 997
981 .flush_tlb_user = xen_flush_tlb, 998 .flush_tlb_user = xen_flush_tlb,
982 .flush_tlb_kernel = xen_flush_tlb, 999 .flush_tlb_kernel = xen_flush_tlb,
@@ -986,9 +1003,6 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
986 .pte_update = paravirt_nop, 1003 .pte_update = paravirt_nop,
987 .pte_update_defer = paravirt_nop, 1004 .pte_update_defer = paravirt_nop,
988 1005
989 .pagetable_setup_start = xen_pagetable_setup_start,
990 .pagetable_setup_done = xen_pagetable_setup_done,
991
992 .alloc_pt = xen_alloc_pt_init, 1006 .alloc_pt = xen_alloc_pt_init,
993 .release_pt = xen_release_pt, 1007 .release_pt = xen_release_pt,
994 .alloc_pd = paravirt_nop, 1008 .alloc_pd = paravirt_nop,
@@ -1023,7 +1037,9 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
1023 .activate_mm = xen_activate_mm, 1037 .activate_mm = xen_activate_mm,
1024 .dup_mmap = xen_dup_mmap, 1038 .dup_mmap = xen_dup_mmap,
1025 .exit_mmap = xen_exit_mmap, 1039 .exit_mmap = xen_exit_mmap,
1040};
1026 1041
1042static const struct pv_misc_ops xen_misc_ops __initdata = {
1027 .set_lazy_mode = xen_set_lazy_mode, 1043 .set_lazy_mode = xen_set_lazy_mode,
1028}; 1044};
1029 1045
@@ -1091,7 +1107,15 @@ asmlinkage void __init xen_start_kernel(void)
1091 BUG_ON(memcmp(xen_start_info->magic, "xen-3.0", 7) != 0); 1107 BUG_ON(memcmp(xen_start_info->magic, "xen-3.0", 7) != 0);
1092 1108
1093 /* Install Xen paravirt ops */ 1109 /* Install Xen paravirt ops */
1094 paravirt_ops = xen_paravirt_ops; 1110 pv_info = xen_info;
1111 pv_init_ops = xen_init_ops;
1112 pv_time_ops = xen_time_ops;
1113 pv_cpu_ops = xen_cpu_ops;
1114 pv_irq_ops = xen_irq_ops;
1115 pv_apic_ops = xen_apic_ops;
1116 pv_mmu_ops = xen_mmu_ops;
1117 pv_misc_ops = xen_misc_ops;
1118
1095 machine_ops = xen_machine_ops; 1119 machine_ops = xen_machine_ops;
1096 1120
1097#ifdef CONFIG_SMP 1121#ifdef CONFIG_SMP
@@ -1124,9 +1148,9 @@ asmlinkage void __init xen_start_kernel(void)
1124 xen_setup_vcpu_info_placement(); 1148 xen_setup_vcpu_info_placement();
1125#endif 1149#endif
1126 1150
1127 paravirt_ops.kernel_rpl = 1; 1151 pv_info.kernel_rpl = 1;
1128 if (xen_feature(XENFEAT_supervisor_mode_kernel)) 1152 if (xen_feature(XENFEAT_supervisor_mode_kernel))
1129 paravirt_ops.kernel_rpl = 0; 1153 pv_info.kernel_rpl = 0;
1130 1154
1131 /* set the limit of our address space */ 1155 /* set the limit of our address space */
1132 reserve_top_address(-HYPERVISOR_VIRT_START + 2 * PAGE_SIZE); 1156 reserve_top_address(-HYPERVISOR_VIRT_START + 2 * PAGE_SIZE);