Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-24 Thread Andrii Anisov

Hello Stefano,


On 23.07.18 21:32, Stefano Stabellini wrote:

also the GIC and timer addresses need to be configurable.
I don't remember we ever had a problem with them. But yes, this should 
be configurable as well.



I usually refer to this (future) feature as arbitrary guest memory map.

I see.

--

*Andrii Anisov*



___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-23 Thread Stefano Stabellini
On Mon, 23 Jul 2018, Andrii Anisov wrote:
> Hello Stefano,
> 
> 
> On 07.07.18 02:11, Stefano Stabellini wrote:
> > Extend allocate_memory to work for non 1:1 mapped domUs. Specifically,
> > memory allocated for domU will be mapped into the domU pseudo-physical
> > address space at the appropriate addresses according to the guest memory
> > map: GUEST_RAM0_BASE and GUEST_RAM1_BASE.
> I would speculate about GUEST_RAMx_BASE and GUEST_RAMx_SIZE macros. Those
> values might not fit the real SoC memory map. And it becomes a problem once we
> decided to assign some peripheral directly to the guest because a RAM space
> specified to VM would overlap with IO range of the assigned device.
> In my practice, we always align those macros with the SoC memory map. This
> becomes more convenient and practical than IO remapping.
> 
> It might be the moment to get those values configurable for the guests. At
> least for those, which are configured from the device tree. Here naturally fit
> making `memory` property similar to `reg` - the list of  values.

Yes, you are right. Those value should be made configurable. It is
already on my roadmap. But I would keep it separate from this series: it
is not just about the position of RAM in the guest address space, also
the GIC and timer addresses need to be configurable. I usually refer to
this (future) feature as arbitrary guest memory map.

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-23 Thread Andrii Anisov

Hello Stefano,


On 07.07.18 02:11, Stefano Stabellini wrote:

Extend allocate_memory to work for non 1:1 mapped domUs. Specifically,
memory allocated for domU will be mapped into the domU pseudo-physical
address space at the appropriate addresses according to the guest memory
map: GUEST_RAM0_BASE and GUEST_RAM1_BASE.
I would speculate about GUEST_RAMx_BASE and GUEST_RAMx_SIZE macros. 
Those values might not fit the real SoC memory map. And it becomes a 
problem once we decided to assign some peripheral directly to the guest 
because a RAM space specified to VM would overlap with IO range of the 
assigned device.
In my practice, we always align those macros with the SoC memory map. 
This becomes more convenient and practical than IO remapping.


It might be the moment to get those values configurable for the guests. 
At least for those, which are configured from the device tree. Here 
naturally fit making `memory` property similar to `reg` - the list of 
 values.


--

*Andrii Anisov*



___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-11 Thread Stefano Stabellini
On Tue, 10 Jul 2018, Julien Grall wrote:
> Hi Stefano,
> 
> On 10/07/18 00:02, Stefano Stabellini wrote:
> > On Mon, 9 Jul 2018, Julien Grall wrote:
> > > On 07/07/18 00:11, Stefano Stabellini wrote:
> > > >mfn_t smfn;
> > > >paddr_t start, size;
> > > > +struct membank *bank;
> > > >  smfn = page_to_mfn(pg);
> > > >start = mfn_to_maddr(smfn);
> > > 
> > > The new code is pretty horrible to read. Can you please add some comments
> > > to
> > > help understanding it?
> > > 
> > > Here is already an example where you set start to MFN. But then override
> > > after
> > > with none comment to understand why.
> > > 
> > > Also, this code as always assumed MFN == GFN so start was making sense.
> > > Now,
> > > you re-purpose it to just the guest-physical address. So more likely you
> > > want
> > > to rework the code a bit.
> > 
> > I'll add more comments in the code. Next time the patch will be clearer.
> > This is a snippet to give you an idea, but it might be best for you to
> > just wait for the next version before reading this again.
> > 
> >  /*
> >   * smfn: the address of the set of pages to map
> >   * start: the address in guest pseudo-physical memory where to map
> >   *the pages
> 
> The best way is to rename start to gaddr or better provide a frame. So there
> are no need for such self-explanatory comment. However, my main issue was not
> the name itself...

Sure, I can do


> >   */
> >  smfn = page_to_mfn(pg);
> >  start = mfn_to_maddr(smfn);
> 
> ... but this specific line. This should have been in a else.

