--- arch/x86/xen/setup.c | 51 ++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index ead8557..fba442e 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -26,6 +26,7 @@ #include <xen/interface/memory.h> #include <xen/interface/physdev.h> #include <xen/features.h> +#include "mmu.h" #include "xen-ops.h" #include "vdso.h" @@ -222,6 +223,26 @@ static void __init xen_set_identity_and_release_chunk( *identity += set_phys_range_identity(start_pfn, end_pfn); } +/* For PVH, the pfns [0..MAX] are mapped to mfn''s in the EPT/NPT. The mfns + * are released as part of this 1:1 mapping hypercall back to the dom heap. We + * don''t use the xen_do_chunk() PV does above because when P2M/EPT/NPT is + * updated, the mfns are already lost as part of the p2m update. + * Also, we map the entire IO space, ie, beyond max_pfn_mapped. + */ +static void __init xen_pvh_identity_map_chunk(unsigned long start_pfn, + unsigned long end_pfn, unsigned long *released, + unsigned long *identity) +{ + unsigned long pfn; + int numpfns=1, add_mapping=1; + + for (pfn = start_pfn; pfn < end_pfn; pfn++) + xen_set_clr_mmio_pvh_pte(pfn, pfn, numpfns, add_mapping); + + *released += end_pfn - start_pfn; + *identity += end_pfn - start_pfn; +} + static unsigned long __init xen_set_identity_and_release( const struct e820entry *list, size_t map_size, unsigned long nr_pages) { @@ -230,6 +251,7 @@ static unsigned long __init xen_set_identity_and_release( unsigned long identity = 0; const struct e820entry *entry; int i; + int xlated_phys = xen_feature(XENFEAT_auto_translated_physmap); /* * Combine non-RAM regions and gaps until a RAM region (or the @@ -251,11 +273,16 @@ static unsigned long __init xen_set_identity_and_release( if (entry->type == E820_RAM) end_pfn = PFN_UP(entry->addr); - if (start_pfn < end_pfn) - xen_set_identity_and_release_chunk( - start_pfn, end_pfn, nr_pages, - &released, &identity); - + if (start_pfn < end_pfn) { + if (xlated_phys) { + xen_pvh_identity_map_chunk(start_pfn, + end_pfn, &released, &identity); + } else { + xen_set_identity_and_release_chunk( + start_pfn, end_pfn, nr_pages, + &released, &identity); + } + } start = end; } } @@ -500,10 +527,9 @@ void __cpuinit xen_enable_syscall(void) #endif /* CONFIG_X86_64 */ } -void __init xen_arch_setup(void) +/* Non auto translated PV domain, ie, it''s not PVH. */ +static __init void inline xen_non_pvh_arch_setup(void) { - xen_panic_handler_init(); - HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); @@ -517,6 +543,15 @@ void __init xen_arch_setup(void) xen_enable_sysenter(); xen_enable_syscall(); +} + +/* This function not called for HVM domain */ +void __init xen_arch_setup(void) +{ + xen_panic_handler_init(); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) + xen_non_pvh_arch_setup(); #ifdef CONFIG_ACPI if (!(xen_start_info->flags & SIF_INITDOMAIN)) { -- 1.7.2.3
On Fri, 21 Sep 2012, Mukesh Rathor wrote:> @@ -500,10 +527,9 @@ void __cpuinit xen_enable_syscall(void) > #endif /* CONFIG_X86_64 */ > } > > -void __init xen_arch_setup(void) > +/* Non auto translated PV domain, ie, it''s not PVH. */ > +static __init void inline xen_non_pvh_arch_setup(void) > { > - xen_panic_handler_init(); > - > HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); > HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); > > @@ -517,6 +543,15 @@ void __init xen_arch_setup(void) > > xen_enable_sysenter(); > xen_enable_syscall(); > +} > + > +/* This function not called for HVM domain */ > +void __init xen_arch_setup(void) > +{ > + xen_panic_handler_init(); > + > + if (!xen_feature(XENFEAT_auto_translated_physmap)) > + xen_non_pvh_arch_setup(); > > #ifdef CONFIG_ACPI > if (!(xen_start_info->flags & SIF_INITDOMAIN)) {IMHO having a xen_non_pvh_arch_setup function is less intuitive than just wrapping all that code around an if (!xen_feature(XENFEAT_auto_translated_physmap)) { Or at least you could name the function xen_pvmmu_arch_setup.
On Mon, 24 Sep 2012 13:14:45 +0100 Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:> On Fri, 21 Sep 2012, Mukesh Rathor wrote: > > @@ -500,10 +527,9 @@ void __cpuinit xen_enable_syscall(void) > > #endif /* CONFIG_X86_64 */ > > } > > > > -void __init xen_arch_setup(void) > > +/* Non auto translated PV domain, ie, it''s not PVH. */ > > +static __init void inline xen_non_pvh_arch_setup(void) > > { > > - xen_panic_handler_init(); > > - > > HYPERVISOR_vm_assist(VMASST_CMD_enable, > > VMASST_TYPE_4gb_segments); HYPERVISOR_vm_assist(VMASST_CMD_enable, > > VMASST_TYPE_writable_pagetables); > > @@ -517,6 +543,15 @@ void __init xen_arch_setup(void) > > > > xen_enable_sysenter(); > > xen_enable_syscall(); > > +} > > + > > +/* This function not called for HVM domain */ > > +void __init xen_arch_setup(void) > > +{ > > + xen_panic_handler_init(); > > + > > + if (!xen_feature(XENFEAT_auto_translated_physmap)) > > + xen_non_pvh_arch_setup(); > > > > #ifdef CONFIG_ACPI > > if (!(xen_start_info->flags & SIF_INITDOMAIN)) { > > IMHO having a xen_non_pvh_arch_setup function is less intuitive > than just wrapping all that code around an > > if (!xen_feature(XENFEAT_auto_translated_physmap)) { >Too much indentation.> Or at least you could name the function xen_pvmmu_arch_setup.ok, fine, i''ll rename it again.
On Fri, Sep 21, 2012 at 12:17:52PM -0700, Mukesh Rathor wrote:> > --- > arch/x86/xen/setup.c | 51 ++++++++++++++++++++++++++++++++++++++++++------- > 1 files changed, 43 insertions(+), 8 deletions(-) > > diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c > index ead8557..fba442e 100644 > --- a/arch/x86/xen/setup.c > +++ b/arch/x86/xen/setup.c > @@ -26,6 +26,7 @@ > #include <xen/interface/memory.h> > #include <xen/interface/physdev.h> > #include <xen/features.h> > +#include "mmu.h" > #include "xen-ops.h" > #include "vdso.h" > > @@ -222,6 +223,26 @@ static void __init xen_set_identity_and_release_chunk( > *identity += set_phys_range_identity(start_pfn, end_pfn); > } > > +/* For PVH, the pfns [0..MAX] are mapped to mfn''s in the EPT/NPT. The mfns > + * are released as part of this 1:1 mapping hypercall back to the dom heap. We > + * don''t use the xen_do_chunk() PV does above because when P2M/EPT/NPT is > + * updated, the mfns are already lost as part of the p2m update. > + * Also, we map the entire IO space, ie, beyond max_pfn_mapped. > + */ > +static void __init xen_pvh_identity_map_chunk(unsigned long start_pfn, > + unsigned long end_pfn, unsigned long *released, > + unsigned long *identity) > +{ > + unsigned long pfn; > + int numpfns=1, add_mapping=1; > + > + for (pfn = start_pfn; pfn < end_pfn; pfn++) > + xen_set_clr_mmio_pvh_pte(pfn, pfn, numpfns, add_mapping); > + > + *released += end_pfn - start_pfn;So this will feed in the populate method that will try to populate back the amount that were released (xen_populate_chunk). Is that OK? You mention that we do not want to call ''xen_do_chunk()'' but the ''xen_populate_chunk'' would do that for XENMEM_populate_physmap call. The modifcation of *released also ends up modifying the "xen_released_pages" value which is a global value that the balloon driver ends up using so we have to be carefull? Perhaps we should just do this (on top of this patch) for right now: diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 8971a26..3d33ac6 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -103,6 +103,15 @@ static unsigned long __init xen_do_chunk(unsigned long start, unsigned long pfn; int ret; + if (xen_feature(XENFEAT_auto_translated_physmap)) { + /* The xen_set_clr_mmio_pvh_pte did the job for us. */ + if (release) + return end - start; + /* And we do not populate back here.. Meaning that the + * later balloon driver can do it based on xen_released_pages. + * This will be fixed in the future. */ + return 0; + } for (pfn = start; pfn < end; pfn++) { unsigned long frame; unsigned long mfn = pfn_to_mfn(pfn);> + *identity += end_pfn - start_pfn; > +} > + > static unsigned long __init xen_set_identity_and_release( > const struct e820entry *list, size_t map_size, unsigned long nr_pages) > { > @@ -230,6 +251,7 @@ static unsigned long __init xen_set_identity_and_release( > unsigned long identity = 0; > const struct e820entry *entry; > int i; > + int xlated_phys = xen_feature(XENFEAT_auto_translated_physmap); > > /* > * Combine non-RAM regions and gaps until a RAM region (or the > @@ -251,11 +273,16 @@ static unsigned long __init xen_set_identity_and_release( > if (entry->type == E820_RAM) > end_pfn = PFN_UP(entry->addr); > > - if (start_pfn < end_pfn) > - xen_set_identity_and_release_chunk( > - start_pfn, end_pfn, nr_pages, > - &released, &identity); > - > + if (start_pfn < end_pfn) { > + if (xlated_phys) { > + xen_pvh_identity_map_chunk(start_pfn, > + end_pfn, &released, &identity); > + } else { > + xen_set_identity_and_release_chunk( > + start_pfn, end_pfn, nr_pages, > + &released, &identity);Might as well just move this in the xen_set_identity_and_release_chunk function. Meaning, leave this function along and just modify xen_set_identity_and_release_chunk to do the modifications, like this: diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 8971a26..3db3f46 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -103,6 +103,15 @@ static unsigned long __init xen_do_chunk(unsigned long start, unsigned long pfn; int ret; + if (xen_feature(XENFEAT_auto_translated_physmap)) { + /* The xen_set_clr_mmio_pvh_pte did the job for us. */ + if (release) + return end - start; + /* And we do not populate back here.. Meaning that the + * later balloon driver can do it based on xen_released_pages. + * This will be fixed in the future. */ + return 0; + } for (pfn = start; pfn < end; pfn++) { unsigned long frame; unsigned long mfn = pfn_to_mfn(pfn); @@ -218,11 +227,15 @@ static void __init xen_set_identity_and_release_chunk( * If the PFNs are currently mapped, the VA mapping also needs * to be updated to be 1:1. */ - for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) - (void)HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - mfn_pte(pfn, PAGE_KERNEL_IO), 0); - + for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) { + if (xen_feature(XENFEAT_auto_translated_physmap)) { + xen_set_clr_mmio_pvh_pte(pfn, pfn, 1, 1); + } else { + (void)HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + mfn_pte(pfn, PAGE_KERNEL_IO), 0); + } + } if (start_pfn < nr_pages) *released += xen_release_chunk( start_pfn, min(end_pfn, nr_pages));> + } > + } > start = end; > } > } > @@ -500,10 +527,9 @@ void __cpuinit xen_enable_syscall(void) > #endif /* CONFIG_X86_64 */ > } > > -void __init xen_arch_setup(void) > +/* Non auto translated PV domain, ie, it''s not PVH. */ > +static __init void inline xen_non_pvh_arch_setup(void) > { > - xen_panic_handler_init(); > - > HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); > HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); > > @@ -517,6 +543,15 @@ void __init xen_arch_setup(void) > > xen_enable_sysenter(); > xen_enable_syscall(); > +} > + > +/* This function not called for HVM domain */ > +void __init xen_arch_setup(void) > +{ > + xen_panic_handler_init(); > + > + if (!xen_feature(XENFEAT_auto_translated_physmap)) > + xen_non_pvh_arch_setup(); >I am not sure what the syscall functions have to do with parsing of the E820. You should split this patch in two - one that deals with the E820 parsing and another that deails with the setup of syscalls.> #ifdef CONFIG_ACPI > if (!(xen_start_info->flags & SIF_INITDOMAIN)) { > -- > 1.7.2.3 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel >
On Fri, 21 Sep 2012, Mukesh Rathor wrote:> > --- > arch/x86/xen/setup.c | 51 ++++++++++++++++++++++++++++++++++++++++++------- > 1 files changed, 43 insertions(+), 8 deletions(-) > > diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c > index ead8557..fba442e 100644 > --- a/arch/x86/xen/setup.c > +++ b/arch/x86/xen/setup.c > @@ -26,6 +26,7 @@ > #include <xen/interface/memory.h> > #include <xen/interface/physdev.h> > #include <xen/features.h> > +#include "mmu.h" > #include "xen-ops.h" > #include "vdso.h" > > @@ -222,6 +223,26 @@ static void __init xen_set_identity_and_release_chunk( > *identity += set_phys_range_identity(start_pfn, end_pfn); > } > > +/* For PVH, the pfns [0..MAX] are mapped to mfn''s in the EPT/NPT. The mfns > + * are released as part of this 1:1 mapping hypercall back to the dom heap. We > + * don''t use the xen_do_chunk() PV does above because when P2M/EPT/NPT is > + * updated, the mfns are already lost as part of the p2m update. > + * Also, we map the entire IO space, ie, beyond max_pfn_mapped. > + */ > +static void __init xen_pvh_identity_map_chunk(unsigned long start_pfn, > + unsigned long end_pfn, unsigned long *released, > + unsigned long *identity) > +{ > + unsigned long pfn; > + int numpfns=1, add_mapping=1;int numpfns = 1, add_mapping = 1> + for (pfn = start_pfn; pfn < end_pfn; pfn++) > + xen_set_clr_mmio_pvh_pte(pfn, pfn, numpfns, add_mapping); > + > + *released += end_pfn - start_pfn; > + *identity += end_pfn - start_pfn; > +} > + > static unsigned long __init xen_set_identity_and_release( > const struct e820entry *list, size_t map_size, unsigned long nr_pages) > { > @@ -230,6 +251,7 @@ static unsigned long __init xen_set_identity_and_release( > unsigned long identity = 0; > const struct e820entry *entry; > int i; > + int xlated_phys = xen_feature(XENFEAT_auto_translated_physmap); > > /* > * Combine non-RAM regions and gaps until a RAM region (or the > @@ -251,11 +273,16 @@ static unsigned long __init xen_set_identity_and_release( > if (entry->type == E820_RAM) > end_pfn = PFN_UP(entry->addr); > > - if (start_pfn < end_pfn) > - xen_set_identity_and_release_chunk( > - start_pfn, end_pfn, nr_pages, > - &released, &identity); > - > + if (start_pfn < end_pfn) { > + if (xlated_phys) { > + xen_pvh_identity_map_chunk(start_pfn, > + end_pfn, &released, &identity); > + } else { > + xen_set_identity_and_release_chunk( > + start_pfn, end_pfn, nr_pages, > + &released, &identity); > + } > + } > start = end; > } > } > @@ -500,10 +527,9 @@ void __cpuinit xen_enable_syscall(void) > #endif /* CONFIG_X86_64 */ > } > > -void __init xen_arch_setup(void) > +/* Non auto translated PV domain, ie, it''s not PVH. */ > +static __init void inline xen_non_pvh_arch_setup(void) > { > - xen_panic_handler_init(); > - > HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); > HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); > > @@ -517,6 +543,15 @@ void __init xen_arch_setup(void) > > xen_enable_sysenter(); > xen_enable_syscall(); > +} > + > +/* This function not called for HVM domain */ > +void __init xen_arch_setup(void) > +{ > + xen_panic_handler_init(); > + > + if (!xen_feature(XENFEAT_auto_translated_physmap)) > + xen_non_pvh_arch_setup(); > > #ifdef CONFIG_ACPI > if (!(xen_start_info->flags & SIF_INITDOMAIN)) { > -- > 1.7.2.3 >