---
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 >