This goes away with having separate functions for DomUs


> >  size = pfn_to_paddr(1UL << order);
> >  if ( !is_hardware_domain(d) )
> 
> Why is_hardware_domain(d)? None of the code below is assuming it is an
> hardware domain and we should not assume the 1:1 mapping. That was the exact
> reason of the BUG_ON(!is_domain_direct_mapped(d)) in the caller and not
> !is_hardware_domain(d).

Yeah, I should have used is_domain_direct_mapped. This also goes away
with having separate functions.


> >  {
> >  /*
> >   * Dom0 is 1:1 mapped, so start is the same as (smfn <<
> >   * PAGE_SHIFT).
> 
> This comment is misplaced.
>
> >   *
> >   * Instead, DomU memory is provided in two banks:
> 
> Why instead? The comment should be split.

OK


> >   *   GUEST_RAM0_BASE - GUEST_RAM0_BASE + GUEST_RAM0_SIZE
> >   *   GUEST_RAM1_BASE - GUEST_RAM1_BASE + GUEST_RAM1_SIZE
> >   *
> >   * Find the right start address for DomUs accordingly.
> >   */
> >
> > 
> > > >size = pfn_to_paddr(1UL << order);
> > > > +if ( !map_11 )
> > > 
> > > I am not sure why map_11 would mean DomU? I don't see any reason to not
> > > allow
> > > that for Dom0. Note that I am not asking to do it, just having clearer
> > > name.
> > 
> > Good point. I think I should just drop the option, which is just
> > confusing, and keep using is_hardware_domain(d) checks like in
> > allocate_memory. Otherwise let me know if you have a better idea.
> 
> TBH, I dislike the way you re-purpose the 2 functions. 80% of this code is not
> necessary because you will never merge the range before the bank or deal with
> 1:1 mappings.

I have introduced two separate functions now, I am not so sure it's an
actual improvement.


> Furthermore, I just spotted a few issues with that code:
>   1) If you request 4GB for a guest and the memory has been allocated in
> one chunk, all the RAM will be starting at GUEST_RAM1_SIZE. While we
> officially don't support guest with hardcoded memory layout, there are some
> existing. Such change will break them depending on your memory layout at boot.

I fixed this.


>   2) If in the future we decide to add more banks (this may happen with
> PCI passthrough), then you have to add yet another if.
>
> What is the problem to provide a separate function to allocate memory for
> non-direct domain? You could just pass the base and the size of the region to
> populate.

You'll see the new functions in the next series. I think there is more
than 20% in common with the older functions. Anyhow, you'll have a
chance to comment on them on the next series.

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-10 Thread Julien Grall

Hi Stefano,

On 10/07/18 00:02, Stefano Stabellini wrote:

On Mon, 9 Jul 2018, Julien Grall wrote:

On 07/07/18 00:11, Stefano Stabellini wrote:

   mfn_t smfn;
   paddr_t start, size;
+struct membank *bank;
 smfn = page_to_mfn(pg);
   start = mfn_to_maddr(smfn);


The new code is pretty horrible to read. Can you please add some comments to
help understanding it?

Here is already an example where you set start to MFN. But then override after
with none comment to understand why.

Also, this code as always assumed MFN == GFN so start was making sense. Now,
you re-purpose it to just the guest-physical address. So more likely you want
to rework the code a bit.


I'll add more comments in the code. Next time the patch will be clearer.
This is a snippet to give you an idea, but it might be best for you to
just wait for the next version before reading this again.

 /*
  * smfn: the address of the set of pages to map
  * start: the address in guest pseudo-physical memory where to map
  *the pages


The best way is to rename start to gaddr or better provide a frame. So 
there are no need for such self-explanatory comment. However, my main 
issue was not the name itself...



  */
 smfn = page_to_mfn(pg);
 start = mfn_to_maddr(smfn);


... but this specific line. This should have been in a else.


 size = pfn_to_paddr(1UL << order);
 if ( !is_hardware_domain(d) )


Why is_hardware_domain(d)? None of the code below is assuming it is an 
hardware domain and we should not assume the 1:1 mapping. That was the 
exact reason of the BUG_ON(!is_domain_direct_mapped(d)) in the caller 
and not !is_hardware_domain(d).



 {
 /*
  * Dom0 is 1:1 mapped, so start is the same as (smfn <<
  * PAGE_SHIFT).


This comment is misplaced.


  *
  * Instead, DomU memory is provided in two banks:


Why instead? The comment should be split.


  *   GUEST_RAM0_BASE - GUEST_RAM0_BASE + GUEST_RAM0_SIZE
  *   GUEST_RAM1_BASE - GUEST_RAM1_BASE + GUEST_RAM1_SIZE
  *
  * Find the right start address for DomUs accordingly.
  */
   




   size = pfn_to_paddr(1UL << order);
+if ( !map_11 )


I am not sure why map_11 would mean DomU? I don't see any reason to not allow
that for Dom0. Note that I am not asking to do it, just having clearer name.


Good point. I think I should just drop the option, which is just
confusing, and keep using is_hardware_domain(d) checks like in
allocate_memory. Otherwise let me know if you have a better idea.


TBH, I dislike the way you re-purpose the 2 functions. 80% of this code 
is not necessary because you will never merge the range before the bank 
or deal with 1:1 mappings.


Furthermore, I just spotted a few issues with that code:
	1) If you request 4GB for a guest and the memory has been allocated in 
one chunk, all the RAM will be starting at GUEST_RAM1_SIZE. While we 
officially don't support guest with hardcoded memory layout, there are 
some existing. Such change will break them depending on your memory 
layout at boot.
	2) If in the future we decide to add more banks (this may happen with 
PCI passthrough), then you have to add yet another if.


What is the problem to provide a separate function to allocate memory 
for non-direct domain? You could just pass the base and the size of the 
region to populate.






+{
+start = GUEST_RAM0_BASE;
+if ( kinfo->mem.nr_banks > 0 )
+{
+for( i = 0; i < kinfo->mem.nr_banks; i++ )
+{
+bank = &kinfo->mem.bank[i];
+start = bank->start + bank->size;
+}
+if ( bank->start == GUEST_RAM0_BASE &&
+start + size > (GUEST_RAM0_BASE + GUEST_RAM0_SIZE) )


The indentation looks wrong.


OK



+start = GUEST_RAM1_BASE;
+if ( bank->start == GUEST_RAM1_BASE &&
+start + size > (GUEST_RAM1_BASE + GUEST_RAM1_SIZE) )
+{
+D11PRINT("Allocation of domain memory exceeds max
amount\n");


This looks quite strange to use D11PRINT here as this related to direct-domain
mapped.
  
You are right, but I didn't feel like replacing all D11PRINT

occurrences. Should I do that? Or should I change just this instance? I
could also just drop this D11PRINT, given that the printk is not even
enabled by default. Let me know.


But then, the D11PRINT below does not make any sense after your change. 
We should really aim to keep that code fairly sane. So I would rename 
D11PRINT unless you are doing what I suggested above.


Cheers,

--
Julien Grall

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-09 Thread Stefano Stabellini
On Mon, 9 Jul 2018, Julien Grall wrote:
> On 07/07/18 00:11, Stefano Stabellini wrote:
> > @@ -263,6 +288,12 @@ static void allocate_memory(struct domain *d, struct
> > kernel_info *kinfo)
> 
> I forgot to mention that very likely you want to update the big comment on top
> of this function.

I'll do

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-09 Thread Stefano Stabellini
On Mon, 9 Jul 2018, Julien Grall wrote:
> Hi Stefano,
> 
> On 07/07/18 00:11, Stefano Stabellini wrote:
> > Extend allocate_memory to work for non 1:1 mapped domUs. Specifically,
> > memory allocated for domU will be mapped into the domU pseudo-physical
> > address space at the appropriate addresses according to the guest memory
> > map: GUEST_RAM0_BASE and GUEST_RAM1_BASE.
> > 
> > To do that, insert_11_bank has been extended to deal with non-dom0
> > mappings starting from GUEST_RAM0_BASE. insert_11_bank has been renamed
> > to insert_bank.
> > 
> > Signed-off-by: Stefano Stabellini 
> > 
> > ---
> > Changes in v2:
> > - new patch
> > ---
> >   xen/arch/arm/domain_build.c | 57
> > ++---
> >   1 file changed, 44 insertions(+), 13 deletions(-)
> > 
> > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> > index 182e3d5..2a6619a 100644
> > --- a/xen/arch/arm/domain_build.c
> > +++ b/xen/arch/arm/domain_build.c
> > @@ -97,27 +97,51 @@ static unsigned int get_allocation_size(paddr_t size)
> >* Returns false if the memory would be below bank 0 or we have run
> >* out of banks. In this case it will free the pages.
> >*/
> > -static bool insert_11_bank(struct domain *d,
> > -   struct kernel_info *kinfo,
> > -   struct page_info *pg,
> > -   unsigned int order)
> > +static bool insert_bank(struct domain *d,
> > +struct kernel_info *kinfo,
> > +struct page_info *pg,
> > +unsigned int order,
> > +bool map_11)
> >   {
> > -int res, i;
> > +int res, i, nr_mem_banks = map_11 ? NR_MEM_BANKS : 2;
> 
> nr_mem_banks should be unsigned. I also would drop "mem_" to shorten a bit the
> name.

OK


> >   mfn_t smfn;
> >   paddr_t start, size;
> > +struct membank *bank;
> > smfn = page_to_mfn(pg);
> >   start = mfn_to_maddr(smfn);
> 
> The new code is pretty horrible to read. Can you please add some comments to
> help understanding it?
> 
> Here is already an example where you set start to MFN. But then override after
> with none comment to understand why.
> 
> Also, this code as always assumed MFN == GFN so start was making sense. Now,
> you re-purpose it to just the guest-physical address. So more likely you want
> to rework the code a bit.

I'll add more comments in the code. Next time the patch will be clearer.
This is a snippet to give you an idea, but it might be best for you to
just wait for the next version before reading this again.

/*
 * smfn: the address of the set of pages to map
 * start: the address in guest pseudo-physical memory where to map
 *the pages
 */
smfn = page_to_mfn(pg);
start = mfn_to_maddr(smfn);
size = pfn_to_paddr(1UL << order);
if ( !is_hardware_domain(d) )
{
/*
 * Dom0 is 1:1 mapped, so start is the same as (smfn <<
 * PAGE_SHIFT).
 *
 * Instead, DomU memory is provided in two banks:
 *   GUEST_RAM0_BASE - GUEST_RAM0_BASE + GUEST_RAM0_SIZE
 *   GUEST_RAM1_BASE - GUEST_RAM1_BASE + GUEST_RAM1_SIZE
 * 
 * Find the right start address for DomUs accordingly.
 */
  


> >   size = pfn_to_paddr(1UL << order);
> > +if ( !map_11 )
> 
> I am not sure why map_11 would mean DomU? I don't see any reason to not allow
> that for Dom0. Note that I am not asking to do it, just having clearer name.

Good point. I think I should just drop the option, which is just
confusing, and keep using is_hardware_domain(d) checks like in
allocate_memory. Otherwise let me know if you have a better idea.


> > +{
> > +start = GUEST_RAM0_BASE;
> > +if ( kinfo->mem.nr_banks > 0 )
> > +{
> > +for( i = 0; i < kinfo->mem.nr_banks; i++ )
> > +{
> > +bank = &kinfo->mem.bank[i];
> > +start = bank->start + bank->size;
> > +}
> > +if ( bank->start == GUEST_RAM0_BASE &&
> > +start + size > (GUEST_RAM0_BASE + GUEST_RAM0_SIZE) )
> 
> The indentation looks wrong.

OK


> > +start = GUEST_RAM1_BASE;
> > +if ( bank->start == GUEST_RAM1_BASE &&
> > +start + size > (GUEST_RAM1_BASE + GUEST_RAM1_SIZE) )
> > +{
> > +D11PRINT("Allocation of domain memory exceeds max
> > amount\n");
> 
> This looks quite strange to use D11PRINT here as this related to direct-domain
> mapped.
 
You are right, but I didn't feel like replacing all D11PRINT
occurrences. Should I do that? Or should I change just this instance? I
could also just drop this D11PRINT, given that the printk is not even
enabled by default. Let me know.


> > +goto fail;
> > +}
> > +}
> > +}
> >   -D11PRINT("Allocated %#"PRIpaddr"-%#"PRIpaddr" (%ld

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-09 Thread Julien Grall



On 07/07/18 00:11, Stefano Stabellini wrote:

@@ -263,6 +288,12 @@ static void allocate_memory(struct domain *d, struct 
kernel_info *kinfo)


I forgot to mention that very likely you want to update the big comment 
on top of this function.


Cheers,
--
Julien Grall

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-09 Thread Julien Grall

Hi Stefano,

On 07/07/18 00:11, Stefano Stabellini wrote:

Extend allocate_memory to work for non 1:1 mapped domUs. Specifically,
memory allocated for domU will be mapped into the domU pseudo-physical
address space at the appropriate addresses according to the guest memory
map: GUEST_RAM0_BASE and GUEST_RAM1_BASE.

To do that, insert_11_bank has been extended to deal with non-dom0
mappings starting from GUEST_RAM0_BASE. insert_11_bank has been renamed
to insert_bank.

Signed-off-by: Stefano Stabellini 

---
Changes in v2:
- new patch
---
  xen/arch/arm/domain_build.c | 57 ++---
  1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 182e3d5..2a6619a 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -97,27 +97,51 @@ static unsigned int get_allocation_size(paddr_t size)
   * Returns false if the memory would be below bank 0 or we have run
   * out of banks. In this case it will free the pages.
   */
-static bool insert_11_bank(struct domain *d,
-   struct kernel_info *kinfo,
-   struct page_info *pg,
-   unsigned int order)
+static bool insert_bank(struct domain *d,
+struct kernel_info *kinfo,
+struct page_info *pg,
+unsigned int order,
+bool map_11)
  {
-int res, i;
+int res, i, nr_mem_banks = map_11 ? NR_MEM_BANKS : 2;


nr_mem_banks should be unsigned. I also would drop "mem_" to shorten a 
bit the name.



  mfn_t smfn;
  paddr_t start, size;
+struct membank *bank;
  
  smfn = page_to_mfn(pg);

  start = mfn_to_maddr(smfn);


The new code is pretty horrible to read. Can you please add some 
comments to help understanding it?


Here is already an example where you set start to MFN. But then override 
after with none comment to understand why.


Also, this code as always assumed MFN == GFN so start was making sense. 
Now, you re-purpose it to just the guest-physical address. So more 
likely you want to rework the code a bit.



  size = pfn_to_paddr(1UL << order);
+if ( !map_11 )


I am not sure why map_11 would mean DomU? I don't see any reason to not 
allow that for Dom0. Note that I am not asking to do it, just having 
clearer name.



+{
+start = GUEST_RAM0_BASE;
+if ( kinfo->mem.nr_banks > 0 )
+{
+for( i = 0; i < kinfo->mem.nr_banks; i++ )
+{
+bank = &kinfo->mem.bank[i];
+start = bank->start + bank->size;
+}
+if ( bank->start == GUEST_RAM0_BASE &&
+start + size > (GUEST_RAM0_BASE + GUEST_RAM0_SIZE) )


The indentation looks wrong.


+start = GUEST_RAM1_BASE;
+if ( bank->start == GUEST_RAM1_BASE &&
+start + size > (GUEST_RAM1_BASE + GUEST_RAM1_SIZE) )
+{
+D11PRINT("Allocation of domain memory exceeds max amount\n");


This looks quite strange to use D11PRINT here as this related to 
direct-domain mapped.



+goto fail;
+}
+}
+}
  
-D11PRINT("Allocated %#"PRIpaddr"-%#"PRIpaddr" (%ldMB/%ldMB, order %d)\n",

+D11PRINT("Allocated %#"PRIpaddr"-%#"PRIpaddr":%#"PRIpaddr"-%#"PRIpaddr" 
(%ldMB/%ldMB, order %d)\n",
+ mfn_to_maddr(smfn), mfn_to_maddr(smfn) + size,
   start, start + size,
   1UL << (order + PAGE_SHIFT - 20),
   /* Don't want format this as PRIpaddr (16 digit hex) */
   (unsigned long)(kinfo->unassigned_mem >> 20),
   order);
  
-if ( kinfo->mem.nr_banks > 0 &&

+if ( map_11 && kinfo->mem.nr_banks > 0 &&


Why do you drop that check? It should be harmless for non-direct mapped 
domain.



   size < MB(128) && >start + size < 
kinfo->mem.bank[0].start )
  {
@@ -125,7 +149,7 @@ static bool insert_11_bank(struct domain *d,
  goto fail;
  }
  
-res = guest_physmap_add_page(d, _gfn(mfn_x(smfn)), smfn, order);

+res = guest_physmap_add_page(d, gaddr_to_gfn(start), smfn, order);
  if ( res )
  panic("Failed map pages to DOM0: %d", res);
  
@@ -141,7 +165,7 @@ static bool insert_11_bank(struct domain *d,
  
  for( i = 0; i < kinfo->mem.nr_banks; i++ )

  {
-struct membank *bank = &kinfo->mem.bank[i];
+bank = &kinfo->mem.bank[i];
  
  /* If possible merge new memory into the start of the bank */

  if ( bank->start == start+size )
@@ -164,7 +188,7 @@ static bool insert_11_bank(struct domain *d,
   * could have inserted the memory into/before we would already
   * have done so, so this must be the right place.
   */
-if ( start + size < bank->start && kinfo->mem.nr_banks < NR_MEM_BANKS )
+if ( start + size < 

[Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests

2018-07-06 Thread Stefano Stabellini
Extend allocate_memory to work for non 1:1 mapped domUs. Specifically,
memory allocated for domU will be mapped into the domU pseudo-physical
address space at the appropriate addresses according to the guest memory
map: GUEST_RAM0_BASE and GUEST_RAM1_BASE.

To do that, insert_11_bank has been extended to deal with non-dom0
mappings starting from GUEST_RAM0_BASE. insert_11_bank has been renamed
to insert_bank.

Signed-off-by: Stefano Stabellini 

---
Changes in v2:
- new patch
---
 xen/arch/arm/domain_build.c | 57 ++---
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 182e3d5..2a6619a 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -97,27 +97,51 @@ static unsigned int get_allocation_size(paddr_t size)
  * Returns false if the memory would be below bank 0 or we have run
  * out of banks. In this case it will free the pages.
  */
-static bool insert_11_bank(struct domain *d,
-   struct kernel_info *kinfo,
-   struct page_info *pg,
-   unsigned int order)
+static bool insert_bank(struct domain *d,
+struct kernel_info *kinfo,
+struct page_info *pg,
+unsigned int order,
+bool map_11)
 {
-int res, i;
+int res, i, nr_mem_banks = map_11 ? NR_MEM_BANKS : 2;
 mfn_t smfn;
 paddr_t start, size;
+struct membank *bank;
 
 smfn = page_to_mfn(pg);
 start = mfn_to_maddr(smfn);
 size = pfn_to_paddr(1UL << order);
+if ( !map_11 )
+{
+start = GUEST_RAM0_BASE;
+if ( kinfo->mem.nr_banks > 0 )
+{
+for( i = 0; i < kinfo->mem.nr_banks; i++ )
+{
+bank = &kinfo->mem.bank[i];
+start = bank->start + bank->size;
+}
+if ( bank->start == GUEST_RAM0_BASE &&
+start + size > (GUEST_RAM0_BASE + GUEST_RAM0_SIZE) )
+start = GUEST_RAM1_BASE;
+if ( bank->start == GUEST_RAM1_BASE &&
+start + size > (GUEST_RAM1_BASE + GUEST_RAM1_SIZE) )
+{
+D11PRINT("Allocation of domain memory exceeds max amount\n");
+goto fail;
+}
+}
+}
 
-D11PRINT("Allocated %#"PRIpaddr"-%#"PRIpaddr" (%ldMB/%ldMB, order %d)\n",
+D11PRINT("Allocated %#"PRIpaddr"-%#"PRIpaddr":%#"PRIpaddr"-%#"PRIpaddr" 
(%ldMB/%ldMB, order %d)\n",
+ mfn_to_maddr(smfn), mfn_to_maddr(smfn) + size,
  start, start + size,
  1UL << (order + PAGE_SHIFT - 20),
  /* Don't want format this as PRIpaddr (16 digit hex) */
  (unsigned long)(kinfo->unassigned_mem >> 20),
  order);
 
-if ( kinfo->mem.nr_banks > 0 &&
+if ( map_11 && kinfo->mem.nr_banks > 0 &&
  size < MB(128) &&
  start + size < kinfo->mem.bank[0].start )
 {
@@ -125,7 +149,7 @@ static bool insert_11_bank(struct domain *d,
 goto fail;
 }
 
-res = guest_physmap_add_page(d, _gfn(mfn_x(smfn)), smfn, order);
+res = guest_physmap_add_page(d, gaddr_to_gfn(start), smfn, order);
 if ( res )
 panic("Failed map pages to DOM0: %d", res);
 
@@ -141,7 +165,7 @@ static bool insert_11_bank(struct domain *d,
 
 for( i = 0; i < kinfo->mem.nr_banks; i++ )
 {
-struct membank *bank = &kinfo->mem.bank[i];
+bank = &kinfo->mem.bank[i];
 
 /* If possible merge new memory into the start of the bank */
 if ( bank->start == start+size )
@@ -164,7 +188,7 @@ static bool insert_11_bank(struct domain *d,
  * could have inserted the memory into/before we would already
  * have done so, so this must be the right place.
  */
-if ( start + size < bank->start && kinfo->mem.nr_banks < NR_MEM_BANKS )
+if ( start + size < bank->start && kinfo->mem.nr_banks < nr_mem_banks )
 {
 memmove(bank + 1, bank,
 sizeof(*bank) * (kinfo->mem.nr_banks - i));
@@ -175,7 +199,7 @@ static bool insert_11_bank(struct domain *d,
 }
 }
 
-if ( i == kinfo->mem.nr_banks && kinfo->mem.nr_banks < NR_MEM_BANKS )
+if ( i == kinfo->mem.nr_banks && kinfo->mem.nr_banks < nr_mem_banks )
 {
 struct membank *bank = &kinfo->mem.bank[kinfo->mem.nr_banks];
 
@@ -253,6 +277,7 @@ static void allocate_memory(struct domain *d, struct 
kernel_info *kinfo)
 struct page_info *pg;
 unsigned int order = get_allocation_size(kinfo->unassigned_mem);
 int i;
+bool hwdom = d->domain_id == 0;
 
 bool lowmem = true;
 unsigned int bits;
@@ -263,6 +288,12 @@ static void allocate_memory(struct domain *d, struct 
kernel_info *kinfo)
 
 kinfo->mem.nr_banks = 0;
 
+if ( !hwdom )
+{
+lowmem = false;
+goto got_bank0;
+