Re: [PATCH] PCI: Add ACS quirk for Cavium ThunderX 2 root port devices

2019-08-05 Thread Shannon Zhao




On 2019/7/26 0:35, Jayachandran Chandrasekharan Nair wrote:

On Wed, Jul 24, 2019 at 01:55:35PM -0500, Bjorn Helgaas wrote:

See
https://lkml.kernel.org/r/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com
for incidental hints (subject, commit log, commit reference).  Your
patch basically extends that commit, so the subject should be very
similar.

On Fri, Jul 19, 2019 at 09:10:35PM +0800, Shannon Zhao wrote:

From: Shannon Zhao 

Like commit f2ddaf8(PCI: Apply Cavium ThunderX ACS quirk to more Root
Ports), it should apply ACS quirk to ThunderX 2 root port devices.


s/root port/Root Port/ to be consistent


Signed-off-by: Shannon Zhao 


I suppose this should have the same stable tag as f2ddaf8dfd4a ("PCI:
Apply Cavium ThunderX ACS quirk to more Root Ports") itself?

---
  drivers/pci/quirks.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 28c64f8..ea7848b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4224,10 +4224,12 @@ static bool pci_quirk_cavium_acs_match(struct pci_dev 
*dev)
 * family by 0xf800 mask (which represents 8 SoCs), while the lower
 * bits of device ID are used to indicate which subdevice is used
 * within the SoC.
+* Effectively selects the ThunderX 2 root ports whose device ID
+* is 0xaf84.
 */
return (pci_is_pcie(dev) &&
(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) &&
-   ((dev->device & 0xf800) == 0xa000));
+   ((dev->device & 0xf800) == 0xa000 || dev->device == 0xaf84));


I'm somewhat doubtful about this because previously we at least
selected a whole class of ThunderX 1 devices:

   ((dev->device & 0xf800) == 0xa000)

while you're adding only a *single* ThunderX device.

I don't want a constant trickle of adding new devices.  Can somebody
from Cavium or Marvell provide a corresponding mask for ThunderX 2, or
confirm that 0xaf84 is really the single device we expect to need
here?
  
We are working on a patch to fix this quirk to handle more Marvell

(Cavium) PCI IDs. Ideally we should be handling ThunderX1, ThunderX2
and the Octeon-TX families here.

Adding the folks working on this reduce the churn here, hopefully
we can get all of it sorted in one patch.
  

That would be better. Please CC me when you send the patch out.

Thanks,
Shannon


[PATCH] PCI: Add ACS quirk for Cavium ThunderX 2 root port devices

2019-07-18 Thread Shannon Zhao
From: Shannon Zhao 

Like commit f2ddaf8(PCI: Apply Cavium ThunderX ACS quirk to more Root
Ports), it should apply ACS quirk to ThunderX 2 root port devices.

Signed-off-by: Shannon Zhao 
---
 drivers/pci/quirks.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 28c64f8..ea7848b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4224,10 +4224,12 @@ static bool pci_quirk_cavium_acs_match(struct pci_dev 
*dev)
 * family by 0xf800 mask (which represents 8 SoCs), while the lower
 * bits of device ID are used to indicate which subdevice is used
 * within the SoC.
+* Effectively selects the ThunderX 2 root ports whose device ID
+* is 0xaf84.
 */
return (pci_is_pcie(dev) &&
(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) &&
-   ((dev->device & 0xf800) == 0xa000));
+   ((dev->device & 0xf800) == 0xa000 || dev->device == 0xaf84));
 }
 
 static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
-- 
1.8.3.1



Re: [PATCH v3 51/59] KVM: arm/arm64: GICv4: Add doorbell interrupt handling

2017-09-06 Thread Shannon Zhao


On 2017/8/1 1:26, Marc Zyngier wrote:
> When a vPE is not running, a VLPI being made pending results in a
> doorbell interrupt being delivered. Let's handle this interrupt
> and update the pending_last flag that indicates that VLPIs are
> pending. The corresponding vcpu is also kicked into action.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  virt/kvm/arm/vgic/vgic-v4.c | 34 ++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
> index 534d3051a078..6af3cde6d7d4 100644
> --- a/virt/kvm/arm/vgic/vgic-v4.c
> +++ b/virt/kvm/arm/vgic/vgic-v4.c
> @@ -21,6 +21,19 @@
>  
>  #include "vgic.h"
>  
> +static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
> +{
> + struct kvm_vcpu *vcpu = info;
> +
> + if (!kvm_vgic_vcpu_pending_irq(vcpu)) {
> + vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true;
> + kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
> + kvm_vcpu_kick(vcpu);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
>  int vgic_v4_init(struct kvm *kvm)
>  {
>   struct vgic_dist *dist = >arch.vgic;
> @@ -57,16 +70,37 @@ int vgic_v4_init(struct kvm *kvm)
>   return ret;
>   }
>  
> + kvm_for_each_vcpu(i, vcpu, kvm) {
> + int irq = dist->its_vm.vpes[i]->irq;
> +
> + ret = request_irq(irq, vgic_v4_doorbell_handler,
> +   0, "vcpu", vcpu);
> + if (ret) {
> + kvm_err("failed to allocate vcpu IRQ%d\n", irq);
> + dist->its_vm.nr_vpes = i;
This overwirtes the nr_vpes while it uses kvm->online_vcpus in
its_alloc_vcpu_irqs to alloc irqs and if this fails it uses the
overwirten nr_vpes other than kvm->online_vcpus in its_free_vcpu_irqs to
free the irqs. So there will be memory leak on error path.

> + break;
> + }
> + }
> +
> + if (ret)
> + vgic_v4_teardown(kvm);
> +
>   return ret;
>  }
>  
>  void vgic_v4_teardown(struct kvm *kvm)
>  {
>   struct its_vm *its_vm = >arch.vgic.its_vm;
> + int i;
>  
>   if (!its_vm->vpes)
>   return;
>  
> + for (i = 0; i < its_vm->nr_vpes; i++) {
> + struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, i);
> + free_irq(its_vm->vpes[i]->irq, vcpu);
> + }
> +
>   its_free_vcpu_irqs(its_vm);
>   kfree(its_vm->vpes);
>   its_vm->nr_vpes = 0;
> 

Thanks,
-- 
Shannon



Re: [PATCH v3 51/59] KVM: arm/arm64: GICv4: Add doorbell interrupt handling

2017-09-06 Thread Shannon Zhao


On 2017/8/1 1:26, Marc Zyngier wrote:
> When a vPE is not running, a VLPI being made pending results in a
> doorbell interrupt being delivered. Let's handle this interrupt
> and update the pending_last flag that indicates that VLPIs are
> pending. The corresponding vcpu is also kicked into action.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  virt/kvm/arm/vgic/vgic-v4.c | 34 ++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
> index 534d3051a078..6af3cde6d7d4 100644
> --- a/virt/kvm/arm/vgic/vgic-v4.c
> +++ b/virt/kvm/arm/vgic/vgic-v4.c
> @@ -21,6 +21,19 @@
>  
>  #include "vgic.h"
>  
> +static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
> +{
> + struct kvm_vcpu *vcpu = info;
> +
> + if (!kvm_vgic_vcpu_pending_irq(vcpu)) {
> + vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true;
> + kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
> + kvm_vcpu_kick(vcpu);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
>  int vgic_v4_init(struct kvm *kvm)
>  {
>   struct vgic_dist *dist = >arch.vgic;
> @@ -57,16 +70,37 @@ int vgic_v4_init(struct kvm *kvm)
>   return ret;
>   }
>  
> + kvm_for_each_vcpu(i, vcpu, kvm) {
> + int irq = dist->its_vm.vpes[i]->irq;
> +
> + ret = request_irq(irq, vgic_v4_doorbell_handler,
> +   0, "vcpu", vcpu);
> + if (ret) {
> + kvm_err("failed to allocate vcpu IRQ%d\n", irq);
> + dist->its_vm.nr_vpes = i;
This overwirtes the nr_vpes while it uses kvm->online_vcpus in
its_alloc_vcpu_irqs to alloc irqs and if this fails it uses the
overwirten nr_vpes other than kvm->online_vcpus in its_free_vcpu_irqs to
free the irqs. So there will be memory leak on error path.

> + break;
> + }
> + }
> +
> + if (ret)
> + vgic_v4_teardown(kvm);
> +
>   return ret;
>  }
>  
>  void vgic_v4_teardown(struct kvm *kvm)
>  {
>   struct its_vm *its_vm = >arch.vgic.its_vm;
> + int i;
>  
>   if (!its_vm->vpes)
>   return;
>  
> + for (i = 0; i < its_vm->nr_vpes; i++) {
> + struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, i);
> + free_irq(its_vm->vpes[i]->irq, vcpu);
> + }
> +
>   its_free_vcpu_irqs(its_vm);
>   kfree(its_vm->vpes);
>   its_vm->nr_vpes = 0;
> 

Thanks,
-- 
Shannon



Re: [PATCH v11 2/6] ACPI: Add APEI GHES Table Generation support

2017-08-25 Thread Shannon Zhao


On 2017/8/25 19:20, gengdongjiu wrote:
>>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>>> >> index 3d78ff6..def1ec1 100644
>>> >> --- a/hw/arm/virt-acpi-build.c
>>> >> +++ b/hw/arm/virt-acpi-build.c
>>> >> @@ -45,6 +45,7 @@
>>> >>  #include "hw/arm/virt.h"
>>> >>  #include "sysemu/numa.h"
>>> >>  #include "kvm_arm.h"
>>> >> +#include "hw/acpi/hest_ghes.h"
>>> >>  
>>> >>  #define ARM_SPI_BASE 32
>>> >>  #define ACPI_POWER_BUTTON_DEVICE "PWRB"
>>> >> @@ -771,6 +772,9 @@ void virt_acpi_build(VirtMachineState *vms, 
>>> >> AcpiBuildTables *tables)
>>> >>  acpi_add_table(table_offsets, tables_blob);
>>> >>  build_spcr(tables_blob, tables->linker, vms);
>>> >>  
>>> >> +acpi_add_table(table_offsets, tables_blob);
>>> >> +ghes_build_acpi(tables_blob, tables->hardware_errors, 
>>> >> tables->linker);
>>> >> +
>> > So we add this table unconditionally. Is there any bad impact if QEMU
>> > runs on old kvm? Does it need to check whether KVM supports RAS?
> this table is added before guest OS boot. so can not use KVM to check it.
No, we can check the RAS capability when we create vcpus like you done
in another patch ans can use that in table generation.

> if the old kvm does not support RAS, it does not have bad impact. only waste 
> table memory.
> May be we can make it as device? if this device is enabled in the qemu
> boot parameters, then we will add this table?
> 

And you need to add a option to virt machine for (migration)
compatibility. On new virt machine it's on by default while off for old
ones.

Thanks,
-- 
Shannon



Re: [PATCH v11 2/6] ACPI: Add APEI GHES Table Generation support

2017-08-25 Thread Shannon Zhao


On 2017/8/25 19:20, gengdongjiu wrote:
>>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>>> >> index 3d78ff6..def1ec1 100644
>>> >> --- a/hw/arm/virt-acpi-build.c
>>> >> +++ b/hw/arm/virt-acpi-build.c
>>> >> @@ -45,6 +45,7 @@
>>> >>  #include "hw/arm/virt.h"
>>> >>  #include "sysemu/numa.h"
>>> >>  #include "kvm_arm.h"
>>> >> +#include "hw/acpi/hest_ghes.h"
>>> >>  
>>> >>  #define ARM_SPI_BASE 32
>>> >>  #define ACPI_POWER_BUTTON_DEVICE "PWRB"
>>> >> @@ -771,6 +772,9 @@ void virt_acpi_build(VirtMachineState *vms, 
>>> >> AcpiBuildTables *tables)
>>> >>  acpi_add_table(table_offsets, tables_blob);
>>> >>  build_spcr(tables_blob, tables->linker, vms);
>>> >>  
>>> >> +acpi_add_table(table_offsets, tables_blob);
>>> >> +ghes_build_acpi(tables_blob, tables->hardware_errors, 
>>> >> tables->linker);
>>> >> +
>> > So we add this table unconditionally. Is there any bad impact if QEMU
>> > runs on old kvm? Does it need to check whether KVM supports RAS?
> this table is added before guest OS boot. so can not use KVM to check it.
No, we can check the RAS capability when we create vcpus like you done
in another patch ans can use that in table generation.

> if the old kvm does not support RAS, it does not have bad impact. only waste 
> table memory.
> May be we can make it as device? if this device is enabled in the qemu
> boot parameters, then we will add this table?
> 

And you need to add a option to virt machine for (migration)
compatibility. On new virt machine it's on by default while off for old
ones.

Thanks,
-- 
Shannon



Re: [PATCH v11 1/6] ACPI: add APEI/HEST/CPER structures and macros

2017-08-25 Thread Shannon Zhao


On 2017/8/25 18:37, gengdongjiu wrote:
>>> +
>>> >> +/* From the ACPI 6.1 spec, "18.3.2.9 Hardware Error Notification" */
>>> >> +
>> > It's better to refer to the first spec version of this structure and
>> > same with others you define.
>  do you mean which spec version? the definition is aligned with the linux 
> kernel.
What I mean here is that it's better to refer to the ACPI spec version
which introduces Hardware Error Notification first time.

>> > 
>>> >> +enum AcpiHestNotifyType {
>>> >> +ACPI_HEST_NOTIFY_POLLED = 0,
>>> >> +ACPI_HEST_NOTIFY_EXTERNAL = 1,
>>> >> +ACPI_HEST_NOTIFY_LOCAL = 2,
>>> >> +ACPI_HEST_NOTIFY_SCI = 3,
>>> >> +ACPI_HEST_NOTIFY_NMI = 4,
>>> >> +ACPI_HEST_NOTIFY_CMCI = 5,  /* ACPI 5.0 */
>>> >> +ACPI_HEST_NOTIFY_MCE = 6,   /* ACPI 5.0 */
>>> >> +ACPI_HEST_NOTIFY_GPIO = 7,  /* ACPI 6.0 */
>>> >> +ACPI_HEST_NOTIFY_SEA = 8,   /* ACPI 6.1 */
>>> >> +ACPI_HEST_NOTIFY_SEI = 9,   /* ACPI 6.1 */
>>> >> +ACPI_HEST_NOTIFY_GSIV = 10, /* ACPI 6.1 */
>>> >> +ACPI_HEST_NOTIFY_RESERVED = 11  /* 11 and greater are reserved */
>> > In ACPI 6.2, 11 is for Software Delegated Exception, is this useful for
>> > your patchset?
>   it is usefull, for all the error source, I reserved the space for them.
> Because the space is allocated one time, is not dynamically allocated.
> so I use the ACPI_HEST_NOTIFY_RESERVED to specify that there is 11 error 
> source.
> 
I mean whether the new type Software Delegated Exception is useful for
RAS. If so, we could add this new type here.

Thanks,
-- 
Shannon



Re: [PATCH v11 1/6] ACPI: add APEI/HEST/CPER structures and macros

2017-08-25 Thread Shannon Zhao


On 2017/8/25 18:37, gengdongjiu wrote:
>>> +
>>> >> +/* From the ACPI 6.1 spec, "18.3.2.9 Hardware Error Notification" */
>>> >> +
>> > It's better to refer to the first spec version of this structure and
>> > same with others you define.
>  do you mean which spec version? the definition is aligned with the linux 
> kernel.
What I mean here is that it's better to refer to the ACPI spec version
which introduces Hardware Error Notification first time.

>> > 
>>> >> +enum AcpiHestNotifyType {
>>> >> +ACPI_HEST_NOTIFY_POLLED = 0,
>>> >> +ACPI_HEST_NOTIFY_EXTERNAL = 1,
>>> >> +ACPI_HEST_NOTIFY_LOCAL = 2,
>>> >> +ACPI_HEST_NOTIFY_SCI = 3,
>>> >> +ACPI_HEST_NOTIFY_NMI = 4,
>>> >> +ACPI_HEST_NOTIFY_CMCI = 5,  /* ACPI 5.0 */
>>> >> +ACPI_HEST_NOTIFY_MCE = 6,   /* ACPI 5.0 */
>>> >> +ACPI_HEST_NOTIFY_GPIO = 7,  /* ACPI 6.0 */
>>> >> +ACPI_HEST_NOTIFY_SEA = 8,   /* ACPI 6.1 */
>>> >> +ACPI_HEST_NOTIFY_SEI = 9,   /* ACPI 6.1 */
>>> >> +ACPI_HEST_NOTIFY_GSIV = 10, /* ACPI 6.1 */
>>> >> +ACPI_HEST_NOTIFY_RESERVED = 11  /* 11 and greater are reserved */
>> > In ACPI 6.2, 11 is for Software Delegated Exception, is this useful for
>> > your patchset?
>   it is usefull, for all the error source, I reserved the space for them.
> Because the space is allocated one time, is not dynamically allocated.
> so I use the ACPI_HEST_NOTIFY_RESERVED to specify that there is 11 error 
> source.
> 
I mean whether the new type Software Delegated Exception is useful for
RAS. If so, we could add this new type here.

Thanks,
-- 
Shannon



Re: [PATCH v11 3/6] ACPI: build and enable APEI GHES in the Makefile and configuration

2017-08-24 Thread Shannon Zhao


On 2017/8/18 22:23, Dongjiu Geng wrote:
> Add CONFIG_ACPI_APEI configuration in the Makefile and
> enable it in the arm-softmmu.mak
> 
> Signed-off-by: Dongjiu Geng 
> ---
>  default-configs/arm-softmmu.mak | 1 +
>  hw/acpi/Makefile.objs   | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index bbdd3c1..c362113 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -129,3 +129,4 @@ CONFIG_ACPI=y
>  CONFIG_SMBIOS=y
>  CONFIG_ASPEED_SOC=y
>  CONFIG_GPIO_KEY=y
> +CONFIG_ACPI_APEI=y
> diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
> index 11c35bc..bafb148 100644
> --- a/hw/acpi/Makefile.objs
> +++ b/hw/acpi/Makefile.objs
> @@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
>  common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
>  common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
>  common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
> +common-obj-$(CONFIG_ACPI_APEI) += hest_ghes.o
>  common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
>  
>  common-obj-y += acpi_interface.o
> 
Fold this patch into previous one.

Thanks,
-- 
Shannon



Re: [PATCH v11 3/6] ACPI: build and enable APEI GHES in the Makefile and configuration

2017-08-24 Thread Shannon Zhao


On 2017/8/18 22:23, Dongjiu Geng wrote:
> Add CONFIG_ACPI_APEI configuration in the Makefile and
> enable it in the arm-softmmu.mak
> 
> Signed-off-by: Dongjiu Geng 
> ---
>  default-configs/arm-softmmu.mak | 1 +
>  hw/acpi/Makefile.objs   | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index bbdd3c1..c362113 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -129,3 +129,4 @@ CONFIG_ACPI=y
>  CONFIG_SMBIOS=y
>  CONFIG_ASPEED_SOC=y
>  CONFIG_GPIO_KEY=y
> +CONFIG_ACPI_APEI=y
> diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
> index 11c35bc..bafb148 100644
> --- a/hw/acpi/Makefile.objs
> +++ b/hw/acpi/Makefile.objs
> @@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
>  common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
>  common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
>  common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
> +common-obj-$(CONFIG_ACPI_APEI) += hest_ghes.o
>  common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
>  
>  common-obj-y += acpi_interface.o
> 
Fold this patch into previous one.

Thanks,
-- 
Shannon



Re: [PATCH v11 2/6] ACPI: Add APEI GHES Table Generation support

2017-08-24 Thread Shannon Zhao


On 2017/8/18 22:23, Dongjiu Geng wrote:
> This implements APEI GHES Table by passing the error CPER info
> to the guest via a fw_cfg_blob. After a CPER info is recorded, an
> SEA(Synchronous External Abort)/SEI(SError Interrupt) exception
> will be injected into the guest OS.
> 
> Below is the table layout, the max number of error soure is 11,
> which is classified by notification type.
> 
>  etc/acpi/tables   etc/hardware_errors
> 
> ==
> + +--++--+
> | | HEST ||address   |  
> +--+
> | +--+|registers |  | 
> Error Status |
> | | GHES0|| ++  | 
> Data Block 0 |
> | +--+ +->| |status_address0 |->| 
> ++
> | | .| |  | ++  | 
> |  CPER  |
> | | error_status_address-+-+ +--->| |status_address1 |--+   | 
> |  CPER  |
> | | .|   || ++  |   | 
> |    |
> | | read_ack_register+-+ ||  .   |  |   | 
> |  CPER  |
> | | read_ack_preserve| | |+--+  |   | 
> +-++
> | | read_ack_write   | | | +->| |status_address10|+ |   | 
> Error Status |
> + +--+ | | |  | ++| |   | 
> Data Block 1 |
> | | GHES1| +-+-+->| | ack_value0 || +-->| 
> ++
> + +--+   | |  | ++| | 
> |  CPER  |
> | | .|   | | +--->| | ack_value1 || | 
> |  CPER  |
> | | error_status_address-+---+ | || ++| | 
> |    |
> | | .| | || |  . || | 
> |  CPER  |
> | | read_ack_register+-+-+| ++| 
> +-++
> | | read_ack_preserve| |   +->| | ack_value10|| | 
> |..  |
> | | read_ack_write   | |   |  | ++| | 
> ++
> + +--| |   |  | | 
> Error Status |
> | | ...  | |   |  | | 
> Data Block 10|
> + +--+ |   |  +>| 
> ++
> | | GHES10   | |   || 
> |  CPER  |
> + +--+ |   || 
> |  CPER  |
> | | .| |   || 
> |    |
> | | error_status_address-+-+   || 
> |  CPER  |
> | | .| |
> +-++
> | | read_ack_register+-+
> | | read_ack_preserve|
> | | read_ack_write   |
> + +--+
> 
> For GHESv2 error source, the OSPM must acknowledges the error via Read Ack 
> register.
> so user space must check the ack value to avoid read-write race condition.
> 
> Signed-off-by: Dongjiu Geng 
> ---
>  hw/acpi/aml-build.c |   2 +
>  hw/acpi/hest_ghes.c | 345 
> 
>  hw/arm/virt-acpi-build.c|   6 +
>  include/hw/acpi/aml-build.h |   1 +
>  include/hw/acpi/hest_ghes.h |  47 ++
>  5 files changed, 401 insertions(+)
>  create mode 100644 hw/acpi/hest_ghes.c
Don't need to add the new file to hw/acpi/Makefile.objs?

>  create mode 100644 include/hw/acpi/hest_ghes.h
> 
> diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> index 36a6cc4..6849e5f 100644
> --- a/hw/acpi/aml-build.c
> +++ b/hw/acpi/aml-build.c
> @@ -1561,6 +1561,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables)
>  tables->table_data = g_array_new(false, true /* clear */, 1);
>  tables->tcpalog = g_array_new(false, true /* clear */, 1);
>  tables->vmgenid = g_array_new(false, true /* clear */, 1);
> +tables->hardware_errors = g_array_new(false, true /* clear */, 1);
>  tables->linker = bios_linker_loader_init();
>  }
>  
> @@ -1571,6 +1572,7 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, 
> bool mfre)
>  g_array_free(tables->table_data, true);
>  g_array_free(tables->tcpalog, mfre);
>  g_array_free(tables->vmgenid, mfre);
> +g_array_free(tables->hardware_errors, mfre);
>  }
>  
>  /* Build rsdt table */
> diff --git a/hw/acpi/hest_ghes.c 

Re: [PATCH v11 2/6] ACPI: Add APEI GHES Table Generation support

2017-08-24 Thread Shannon Zhao


On 2017/8/18 22:23, Dongjiu Geng wrote:
> This implements APEI GHES Table by passing the error CPER info
> to the guest via a fw_cfg_blob. After a CPER info is recorded, an
> SEA(Synchronous External Abort)/SEI(SError Interrupt) exception
> will be injected into the guest OS.
> 
> Below is the table layout, the max number of error soure is 11,
> which is classified by notification type.
> 
>  etc/acpi/tables   etc/hardware_errors
> 
> ==
> + +--++--+
> | | HEST ||address   |  
> +--+
> | +--+|registers |  | 
> Error Status |
> | | GHES0|| ++  | 
> Data Block 0 |
> | +--+ +->| |status_address0 |->| 
> ++
> | | .| |  | ++  | 
> |  CPER  |
> | | error_status_address-+-+ +--->| |status_address1 |--+   | 
> |  CPER  |
> | | .|   || ++  |   | 
> |    |
> | | read_ack_register+-+ ||  .   |  |   | 
> |  CPER  |
> | | read_ack_preserve| | |+--+  |   | 
> +-++
> | | read_ack_write   | | | +->| |status_address10|+ |   | 
> Error Status |
> + +--+ | | |  | ++| |   | 
> Data Block 1 |
> | | GHES1| +-+-+->| | ack_value0 || +-->| 
> ++
> + +--+   | |  | ++| | 
> |  CPER  |
> | | .|   | | +--->| | ack_value1 || | 
> |  CPER  |
> | | error_status_address-+---+ | || ++| | 
> |    |
> | | .| | || |  . || | 
> |  CPER  |
> | | read_ack_register+-+-+| ++| 
> +-++
> | | read_ack_preserve| |   +->| | ack_value10|| | 
> |..  |
> | | read_ack_write   | |   |  | ++| | 
> ++
> + +--| |   |  | | 
> Error Status |
> | | ...  | |   |  | | 
> Data Block 10|
> + +--+ |   |  +>| 
> ++
> | | GHES10   | |   || 
> |  CPER  |
> + +--+ |   || 
> |  CPER  |
> | | .| |   || 
> |    |
> | | error_status_address-+-+   || 
> |  CPER  |
> | | .| |
> +-++
> | | read_ack_register+-+
> | | read_ack_preserve|
> | | read_ack_write   |
> + +--+
> 
> For GHESv2 error source, the OSPM must acknowledges the error via Read Ack 
> register.
> so user space must check the ack value to avoid read-write race condition.
> 
> Signed-off-by: Dongjiu Geng 
> ---
>  hw/acpi/aml-build.c |   2 +
>  hw/acpi/hest_ghes.c | 345 
> 
>  hw/arm/virt-acpi-build.c|   6 +
>  include/hw/acpi/aml-build.h |   1 +
>  include/hw/acpi/hest_ghes.h |  47 ++
>  5 files changed, 401 insertions(+)
>  create mode 100644 hw/acpi/hest_ghes.c
Don't need to add the new file to hw/acpi/Makefile.objs?

>  create mode 100644 include/hw/acpi/hest_ghes.h
> 
> diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> index 36a6cc4..6849e5f 100644
> --- a/hw/acpi/aml-build.c
> +++ b/hw/acpi/aml-build.c
> @@ -1561,6 +1561,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables)
>  tables->table_data = g_array_new(false, true /* clear */, 1);
>  tables->tcpalog = g_array_new(false, true /* clear */, 1);
>  tables->vmgenid = g_array_new(false, true /* clear */, 1);
> +tables->hardware_errors = g_array_new(false, true /* clear */, 1);
>  tables->linker = bios_linker_loader_init();
>  }
>  
> @@ -1571,6 +1572,7 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, 
> bool mfre)
>  g_array_free(tables->table_data, true);
>  g_array_free(tables->tcpalog, mfre);
>  g_array_free(tables->vmgenid, mfre);
> +g_array_free(tables->hardware_errors, mfre);
>  }
>  
>  /* Build rsdt table */
> diff --git a/hw/acpi/hest_ghes.c b/hw/acpi/hest_ghes.c
> new 

Re: [PATCH v11 1/6] ACPI: add APEI/HEST/CPER structures and macros

2017-08-24 Thread Shannon Zhao


On 2017/8/18 22:23, Dongjiu Geng wrote:
> (1) Add related APEI/HEST table structures and  macros, these
> definition refer to ACPI 6.1 and UEFI 2.6 spec.
> (2) Add generic error status block and CPER memory section
> definition, user space only handle memory section errors.
> 
> Signed-off-by: Dongjiu Geng 
> ---
>  include/hw/acpi/acpi-defs.h | 193 
> 
>  1 file changed, 193 insertions(+)
> 
> diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> index 72be675..3b4bad7 100644
> --- a/include/hw/acpi/acpi-defs.h
> +++ b/include/hw/acpi/acpi-defs.h
> @@ -297,6 +297,44 @@ typedef struct AcpiMultipleApicTable 
> AcpiMultipleApicTable;
>  #define ACPI_APIC_GENERIC_TRANSLATOR15
>  #define ACPI_APIC_RESERVED  16   /* 16 and greater are reserved 
> */
>  
> +/* UEFI Spec 2.6, "N.2.5 Memory Error Section */
missing "

> +#define UEFI_CPER_MEM_VALID_ERROR_STATUS 0x0001
> +#define UEFI_CPER_MEM_VALID_PA   0x0002
> +#define UEFI_CPER_MEM_VALID_PA_MASK  0x0004
> +#define UEFI_CPER_MEM_VALID_NODE 0x0008
> +#define UEFI_CPER_MEM_VALID_CARD 0x0010
> +#define UEFI_CPER_MEM_VALID_MODULE   0x0020
> +#define UEFI_CPER_MEM_VALID_BANK 0x0040
> +#define UEFI_CPER_MEM_VALID_DEVICE   0x0080
> +#define UEFI_CPER_MEM_VALID_ROW  0x0100
> +#define UEFI_CPER_MEM_VALID_COLUMN   0x0200
> +#define UEFI_CPER_MEM_VALID_BIT_POSITION 0x0400
> +#define UEFI_CPER_MEM_VALID_REQUESTOR0x0800
> +#define UEFI_CPER_MEM_VALID_RESPONDER0x1000
> +#define UEFI_CPER_MEM_VALID_TARGET   0x2000
> +#define UEFI_CPER_MEM_VALID_ERROR_TYPE   0x4000
> +#define UEFI_CPER_MEM_VALID_RANK_NUMBER  0x8000
> +#define UEFI_CPER_MEM_VALID_CARD_HANDLE  0x1
> +#define UEFI_CPER_MEM_VALID_MODULE_HANDLE0x2
> +#define UEFI_CPER_MEM_ERROR_TYPE_MULTI_ECC   3
> +
> +/* From the ACPI 6.1 spec, "18.3.2.9 Hardware Error Notification" */
> +
It's better to refer to the first spec version of this structure and
same with others you define.

> +enum AcpiHestNotifyType {
> +ACPI_HEST_NOTIFY_POLLED = 0,
> +ACPI_HEST_NOTIFY_EXTERNAL = 1,
> +ACPI_HEST_NOTIFY_LOCAL = 2,
> +ACPI_HEST_NOTIFY_SCI = 3,
> +ACPI_HEST_NOTIFY_NMI = 4,
> +ACPI_HEST_NOTIFY_CMCI = 5,  /* ACPI 5.0 */
> +ACPI_HEST_NOTIFY_MCE = 6,   /* ACPI 5.0 */
> +ACPI_HEST_NOTIFY_GPIO = 7,  /* ACPI 6.0 */
> +ACPI_HEST_NOTIFY_SEA = 8,   /* ACPI 6.1 */
> +ACPI_HEST_NOTIFY_SEI = 9,   /* ACPI 6.1 */
> +ACPI_HEST_NOTIFY_GSIV = 10, /* ACPI 6.1 */
> +ACPI_HEST_NOTIFY_RESERVED = 11  /* 11 and greater are reserved */
In ACPI 6.2, 11 is for Software Delegated Exception, is this useful for
your patchset?

> +};
> +
>  /*
>   * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
>   */
> @@ -474,6 +512,161 @@ struct AcpiSystemResourceAffinityTable {
>  } QEMU_PACKED;
>  typedef struct AcpiSystemResourceAffinityTable 
> AcpiSystemResourceAffinityTable;
>  
> +/* Hardware Error Notification, from the ACPI 6.1
> + * spec, "18.3.2.9 Hardware Error Notification"
> + */
Use below style for multiple comment lines
/*
 * XXX
 */

> +struct AcpiHestNotify {
> +uint8_t type;
> +uint8_t length;
> +uint16_t config_write_enable;
> +uint32_t poll_interval;
> +uint32_t vector;
> +uint32_t polling_threshold_value;
> +uint32_t polling_threshold_window;
> +uint32_t error_threshold_value;
> +uint32_t error_threshold_window;
> +} QEMU_PACKED;
> +typedef struct AcpiHestNotify AcpiHestNotify;
> +
> +/* From ACPI 6.1, sections "18.3.2.1 IA-32 Architecture Machine
> + * Check Exception" through "18.3.2.8 Generic Hardware Error Source version 
> 2".
> + */
> +enum AcpiHestSourceType {
> +ACPI_HEST_SOURCE_IA32_CHECK = 0,
> +ACPI_HEST_SOURCE_IA32_CORRECTED_CHECK = 1,
> +ACPI_HEST_SOURCE_IA32_NMI = 2,
What's 3, 4, 5 for?

> +ACPI_HEST_SOURCE_AER_ROOT_PORT = 6,
> +ACPI_HEST_SOURCE_AER_ENDPOINT = 7,
> +ACPI_HEST_SOURCE_AER_BRIDGE = 8,
> +ACPI_HEST_SOURCE_GENERIC_ERROR = 9,
> +ACPI_HEST_SOURCE_GENERIC_ERROR_V2 = 10,
> +ACPI_HEST_SOURCE_RESERVED = 11/* 11 and greater are reserved */
> +};
> +
> +/* Block status bitmasks from ACPI 6.1, "18.3.2.7.1 Generic Error Data" */
> +#define ACPI_GEBS_UNCORRECTABLE (1)
> +#define ACPI_GEBS_CORRECTABLE   (1 << 1)
> +#define ACPI_GEBS_MULTIPLE_UNCORRECTABLE(1 << 2)
> +#define ACPI_GEBS_MULTIPLE_CORRECTABLE  (1 << 3)
> +/* 10 bits, error data entry count */
> +#define ACPI_GEBS_ERROR_ENTRY_COUNT (0x3FF << 4)
> +
> +/* Generic Hardware Error Source Structure, refer to ACPI 6.1
> + * "18.3.2.7 Generic Hardware Error Source". in this struct the
> + * "type" field has to be ACPI_HEST_SOURCE_GENERIC_ERROR
> + */
> +
> +struct AcpiGenericHardwareErrorSource {
> +uint16_t type;
> +uint16_t source_id;
> +

Re: [PATCH v11 1/6] ACPI: add APEI/HEST/CPER structures and macros

2017-08-24 Thread Shannon Zhao


On 2017/8/18 22:23, Dongjiu Geng wrote:
> (1) Add related APEI/HEST table structures and  macros, these
> definition refer to ACPI 6.1 and UEFI 2.6 spec.
> (2) Add generic error status block and CPER memory section
> definition, user space only handle memory section errors.
> 
> Signed-off-by: Dongjiu Geng 
> ---
>  include/hw/acpi/acpi-defs.h | 193 
> 
>  1 file changed, 193 insertions(+)
> 
> diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> index 72be675..3b4bad7 100644
> --- a/include/hw/acpi/acpi-defs.h
> +++ b/include/hw/acpi/acpi-defs.h
> @@ -297,6 +297,44 @@ typedef struct AcpiMultipleApicTable 
> AcpiMultipleApicTable;
>  #define ACPI_APIC_GENERIC_TRANSLATOR15
>  #define ACPI_APIC_RESERVED  16   /* 16 and greater are reserved 
> */
>  
> +/* UEFI Spec 2.6, "N.2.5 Memory Error Section */
missing "

> +#define UEFI_CPER_MEM_VALID_ERROR_STATUS 0x0001
> +#define UEFI_CPER_MEM_VALID_PA   0x0002
> +#define UEFI_CPER_MEM_VALID_PA_MASK  0x0004
> +#define UEFI_CPER_MEM_VALID_NODE 0x0008
> +#define UEFI_CPER_MEM_VALID_CARD 0x0010
> +#define UEFI_CPER_MEM_VALID_MODULE   0x0020
> +#define UEFI_CPER_MEM_VALID_BANK 0x0040
> +#define UEFI_CPER_MEM_VALID_DEVICE   0x0080
> +#define UEFI_CPER_MEM_VALID_ROW  0x0100
> +#define UEFI_CPER_MEM_VALID_COLUMN   0x0200
> +#define UEFI_CPER_MEM_VALID_BIT_POSITION 0x0400
> +#define UEFI_CPER_MEM_VALID_REQUESTOR0x0800
> +#define UEFI_CPER_MEM_VALID_RESPONDER0x1000
> +#define UEFI_CPER_MEM_VALID_TARGET   0x2000
> +#define UEFI_CPER_MEM_VALID_ERROR_TYPE   0x4000
> +#define UEFI_CPER_MEM_VALID_RANK_NUMBER  0x8000
> +#define UEFI_CPER_MEM_VALID_CARD_HANDLE  0x1
> +#define UEFI_CPER_MEM_VALID_MODULE_HANDLE0x2
> +#define UEFI_CPER_MEM_ERROR_TYPE_MULTI_ECC   3
> +
> +/* From the ACPI 6.1 spec, "18.3.2.9 Hardware Error Notification" */
> +
It's better to refer to the first spec version of this structure and
same with others you define.

> +enum AcpiHestNotifyType {
> +ACPI_HEST_NOTIFY_POLLED = 0,
> +ACPI_HEST_NOTIFY_EXTERNAL = 1,
> +ACPI_HEST_NOTIFY_LOCAL = 2,
> +ACPI_HEST_NOTIFY_SCI = 3,
> +ACPI_HEST_NOTIFY_NMI = 4,
> +ACPI_HEST_NOTIFY_CMCI = 5,  /* ACPI 5.0 */
> +ACPI_HEST_NOTIFY_MCE = 6,   /* ACPI 5.0 */
> +ACPI_HEST_NOTIFY_GPIO = 7,  /* ACPI 6.0 */
> +ACPI_HEST_NOTIFY_SEA = 8,   /* ACPI 6.1 */
> +ACPI_HEST_NOTIFY_SEI = 9,   /* ACPI 6.1 */
> +ACPI_HEST_NOTIFY_GSIV = 10, /* ACPI 6.1 */
> +ACPI_HEST_NOTIFY_RESERVED = 11  /* 11 and greater are reserved */
In ACPI 6.2, 11 is for Software Delegated Exception, is this useful for
your patchset?

> +};
> +
>  /*
>   * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
>   */
> @@ -474,6 +512,161 @@ struct AcpiSystemResourceAffinityTable {
>  } QEMU_PACKED;
>  typedef struct AcpiSystemResourceAffinityTable 
> AcpiSystemResourceAffinityTable;
>  
> +/* Hardware Error Notification, from the ACPI 6.1
> + * spec, "18.3.2.9 Hardware Error Notification"
> + */
Use below style for multiple comment lines
/*
 * XXX
 */

> +struct AcpiHestNotify {
> +uint8_t type;
> +uint8_t length;
> +uint16_t config_write_enable;
> +uint32_t poll_interval;
> +uint32_t vector;
> +uint32_t polling_threshold_value;
> +uint32_t polling_threshold_window;
> +uint32_t error_threshold_value;
> +uint32_t error_threshold_window;
> +} QEMU_PACKED;
> +typedef struct AcpiHestNotify AcpiHestNotify;
> +
> +/* From ACPI 6.1, sections "18.3.2.1 IA-32 Architecture Machine
> + * Check Exception" through "18.3.2.8 Generic Hardware Error Source version 
> 2".
> + */
> +enum AcpiHestSourceType {
> +ACPI_HEST_SOURCE_IA32_CHECK = 0,
> +ACPI_HEST_SOURCE_IA32_CORRECTED_CHECK = 1,
> +ACPI_HEST_SOURCE_IA32_NMI = 2,
What's 3, 4, 5 for?

> +ACPI_HEST_SOURCE_AER_ROOT_PORT = 6,
> +ACPI_HEST_SOURCE_AER_ENDPOINT = 7,
> +ACPI_HEST_SOURCE_AER_BRIDGE = 8,
> +ACPI_HEST_SOURCE_GENERIC_ERROR = 9,
> +ACPI_HEST_SOURCE_GENERIC_ERROR_V2 = 10,
> +ACPI_HEST_SOURCE_RESERVED = 11/* 11 and greater are reserved */
> +};
> +
> +/* Block status bitmasks from ACPI 6.1, "18.3.2.7.1 Generic Error Data" */
> +#define ACPI_GEBS_UNCORRECTABLE (1)
> +#define ACPI_GEBS_CORRECTABLE   (1 << 1)
> +#define ACPI_GEBS_MULTIPLE_UNCORRECTABLE(1 << 2)
> +#define ACPI_GEBS_MULTIPLE_CORRECTABLE  (1 << 3)
> +/* 10 bits, error data entry count */
> +#define ACPI_GEBS_ERROR_ENTRY_COUNT (0x3FF << 4)
> +
> +/* Generic Hardware Error Source Structure, refer to ACPI 6.1
> + * "18.3.2.7 Generic Hardware Error Source". in this struct the
> + * "type" field has to be ACPI_HEST_SOURCE_GENERIC_ERROR
> + */
> +
> +struct AcpiGenericHardwareErrorSource {
> +uint16_t type;
> +uint16_t source_id;
> +uint16_t related_source_id;
> + 

[PATCH v2] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-12 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

The EFI DT parameters for bare metal are located under /chosen node,
while for Xen Dom0 they are located under /hyperviosr/uefi node. These
parameters under /chosen and /hyperviosr/uefi are not expected to appear
at the same time.
Parse these EFI parameters and initialize EFI like the way for bare
metal except the runtime services because the runtime services for Xen
Dom0 are available through hypercalls and they are always enabled. So it
sets the EFI_RUNTIME_SERVICES flag if it finds /hyperviosr/uefi node and
bails out in arm_enable_runtime_services() when EFI_RUNTIME_SERVICES
flag is set already.

CC: Matt Fleming <m...@codeblueprint.co.uk>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
---
v2: rebase it on top of EFI and Xen next branch, add some comments to
explain the codes. 
---
 arch/arm/xen/enlighten.c   | 22 +++
 drivers/firmware/efi/arm-runtime.c |  5 +++
 drivers/firmware/efi/efi.c | 81 ++
 3 files changed, 92 insertions(+), 16 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..d4f36eb 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -15,7 +15,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -261,6 +263,19 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   /*
+* Check if Xen supports EFI by checking whether there is the
+* "/hypervisor/uefi" node in DT. If so, runtime services are available
+* through proxy functions (e.g. in case of Xen dom0 EFI implementation
+* they call special hypercall which executes relevant EFI functions)
+* and that is why they are always enabled.
+*/
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   if ((of_get_flat_dt_subnode_by_name(node, "uefi") > 0) &&
+   !efi_runtime_disabled())
+   set_bit(EFI_RUNTIME_SERVICES, );
+   }
+
return 0;
 }
 
@@ -352,6 +367,13 @@ static int __init xen_guest_init(void)
return -ENODEV;
}
 
+   /*
+* The fdt parsing codes have set EFI_RUNTIME_SERVICES if Xen EFI
+* parameters are found. Force enable runtime services.
+*/
+   if (efi_enabled(EFI_RUNTIME_SERVICES))
+   xen_efi_runtime_setup();
+
shared_info_page = (struct shared_info *)get_zeroed_page(GFP_KERNEL);
 
if (!shared_info_page) {
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 17ccf0a..c394b81 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -107,6 +107,11 @@ static int __init arm_enable_runtime_services(void)
return 0;
}
 
+   if (efi_enabled(EFI_RUNTIME_SERVICES)) {
+   pr_info("EFI runtime services access via paravirt.\n");
+   return 0;
+   }
+
pr_info("Remapping and enabling EFI services.\n");
 
mapsize = efi.memmap.map_end - efi.memmap.map;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 05509f3..1c6f9dd 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -472,12 +472,14 @@ device_initcall(efi_load_efivars);
FIELD_SIZEOF(struct efi_fdt_params, field) \
}
 
-static __initdata struct {
+struct params {
const char name[32];
const char propname[32];
int offset;
int size;
-} dt_params[] = {
+};
+
+static __initdata struct params fdt_params[] = {
UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
@@ -485,44 +487,91 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
+static __initdata struct params xen_fdt_params[] = {
+   UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
+   UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
+   UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
+   UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
+   UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
+};
+
+#define EFI_FDT_PARAMS_SIZEARRAY_SIZE(fdt_params)
+
+static __initdata struct {
+   const char *uname;
+   const char *subnode;
+   stru

[PATCH v2] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-12 Thread Shannon Zhao
From: Shannon Zhao 

The EFI DT parameters for bare metal are located under /chosen node,
while for Xen Dom0 they are located under /hyperviosr/uefi node. These
parameters under /chosen and /hyperviosr/uefi are not expected to appear
at the same time.
Parse these EFI parameters and initialize EFI like the way for bare
metal except the runtime services because the runtime services for Xen
Dom0 are available through hypercalls and they are always enabled. So it
sets the EFI_RUNTIME_SERVICES flag if it finds /hyperviosr/uefi node and
bails out in arm_enable_runtime_services() when EFI_RUNTIME_SERVICES
flag is set already.

CC: Matt Fleming 
Signed-off-by: Shannon Zhao 
---
v2: rebase it on top of EFI and Xen next branch, add some comments to
explain the codes. 
---
 arch/arm/xen/enlighten.c   | 22 +++
 drivers/firmware/efi/arm-runtime.c |  5 +++
 drivers/firmware/efi/efi.c | 81 ++
 3 files changed, 92 insertions(+), 16 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..d4f36eb 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -15,7 +15,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -261,6 +263,19 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   /*
+* Check if Xen supports EFI by checking whether there is the
+* "/hypervisor/uefi" node in DT. If so, runtime services are available
+* through proxy functions (e.g. in case of Xen dom0 EFI implementation
+* they call special hypercall which executes relevant EFI functions)
+* and that is why they are always enabled.
+*/
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   if ((of_get_flat_dt_subnode_by_name(node, "uefi") > 0) &&
+   !efi_runtime_disabled())
+   set_bit(EFI_RUNTIME_SERVICES, );
+   }
+
return 0;
 }
 
@@ -352,6 +367,13 @@ static int __init xen_guest_init(void)
return -ENODEV;
}
 
+   /*
+* The fdt parsing codes have set EFI_RUNTIME_SERVICES if Xen EFI
+* parameters are found. Force enable runtime services.
+*/
+   if (efi_enabled(EFI_RUNTIME_SERVICES))
+   xen_efi_runtime_setup();
+
shared_info_page = (struct shared_info *)get_zeroed_page(GFP_KERNEL);
 
if (!shared_info_page) {
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 17ccf0a..c394b81 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -107,6 +107,11 @@ static int __init arm_enable_runtime_services(void)
return 0;
}
 
+   if (efi_enabled(EFI_RUNTIME_SERVICES)) {
+   pr_info("EFI runtime services access via paravirt.\n");
+   return 0;
+   }
+
pr_info("Remapping and enabling EFI services.\n");
 
mapsize = efi.memmap.map_end - efi.memmap.map;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 05509f3..1c6f9dd 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -472,12 +472,14 @@ device_initcall(efi_load_efivars);
FIELD_SIZEOF(struct efi_fdt_params, field) \
}
 
-static __initdata struct {
+struct params {
const char name[32];
const char propname[32];
int offset;
int size;
-} dt_params[] = {
+};
+
+static __initdata struct params fdt_params[] = {
UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
@@ -485,44 +487,91 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
+static __initdata struct params xen_fdt_params[] = {
+   UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
+   UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
+   UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
+   UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
+   UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
+};
+
+#define EFI_FDT_PARAMS_SIZEARRAY_SIZE(fdt_params)
+
+static __initdata struct {
+   const char *uname;
+   const char *subnode;
+   struct params *params;
+} dt_params[] = {
+   { "hypervisor", "

Re: [PATCH] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-11 Thread Shannon Zhao


On 2016/5/12 7:24, Matt Fleming wrote:
> On Wed, 11 May, at 09:35:47PM, Shannon Zhao wrote:
>>> > > 
>>> > > Also, why do you need to setup efi.runtime_version here? Isn't that
>>> > > done inside uefi_init()?
>>> > > 
>> > I don't see any codes which setup efi.runtime_version in uefi_init().
>  
> Look in the EFI tree,
> 
>   
> https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/tree/drivers/firmware/efi/arm-init.c?h=next#n120
> 
Ah, there are some patches in EFI tree introducing this change, but they
are not in kernel matser but I didn't notice this, sorry.

>>> > > Here is how I would have expected this patch to look:
>>> > > 
>>> > >   - Add FDT code to find hypervisor EFI params
>>> > > 
>>> > >   - Force enable EFI_RUNTIME_SERVICES for Xen and call
>>> > > xen_efi_runtime_setup() inside xen_guest_init()
>>> > > 
>>> > >   - Change arm_enable_runtime_services() to handle the case where
>>> > > EFI_RUNTIME_SERVICES is already set
>>> > > 
>>> > > Am I misunderstanding some ordering issues?
>> > 
>> > Since xen_guest_init() and arm_enable_runtime_services() are both
>> > early_initcall and the calling order is random I think.
> Urgh, right, I missed that.
> 
>> > And when we call xen_efi_runtime_setup() and setup
>> > efi.runtime_version in xen_guest_init(), the efi.systab might be
>> > NULL. So it needs to map the systanle explicitly before we use
>> > efi.systab.
> Could you explain why you need to copy efi.runtime_version instead of
> letting the existing code in uefi_init() set it up?
> 
> Also, efi.systab isn't used by xen_efi_runtime_setup() as far I can
> see, not sure why you need that either?
As said above, I will rebase this patch on top of the EFI next branch.

Thanks,
-- 
Shannon



Re: [PATCH] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-11 Thread Shannon Zhao


On 2016/5/12 7:24, Matt Fleming wrote:
> On Wed, 11 May, at 09:35:47PM, Shannon Zhao wrote:
>>> > > 
>>> > > Also, why do you need to setup efi.runtime_version here? Isn't that
>>> > > done inside uefi_init()?
>>> > > 
>> > I don't see any codes which setup efi.runtime_version in uefi_init().
>  
> Look in the EFI tree,
> 
>   
> https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/tree/drivers/firmware/efi/arm-init.c?h=next#n120
> 
Ah, there are some patches in EFI tree introducing this change, but they
are not in kernel matser but I didn't notice this, sorry.

>>> > > Here is how I would have expected this patch to look:
>>> > > 
>>> > >   - Add FDT code to find hypervisor EFI params
>>> > > 
>>> > >   - Force enable EFI_RUNTIME_SERVICES for Xen and call
>>> > > xen_efi_runtime_setup() inside xen_guest_init()
>>> > > 
>>> > >   - Change arm_enable_runtime_services() to handle the case where
>>> > > EFI_RUNTIME_SERVICES is already set
>>> > > 
>>> > > Am I misunderstanding some ordering issues?
>> > 
>> > Since xen_guest_init() and arm_enable_runtime_services() are both
>> > early_initcall and the calling order is random I think.
> Urgh, right, I missed that.
> 
>> > And when we call xen_efi_runtime_setup() and setup
>> > efi.runtime_version in xen_guest_init(), the efi.systab might be
>> > NULL. So it needs to map the systanle explicitly before we use
>> > efi.systab.
> Could you explain why you need to copy efi.runtime_version instead of
> letting the existing code in uefi_init() set it up?
> 
> Also, efi.systab isn't used by xen_efi_runtime_setup() as far I can
> see, not sure why you need that either?
As said above, I will rebase this patch on top of the EFI next branch.

Thanks,
-- 
Shannon



Re: [PATCH] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-11 Thread Shannon Zhao
On 2016年05月11日 20:27, Matt Fleming wrote:
> On Fri, 06 May, at 04:32:06PM, Shannon Zhao wrote:
>> > From: Shannon Zhao <shannon.z...@linaro.org>
>> > 
>> > Add a new function to parse DT parameters for Xen specific UEFI just
>> > like the way for normal UEFI. Then it could reuse the existing codes.
>> > 
>> > If Xen supports EFI, initialize runtime services.
>  
> This commit log would benefit from a little expansion. I'd like to see
> information that answers the following questions,
> 
>  - How do the Xen DT paramters differ from bare metal?
>  - What existing code is reused with your patch?
>  - How are Xen runtime services different from bare metal?
>  - Why is it OK to force enable EFI runtime services for Xen?
> 
> I think it would also be good to explicitly state that we do not
> expect to find both Xen EFI DT parameters and bare metal EFI DT
> parameters when performing the search; the two should be mutually
> exclusive.
> 
>> > CC: Matt Fleming <m...@codeblueprint.co.uk>
>> > Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
>> > ---
>> > Drop using of EFI_PARAVIRT. Discussion can be found from [1].
>> > [1] https://lkml.org/lkml/2016/4/29/8
>> > ---
>> >  arch/arm/include/asm/efi.h |  2 +
>> >  arch/arm/xen/enlighten.c   | 16 
>> >  arch/arm64/include/asm/efi.h   |  2 +
>> >  drivers/firmware/efi/arm-runtime.c | 70 +++-
>> >  drivers/firmware/efi/efi.c | 81 
>> > ++
>> >  5 files changed, 137 insertions(+), 34 deletions(-)
>> > 
>> > diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
>> > index e0eea72..5ba4343 100644
>> > --- a/arch/arm/include/asm/efi.h
>> > +++ b/arch/arm/include/asm/efi.h
>> > @@ -52,9 +52,11 @@ static inline void efi_set_pgd(struct mm_struct *mm)
>> >  
>> >  void efi_virtmap_load(void);
>> >  void efi_virtmap_unload(void);
>> > +int xen_arm_enable_runtime_services(void);
>> >  
>> >  #else
>> >  #define efi_init()
>> > +#define xen_arm_enable_runtime_services() (0)
>> >  #endif /* CONFIG_EFI */
>> >  
>> >  /* arch specific definitions used by the stub code */
>> > diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
>> > index 13e3e9f..3362870 100644
>> > --- a/arch/arm/xen/enlighten.c
>> > +++ b/arch/arm/xen/enlighten.c
>> > @@ -16,6 +16,7 @@
>> >  #include 
>> >  #include 
>> >  #include 
>> > +#include 
>> >  #include 
>> >  #include 
>> >  #include 
>> > @@ -261,6 +262,13 @@ static int __init fdt_find_hyper_node(unsigned long 
>> > node, const char *uname,
>> >!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
>> >hyper_node.version = s + strlen(hyper_node.prefix);
>> >  
>> > +  if (IS_ENABLED(CONFIG_XEN_EFI)) {
>> > +  /* Check if Xen supports EFI */
>> > +  if ((of_get_flat_dt_subnode_by_name(node, "uefi") > 0) &&
>> > +  !efi_runtime_disabled())
>> > +  set_bit(EFI_RUNTIME_SERVICES, );
>> > +  }
>> > +
>> >return 0;
>> >  }
>> >  
> The above comment could do with including similar information to the
> commit log as to why we want to force enable runtime services. For x86
> we have this,
> 
>*
>* When EFI_PARAVIRT is in force then we could not map runtime
>* service memory region because we do not have direct access to it.
>* However, runtime services are available through proxy functions
>* (e.g. in case of Xen dom0 EFI implementation they call special
>* hypercall which executes relevant EFI functions) and that is why
>* they are always enabled.
>*/
> 
> We need something similar here.
> 
>> > @@ -338,6 +346,7 @@ static int __init xen_guest_init(void)
>> >  {
>> >struct xen_add_to_physmap xatp;
>> >struct shared_info *shared_info_page = NULL;
>> > +  int ret;
>> >  
>> >if (!xen_domain())
>> >return 0;
>> > @@ -352,6 +361,13 @@ static int __init xen_guest_init(void)
>> >return -ENODEV;
>> >}
>> >  
>> > +  if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_BOOT) &&
>> > +  efi_enabled(EFI_RUNTIME_SERVICES)) {
>> > +  

Re: [PATCH] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-11 Thread Shannon Zhao
On 2016年05月11日 20:27, Matt Fleming wrote:
> On Fri, 06 May, at 04:32:06PM, Shannon Zhao wrote:
>> > From: Shannon Zhao 
>> > 
>> > Add a new function to parse DT parameters for Xen specific UEFI just
>> > like the way for normal UEFI. Then it could reuse the existing codes.
>> > 
>> > If Xen supports EFI, initialize runtime services.
>  
> This commit log would benefit from a little expansion. I'd like to see
> information that answers the following questions,
> 
>  - How do the Xen DT paramters differ from bare metal?
>  - What existing code is reused with your patch?
>  - How are Xen runtime services different from bare metal?
>  - Why is it OK to force enable EFI runtime services for Xen?
> 
> I think it would also be good to explicitly state that we do not
> expect to find both Xen EFI DT parameters and bare metal EFI DT
> parameters when performing the search; the two should be mutually
> exclusive.
> 
>> > CC: Matt Fleming 
>> > Signed-off-by: Shannon Zhao 
>> > ---
>> > Drop using of EFI_PARAVIRT. Discussion can be found from [1].
>> > [1] https://lkml.org/lkml/2016/4/29/8
>> > ---
>> >  arch/arm/include/asm/efi.h |  2 +
>> >  arch/arm/xen/enlighten.c   | 16 
>> >  arch/arm64/include/asm/efi.h   |  2 +
>> >  drivers/firmware/efi/arm-runtime.c | 70 +++-
>> >  drivers/firmware/efi/efi.c | 81 
>> > ++
>> >  5 files changed, 137 insertions(+), 34 deletions(-)
>> > 
>> > diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
>> > index e0eea72..5ba4343 100644
>> > --- a/arch/arm/include/asm/efi.h
>> > +++ b/arch/arm/include/asm/efi.h
>> > @@ -52,9 +52,11 @@ static inline void efi_set_pgd(struct mm_struct *mm)
>> >  
>> >  void efi_virtmap_load(void);
>> >  void efi_virtmap_unload(void);
>> > +int xen_arm_enable_runtime_services(void);
>> >  
>> >  #else
>> >  #define efi_init()
>> > +#define xen_arm_enable_runtime_services() (0)
>> >  #endif /* CONFIG_EFI */
>> >  
>> >  /* arch specific definitions used by the stub code */
>> > diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
>> > index 13e3e9f..3362870 100644
>> > --- a/arch/arm/xen/enlighten.c
>> > +++ b/arch/arm/xen/enlighten.c
>> > @@ -16,6 +16,7 @@
>> >  #include 
>> >  #include 
>> >  #include 
>> > +#include 
>> >  #include 
>> >  #include 
>> >  #include 
>> > @@ -261,6 +262,13 @@ static int __init fdt_find_hyper_node(unsigned long 
>> > node, const char *uname,
>> >!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
>> >hyper_node.version = s + strlen(hyper_node.prefix);
>> >  
>> > +  if (IS_ENABLED(CONFIG_XEN_EFI)) {
>> > +  /* Check if Xen supports EFI */
>> > +  if ((of_get_flat_dt_subnode_by_name(node, "uefi") > 0) &&
>> > +  !efi_runtime_disabled())
>> > +  set_bit(EFI_RUNTIME_SERVICES, );
>> > +  }
>> > +
>> >return 0;
>> >  }
>> >  
> The above comment could do with including similar information to the
> commit log as to why we want to force enable runtime services. For x86
> we have this,
> 
>*
>* When EFI_PARAVIRT is in force then we could not map runtime
>* service memory region because we do not have direct access to it.
>* However, runtime services are available through proxy functions
>* (e.g. in case of Xen dom0 EFI implementation they call special
>* hypercall which executes relevant EFI functions) and that is why
>* they are always enabled.
>*/
> 
> We need something similar here.
> 
>> > @@ -338,6 +346,7 @@ static int __init xen_guest_init(void)
>> >  {
>> >struct xen_add_to_physmap xatp;
>> >struct shared_info *shared_info_page = NULL;
>> > +  int ret;
>> >  
>> >if (!xen_domain())
>> >return 0;
>> > @@ -352,6 +361,13 @@ static int __init xen_guest_init(void)
>> >return -ENODEV;
>> >}
>> >  
>> > +  if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_BOOT) &&
>> > +  efi_enabled(EFI_RUNTIME_SERVICES)) {
>> > +  ret = xen_arm_enable_runtime_services();
>> > +  if (re

[PATCH] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-06 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Add a new function to parse DT parameters for Xen specific UEFI just
like the way for normal UEFI. Then it could reuse the existing codes.

If Xen supports EFI, initialize runtime services.

CC: Matt Fleming <m...@codeblueprint.co.uk>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
---
Drop using of EFI_PARAVIRT. Discussion can be found from [1].
[1] https://lkml.org/lkml/2016/4/29/8
---
 arch/arm/include/asm/efi.h |  2 +
 arch/arm/xen/enlighten.c   | 16 
 arch/arm64/include/asm/efi.h   |  2 +
 drivers/firmware/efi/arm-runtime.c | 70 +++-
 drivers/firmware/efi/efi.c | 81 ++
 5 files changed, 137 insertions(+), 34 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index e0eea72..5ba4343 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -52,9 +52,11 @@ static inline void efi_set_pgd(struct mm_struct *mm)
 
 void efi_virtmap_load(void);
 void efi_virtmap_unload(void);
+int xen_arm_enable_runtime_services(void);
 
 #else
 #define efi_init()
+#define xen_arm_enable_runtime_services() (0)
 #endif /* CONFIG_EFI */
 
 /* arch specific definitions used by the stub code */
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..3362870 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -261,6 +262,13 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   /* Check if Xen supports EFI */
+   if ((of_get_flat_dt_subnode_by_name(node, "uefi") > 0) &&
+   !efi_runtime_disabled())
+   set_bit(EFI_RUNTIME_SERVICES, );
+   }
+
return 0;
 }
 
@@ -338,6 +346,7 @@ static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
struct shared_info *shared_info_page = NULL;
+   int ret;
 
if (!xen_domain())
return 0;
@@ -352,6 +361,13 @@ static int __init xen_guest_init(void)
return -ENODEV;
}
 
+   if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_BOOT) &&
+   efi_enabled(EFI_RUNTIME_SERVICES)) {
+   ret = xen_arm_enable_runtime_services();
+   if (ret)
+   return ret;
+   }
+
shared_info_page = (struct shared_info *)get_zeroed_page(GFP_KERNEL);
 
if (!shared_info_page) {
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 8e88a69..574bee5 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -8,8 +8,10 @@
 
 #ifdef CONFIG_EFI
 extern void efi_init(void);
+int xen_arm_enable_runtime_services(void);
 #else
 #define efi_init()
+#define xen_arm_enable_runtime_services() (0)
 #endif
 
 int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 6ae21e4..211ec10 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern u64 efi_system_table;
 
@@ -39,6 +40,33 @@ static struct mm_struct efi_mm = {
.mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
 };
 
+static int __init efi_remap_init(void)
+{
+   u64 mapsize;
+
+   pr_info("Remapping and enabling EFI services.\n");
+
+   mapsize = memmap.map_end - memmap.map;
+   memmap.map = (__force void *)ioremap_cache(memmap.phys_map,
+  mapsize);
+   if (!memmap.map) {
+   pr_err("Failed to remap EFI memory map\n");
+   return -ENOMEM;
+   }
+   memmap.map_end = memmap.map + mapsize;
+   efi.memmap = 
+
+   efi.systab = (__force void *)ioremap_cache(efi_system_table,
+  sizeof(efi_system_table_t));
+   if (!efi.systab) {
+   pr_err("Failed to remap EFI System Table\n");
+   return -ENOMEM;
+   }
+   set_bit(EFI_SYSTEM_TABLES, );
+
+   return 0;
+}
+
 static bool __init efi_virtmap_init(void)
 {
efi_memory_desc_t *md;
@@ -75,7 +103,7 @@ static bool __init efi_virtmap_init(void)
  */
 static int __init arm_enable_runtime_services(void)
 {
-   u64 mapsize;
+   int ret;
 
if (!efi_enabled(EFI_BOOT)) {
pr_info("EFI services will not be available.\n");
@@ -87,25 +115,14 @@ static int __init arm_enable_runtime_services(void

[PATCH] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-05-06 Thread Shannon Zhao
From: Shannon Zhao 

Add a new function to parse DT parameters for Xen specific UEFI just
like the way for normal UEFI. Then it could reuse the existing codes.

If Xen supports EFI, initialize runtime services.

CC: Matt Fleming 
Signed-off-by: Shannon Zhao 
---
Drop using of EFI_PARAVIRT. Discussion can be found from [1].
[1] https://lkml.org/lkml/2016/4/29/8
---
 arch/arm/include/asm/efi.h |  2 +
 arch/arm/xen/enlighten.c   | 16 
 arch/arm64/include/asm/efi.h   |  2 +
 drivers/firmware/efi/arm-runtime.c | 70 +++-
 drivers/firmware/efi/efi.c | 81 ++
 5 files changed, 137 insertions(+), 34 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index e0eea72..5ba4343 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -52,9 +52,11 @@ static inline void efi_set_pgd(struct mm_struct *mm)
 
 void efi_virtmap_load(void);
 void efi_virtmap_unload(void);
+int xen_arm_enable_runtime_services(void);
 
 #else
 #define efi_init()
+#define xen_arm_enable_runtime_services() (0)
 #endif /* CONFIG_EFI */
 
 /* arch specific definitions used by the stub code */
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..3362870 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -261,6 +262,13 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   /* Check if Xen supports EFI */
+   if ((of_get_flat_dt_subnode_by_name(node, "uefi") > 0) &&
+   !efi_runtime_disabled())
+   set_bit(EFI_RUNTIME_SERVICES, );
+   }
+
return 0;
 }
 
@@ -338,6 +346,7 @@ static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
struct shared_info *shared_info_page = NULL;
+   int ret;
 
if (!xen_domain())
return 0;
@@ -352,6 +361,13 @@ static int __init xen_guest_init(void)
return -ENODEV;
}
 
+   if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_BOOT) &&
+   efi_enabled(EFI_RUNTIME_SERVICES)) {
+   ret = xen_arm_enable_runtime_services();
+   if (ret)
+   return ret;
+   }
+
shared_info_page = (struct shared_info *)get_zeroed_page(GFP_KERNEL);
 
if (!shared_info_page) {
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 8e88a69..574bee5 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -8,8 +8,10 @@
 
 #ifdef CONFIG_EFI
 extern void efi_init(void);
+int xen_arm_enable_runtime_services(void);
 #else
 #define efi_init()
+#define xen_arm_enable_runtime_services() (0)
 #endif
 
 int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 6ae21e4..211ec10 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern u64 efi_system_table;
 
@@ -39,6 +40,33 @@ static struct mm_struct efi_mm = {
.mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
 };
 
+static int __init efi_remap_init(void)
+{
+   u64 mapsize;
+
+   pr_info("Remapping and enabling EFI services.\n");
+
+   mapsize = memmap.map_end - memmap.map;
+   memmap.map = (__force void *)ioremap_cache(memmap.phys_map,
+  mapsize);
+   if (!memmap.map) {
+   pr_err("Failed to remap EFI memory map\n");
+   return -ENOMEM;
+   }
+   memmap.map_end = memmap.map + mapsize;
+   efi.memmap = 
+
+   efi.systab = (__force void *)ioremap_cache(efi_system_table,
+  sizeof(efi_system_table_t));
+   if (!efi.systab) {
+   pr_err("Failed to remap EFI System Table\n");
+   return -ENOMEM;
+   }
+   set_bit(EFI_SYSTEM_TABLES, );
+
+   return 0;
+}
+
 static bool __init efi_virtmap_init(void)
 {
efi_memory_desc_t *md;
@@ -75,7 +103,7 @@ static bool __init efi_virtmap_init(void)
  */
 static int __init arm_enable_runtime_services(void)
 {
-   u64 mapsize;
+   int ret;
 
if (!efi_enabled(EFI_BOOT)) {
pr_info("EFI services will not be available.\n");
@@ -87,25 +115,14 @@ static int __init arm_enable_runtime_services(void)
return 0;
}
 
-   pr_info("Remapping and enabling EFI services.\n"

Re: [Xen-devel] efi_enabled(EFI_PARAVIRT) use

2016-05-03 Thread Shannon Zhao


On 2016/4/30 22:14, Shannon Zhao wrote:
>> I already proposed when this patch was first under review to make the
>> > arm_enable_runtime_services() function bail early without error if the
>> > EFI_RUNTIME_SERVICES flag is already set, and the xen code could set
>> > that bit as well when it installs its paravirtualized alternatives. I
>> > don't remember exactly why that was shot down, though, but I think it
>> > is the only reason this code introduces references to EFI_PARAVIRT in
>> > the first place.
>> > 
> Yes, in this patch we could set EFI_RUNTIME_SERVICES flag in
> fdt_find_hyper_node instead of setting EFI_PARAVIRT flag, and then bail
> out early in arm_enable_runtime_services() as you said. Then call
> xen_efi_runtime_setup() in xen_guest_init().

Hi Ard,

If it sets EFI_RUNTIME_SERVICES flag in fdt_find_hyper_node and in
arm_enable_runtime_services() it checks whether it's a Dom0 through
xen_init_domain() and the EFI_RUNTIME_SERVICES flag is set, then call
xen_efi_runtime_setup(). Is it ok?

Thanks,
-- 
Shannon



Re: [Xen-devel] efi_enabled(EFI_PARAVIRT) use

2016-05-03 Thread Shannon Zhao


On 2016/4/30 22:14, Shannon Zhao wrote:
>> I already proposed when this patch was first under review to make the
>> > arm_enable_runtime_services() function bail early without error if the
>> > EFI_RUNTIME_SERVICES flag is already set, and the xen code could set
>> > that bit as well when it installs its paravirtualized alternatives. I
>> > don't remember exactly why that was shot down, though, but I think it
>> > is the only reason this code introduces references to EFI_PARAVIRT in
>> > the first place.
>> > 
> Yes, in this patch we could set EFI_RUNTIME_SERVICES flag in
> fdt_find_hyper_node instead of setting EFI_PARAVIRT flag, and then bail
> out early in arm_enable_runtime_services() as you said. Then call
> xen_efi_runtime_setup() in xen_guest_init().

Hi Ard,

If it sets EFI_RUNTIME_SERVICES flag in fdt_find_hyper_node and in
arm_enable_runtime_services() it checks whether it's a Dom0 through
xen_init_domain() and the EFI_RUNTIME_SERVICES flag is set, then call
xen_efi_runtime_setup(). Is it ok?

Thanks,
-- 
Shannon



Re: [Xen-devel] efi_enabled(EFI_PARAVIRT) use

2016-05-02 Thread Shannon Zhao


On 2016/5/2 18:45, Matt Fleming wrote:
> On Sun, 01 May, at 10:36:51PM, Shannon Zhao wrote:
>> So is there any other way you suggest?
> 
> Would this work (compile tested but not runtime tested)?
> 
> ---
> 
> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 3a69ed5ecfcb..13d8be16447a 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -469,12 +469,14 @@ device_initcall(efi_load_efivars);
>   FIELD_SIZEOF(struct efi_fdt_params, field) \
>   }
>  
> -static __initdata struct {
> +struct params {
>   const char name[32];
>   const char propname[32];
>   int offset;
>   int size;
> -} dt_params[] = {
> +};
> +
> +static __initdata struct params fdt_params[] = {
>   UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
>   UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
>   UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
> @@ -482,44 +484,83 @@ static __initdata struct {
>   UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
>  };
>  
> +static __initdata struct params xen_fdt_params[] = {
> + UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
> + UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
> + UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
> + UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
> + UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
> +};
> +
> +#define EFI_FDT_PARAMS_SIZE  ARRAY_SIZE(fdt_params)
> +
> +static __initdata struct {
> + const char *uname;
> + struct params *params;
> +} dt_params[] = {
> + { "hypervisor", xen_fdt_params },
While the uefi params are located under /hypervisor/uefi node not
/hypervisor node.

> + { "chosen", fdt_params },
> +};
> +
>  struct param_info {
>   int found;
>   void *params;
> + const char *missing;
>  };
>  
> -static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
> -int depth, void *data)
> +static int __init __find_uefi_params(unsigned long node,
> +  struct param_info *info,
> +  struct params *params)
>  {
> - struct param_info *info = data;
>   const void *prop;
>   void *dest;
>   u64 val;
>   int i, len;
>  
> - if (depth != 1 || strcmp(uname, "chosen") != 0)
> - return 0;
> -
> - for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
> - prop = of_get_flat_dt_prop(node, dt_params[i].propname, );
> - if (!prop)
> + for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) {
> + prop = of_get_flat_dt_prop(node, params[i].propname, );
> + if (!prop) {
> + info->missing = params[i].name;
>   return 0;
> - dest = info->params + dt_params[i].offset;
> + }
> +
> + dest = info->params + params[i].offset;
>   info->found++;
>  
>   val = of_read_number(prop, len / sizeof(u32));
>  
> - if (dt_params[i].size == sizeof(u32))
> + if (params[i].size == sizeof(u32))
>   *(u32 *)dest = val;
>   else
>   *(u64 *)dest = val;
>  
>   if (efi_enabled(EFI_DBG))
> - pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
> - dt_params[i].size * 2, val);
> + pr_info("  %s: 0x%0*llx\n", params[i].name,
> + params[i].size * 2, val);
>   }
> +
>   return 1;
>  }
>  
> +static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
> +int depth, void *data)
> +{
> + struct param_info *info = data;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
> +
> + if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) {
> + info->missing = dt_params[i].params[0].name;
> + continue;
> + }
> +
So here it needs to check whether the node is /hypervisor. If so, get
the subnode "uefi". Like below:
if (strcmp(uname, "hypervisor") == 0

Re: [Xen-devel] efi_enabled(EFI_PARAVIRT) use

2016-05-02 Thread Shannon Zhao


On 2016/5/2 18:45, Matt Fleming wrote:
> On Sun, 01 May, at 10:36:51PM, Shannon Zhao wrote:
>> So is there any other way you suggest?
> 
> Would this work (compile tested but not runtime tested)?
> 
> ---
> 
> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 3a69ed5ecfcb..13d8be16447a 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -469,12 +469,14 @@ device_initcall(efi_load_efivars);
>   FIELD_SIZEOF(struct efi_fdt_params, field) \
>   }
>  
> -static __initdata struct {
> +struct params {
>   const char name[32];
>   const char propname[32];
>   int offset;
>   int size;
> -} dt_params[] = {
> +};
> +
> +static __initdata struct params fdt_params[] = {
>   UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
>   UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
>   UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
> @@ -482,44 +484,83 @@ static __initdata struct {
>   UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
>  };
>  
> +static __initdata struct params xen_fdt_params[] = {
> + UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
> + UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
> + UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
> + UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
> + UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
> +};
> +
> +#define EFI_FDT_PARAMS_SIZE  ARRAY_SIZE(fdt_params)
> +
> +static __initdata struct {
> + const char *uname;
> + struct params *params;
> +} dt_params[] = {
> + { "hypervisor", xen_fdt_params },
While the uefi params are located under /hypervisor/uefi node not
/hypervisor node.

> + { "chosen", fdt_params },
> +};
> +
>  struct param_info {
>   int found;
>   void *params;
> + const char *missing;
>  };
>  
> -static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
> -int depth, void *data)
> +static int __init __find_uefi_params(unsigned long node,
> +  struct param_info *info,
> +  struct params *params)
>  {
> - struct param_info *info = data;
>   const void *prop;
>   void *dest;
>   u64 val;
>   int i, len;
>  
> - if (depth != 1 || strcmp(uname, "chosen") != 0)
> - return 0;
> -
> - for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
> - prop = of_get_flat_dt_prop(node, dt_params[i].propname, );
> - if (!prop)
> + for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) {
> + prop = of_get_flat_dt_prop(node, params[i].propname, );
> + if (!prop) {
> + info->missing = params[i].name;
>   return 0;
> - dest = info->params + dt_params[i].offset;
> + }
> +
> + dest = info->params + params[i].offset;
>   info->found++;
>  
>   val = of_read_number(prop, len / sizeof(u32));
>  
> - if (dt_params[i].size == sizeof(u32))
> + if (params[i].size == sizeof(u32))
>   *(u32 *)dest = val;
>   else
>   *(u64 *)dest = val;
>  
>   if (efi_enabled(EFI_DBG))
> - pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
> - dt_params[i].size * 2, val);
> + pr_info("  %s: 0x%0*llx\n", params[i].name,
> + params[i].size * 2, val);
>   }
> +
>   return 1;
>  }
>  
> +static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
> +int depth, void *data)
> +{
> + struct param_info *info = data;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
> +
> + if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) {
> + info->missing = dt_params[i].params[0].name;
> + continue;
> + }
> +
So here it needs to check whether the node is /hypervisor. If so, get
the subnode "uefi". Like below:
if (strcmp(uname, "hypervisor") == 0

Re: efi_enabled(EFI_PARAVIRT) use

2016-05-01 Thread Shannon Zhao
On 2016年05月01日 21:26, Matt Fleming wrote:
> On Sun, 01 May, at 11:24:18AM, Shannon Zhao wrote:
>> Because the UEFI params for Dom0 are located under /hypervisor/uefi node
>> instead of /chosen. So it needs to check whether it's a Dom0 then search
>> and parse different node with different params arrays.
>  
> Why can't you search both nodes? 
Before searching, it needs to decide which uefi params array should be
passed to of_scan_flat_dt().

> Would you ever expect to see both for
> a Dom0 kernel?
> 
>> So it still needs add another check to firstly parse the fdt to see if
>> there is "xen,uefi-system-table" under /hypervisor/uefi node, right? I
>> think it's a bit redundant compared with xen_initial_domain().
> 
> Sometimes you really do need to check xen_initial_domain(), but I do
> not think this is such a case. And if we can get by without adding
> that check, the code will be better for it.
> 
So is there any other way you suggest?

Thanks,
-- 
Shannon


Re: efi_enabled(EFI_PARAVIRT) use

2016-05-01 Thread Shannon Zhao
On 2016年05月01日 21:26, Matt Fleming wrote:
> On Sun, 01 May, at 11:24:18AM, Shannon Zhao wrote:
>> Because the UEFI params for Dom0 are located under /hypervisor/uefi node
>> instead of /chosen. So it needs to check whether it's a Dom0 then search
>> and parse different node with different params arrays.
>  
> Why can't you search both nodes? 
Before searching, it needs to decide which uefi params array should be
passed to of_scan_flat_dt().

> Would you ever expect to see both for
> a Dom0 kernel?
> 
>> So it still needs add another check to firstly parse the fdt to see if
>> there is "xen,uefi-system-table" under /hypervisor/uefi node, right? I
>> think it's a bit redundant compared with xen_initial_domain().
> 
> Sometimes you really do need to check xen_initial_domain(), but I do
> not think this is such a case. And if we can get by without adding
> that check, the code will be better for it.
> 
So is there any other way you suggest?

Thanks,
-- 
Shannon


Re: efi_enabled(EFI_PARAVIRT) use

2016-04-30 Thread Shannon Zhao
On 2016年05月01日 04:44, Matt Fleming wrote:
>> While I still have a question, in this patch we use
>> > efi_enabled(EFI_PARAVIRT) as a condition to make fdt_find_uefi_params()
>> > and efi_get_fdt_params() execute different ways. So it needs to find a
>> > new condition for that if we need to get rid of EFI_PARAVIRT. One I
>> > think is that xen_initial_domain() check. Is that fine?
> Hmm... why do you actually need to check whether you're running on a
> PV machine in fdt_find_uefi_params()?
Because the UEFI params for Dom0 are located under /hypervisor/uefi node
instead of /chosen. So it needs to check whether it's a Dom0 then search
and parse different node with different params arrays.

> Can't you infer that from the DT
> params you discover?
> 

> I could understand maybe only accepting the "xen,uefi-system-table"
> property if IS_ENABLED(CONFIG_XEN) but surely you don't also need to
> filter based on whether you're booting a PV kernel?
> 
> Let me put it this way: when would you see "xen,uefi-system-table" and
> *not* be booting a PV kernel?
So it still needs add another check to firstly parse the fdt to see if
there is "xen,uefi-system-table" under /hypervisor/uefi node, right? I
think it's a bit redundant compared with xen_initial_domain().

Thanks,
-- 
Shannon


Re: efi_enabled(EFI_PARAVIRT) use

2016-04-30 Thread Shannon Zhao
On 2016年05月01日 04:44, Matt Fleming wrote:
>> While I still have a question, in this patch we use
>> > efi_enabled(EFI_PARAVIRT) as a condition to make fdt_find_uefi_params()
>> > and efi_get_fdt_params() execute different ways. So it needs to find a
>> > new condition for that if we need to get rid of EFI_PARAVIRT. One I
>> > think is that xen_initial_domain() check. Is that fine?
> Hmm... why do you actually need to check whether you're running on a
> PV machine in fdt_find_uefi_params()?
Because the UEFI params for Dom0 are located under /hypervisor/uefi node
instead of /chosen. So it needs to check whether it's a Dom0 then search
and parse different node with different params arrays.

> Can't you infer that from the DT
> params you discover?
> 

> I could understand maybe only accepting the "xen,uefi-system-table"
> property if IS_ENABLED(CONFIG_XEN) but surely you don't also need to
> filter based on whether you're booting a PV kernel?
> 
> Let me put it this way: when would you see "xen,uefi-system-table" and
> *not* be booting a PV kernel?
So it still needs add another check to firstly parse the fdt to see if
there is "xen,uefi-system-table" under /hypervisor/uefi node, right? I
think it's a bit redundant compared with xen_initial_domain().

Thanks,
-- 
Shannon


Re: efi_enabled(EFI_PARAVIRT) use

2016-04-30 Thread Shannon Zhao
On 2016年04月29日 22:53, Ard Biesheuvel wrote:
> On 29 April 2016 at 16:39, Matt Fleming  wrote:
>> On Fri, 29 Apr, at 11:34:45AM, Stefano Stabellini wrote:
>>> On Fri, 29 Apr 2016, Ingo Molnar wrote:
 Also, it would be nice to have all things EFI in a single tree, the 
 conflicts are
 going to be painful! There's very little reason not to carry this kind of 
 commit:

  arch/arm/xen/enlighten.c   |  6 +
  drivers/firmware/efi/arm-runtime.c | 17 +-
  drivers/firmware/efi/efi.c | 45 
 --
  3 files changed, 56 insertions(+), 12 deletions(-)

 in the EFI tree.
>>>
>>> That's true. I'll drop this commit from xentip and let Matt pick it up
>>> or request changes as he sees fit.
>>
>> One small change I think would be sensible to make is to expand
>> EFI_PARAVIRT into a few more bits to clearly indicate the quirks on
>> Xen, and in the process, to delete EFI_PARAVIRT.
>>
Sure. How should I add this change? Rework this patch or add new one on
top of it?

>> That should address Ingo's major concern, and also make it much easier
>> to rework the code in a piecemeal fashion.
>>
>> Could somebody enumerate the things that make Xen (dom0) different on
>> arm* compared with bare metal EFI boot? The list I made for x86 was,
>>
>>   1. Has no EFI memory map
>>   2. Runtime regions do not need to be mapped
>>   3. Cannot call SetVirtualAddressMap()
>>   4. /sys/firmware/efi/fw_vendor is invisible
>>
>> The first maps to not setting EFI_MEMMAP, the second to not setting
>> EFI_RUNTIME. If we add EFI_ALREADY_VIRTUAL and EFI_FW_VENDOR_INVISIBLE
>> to efi.flags that should cover everything on x86. Does arm* require
>> anything else?
> 
> I already proposed when this patch was first under review to make the
> arm_enable_runtime_services() function bail early without error if the
> EFI_RUNTIME_SERVICES flag is already set, and the xen code could set
> that bit as well when it installs its paravirtualized alternatives. I
> don't remember exactly why that was shot down, though, but I think it
> is the only reason this code introduces references to EFI_PARAVIRT in
> the first place.
> 
Yes, in this patch we could set EFI_RUNTIME_SERVICES flag in
fdt_find_hyper_node instead of setting EFI_PARAVIRT flag, and then bail
out early in arm_enable_runtime_services() as you said. Then call
xen_efi_runtime_setup() in xen_guest_init().

While I still have a question, in this patch we use
efi_enabled(EFI_PARAVIRT) as a condition to make fdt_find_uefi_params()
and efi_get_fdt_params() execute different ways. So it needs to find a
new condition for that if we need to get rid of EFI_PARAVIRT. One I
think is that xen_initial_domain() check. Is that fine?

Thanks,
-- 
Shannon


Re: efi_enabled(EFI_PARAVIRT) use

2016-04-30 Thread Shannon Zhao
On 2016年04月29日 22:53, Ard Biesheuvel wrote:
> On 29 April 2016 at 16:39, Matt Fleming  wrote:
>> On Fri, 29 Apr, at 11:34:45AM, Stefano Stabellini wrote:
>>> On Fri, 29 Apr 2016, Ingo Molnar wrote:
 Also, it would be nice to have all things EFI in a single tree, the 
 conflicts are
 going to be painful! There's very little reason not to carry this kind of 
 commit:

  arch/arm/xen/enlighten.c   |  6 +
  drivers/firmware/efi/arm-runtime.c | 17 +-
  drivers/firmware/efi/efi.c | 45 
 --
  3 files changed, 56 insertions(+), 12 deletions(-)

 in the EFI tree.
>>>
>>> That's true. I'll drop this commit from xentip and let Matt pick it up
>>> or request changes as he sees fit.
>>
>> One small change I think would be sensible to make is to expand
>> EFI_PARAVIRT into a few more bits to clearly indicate the quirks on
>> Xen, and in the process, to delete EFI_PARAVIRT.
>>
Sure. How should I add this change? Rework this patch or add new one on
top of it?

>> That should address Ingo's major concern, and also make it much easier
>> to rework the code in a piecemeal fashion.
>>
>> Could somebody enumerate the things that make Xen (dom0) different on
>> arm* compared with bare metal EFI boot? The list I made for x86 was,
>>
>>   1. Has no EFI memory map
>>   2. Runtime regions do not need to be mapped
>>   3. Cannot call SetVirtualAddressMap()
>>   4. /sys/firmware/efi/fw_vendor is invisible
>>
>> The first maps to not setting EFI_MEMMAP, the second to not setting
>> EFI_RUNTIME. If we add EFI_ALREADY_VIRTUAL and EFI_FW_VENDOR_INVISIBLE
>> to efi.flags that should cover everything on x86. Does arm* require
>> anything else?
> 
> I already proposed when this patch was first under review to make the
> arm_enable_runtime_services() function bail early without error if the
> EFI_RUNTIME_SERVICES flag is already set, and the xen code could set
> that bit as well when it installs its paravirtualized alternatives. I
> don't remember exactly why that was shot down, though, but I think it
> is the only reason this code introduces references to EFI_PARAVIRT in
> the first place.
> 
Yes, in this patch we could set EFI_RUNTIME_SERVICES flag in
fdt_find_hyper_node instead of setting EFI_PARAVIRT flag, and then bail
out early in arm_enable_runtime_services() as you said. Then call
xen_efi_runtime_setup() in xen_guest_init().

While I still have a question, in this patch we use
efi_enabled(EFI_PARAVIRT) as a condition to make fdt_find_uefi_params()
and efi_get_fdt_params() execute different ways. So it needs to find a
new condition for that if we need to get rid of EFI_PARAVIRT. One I
think is that xen_initial_domain() check. Is that fine?

Thanks,
-- 
Shannon


Re: efi_enabled(EFI_PARAVIRT) use

2016-04-30 Thread Shannon Zhao
On 2016年04月29日 23:37, Stefano Stabellini wrote:
> On Fri, 29 Apr 2016, Stefano Stabellini wrote:
>> On Fri, 29 Apr 2016, Matt Fleming wrote:
>>> On Fri, 29 Apr, at 11:34:45AM, Stefano Stabellini wrote:
 On Fri, 29 Apr 2016, Ingo Molnar wrote:
> Also, it would be nice to have all things EFI in a single tree, the 
> conflicts are 
> going to be painful! There's very little reason not to carry this kind of 
> commit:
>
>  arch/arm/xen/enlighten.c   |  6 +
>  drivers/firmware/efi/arm-runtime.c | 17 +-
>  drivers/firmware/efi/efi.c | 45 
> --
>  3 files changed, 56 insertions(+), 12 deletions(-)
>
> in the EFI tree.

 That's true. I'll drop this commit from xentip and let Matt pick it up
 or request changes as he sees fit.
>>>
>>> One small change I think would be sensible to make is to expand
>>> EFI_PARAVIRT into a few more bits to clearly indicate the quirks on
>>> Xen, and in the process, to delete EFI_PARAVIRT.
>>>
>>> That should address Ingo's major concern, and also make it much easier
>>> to rework the code in a piecemeal fashion.
>>>
>>> Could somebody enumerate the things that make Xen (dom0) different on
>>> arm* compared with bare metal EFI boot? The list I made for x86 was,
>>>
>>>   1. Has no EFI memory map
>>>   2. Runtime regions do not need to be mapped
>>>   3. Cannot call SetVirtualAddressMap()
>>>   4. /sys/firmware/efi/fw_vendor is invisible
>>>
>>> The first maps to not setting EFI_MEMMAP, the second to not setting
>>> EFI_RUNTIME. If we add EFI_ALREADY_VIRTUAL and EFI_FW_VENDOR_INVISIBLE
>>> to efi.flags that should cover everything on x86. Does arm* require
>>> anything else?
>>
>> Xen on ARM is different, the impact should be limited:
>>
>> - there are no BootServices (ExitBootServices has already been called)
>> - RuntimeServices go via hypercalls
>>
>> The UEFI memory map is still available at an address specified on device
>> tree like on native, but the compatibility string is different
>> ("xen,uefi-mmap-start") to clarify that we are booting on Xen rather
>> than native.
>>
>> That's pretty much it, Shannon please confirm.
> 
> This is to say that Xen on ARM might only need EFI_RUNTIME.
> 
Yes, it needs EFI_RUNTIME_SERVICES.

Thanks,
-- 
Shannon


Re: efi_enabled(EFI_PARAVIRT) use

2016-04-30 Thread Shannon Zhao
On 2016年04月29日 23:37, Stefano Stabellini wrote:
> On Fri, 29 Apr 2016, Stefano Stabellini wrote:
>> On Fri, 29 Apr 2016, Matt Fleming wrote:
>>> On Fri, 29 Apr, at 11:34:45AM, Stefano Stabellini wrote:
 On Fri, 29 Apr 2016, Ingo Molnar wrote:
> Also, it would be nice to have all things EFI in a single tree, the 
> conflicts are 
> going to be painful! There's very little reason not to carry this kind of 
> commit:
>
>  arch/arm/xen/enlighten.c   |  6 +
>  drivers/firmware/efi/arm-runtime.c | 17 +-
>  drivers/firmware/efi/efi.c | 45 
> --
>  3 files changed, 56 insertions(+), 12 deletions(-)
>
> in the EFI tree.

 That's true. I'll drop this commit from xentip and let Matt pick it up
 or request changes as he sees fit.
>>>
>>> One small change I think would be sensible to make is to expand
>>> EFI_PARAVIRT into a few more bits to clearly indicate the quirks on
>>> Xen, and in the process, to delete EFI_PARAVIRT.
>>>
>>> That should address Ingo's major concern, and also make it much easier
>>> to rework the code in a piecemeal fashion.
>>>
>>> Could somebody enumerate the things that make Xen (dom0) different on
>>> arm* compared with bare metal EFI boot? The list I made for x86 was,
>>>
>>>   1. Has no EFI memory map
>>>   2. Runtime regions do not need to be mapped
>>>   3. Cannot call SetVirtualAddressMap()
>>>   4. /sys/firmware/efi/fw_vendor is invisible
>>>
>>> The first maps to not setting EFI_MEMMAP, the second to not setting
>>> EFI_RUNTIME. If we add EFI_ALREADY_VIRTUAL and EFI_FW_VENDOR_INVISIBLE
>>> to efi.flags that should cover everything on x86. Does arm* require
>>> anything else?
>>
>> Xen on ARM is different, the impact should be limited:
>>
>> - there are no BootServices (ExitBootServices has already been called)
>> - RuntimeServices go via hypercalls
>>
>> The UEFI memory map is still available at an address specified on device
>> tree like on native, but the compatibility string is different
>> ("xen,uefi-mmap-start") to clarify that we are booting on Xen rather
>> than native.
>>
>> That's pretty much it, Shannon please confirm.
> 
> This is to say that Xen on ARM might only need EFI_RUNTIME.
> 
Yes, it needs EFI_RUNTIME_SERVICES.

Thanks,
-- 
Shannon


Re: [PATCH v11 01/17] Xen: ACPI: Hide UART used by Xen

2016-04-15 Thread Shannon Zhao
Hi Rafael,

Could you please give your comments on this patch? Thanks in advanced!

On 2016/4/7 20:03, Shannon Zhao wrote:
> From: Shannon Zhao <shannon.z...@linaro.org>
> 
> ACPI 6.0 introduces a new table STAO to list the devices which are used
> by Xen and can't be used by Dom0. On Xen virtual platforms, the physical
> UART is used by Xen. So here it hides UART from Dom0.
> 
> CC: "Rafael J. Wysocki" <r...@rjwysocki.net> (supporter:ACPI)
> CC: Len Brown <l...@kernel.org> (supporter:ACPI)
> CC: linux-a...@vger.kernel.org (open list:ACPI)
> Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
> ---
>  drivers/acpi/scan.c | 74 
> +
>  1 file changed, 74 insertions(+)
> 
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 5f28cf7..cfc73fe 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -46,6 +46,13 @@ DEFINE_MUTEX(acpi_device_lock);
>  LIST_HEAD(acpi_wakeup_device_list);
>  static DEFINE_MUTEX(acpi_hp_context_lock);
>  
> +/*
> + * The UART device described by the SPCR table is the only object which needs
> + * special-casing. Everything else is covered by ACPI namespace paths in STAO
> + * table.
> + */
> +static u64 spcr_uart_addr;
> +
>  struct acpi_dep_data {
>   struct list_head node;
>   acpi_handle master;
> @@ -1453,6 +1460,41 @@ static int acpi_add_single_object(struct acpi_device 
> **child,
>   return 0;
>  }
>  
> +static acpi_status acpi_get_resource_memory(struct acpi_resource *ares,
> + void *context)
> +{
> + struct resource *res = context;
> +
> + if (acpi_dev_resource_memory(ares, res))
> + return AE_CTRL_TERMINATE;
> +
> + return AE_OK;
> +}
> +
> +static bool acpi_device_should_be_hidden(acpi_handle handle)
> +{
> + acpi_status status;
> + struct resource res;
> +
> + /* Check if it should ignore the UART device */
> + if (!(spcr_uart_addr && acpi_has_method(handle, METHOD_NAME__CRS)))
> + return false;
> +
> + /*
> +  * The UART device described in SPCR table is assumed to have only one
> +  * memory resource present. So we only look for the first one here.
> +  */
> + status = acpi_walk_resources(handle, METHOD_NAME__CRS,
> +  acpi_get_resource_memory, );
> + if (ACPI_FAILURE(status) || res.start != spcr_uart_addr)
> + return false;
> +
> + acpi_handle_info(handle, "The UART device @%pa in SPCR table will be 
> hidden\n",
> +  );
> +
> + return true;
> +}
> +
>  static int acpi_bus_type_and_status(acpi_handle handle, int *type,
>   unsigned long long *sta)
>  {
> @@ -1466,6 +1508,9 @@ static int acpi_bus_type_and_status(acpi_handle handle, 
> int *type,
>   switch (acpi_type) {
>   case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */
>   case ACPI_TYPE_DEVICE:
> + if (acpi_device_should_be_hidden(handle))
> + return -ENODEV;
> +
>   *type = ACPI_BUS_TYPE_DEVICE;
>   status = acpi_bus_get_status_handle(handle, sta);
>   if (ACPI_FAILURE(status))
> @@ -1916,9 +1961,24 @@ static int acpi_bus_scan_fixed(void)
>   return result < 0 ? result : 0;
>  }
>  
> +static void __init acpi_get_spcr_uart_addr(void)
> +{
> + acpi_status status;
> + struct acpi_table_spcr *spcr_ptr;
> +
> + status = acpi_get_table(ACPI_SIG_SPCR, 0,
> + (struct acpi_table_header **)_ptr);
> + if (ACPI_SUCCESS(status))
> + spcr_uart_addr = spcr_ptr->serial_port.address;
> + else
> + printk(KERN_WARNING PREFIX "STAO table present, but SPCR is 
> missing\n");
> +}
> +
>  int __init acpi_scan_init(void)
>  {
>   int result;
> + acpi_status status;
> + struct acpi_table_stao *stao_ptr;
>  
>   acpi_pci_root_init();
>   acpi_pci_link_init();
> @@ -1934,6 +1994,20 @@ int __init acpi_scan_init(void)
>  
>   acpi_scan_add_handler(_device_handler);
>  
> + /*
> +  * If there is STAO table, check whether it needs to ignore the UART
> +  * device in SPCR table.
> +  */
> + status = acpi_get_table(ACPI_SIG_STAO, 0,
> + (struct acpi_table_header **)_ptr);
> + if (ACPI_SUCCESS(status)) {
> + if (stao_ptr->header.length > sizeof(struct acpi_table_stao))
> + printk(KERN_INFO PREFIX "STAO Name List not yet 
> supported.");
> +
> + if (stao_ptr->ignore_uart)
> + acpi_get_spcr_uart_addr();
> + }
> +
>   mutex_lock(_scan_lock);
>   /*
>* Enumerate devices in the ACPI namespace.
> 

-- 
Shannon



Re: [PATCH v11 01/17] Xen: ACPI: Hide UART used by Xen

2016-04-15 Thread Shannon Zhao
Hi Rafael,

Could you please give your comments on this patch? Thanks in advanced!

On 2016/4/7 20:03, Shannon Zhao wrote:
> From: Shannon Zhao 
> 
> ACPI 6.0 introduces a new table STAO to list the devices which are used
> by Xen and can't be used by Dom0. On Xen virtual platforms, the physical
> UART is used by Xen. So here it hides UART from Dom0.
> 
> CC: "Rafael J. Wysocki"  (supporter:ACPI)
> CC: Len Brown  (supporter:ACPI)
> CC: linux-a...@vger.kernel.org (open list:ACPI)
> Signed-off-by: Shannon Zhao 
> ---
>  drivers/acpi/scan.c | 74 
> +
>  1 file changed, 74 insertions(+)
> 
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 5f28cf7..cfc73fe 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -46,6 +46,13 @@ DEFINE_MUTEX(acpi_device_lock);
>  LIST_HEAD(acpi_wakeup_device_list);
>  static DEFINE_MUTEX(acpi_hp_context_lock);
>  
> +/*
> + * The UART device described by the SPCR table is the only object which needs
> + * special-casing. Everything else is covered by ACPI namespace paths in STAO
> + * table.
> + */
> +static u64 spcr_uart_addr;
> +
>  struct acpi_dep_data {
>   struct list_head node;
>   acpi_handle master;
> @@ -1453,6 +1460,41 @@ static int acpi_add_single_object(struct acpi_device 
> **child,
>   return 0;
>  }
>  
> +static acpi_status acpi_get_resource_memory(struct acpi_resource *ares,
> + void *context)
> +{
> + struct resource *res = context;
> +
> + if (acpi_dev_resource_memory(ares, res))
> + return AE_CTRL_TERMINATE;
> +
> + return AE_OK;
> +}
> +
> +static bool acpi_device_should_be_hidden(acpi_handle handle)
> +{
> + acpi_status status;
> + struct resource res;
> +
> + /* Check if it should ignore the UART device */
> + if (!(spcr_uart_addr && acpi_has_method(handle, METHOD_NAME__CRS)))
> + return false;
> +
> + /*
> +  * The UART device described in SPCR table is assumed to have only one
> +  * memory resource present. So we only look for the first one here.
> +  */
> + status = acpi_walk_resources(handle, METHOD_NAME__CRS,
> +  acpi_get_resource_memory, );
> + if (ACPI_FAILURE(status) || res.start != spcr_uart_addr)
> + return false;
> +
> + acpi_handle_info(handle, "The UART device @%pa in SPCR table will be 
> hidden\n",
> +  );
> +
> + return true;
> +}
> +
>  static int acpi_bus_type_and_status(acpi_handle handle, int *type,
>   unsigned long long *sta)
>  {
> @@ -1466,6 +1508,9 @@ static int acpi_bus_type_and_status(acpi_handle handle, 
> int *type,
>   switch (acpi_type) {
>   case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */
>   case ACPI_TYPE_DEVICE:
> + if (acpi_device_should_be_hidden(handle))
> + return -ENODEV;
> +
>   *type = ACPI_BUS_TYPE_DEVICE;
>   status = acpi_bus_get_status_handle(handle, sta);
>   if (ACPI_FAILURE(status))
> @@ -1916,9 +1961,24 @@ static int acpi_bus_scan_fixed(void)
>   return result < 0 ? result : 0;
>  }
>  
> +static void __init acpi_get_spcr_uart_addr(void)
> +{
> + acpi_status status;
> + struct acpi_table_spcr *spcr_ptr;
> +
> + status = acpi_get_table(ACPI_SIG_SPCR, 0,
> + (struct acpi_table_header **)_ptr);
> + if (ACPI_SUCCESS(status))
> + spcr_uart_addr = spcr_ptr->serial_port.address;
> + else
> + printk(KERN_WARNING PREFIX "STAO table present, but SPCR is 
> missing\n");
> +}
> +
>  int __init acpi_scan_init(void)
>  {
>   int result;
> + acpi_status status;
> + struct acpi_table_stao *stao_ptr;
>  
>   acpi_pci_root_init();
>   acpi_pci_link_init();
> @@ -1934,6 +1994,20 @@ int __init acpi_scan_init(void)
>  
>   acpi_scan_add_handler(_device_handler);
>  
> + /*
> +  * If there is STAO table, check whether it needs to ignore the UART
> +  * device in SPCR table.
> +  */
> + status = acpi_get_table(ACPI_SIG_STAO, 0,
> + (struct acpi_table_header **)_ptr);
> + if (ACPI_SUCCESS(status)) {
> + if (stao_ptr->header.length > sizeof(struct acpi_table_stao))
> + printk(KERN_INFO PREFIX "STAO Name List not yet 
> supported.");
> +
> + if (stao_ptr->ignore_uart)
> + acpi_get_spcr_uart_addr();
> + }
> +
>   mutex_lock(_scan_lock);
>   /*
>* Enumerate devices in the ACPI namespace.
> 

-- 
Shannon



[PATCH v11 05/17] xen: memory : Add new XENMAPSPACE type XENMAPSPACE_dev_mmio

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Add a new type of Xen map space for Dom0 to map device's MMIO region.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 include/xen/interface/memory.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index 2ecfe4f..9aa8988 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -160,6 +160,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);
 #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
* XENMEM_add_to_physmap_range only.
*/
+#define XENMAPSPACE_dev_mmio 5 /* device mmio region */
 
 /*
  * Sets the GPFN at which a particular page appears in the specified guest's
-- 
2.0.4




[PATCH v11 02/17] xen/grant-table: Move xlated_setup_gnttab_pages to common place

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Move xlated_setup_gnttab_pages to common place, so it can be reused by
ARM to setup grant table.

Rename it to xen_xlate_map_ballooned_pages.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 arch/x86/xen/grant-table.c | 57 +--
 drivers/xen/xlate_mmu.c| 61 ++
 include/xen/xen-ops.h  |  2 ++
 3 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index e079500..de4144c 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -111,63 +111,18 @@ int arch_gnttab_init(unsigned long nr_shared)
 }
 
 #ifdef CONFIG_XEN_PVH
-#include 
 #include 
-#include 
-static int __init xlated_setup_gnttab_pages(void)
-{
-   struct page **pages;
-   xen_pfn_t *pfns;
-   void *vaddr;
-   int rc;
-   unsigned int i;
-   unsigned long nr_grant_frames = gnttab_max_grant_frames();
-
-   BUG_ON(nr_grant_frames == 0);
-   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
-   if (!pages)
-   return -ENOMEM;
-
-   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
-   if (!pfns) {
-   kfree(pages);
-   return -ENOMEM;
-   }
-   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
-   if (rc) {
-   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   kfree(pages);
-   kfree(pfns);
-   return rc;
-   }
-   for (i = 0; i < nr_grant_frames; i++)
-   pfns[i] = page_to_pfn(pages[i]);
-
-   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
-   if (!vaddr) {
-   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   free_xenballooned_pages(nr_grant_frames, pages);
-   kfree(pages);
-   kfree(pfns);
-   return -ENOMEM;
-   }
-   kfree(pages);
-
-   xen_auto_xlat_grant_frames.pfn = pfns;
-   xen_auto_xlat_grant_frames.count = nr_grant_frames;
-   xen_auto_xlat_grant_frames.vaddr = vaddr;
-
-   return 0;
-}
-
+#include 
 static int __init xen_pvh_gnttab_setup(void)
 {
if (!xen_pvh_domain())
return -ENODEV;
 
-   return xlated_setup_gnttab_pages();
+   xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
+
+   return xen_xlate_map_ballooned_pages(_auto_xlat_grant_frames.pfn,
+_auto_xlat_grant_frames.vaddr,
+xen_auto_xlat_grant_frames.count);
 }
 /* Call it _before_ __gnttab_init as we need to initialize the
  * xen_auto_xlat_grant_frames first. */
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 5063c5e..9692656 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -29,6 +29,8 @@
  */
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -37,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
 
@@ -185,3 +188,61 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
return 0;
 }
 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
+
+/**
+ * xen_xlate_map_ballooned_pages - map a new set of ballooned pages
+ * @gfns: returns the array of corresponding GFNs
+ * @virt: returns the virtual address of the mapped region
+ * @nr_grant_frames: number of GFNs
+ * @return 0 on success, error otherwise
+ *
+ * This allocates a set of ballooned pages and maps them into the
+ * kernel's address space.
+ */
+int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
+unsigned long nr_grant_frames)
+{
+   struct page **pages;
+   xen_pfn_t *pfns;
+   void *vaddr;
+   int rc;
+   unsigned int i;
+
+   BUG_ON(nr_grant_frames == 0);
+   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
+   if (!pages)
+   return -ENOMEM;
+
+   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
+   if (!pfns) {
+   kfree(pages);
+   return -ENOMEM;
+   }
+   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
+   if (rc) {
+   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
+   nr_grant_frames, rc);
+   kfree(pages);
+   kfree(pfns);
+   return rc;
+   }
+   for (i = 0; i < nr_grant_frames; i++)
+   pfns[i] = page_to_pfn(pages[i]);
+
+   vaddr = vmap

[PATCH v11 03/17] Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Make xen_xlate_map_ballooned_pages work with 64K pages. In that case
Kernel pages are 64K in size but Xen pages remain 4K in size. Xen pfns
refer to 4K pages.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 drivers/xen/xlate_mmu.c | 38 +++---
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 9692656..23f1387 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -189,6 +189,18 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
 
+struct map_balloon_pages {
+   xen_pfn_t *pfns;
+   unsigned int idx;
+};
+
+static void setup_balloon_gfn(unsigned long gfn, void *data)
+{
+   struct map_balloon_pages *info = data;
+
+   info->pfns[info->idx++] = gfn;
+}
+
 /**
  * xen_xlate_map_ballooned_pages - map a new set of ballooned pages
  * @gfns: returns the array of corresponding GFNs
@@ -205,11 +217,13 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t 
**gfns, void **virt,
struct page **pages;
xen_pfn_t *pfns;
void *vaddr;
+   struct map_balloon_pages data;
int rc;
-   unsigned int i;
+   unsigned long nr_pages;
 
BUG_ON(nr_grant_frames == 0);
-   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
+   nr_pages = DIV_ROUND_UP(nr_grant_frames, XEN_PFN_PER_PAGE);
+   pages = kcalloc(nr_pages, sizeof(pages[0]), GFP_KERNEL);
if (!pages)
return -ENOMEM;
 
@@ -218,22 +232,24 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t 
**gfns, void **virt,
kfree(pages);
return -ENOMEM;
}
-   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
+   rc = alloc_xenballooned_pages(nr_pages, pages);
if (rc) {
-   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
+   pr_warn("%s Couldn't balloon alloc %ld pages rc:%d\n", __func__,
+   nr_pages, rc);
kfree(pages);
kfree(pfns);
return rc;
}
-   for (i = 0; i < nr_grant_frames; i++)
-   pfns[i] = page_to_pfn(pages[i]);
 
-   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
+   data.pfns = pfns;
+   data.idx = 0;
+   xen_for_each_gfn(pages, nr_grant_frames, setup_balloon_gfn, );
+
+   vaddr = vmap(pages, nr_pages, 0, PAGE_KERNEL);
if (!vaddr) {
-   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   free_xenballooned_pages(nr_grant_frames, pages);
+   pr_warn("%s Couldn't map %ld pages rc:%d\n", __func__,
+   nr_pages, rc);
+   free_xenballooned_pages(nr_pages, pages);
kfree(pages);
kfree(pfns);
return -ENOMEM;
-- 
2.0.4




[PATCH v11 08/17] Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Sync the changes of HVM_PARAM_CALLBACK_VIA ABI introduced by
Xen commit  (public/hvm: export the HVM_PARAM_CALLBACK_VIA
ABI in the API).

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 include/xen/interface/hvm/params.h | 27 +--
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/include/xen/interface/hvm/params.h 
b/include/xen/interface/hvm/params.h
index a6c7991..70ad208 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -27,16 +27,31 @@
  * Parameter space for HVMOP_{set,get}_param.
  */
 
+#define HVM_PARAM_CALLBACK_IRQ 0
 /*
  * How should CPU0 event-channel notifications be delivered?
- * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
- * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
- *  Domain = val[47:32], Bus  = val[31:16],
- *  DevFn  = val[15: 8], IntX = val[ 1: 0]
- * val[63:56] == 2: val[7:0] is a vector number.
+ *
  * If val == 0 then CPU0 event-channel notifications are not delivered.
+ * If val != 0, val[63:56] encodes the type, as follows:
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_GSI  0
+/*
+ * val[55:0] is a delivery GSI.  GSI 0 cannot be used, as it aliases val == 0,
+ * and disables all notifications.
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1
+/*
+ * val[55:0] is a delivery PCI INTx line:
+ * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_VECTOR   2
+/*
+ * val[7:0] is a vector number.  Check for XENFEAT_hvm_callback_vector to know
+ * if this delivery method is available.
  */
-#define HVM_PARAM_CALLBACK_IRQ 0
 
 #define HVM_PARAM_STORE_PFN1
 #define HVM_PARAM_STORE_EVTCHN 2
-- 
2.0.4




[PATCH v11 05/17] xen: memory : Add new XENMAPSPACE type XENMAPSPACE_dev_mmio

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Add a new type of Xen map space for Dom0 to map device's MMIO region.

Signed-off-by: Shannon Zhao 
Reviewed-by: Julien Grall 
---
 include/xen/interface/memory.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index 2ecfe4f..9aa8988 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -160,6 +160,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);
 #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
* XENMEM_add_to_physmap_range only.
*/
+#define XENMAPSPACE_dev_mmio 5 /* device mmio region */
 
 /*
  * Sets the GPFN at which a particular page appears in the specified guest's
-- 
2.0.4




[PATCH v11 02/17] xen/grant-table: Move xlated_setup_gnttab_pages to common place

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Move xlated_setup_gnttab_pages to common place, so it can be reused by
ARM to setup grant table.

Rename it to xen_xlate_map_ballooned_pages.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Julien Grall 
---
 arch/x86/xen/grant-table.c | 57 +--
 drivers/xen/xlate_mmu.c| 61 ++
 include/xen/xen-ops.h  |  2 ++
 3 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index e079500..de4144c 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -111,63 +111,18 @@ int arch_gnttab_init(unsigned long nr_shared)
 }
 
 #ifdef CONFIG_XEN_PVH
-#include 
 #include 
-#include 
-static int __init xlated_setup_gnttab_pages(void)
-{
-   struct page **pages;
-   xen_pfn_t *pfns;
-   void *vaddr;
-   int rc;
-   unsigned int i;
-   unsigned long nr_grant_frames = gnttab_max_grant_frames();
-
-   BUG_ON(nr_grant_frames == 0);
-   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
-   if (!pages)
-   return -ENOMEM;
-
-   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
-   if (!pfns) {
-   kfree(pages);
-   return -ENOMEM;
-   }
-   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
-   if (rc) {
-   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   kfree(pages);
-   kfree(pfns);
-   return rc;
-   }
-   for (i = 0; i < nr_grant_frames; i++)
-   pfns[i] = page_to_pfn(pages[i]);
-
-   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
-   if (!vaddr) {
-   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   free_xenballooned_pages(nr_grant_frames, pages);
-   kfree(pages);
-   kfree(pfns);
-   return -ENOMEM;
-   }
-   kfree(pages);
-
-   xen_auto_xlat_grant_frames.pfn = pfns;
-   xen_auto_xlat_grant_frames.count = nr_grant_frames;
-   xen_auto_xlat_grant_frames.vaddr = vaddr;
-
-   return 0;
-}
-
+#include 
 static int __init xen_pvh_gnttab_setup(void)
 {
if (!xen_pvh_domain())
return -ENODEV;
 
-   return xlated_setup_gnttab_pages();
+   xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
+
+   return xen_xlate_map_ballooned_pages(_auto_xlat_grant_frames.pfn,
+_auto_xlat_grant_frames.vaddr,
+xen_auto_xlat_grant_frames.count);
 }
 /* Call it _before_ __gnttab_init as we need to initialize the
  * xen_auto_xlat_grant_frames first. */
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 5063c5e..9692656 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -29,6 +29,8 @@
  */
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -37,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
 
@@ -185,3 +188,61 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
return 0;
 }
 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
+
+/**
+ * xen_xlate_map_ballooned_pages - map a new set of ballooned pages
+ * @gfns: returns the array of corresponding GFNs
+ * @virt: returns the virtual address of the mapped region
+ * @nr_grant_frames: number of GFNs
+ * @return 0 on success, error otherwise
+ *
+ * This allocates a set of ballooned pages and maps them into the
+ * kernel's address space.
+ */
+int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
+unsigned long nr_grant_frames)
+{
+   struct page **pages;
+   xen_pfn_t *pfns;
+   void *vaddr;
+   int rc;
+   unsigned int i;
+
+   BUG_ON(nr_grant_frames == 0);
+   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
+   if (!pages)
+   return -ENOMEM;
+
+   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
+   if (!pfns) {
+   kfree(pages);
+   return -ENOMEM;
+   }
+   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
+   if (rc) {
+   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
+   nr_grant_frames, rc);
+   kfree(pages);
+   kfree(pfns);
+   return rc;
+   }
+   for (i = 0; i < nr_grant_frames; i++)
+   pfns[i] = page_to_pfn(pages[i]);
+
+   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
+   if (!vaddr) {
+   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func_

[PATCH v11 03/17] Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Make xen_xlate_map_ballooned_pages work with 64K pages. In that case
Kernel pages are 64K in size but Xen pages remain 4K in size. Xen pfns
refer to 4K pages.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Julien Grall 
---
 drivers/xen/xlate_mmu.c | 38 +++---
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 9692656..23f1387 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -189,6 +189,18 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
 
+struct map_balloon_pages {
+   xen_pfn_t *pfns;
+   unsigned int idx;
+};
+
+static void setup_balloon_gfn(unsigned long gfn, void *data)
+{
+   struct map_balloon_pages *info = data;
+
+   info->pfns[info->idx++] = gfn;
+}
+
 /**
  * xen_xlate_map_ballooned_pages - map a new set of ballooned pages
  * @gfns: returns the array of corresponding GFNs
@@ -205,11 +217,13 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t 
**gfns, void **virt,
struct page **pages;
xen_pfn_t *pfns;
void *vaddr;
+   struct map_balloon_pages data;
int rc;
-   unsigned int i;
+   unsigned long nr_pages;
 
BUG_ON(nr_grant_frames == 0);
-   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
+   nr_pages = DIV_ROUND_UP(nr_grant_frames, XEN_PFN_PER_PAGE);
+   pages = kcalloc(nr_pages, sizeof(pages[0]), GFP_KERNEL);
if (!pages)
return -ENOMEM;
 
@@ -218,22 +232,24 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t 
**gfns, void **virt,
kfree(pages);
return -ENOMEM;
}
-   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
+   rc = alloc_xenballooned_pages(nr_pages, pages);
if (rc) {
-   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
+   pr_warn("%s Couldn't balloon alloc %ld pages rc:%d\n", __func__,
+   nr_pages, rc);
kfree(pages);
kfree(pfns);
return rc;
}
-   for (i = 0; i < nr_grant_frames; i++)
-   pfns[i] = page_to_pfn(pages[i]);
 
-   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
+   data.pfns = pfns;
+   data.idx = 0;
+   xen_for_each_gfn(pages, nr_grant_frames, setup_balloon_gfn, );
+
+   vaddr = vmap(pages, nr_pages, 0, PAGE_KERNEL);
if (!vaddr) {
-   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   free_xenballooned_pages(nr_grant_frames, pages);
+   pr_warn("%s Couldn't map %ld pages rc:%d\n", __func__,
+   nr_pages, rc);
+   free_xenballooned_pages(nr_pages, pages);
kfree(pages);
kfree(pfns);
return -ENOMEM;
-- 
2.0.4




[PATCH v11 08/17] Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Sync the changes of HVM_PARAM_CALLBACK_VIA ABI introduced by
Xen commit  (public/hvm: export the HVM_PARAM_CALLBACK_VIA
ABI in the API).

Signed-off-by: Shannon Zhao 
Acked-by: Stefano Stabellini 
---
 include/xen/interface/hvm/params.h | 27 +--
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/include/xen/interface/hvm/params.h 
b/include/xen/interface/hvm/params.h
index a6c7991..70ad208 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -27,16 +27,31 @@
  * Parameter space for HVMOP_{set,get}_param.
  */
 
+#define HVM_PARAM_CALLBACK_IRQ 0
 /*
  * How should CPU0 event-channel notifications be delivered?
- * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
- * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
- *  Domain = val[47:32], Bus  = val[31:16],
- *  DevFn  = val[15: 8], IntX = val[ 1: 0]
- * val[63:56] == 2: val[7:0] is a vector number.
+ *
  * If val == 0 then CPU0 event-channel notifications are not delivered.
+ * If val != 0, val[63:56] encodes the type, as follows:
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_GSI  0
+/*
+ * val[55:0] is a delivery GSI.  GSI 0 cannot be used, as it aliases val == 0,
+ * and disables all notifications.
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1
+/*
+ * val[55:0] is a delivery PCI INTx line:
+ * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_VECTOR   2
+/*
+ * val[7:0] is a vector number.  Check for XENFEAT_hvm_callback_vector to know
+ * if this delivery method is available.
  */
-#define HVM_PARAM_CALLBACK_IRQ 0
 
 #define HVM_PARAM_STORE_PFN1
 #define HVM_PARAM_STORE_EVTCHN 2
-- 
2.0.4




[PATCH v11 01/17] Xen: ACPI: Hide UART used by Xen

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

ACPI 6.0 introduces a new table STAO to list the devices which are used
by Xen and can't be used by Dom0. On Xen virtual platforms, the physical
UART is used by Xen. So here it hides UART from Dom0.

CC: "Rafael J. Wysocki" <r...@rjwysocki.net> (supporter:ACPI)
CC: Len Brown <l...@kernel.org> (supporter:ACPI)
CC: linux-a...@vger.kernel.org (open list:ACPI)
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
---
 drivers/acpi/scan.c | 74 +
 1 file changed, 74 insertions(+)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5f28cf7..cfc73fe 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -46,6 +46,13 @@ DEFINE_MUTEX(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 static DEFINE_MUTEX(acpi_hp_context_lock);
 
+/*
+ * The UART device described by the SPCR table is the only object which needs
+ * special-casing. Everything else is covered by ACPI namespace paths in STAO
+ * table.
+ */
+static u64 spcr_uart_addr;
+
 struct acpi_dep_data {
struct list_head node;
acpi_handle master;
@@ -1453,6 +1460,41 @@ static int acpi_add_single_object(struct acpi_device 
**child,
return 0;
 }
 
+static acpi_status acpi_get_resource_memory(struct acpi_resource *ares,
+   void *context)
+{
+   struct resource *res = context;
+
+   if (acpi_dev_resource_memory(ares, res))
+   return AE_CTRL_TERMINATE;
+
+   return AE_OK;
+}
+
+static bool acpi_device_should_be_hidden(acpi_handle handle)
+{
+   acpi_status status;
+   struct resource res;
+
+   /* Check if it should ignore the UART device */
+   if (!(spcr_uart_addr && acpi_has_method(handle, METHOD_NAME__CRS)))
+   return false;
+
+   /*
+* The UART device described in SPCR table is assumed to have only one
+* memory resource present. So we only look for the first one here.
+*/
+   status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+acpi_get_resource_memory, );
+   if (ACPI_FAILURE(status) || res.start != spcr_uart_addr)
+   return false;
+
+   acpi_handle_info(handle, "The UART device @%pa in SPCR table will be 
hidden\n",
+);
+
+   return true;
+}
+
 static int acpi_bus_type_and_status(acpi_handle handle, int *type,
unsigned long long *sta)
 {
@@ -1466,6 +1508,9 @@ static int acpi_bus_type_and_status(acpi_handle handle, 
int *type,
switch (acpi_type) {
case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */
case ACPI_TYPE_DEVICE:
+   if (acpi_device_should_be_hidden(handle))
+   return -ENODEV;
+
*type = ACPI_BUS_TYPE_DEVICE;
status = acpi_bus_get_status_handle(handle, sta);
if (ACPI_FAILURE(status))
@@ -1916,9 +1961,24 @@ static int acpi_bus_scan_fixed(void)
return result < 0 ? result : 0;
 }
 
+static void __init acpi_get_spcr_uart_addr(void)
+{
+   acpi_status status;
+   struct acpi_table_spcr *spcr_ptr;
+
+   status = acpi_get_table(ACPI_SIG_SPCR, 0,
+   (struct acpi_table_header **)_ptr);
+   if (ACPI_SUCCESS(status))
+   spcr_uart_addr = spcr_ptr->serial_port.address;
+   else
+   printk(KERN_WARNING PREFIX "STAO table present, but SPCR is 
missing\n");
+}
+
 int __init acpi_scan_init(void)
 {
int result;
+   acpi_status status;
+   struct acpi_table_stao *stao_ptr;
 
acpi_pci_root_init();
acpi_pci_link_init();
@@ -1934,6 +1994,20 @@ int __init acpi_scan_init(void)
 
acpi_scan_add_handler(_device_handler);
 
+   /*
+* If there is STAO table, check whether it needs to ignore the UART
+* device in SPCR table.
+*/
+   status = acpi_get_table(ACPI_SIG_STAO, 0,
+   (struct acpi_table_header **)_ptr);
+   if (ACPI_SUCCESS(status)) {
+   if (stao_ptr->header.length > sizeof(struct acpi_table_stao))
+   printk(KERN_INFO PREFIX "STAO Name List not yet 
supported.");
+
+   if (stao_ptr->ignore_uart)
+   acpi_get_spcr_uart_addr();
+   }
+
mutex_lock(_scan_lock);
/*
 * Enumerate devices in the ACPI namespace.
-- 
2.0.4




[PATCH v11 09/17] xen/hvm/params: Add a new delivery type for event-channel in HVM_PARAM_CALLBACK_IRQ

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

This new delivery type which is for ARM shares the same value with
HVM_PARAM_CALLBACK_TYPE_VECTOR which is for x86.

val[15:8] is flag: val[7:0] is a PPI.
To the flag, bit 8 stands the interrupt mode is edge(1) or level(0) and
bit 9 stands the interrupt polarity is active low(1) or high(0).

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 include/xen/interface/hvm/params.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/xen/interface/hvm/params.h 
b/include/xen/interface/hvm/params.h
index 70ad208..4d61fc5 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -47,11 +47,24 @@
  * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
  */
 
+#if defined(__i386__) || defined(__x86_64__)
 #define HVM_PARAM_CALLBACK_TYPE_VECTOR   2
 /*
  * val[7:0] is a vector number.  Check for XENFEAT_hvm_callback_vector to know
  * if this delivery method is available.
  */
+#elif defined(__arm__) || defined(__aarch64__)
+#define HVM_PARAM_CALLBACK_TYPE_PPI  2
+/*
+ * val[55:16] needs to be zero.
+ * val[15:8] is interrupt flag of the PPI used by event-channel:
+ *  bit 8: the PPI is edge(1) or level(0) triggered
+ *  bit 9: the PPI is active low(1) or high(0)
+ * val[7:0] is a PPI number used by event-channel.
+ * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to
+ * the notification is handled by the interrupt controller.
+ */
+#endif
 
 #define HVM_PARAM_STORE_PFN1
 #define HVM_PARAM_STORE_EVTCHN 2
-- 
2.0.4




[PATCH v11 01/17] Xen: ACPI: Hide UART used by Xen

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

ACPI 6.0 introduces a new table STAO to list the devices which are used
by Xen and can't be used by Dom0. On Xen virtual platforms, the physical
UART is used by Xen. So here it hides UART from Dom0.

CC: "Rafael J. Wysocki"  (supporter:ACPI)
CC: Len Brown  (supporter:ACPI)
CC: linux-a...@vger.kernel.org (open list:ACPI)
Signed-off-by: Shannon Zhao 
---
 drivers/acpi/scan.c | 74 +
 1 file changed, 74 insertions(+)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5f28cf7..cfc73fe 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -46,6 +46,13 @@ DEFINE_MUTEX(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 static DEFINE_MUTEX(acpi_hp_context_lock);
 
+/*
+ * The UART device described by the SPCR table is the only object which needs
+ * special-casing. Everything else is covered by ACPI namespace paths in STAO
+ * table.
+ */
+static u64 spcr_uart_addr;
+
 struct acpi_dep_data {
struct list_head node;
acpi_handle master;
@@ -1453,6 +1460,41 @@ static int acpi_add_single_object(struct acpi_device 
**child,
return 0;
 }
 
+static acpi_status acpi_get_resource_memory(struct acpi_resource *ares,
+   void *context)
+{
+   struct resource *res = context;
+
+   if (acpi_dev_resource_memory(ares, res))
+   return AE_CTRL_TERMINATE;
+
+   return AE_OK;
+}
+
+static bool acpi_device_should_be_hidden(acpi_handle handle)
+{
+   acpi_status status;
+   struct resource res;
+
+   /* Check if it should ignore the UART device */
+   if (!(spcr_uart_addr && acpi_has_method(handle, METHOD_NAME__CRS)))
+   return false;
+
+   /*
+* The UART device described in SPCR table is assumed to have only one
+* memory resource present. So we only look for the first one here.
+*/
+   status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+acpi_get_resource_memory, );
+   if (ACPI_FAILURE(status) || res.start != spcr_uart_addr)
+   return false;
+
+   acpi_handle_info(handle, "The UART device @%pa in SPCR table will be 
hidden\n",
+);
+
+   return true;
+}
+
 static int acpi_bus_type_and_status(acpi_handle handle, int *type,
unsigned long long *sta)
 {
@@ -1466,6 +1508,9 @@ static int acpi_bus_type_and_status(acpi_handle handle, 
int *type,
switch (acpi_type) {
case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */
case ACPI_TYPE_DEVICE:
+   if (acpi_device_should_be_hidden(handle))
+   return -ENODEV;
+
*type = ACPI_BUS_TYPE_DEVICE;
status = acpi_bus_get_status_handle(handle, sta);
if (ACPI_FAILURE(status))
@@ -1916,9 +1961,24 @@ static int acpi_bus_scan_fixed(void)
return result < 0 ? result : 0;
 }
 
+static void __init acpi_get_spcr_uart_addr(void)
+{
+   acpi_status status;
+   struct acpi_table_spcr *spcr_ptr;
+
+   status = acpi_get_table(ACPI_SIG_SPCR, 0,
+   (struct acpi_table_header **)_ptr);
+   if (ACPI_SUCCESS(status))
+   spcr_uart_addr = spcr_ptr->serial_port.address;
+   else
+   printk(KERN_WARNING PREFIX "STAO table present, but SPCR is 
missing\n");
+}
+
 int __init acpi_scan_init(void)
 {
int result;
+   acpi_status status;
+   struct acpi_table_stao *stao_ptr;
 
acpi_pci_root_init();
acpi_pci_link_init();
@@ -1934,6 +1994,20 @@ int __init acpi_scan_init(void)
 
acpi_scan_add_handler(_device_handler);
 
+   /*
+* If there is STAO table, check whether it needs to ignore the UART
+* device in SPCR table.
+*/
+   status = acpi_get_table(ACPI_SIG_STAO, 0,
+   (struct acpi_table_header **)_ptr);
+   if (ACPI_SUCCESS(status)) {
+   if (stao_ptr->header.length > sizeof(struct acpi_table_stao))
+   printk(KERN_INFO PREFIX "STAO Name List not yet 
supported.");
+
+   if (stao_ptr->ignore_uart)
+   acpi_get_spcr_uart_addr();
+   }
+
mutex_lock(_scan_lock);
/*
 * Enumerate devices in the ACPI namespace.
-- 
2.0.4




[PATCH v11 09/17] xen/hvm/params: Add a new delivery type for event-channel in HVM_PARAM_CALLBACK_IRQ

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

This new delivery type which is for ARM shares the same value with
HVM_PARAM_CALLBACK_TYPE_VECTOR which is for x86.

val[15:8] is flag: val[7:0] is a PPI.
To the flag, bit 8 stands the interrupt mode is edge(1) or level(0) and
bit 9 stands the interrupt polarity is active low(1) or high(0).

Signed-off-by: Shannon Zhao 
Acked-by: Stefano Stabellini 
Reviewed-by: Julien Grall 
---
 include/xen/interface/hvm/params.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/xen/interface/hvm/params.h 
b/include/xen/interface/hvm/params.h
index 70ad208..4d61fc5 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -47,11 +47,24 @@
  * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
  */
 
+#if defined(__i386__) || defined(__x86_64__)
 #define HVM_PARAM_CALLBACK_TYPE_VECTOR   2
 /*
  * val[7:0] is a vector number.  Check for XENFEAT_hvm_callback_vector to know
  * if this delivery method is available.
  */
+#elif defined(__arm__) || defined(__aarch64__)
+#define HVM_PARAM_CALLBACK_TYPE_PPI  2
+/*
+ * val[55:16] needs to be zero.
+ * val[15:8] is interrupt flag of the PPI used by event-channel:
+ *  bit 8: the PPI is edge(1) or level(0) triggered
+ *  bit 9: the PPI is active low(1) or high(0)
+ * val[7:0] is a PPI number used by event-channel.
+ * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to
+ * the notification is handled by the interrupt controller.
+ */
+#endif
 
 #define HVM_PARAM_STORE_PFN1
 #define HVM_PARAM_STORE_EVTCHN 2
-- 
2.0.4




[PATCH v11 12/17] ARM64: ACPI: Check if it runs on Xen to enable or disable ACPI

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

When it's a Xen domain0 booting with ACPI, it will supply a /chosen and
a /hypervisor node in DT. So check if it needs to enable ACPI.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Acked-by: Hanjun Guo <hanjun@linaro.org>
---
 arch/arm64/kernel/acpi.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index d1ce8e2..57ee317 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -67,10 +67,15 @@ static int __init dt_scan_depth1_nodes(unsigned long node,
 {
/*
 * Return 1 as soon as we encounter a node at depth 1 that is
-* not the /chosen node.
+* not the /chosen node, or /hypervisor node with compatible
+* string "xen,xen".
 */
-   if (depth == 1 && (strcmp(uname, "chosen") != 0))
-   return 1;
+   if (depth == 1 && (strcmp(uname, "chosen") != 0)) {
+   if (strcmp(uname, "hypervisor") != 0 ||
+   !of_flat_dt_is_compatible(node, "xen,xen"))
+   return 1;
+   }
+
return 0;
 }
 
@@ -184,7 +189,8 @@ void __init acpi_boot_table_init(void)
/*
 * Enable ACPI instead of device tree unless
 * - ACPI has been disabled explicitly (acpi=off), or
-* - the device tree is not empty (it has more than just a /chosen node)
+* - the device tree is not empty (it has more than just a /chosen node,
+*   and a /hypervisor node when running on Xen)
 *   and ACPI has not been force enabled (acpi=force)
 */
if (param_acpi_off ||
-- 
2.0.4




[PATCH v11 14/17] XEN: EFI: Move x86 specific codes to architecture directory

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Move x86 specific codes to architecture directory and export those EFI
runtime service functions. This will be useful for initializing runtime
service on ARM later.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/x86/xen/efi.c| 112 
 drivers/xen/efi.c | 174 ++
 include/xen/xen-ops.h |  30 ++---
 3 files changed, 168 insertions(+), 148 deletions(-)

diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c
index be14cc3..86527f1 100644
--- a/arch/x86/xen/efi.c
+++ b/arch/x86/xen/efi.c
@@ -20,10 +20,122 @@
 #include 
 #include 
 
+#include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
+
+static efi_char16_t vendor[100] __initdata;
+
+static efi_system_table_t efi_systab_xen __initdata = {
+   .hdr = {
+   .signature  = EFI_SYSTEM_TABLE_SIGNATURE,
+   .revision   = 0, /* Initialized later. */
+   .headersize = 0, /* Ignored by Linux Kernel. */
+   .crc32  = 0, /* Ignored by Linux Kernel. */
+   .reserved   = 0
+   },
+   .fw_vendor  = EFI_INVALID_TABLE_ADDR, /* Initialized later. */
+   .fw_revision= 0,  /* Initialized later. */
+   .con_in_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_in = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .runtime= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .boottime   = (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .nr_tables  = 0,  /* Initialized later. */
+   .tables = EFI_INVALID_TABLE_ADDR  /* Initialized later. */
+};
+
+static const struct efi efi_xen __initconst = {
+   .systab   = NULL, /* Initialized later. */
+   .runtime_version  = 0,/* Initialized later. */
+   .mps  = EFI_INVALID_TABLE_ADDR,
+   .acpi = EFI_INVALID_TABLE_ADDR,
+   .acpi20   = EFI_INVALID_TABLE_ADDR,
+   .smbios   = EFI_INVALID_TABLE_ADDR,
+   .smbios3  = EFI_INVALID_TABLE_ADDR,
+   .sal_systab   = EFI_INVALID_TABLE_ADDR,
+   .boot_info= EFI_INVALID_TABLE_ADDR,
+   .hcdp = EFI_INVALID_TABLE_ADDR,
+   .uga  = EFI_INVALID_TABLE_ADDR,
+   .uv_systab= EFI_INVALID_TABLE_ADDR,
+   .fw_vendor= EFI_INVALID_TABLE_ADDR,
+   .runtime  = EFI_INVALID_TABLE_ADDR,
+   .config_table = EFI_INVALID_TABLE_ADDR,
+   .get_time = xen_efi_get_time,
+   .set_time = xen_efi_set_time,
+   .get_wakeup_time  = xen_efi_get_wakeup_time,
+   .set_wakeup_time  = xen_efi_set_wakeup_time,
+   .get_variable = xen_efi_get_variable,
+   .get_next_variable= xen_efi_get_next_variable,
+   .set_variable = xen_efi_set_variable,
+   .query_variable_info  = xen_efi_query_variable_info,
+   .update_capsule   = xen_efi_update_capsule,
+   .query_capsule_caps   = xen_efi_query_capsule_caps,
+   .get_next_high_mono_count = xen_efi_get_next_high_mono_count,
+   .reset_system = NULL, /* Functionality provided by Xen. */
+   .set_virtual_address_map  = NULL, /* Not used under Xen. */
+   .memmap   = NULL, /* Not used under Xen. */
+   .flags= 0 /* Initialized later. */
+};
+
+static efi_system_table_t __init *xen_efi_probe(void)
+{
+   struct xen_platform_op op = {
+   .cmd = XENPF_firmware_info,
+   .u.firmware_info = {
+   .type = XEN_FW_EFI_INFO,
+   .index = XEN_FW_EFI_CONFIG_TABLE
+   }
+   };
+   union xenpf_efi_info *info = _info.u.efi_info;
+
+   if (!xen_initial_domain() || HYPERVISOR_platform_op() < 0)
+   return NULL;
+
+   /* Here we know that Xen runs on EFI platform. */
+
+   efi = efi_xen;
+
+   efi_systab_xen.tables = info->cfg.addr;
+   efi_systab_xen.nr_tables = info->cfg.nent;
+
+   op.cmd = XENPF_firmware_info;
+   op.u.firmware_

[PATCH v11 06/17] Xen: ARM: Add support for mapping platform device mmio

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Add a bus_notifier for platform bus device in order to map the device
mmio regions when DOM0 booting with ACPI.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 drivers/xen/Makefile |   1 +
 drivers/xen/arm-device.c | 153 +++
 2 files changed, 154 insertions(+)
 create mode 100644 drivers/xen/arm-device.c

diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 9b7a35c..415f286 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -9,6 +9,7 @@ CFLAGS_features.o   := $(nostackp)
 
 CFLAGS_efi.o   += -fshort-wchar
 
+dom0-$(CONFIG_ARM64) += arm-device.o
 dom0-$(CONFIG_PCI) += pci.o
 dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
 dom0-$(CONFIG_XEN_ACPI) += acpi.o $(xen-pad-y)
diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
new file mode 100644
index 000..b918e8e
--- /dev/null
+++ b/drivers/xen/arm-device.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2015, Linaro Limited, Shannon Zhao
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int xen_unmap_device_mmio(const struct resource *resources,
+unsigned int count)
+{
+   unsigned int i, j, nr;
+   int rc = 0;
+   const struct resource *r;
+   struct xen_remove_from_physmap xrp;
+
+   for (i = 0; i < count; i++) {
+   r = [i];
+   nr = DIV_ROUND_UP(resource_size(r), XEN_PAGE_SIZE);
+   if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0))
+   continue;
+
+   for (j = 0; j < nr; j++) {
+   xrp.domid = DOMID_SELF;
+   xrp.gpfn = XEN_PFN_DOWN(r->start) + j;
+   rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap,
+ );
+   if (rc)
+   return rc;
+   }
+   }
+
+   return rc;
+}
+
+static int xen_map_device_mmio(const struct resource *resources,
+  unsigned int count)
+{
+   unsigned int i, j, nr;
+   int rc = 0;
+   const struct resource *r;
+   xen_pfn_t *gpfns;
+   xen_ulong_t *idxs;
+   int *errs;
+   struct xen_add_to_physmap_range xatp;
+
+   for (i = 0; i < count; i++) {
+   r = [i];
+   nr = DIV_ROUND_UP(resource_size(r), XEN_PAGE_SIZE);
+   if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0))
+   continue;
+
+   gpfns = kzalloc(sizeof(xen_pfn_t) * nr, GFP_KERNEL);
+   idxs = kzalloc(sizeof(xen_ulong_t) * nr, GFP_KERNEL);
+   errs = kzalloc(sizeof(int) * nr, GFP_KERNEL);
+   if (!gpfns || !idxs || !errs) {
+   kfree(gpfns);
+   kfree(idxs);
+   kfree(errs);
+   rc = -ENOMEM;
+   goto unmap;
+   }
+
+   for (j = 0; j < nr; j++) {
+   /*
+* The regions are always mapped 1:1 to DOM0 and this is
+* fine because the memory map for DOM0 is the same as
+* the host (except for the RAM).
+*/
+   gpfns[j] = XEN_PFN_DOWN(r->start) + j;
+   idxs[j] = XEN_PFN_DOWN(r->start) + j;
+   }
+
+   xatp.domid = DOMID_SELF;
+   xatp.size = nr;
+   xatp.space = XENMAPSPACE_dev_mmio;
+
+   set_xen_guest_handle(xatp.gpfns, gpfns);
+   set_xen_guest_handle(xatp.idxs, idxs);
+   set_xen_guest_handle(xatp.errs, errs);
+
+   rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, );
+   kfree(gpfns);
+   kfree(idxs);
+   kfree(errs);
+   if (rc)
+   goto unmap;
+   }
+
+   return rc;
+
+unmap:
+   xen_unmap_device_mmio(resources, i);
+   return rc;
+}
+
+static int xen_platform_notifier(struct notifier_block *nb,
+unsign

[PATCH v11 14/17] XEN: EFI: Move x86 specific codes to architecture directory

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Move x86 specific codes to architecture directory and export those EFI
runtime service functions. This will be useful for initializing runtime
service on ARM later.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 arch/x86/xen/efi.c| 112 
 drivers/xen/efi.c | 174 ++
 include/xen/xen-ops.h |  30 ++---
 3 files changed, 168 insertions(+), 148 deletions(-)

diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c
index be14cc3..86527f1 100644
--- a/arch/x86/xen/efi.c
+++ b/arch/x86/xen/efi.c
@@ -20,10 +20,122 @@
 #include 
 #include 
 
+#include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
+
+static efi_char16_t vendor[100] __initdata;
+
+static efi_system_table_t efi_systab_xen __initdata = {
+   .hdr = {
+   .signature  = EFI_SYSTEM_TABLE_SIGNATURE,
+   .revision   = 0, /* Initialized later. */
+   .headersize = 0, /* Ignored by Linux Kernel. */
+   .crc32  = 0, /* Ignored by Linux Kernel. */
+   .reserved   = 0
+   },
+   .fw_vendor  = EFI_INVALID_TABLE_ADDR, /* Initialized later. */
+   .fw_revision= 0,  /* Initialized later. */
+   .con_in_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_in = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .runtime= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .boottime   = (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .nr_tables  = 0,  /* Initialized later. */
+   .tables = EFI_INVALID_TABLE_ADDR  /* Initialized later. */
+};
+
+static const struct efi efi_xen __initconst = {
+   .systab   = NULL, /* Initialized later. */
+   .runtime_version  = 0,/* Initialized later. */
+   .mps  = EFI_INVALID_TABLE_ADDR,
+   .acpi = EFI_INVALID_TABLE_ADDR,
+   .acpi20   = EFI_INVALID_TABLE_ADDR,
+   .smbios   = EFI_INVALID_TABLE_ADDR,
+   .smbios3  = EFI_INVALID_TABLE_ADDR,
+   .sal_systab   = EFI_INVALID_TABLE_ADDR,
+   .boot_info= EFI_INVALID_TABLE_ADDR,
+   .hcdp = EFI_INVALID_TABLE_ADDR,
+   .uga  = EFI_INVALID_TABLE_ADDR,
+   .uv_systab= EFI_INVALID_TABLE_ADDR,
+   .fw_vendor= EFI_INVALID_TABLE_ADDR,
+   .runtime  = EFI_INVALID_TABLE_ADDR,
+   .config_table = EFI_INVALID_TABLE_ADDR,
+   .get_time = xen_efi_get_time,
+   .set_time = xen_efi_set_time,
+   .get_wakeup_time  = xen_efi_get_wakeup_time,
+   .set_wakeup_time  = xen_efi_set_wakeup_time,
+   .get_variable = xen_efi_get_variable,
+   .get_next_variable= xen_efi_get_next_variable,
+   .set_variable = xen_efi_set_variable,
+   .query_variable_info  = xen_efi_query_variable_info,
+   .update_capsule   = xen_efi_update_capsule,
+   .query_capsule_caps   = xen_efi_query_capsule_caps,
+   .get_next_high_mono_count = xen_efi_get_next_high_mono_count,
+   .reset_system = NULL, /* Functionality provided by Xen. */
+   .set_virtual_address_map  = NULL, /* Not used under Xen. */
+   .memmap   = NULL, /* Not used under Xen. */
+   .flags= 0 /* Initialized later. */
+};
+
+static efi_system_table_t __init *xen_efi_probe(void)
+{
+   struct xen_platform_op op = {
+   .cmd = XENPF_firmware_info,
+   .u.firmware_info = {
+   .type = XEN_FW_EFI_INFO,
+   .index = XEN_FW_EFI_CONFIG_TABLE
+   }
+   };
+   union xenpf_efi_info *info = _info.u.efi_info;
+
+   if (!xen_initial_domain() || HYPERVISOR_platform_op() < 0)
+   return NULL;
+
+   /* Here we know that Xen runs on EFI platform. */
+
+   efi = efi_xen;
+
+   efi_systab_xen.tables = info->cfg.addr;
+   efi_systab_xen.nr_tables = info->cfg.nent;
+
+   op.cmd = XENPF_firmware_info;
+   op.u.firmware_info.type = XEN_FW_EFI_INFO;
+   op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
+   info->vendor.bufsz = s

[PATCH v11 06/17] Xen: ARM: Add support for mapping platform device mmio

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Add a bus_notifier for platform bus device in order to map the device
mmio regions when DOM0 booting with ACPI.

Signed-off-by: Shannon Zhao 
Acked-by: Stefano Stabellini 
---
 drivers/xen/Makefile |   1 +
 drivers/xen/arm-device.c | 153 +++
 2 files changed, 154 insertions(+)
 create mode 100644 drivers/xen/arm-device.c

diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 9b7a35c..415f286 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -9,6 +9,7 @@ CFLAGS_features.o   := $(nostackp)
 
 CFLAGS_efi.o   += -fshort-wchar
 
+dom0-$(CONFIG_ARM64) += arm-device.o
 dom0-$(CONFIG_PCI) += pci.o
 dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
 dom0-$(CONFIG_XEN_ACPI) += acpi.o $(xen-pad-y)
diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
new file mode 100644
index 000..b918e8e
--- /dev/null
+++ b/drivers/xen/arm-device.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2015, Linaro Limited, Shannon Zhao
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int xen_unmap_device_mmio(const struct resource *resources,
+unsigned int count)
+{
+   unsigned int i, j, nr;
+   int rc = 0;
+   const struct resource *r;
+   struct xen_remove_from_physmap xrp;
+
+   for (i = 0; i < count; i++) {
+   r = [i];
+   nr = DIV_ROUND_UP(resource_size(r), XEN_PAGE_SIZE);
+   if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0))
+   continue;
+
+   for (j = 0; j < nr; j++) {
+   xrp.domid = DOMID_SELF;
+   xrp.gpfn = XEN_PFN_DOWN(r->start) + j;
+   rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap,
+ );
+   if (rc)
+   return rc;
+   }
+   }
+
+   return rc;
+}
+
+static int xen_map_device_mmio(const struct resource *resources,
+  unsigned int count)
+{
+   unsigned int i, j, nr;
+   int rc = 0;
+   const struct resource *r;
+   xen_pfn_t *gpfns;
+   xen_ulong_t *idxs;
+   int *errs;
+   struct xen_add_to_physmap_range xatp;
+
+   for (i = 0; i < count; i++) {
+   r = [i];
+   nr = DIV_ROUND_UP(resource_size(r), XEN_PAGE_SIZE);
+   if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0))
+   continue;
+
+   gpfns = kzalloc(sizeof(xen_pfn_t) * nr, GFP_KERNEL);
+   idxs = kzalloc(sizeof(xen_ulong_t) * nr, GFP_KERNEL);
+   errs = kzalloc(sizeof(int) * nr, GFP_KERNEL);
+   if (!gpfns || !idxs || !errs) {
+   kfree(gpfns);
+   kfree(idxs);
+   kfree(errs);
+   rc = -ENOMEM;
+   goto unmap;
+   }
+
+   for (j = 0; j < nr; j++) {
+   /*
+* The regions are always mapped 1:1 to DOM0 and this is
+* fine because the memory map for DOM0 is the same as
+* the host (except for the RAM).
+*/
+   gpfns[j] = XEN_PFN_DOWN(r->start) + j;
+   idxs[j] = XEN_PFN_DOWN(r->start) + j;
+   }
+
+   xatp.domid = DOMID_SELF;
+   xatp.size = nr;
+   xatp.space = XENMAPSPACE_dev_mmio;
+
+   set_xen_guest_handle(xatp.gpfns, gpfns);
+   set_xen_guest_handle(xatp.idxs, idxs);
+   set_xen_guest_handle(xatp.errs, errs);
+
+   rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, );
+   kfree(gpfns);
+   kfree(idxs);
+   kfree(errs);
+   if (rc)
+   goto unmap;
+   }
+
+   return rc;
+
+unmap:
+   xen_unmap_device_mmio(resources, i);
+   return rc;
+}
+
+static int xen_platform_notifier(struct notifier_block *nb,
+unsigned long action, void *data)
+{
+   struct platform_device *pdev = to_platform_device(data);
+   in

[PATCH v11 12/17] ARM64: ACPI: Check if it runs on Xen to enable or disable ACPI

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

When it's a Xen domain0 booting with ACPI, it will supply a /chosen and
a /hypervisor node in DT. So check if it needs to enable ACPI.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
Acked-by: Hanjun Guo 
---
 arch/arm64/kernel/acpi.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index d1ce8e2..57ee317 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -67,10 +67,15 @@ static int __init dt_scan_depth1_nodes(unsigned long node,
 {
/*
 * Return 1 as soon as we encounter a node at depth 1 that is
-* not the /chosen node.
+* not the /chosen node, or /hypervisor node with compatible
+* string "xen,xen".
 */
-   if (depth == 1 && (strcmp(uname, "chosen") != 0))
-   return 1;
+   if (depth == 1 && (strcmp(uname, "chosen") != 0)) {
+   if (strcmp(uname, "hypervisor") != 0 ||
+   !of_flat_dt_is_compatible(node, "xen,xen"))
+   return 1;
+   }
+
return 0;
 }
 
@@ -184,7 +189,8 @@ void __init acpi_boot_table_init(void)
/*
 * Enable ACPI instead of device tree unless
 * - ACPI has been disabled explicitly (acpi=off), or
-* - the device tree is not empty (it has more than just a /chosen node)
+* - the device tree is not empty (it has more than just a /chosen node,
+*   and a /hypervisor node when running on Xen)
 *   and ACPI has not been force enabled (acpi=force)
 */
if (param_acpi_off ||
-- 
2.0.4




[PATCH v11 04/17] arm/xen: Use xen_xlate_map_ballooned_pages to setup grant table

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Use xen_xlate_map_ballooned_pages to setup grant table. Then it doesn't
rely on DT or ACPI to pass the start address and size of grant table.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 arch/arm/xen/enlighten.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 75cd734..d94f726 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -282,18 +282,10 @@ static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
struct shared_info *shared_info_page = NULL;
-   struct resource res;
-   phys_addr_t grant_frames;
 
if (!xen_domain())
return 0;
 
-   if (of_address_to_resource(xen_node, GRANT_TABLE_PHYSADDR, )) {
-   pr_err("Xen grant table base address not found\n");
-   return -ENODEV;
-   }
-   grant_frames = res.start;
-
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
if (!xen_events_irq) {
pr_err("Xen event channel interrupt not found\n");
@@ -328,7 +320,10 @@ static int __init xen_guest_init(void)
if (xen_vcpu_info == NULL)
return -ENOMEM;
 
-   if (gnttab_setup_auto_xlat_frames(grant_frames)) {
+   xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
+   if (xen_xlate_map_ballooned_pages(_auto_xlat_grant_frames.pfn,
+ _auto_xlat_grant_frames.vaddr,
+ xen_auto_xlat_grant_frames.count)) {
free_percpu(xen_vcpu_info);
return -ENOMEM;
}
-- 
2.0.4




[PATCH v11 07/17] Xen: ARM: Add support for mapping AMBA device mmio

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Add a bus_notifier for AMBA bus device in order to map the device
mmio regions when DOM0 booting with ACPI.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 drivers/xen/arm-device.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
index b918e8e..778acf8 100644
--- a/drivers/xen/arm-device.c
+++ b/drivers/xen/arm-device.c
@@ -151,3 +151,46 @@ static int __init register_xen_platform_notifier(void)
 }
 
 arch_initcall(register_xen_platform_notifier);
+
+#ifdef CONFIG_ARM_AMBA
+#include 
+
+static int xen_amba_notifier(struct notifier_block *nb,
+unsigned long action, void *data)
+{
+   struct amba_device *adev = to_amba_device(data);
+   int r = 0;
+
+   switch (action) {
+   case BUS_NOTIFY_ADD_DEVICE:
+   r = xen_map_device_mmio(>res, 1);
+   break;
+   case BUS_NOTIFY_DEL_DEVICE:
+   r = xen_unmap_device_mmio(>res, 1);
+   break;
+   default:
+   return NOTIFY_DONE;
+   }
+   if (r)
+   dev_err(>dev, "AMBA: Failed to %s device %s MMIO!\n",
+   action == BUS_NOTIFY_ADD_DEVICE ? "map" :
+   (action == BUS_NOTIFY_DEL_DEVICE ? "unmap" : "?"),
+   adev->dev.init_name);
+
+   return NOTIFY_OK;
+}
+
+static struct notifier_block amba_device_nb = {
+   .notifier_call = xen_amba_notifier,
+};
+
+static int __init register_xen_amba_notifier(void)
+{
+   if (!xen_initial_domain() || acpi_disabled)
+   return 0;
+
+   return bus_register_notifier(_bustype, _device_nb);
+}
+
+arch_initcall(register_xen_amba_notifier);
+#endif
-- 
2.0.4




[PATCH v11 16/17] FDT: Add a helper to get the subnode by given name

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Sometimes it needs to check if there is a subnode of given node in FDT
by given name. Introduce this helper to get the subnode if it exists.

CC: Rob Herring <r...@kernel.org>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 drivers/of/fdt.c   | 13 +
 include/linux/of_fdt.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 3349d2a..5c8b2f2 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -645,6 +645,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
 }
 
 /**
+ * of_get_flat_dt_subnode_by_name - get the subnode by given name
+ *
+ * @node: the parent node
+ * @uname: the name of subnode
+ * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+
+int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
+{
+   return fdt_subnode_offset(initial_boot_params, node, uname);
+}
+
+/**
  * of_get_flat_dt_root - find the root node in the flat blob
  */
 unsigned long __init of_get_flat_dt_root(void)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 2fbe868..2c3707e 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -52,6 +52,8 @@ extern char __dtb_end[];
 extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
 int depth, void *data),
   void *data);
+extern int of_get_flat_dt_subnode_by_name(unsigned long node,
+ const char *uname);
 extern const void *of_get_flat_dt_prop(unsigned long node, const char *name,
   int *size);
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
-- 
2.0.4




[PATCH v11 07/17] Xen: ARM: Add support for mapping AMBA device mmio

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Add a bus_notifier for AMBA bus device in order to map the device
mmio regions when DOM0 booting with ACPI.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Julien Grall 
---
 drivers/xen/arm-device.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
index b918e8e..778acf8 100644
--- a/drivers/xen/arm-device.c
+++ b/drivers/xen/arm-device.c
@@ -151,3 +151,46 @@ static int __init register_xen_platform_notifier(void)
 }
 
 arch_initcall(register_xen_platform_notifier);
+
+#ifdef CONFIG_ARM_AMBA
+#include 
+
+static int xen_amba_notifier(struct notifier_block *nb,
+unsigned long action, void *data)
+{
+   struct amba_device *adev = to_amba_device(data);
+   int r = 0;
+
+   switch (action) {
+   case BUS_NOTIFY_ADD_DEVICE:
+   r = xen_map_device_mmio(>res, 1);
+   break;
+   case BUS_NOTIFY_DEL_DEVICE:
+   r = xen_unmap_device_mmio(>res, 1);
+   break;
+   default:
+   return NOTIFY_DONE;
+   }
+   if (r)
+   dev_err(>dev, "AMBA: Failed to %s device %s MMIO!\n",
+   action == BUS_NOTIFY_ADD_DEVICE ? "map" :
+   (action == BUS_NOTIFY_DEL_DEVICE ? "unmap" : "?"),
+   adev->dev.init_name);
+
+   return NOTIFY_OK;
+}
+
+static struct notifier_block amba_device_nb = {
+   .notifier_call = xen_amba_notifier,
+};
+
+static int __init register_xen_amba_notifier(void)
+{
+   if (!xen_initial_domain() || acpi_disabled)
+   return 0;
+
+   return bus_register_notifier(_bustype, _device_nb);
+}
+
+arch_initcall(register_xen_amba_notifier);
+#endif
-- 
2.0.4




[PATCH v11 16/17] FDT: Add a helper to get the subnode by given name

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Sometimes it needs to check if there is a subnode of given node in FDT
by given name. Introduce this helper to get the subnode if it exists.

CC: Rob Herring 
Signed-off-by: Shannon Zhao 
Acked-by: Stefano Stabellini 
Acked-by: Rob Herring 
---
 drivers/of/fdt.c   | 13 +
 include/linux/of_fdt.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 3349d2a..5c8b2f2 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -645,6 +645,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
 }
 
 /**
+ * of_get_flat_dt_subnode_by_name - get the subnode by given name
+ *
+ * @node: the parent node
+ * @uname: the name of subnode
+ * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+
+int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
+{
+   return fdt_subnode_offset(initial_boot_params, node, uname);
+}
+
+/**
  * of_get_flat_dt_root - find the root node in the flat blob
  */
 unsigned long __init of_get_flat_dt_root(void)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 2fbe868..2c3707e 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -52,6 +52,8 @@ extern char __dtb_end[];
 extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
 int depth, void *data),
   void *data);
+extern int of_get_flat_dt_subnode_by_name(unsigned long node,
+ const char *uname);
 extern const void *of_get_flat_dt_prop(unsigned long node, const char *name,
   int *size);
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
-- 
2.0.4




[PATCH v11 04/17] arm/xen: Use xen_xlate_map_ballooned_pages to setup grant table

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Use xen_xlate_map_ballooned_pages to setup grant table. Then it doesn't
rely on DT or ACPI to pass the start address and size of grant table.

Signed-off-by: Shannon Zhao 
Acked-by: Stefano Stabellini 
Reviewed-by: Julien Grall 
---
 arch/arm/xen/enlighten.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 75cd734..d94f726 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -282,18 +282,10 @@ static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
struct shared_info *shared_info_page = NULL;
-   struct resource res;
-   phys_addr_t grant_frames;
 
if (!xen_domain())
return 0;
 
-   if (of_address_to_resource(xen_node, GRANT_TABLE_PHYSADDR, )) {
-   pr_err("Xen grant table base address not found\n");
-   return -ENODEV;
-   }
-   grant_frames = res.start;
-
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
if (!xen_events_irq) {
pr_err("Xen event channel interrupt not found\n");
@@ -328,7 +320,10 @@ static int __init xen_guest_init(void)
if (xen_vcpu_info == NULL)
return -ENOMEM;
 
-   if (gnttab_setup_auto_xlat_frames(grant_frames)) {
+   xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
+   if (xen_xlate_map_ballooned_pages(_auto_xlat_grant_frames.pfn,
+ _auto_xlat_grant_frames.vaddr,
+ xen_auto_xlat_grant_frames.count)) {
free_percpu(xen_vcpu_info);
return -ENOMEM;
}
-- 
2.0.4




[PATCH v11 13/17] ARM: Xen: Document UEFI support on Xen ARM virtual platforms

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Add a "uefi" node under /hypervisor node in FDT, then Linux kernel could
scan this to get the UEFI information.

CC: Rob Herring <r...@kernel.org>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Rob Herring <r...@kernel.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 Documentation/devicetree/bindings/arm/xen.txt | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/xen.txt 
b/Documentation/devicetree/bindings/arm/xen.txt
index 0f7b9c2..c9b9321 100644
--- a/Documentation/devicetree/bindings/arm/xen.txt
+++ b/Documentation/devicetree/bindings/arm/xen.txt
@@ -11,10 +11,32 @@ the following properties:
   memory where the grant table should be mapped to, using an
   HYPERVISOR_memory_op hypercall. The memory region is large enough to map
   the whole grant table (it is larger or equal to gnttab_max_grant_frames()).
+  This property is unnecessary when booting Dom0 using ACPI.
 
 - interrupts: the interrupt used by Xen to inject event notifications.
   A GIC node is also required.
+  This property is unnecessary when booting Dom0 using ACPI.
 
+To support UEFI on Xen ARM virtual platforms, Xen populates the FDT "uefi" node
+under /hypervisor with following parameters:
+
+
+Name  | Size   | Description
+
+xen,uefi-system-table | 64-bit | Guest physical address of the UEFI System
+ || Table.
+
+xen,uefi-mmap-start   | 64-bit | Guest physical address of the UEFI memory
+ || map.
+
+xen,uefi-mmap-size| 32-bit | Size in bytes of the UEFI memory map
+  || pointed to in previous entry.
+
+xen,uefi-mmap-desc-size   | 32-bit | Size in bytes of each entry in the UEFI
+  || memory map.
+
+xen,uefi-mmap-desc-ver| 32-bit | Version of the mmap descriptor format.
+
 
 Example (assuming #address-cells = <2> and #size-cells = <2>):
 
@@ -22,4 +44,17 @@ hypervisor {
compatible = "xen,xen-4.3", "xen,xen";
reg = <0 0xb000 0 0x2>;
interrupts = <1 15 0xf08>;
+   uefi {
+   xen,uefi-system-table = <0x>;
+   xen,uefi-mmap-start = <0x>;
+   xen,uefi-mmap-size = <0x>;
+   xen,uefi-mmap-desc-size = <0x>;
+   xen,uefi-mmap-desc-ver = <0x>;
+};
 };
+
+The format and meaning of the "xen,uefi-*" parameters are similar to those in
+Documentation/arm/uefi.txt, which are provided by the regular UEFI stub. 
However
+they differ because they are provided by the Xen hypervisor, together with a 
set
+of UEFI runtime services implemented via hypercalls, see
+http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
-- 
2.0.4




[PATCH v11 11/17] ARM: XEN: Move xen_early_init() before efi_init()

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Move xen_early_init() before efi_init(), then when calling efi_init()
could initialize Xen specific UEFI.

Check if it runs on Xen hypervisor through the flat dts.

Cc: Russell King <li...@arm.linux.org.uk>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 arch/arm/kernel/setup.c   |  2 +-
 arch/arm/xen/enlighten.c  | 56 ++-
 arch/arm64/kernel/setup.c |  2 +-
 3 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 139791e..5bc7516 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1035,6 +1035,7 @@ void __init setup_arch(char **cmdline_p)
early_paging_init(mdesc);
 #endif
setup_dma_zone(mdesc);
+   xen_early_init();
efi_init();
sanity_check_meminfo();
arm_memblock_init(mdesc);
@@ -1051,7 +1052,6 @@ void __init setup_arch(char **cmdline_p)
 
arm_dt_init_cpu_maps();
psci_dt_init();
-   xen_early_init();
 #ifdef CONFIG_SMP
if (is_smp()) {
if (!mdesc->smp_init || !mdesc->smp_init()) {
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 06bd61a..13e3e9f 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -53,8 +54,6 @@ struct xen_memory_region 
xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
 
 static __read_mostly unsigned int xen_events_irq;
 
-static __initdata struct device_node *xen_node;
-
 int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
   unsigned long addr,
   xen_pfn_t *gfn, int nr,
@@ -238,6 +237,33 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
return IRQ_HANDLED;
 }
 
+static __initdata struct {
+   const char *compat;
+   const char *prefix;
+   const char *version;
+   bool found;
+} hyper_node = {"xen,xen", "xen,xen-", NULL, false};
+
+static int __init fdt_find_hyper_node(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+   const void *s = NULL;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
+
+   if (of_flat_dt_is_compatible(node, hyper_node.compat))
+   hyper_node.found = true;
+
+   s = of_get_flat_dt_prop(node, "compatible", );
+   if (strlen(hyper_node.prefix) + 3  < len &&
+   !strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
+   hyper_node.version = s + strlen(hyper_node.prefix);
+
+   return 0;
+}
+
 /*
  * see Documentation/devicetree/bindings/arm/xen.txt for the
  * documentation of the Xen Device Tree format.
@@ -245,26 +271,18 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
 #define GRANT_TABLE_PHYSADDR 0
 void __init xen_early_init(void)
 {
-   int len;
-   const char *s = NULL;
-   const char *version = NULL;
-   const char *xen_prefix = "xen,xen-";
-
-   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
-   if (!xen_node) {
+   of_scan_flat_dt(fdt_find_hyper_node, NULL);
+   if (!hyper_node.found) {
pr_debug("No Xen support\n");
return;
}
-   s = of_get_property(xen_node, "compatible", );
-   if (strlen(xen_prefix) + 3  < len &&
-   !strncmp(xen_prefix, s, strlen(xen_prefix)))
-   version = s + strlen(xen_prefix);
-   if (version == NULL) {
+
+   if (hyper_node.version == NULL) {
pr_debug("Xen version not found\n");
return;
}
 
-   pr_info("Xen %s support found\n", version);
+   pr_info("Xen %s support found\n", hyper_node.version);
 
xen_domain_type = XEN_HVM_DOMAIN;
 
@@ -305,6 +323,14 @@ static void __init xen_acpi_guest_init(void)
 
 static void __init xen_dt_guest_init(void)
 {
+   struct device_node *xen_node;
+
+   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
+   if (!xen_node) {
+   pr_err("Xen support was detected before, but it has 
disappeared\n");
+   return;
+   }
+
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
 }
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 9dc6776..7cf992f 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -320,6 +320,7 @@ void __init setup_arch(char **cmdline_p)
 */
cpu_uninstall_idmap();
 
+   xen_early_init();
e

[PATCH v11 10/17] arm/xen: Get event-channel irq through HVM_PARAM when booting with ACPI

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

The kernel will get the event-channel IRQ through
HVM_PARAM_CALLBACK_IRQ.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Reviewed-by: Julien Grall <julien.gr...@arm.com>
---
 arch/arm/xen/enlighten.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index d94f726..06bd61a 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -278,6 +279,35 @@ void __init xen_early_init(void)
add_preferred_console("hvc", 0, NULL);
 }
 
+static void __init xen_acpi_guest_init(void)
+{
+#ifdef CONFIG_ACPI
+   struct xen_hvm_param a;
+   int interrupt, trigger, polarity;
+
+   a.domid = DOMID_SELF;
+   a.index = HVM_PARAM_CALLBACK_IRQ;
+
+   if (HYPERVISOR_hvm_op(HVMOP_get_param, )
+   || (a.value >> 56) != HVM_PARAM_CALLBACK_TYPE_PPI) {
+   xen_events_irq = 0;
+   return;
+   }
+
+   interrupt = a.value & 0xff;
+   trigger = ((a.value >> 8) & 0x1) ? ACPI_EDGE_SENSITIVE
+: ACPI_LEVEL_SENSITIVE;
+   polarity = ((a.value >> 8) & 0x2) ? ACPI_ACTIVE_LOW
+ : ACPI_ACTIVE_HIGH;
+   xen_events_irq = acpi_register_gsi(NULL, interrupt, trigger, polarity);
+#endif
+}
+
+static void __init xen_dt_guest_init(void)
+{
+   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+}
+
 static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
@@ -286,7 +316,11 @@ static int __init xen_guest_init(void)
if (!xen_domain())
return 0;
 
-   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+   if (!acpi_disabled)
+   xen_acpi_guest_init();
+   else
+   xen_dt_guest_init();
+
if (!xen_events_irq) {
pr_err("Xen event channel interrupt not found\n");
return -ENODEV;
-- 
2.0.4




[PATCH v11 13/17] ARM: Xen: Document UEFI support on Xen ARM virtual platforms

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Add a "uefi" node under /hypervisor node in FDT, then Linux kernel could
scan this to get the UEFI information.

CC: Rob Herring 
Signed-off-by: Shannon Zhao 
Acked-by: Rob Herring 
Reviewed-by: Stefano Stabellini 
---
 Documentation/devicetree/bindings/arm/xen.txt | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/xen.txt 
b/Documentation/devicetree/bindings/arm/xen.txt
index 0f7b9c2..c9b9321 100644
--- a/Documentation/devicetree/bindings/arm/xen.txt
+++ b/Documentation/devicetree/bindings/arm/xen.txt
@@ -11,10 +11,32 @@ the following properties:
   memory where the grant table should be mapped to, using an
   HYPERVISOR_memory_op hypercall. The memory region is large enough to map
   the whole grant table (it is larger or equal to gnttab_max_grant_frames()).
+  This property is unnecessary when booting Dom0 using ACPI.
 
 - interrupts: the interrupt used by Xen to inject event notifications.
   A GIC node is also required.
+  This property is unnecessary when booting Dom0 using ACPI.
 
+To support UEFI on Xen ARM virtual platforms, Xen populates the FDT "uefi" node
+under /hypervisor with following parameters:
+
+
+Name  | Size   | Description
+
+xen,uefi-system-table | 64-bit | Guest physical address of the UEFI System
+ || Table.
+
+xen,uefi-mmap-start   | 64-bit | Guest physical address of the UEFI memory
+ || map.
+
+xen,uefi-mmap-size| 32-bit | Size in bytes of the UEFI memory map
+  || pointed to in previous entry.
+
+xen,uefi-mmap-desc-size   | 32-bit | Size in bytes of each entry in the UEFI
+  || memory map.
+
+xen,uefi-mmap-desc-ver| 32-bit | Version of the mmap descriptor format.
+
 
 Example (assuming #address-cells = <2> and #size-cells = <2>):
 
@@ -22,4 +44,17 @@ hypervisor {
compatible = "xen,xen-4.3", "xen,xen";
reg = <0 0xb000 0 0x2>;
interrupts = <1 15 0xf08>;
+   uefi {
+   xen,uefi-system-table = <0x>;
+   xen,uefi-mmap-start = <0x>;
+   xen,uefi-mmap-size = <0x>;
+   xen,uefi-mmap-desc-size = <0x>;
+   xen,uefi-mmap-desc-ver = <0x>;
+};
 };
+
+The format and meaning of the "xen,uefi-*" parameters are similar to those in
+Documentation/arm/uefi.txt, which are provided by the regular UEFI stub. 
However
+they differ because they are provided by the Xen hypervisor, together with a 
set
+of UEFI runtime services implemented via hypercalls, see
+http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
-- 
2.0.4




[PATCH v11 11/17] ARM: XEN: Move xen_early_init() before efi_init()

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Move xen_early_init() before efi_init(), then when calling efi_init()
could initialize Xen specific UEFI.

Check if it runs on Xen hypervisor through the flat dts.

Cc: Russell King 
Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Julien Grall 
---
 arch/arm/kernel/setup.c   |  2 +-
 arch/arm/xen/enlighten.c  | 56 ++-
 arch/arm64/kernel/setup.c |  2 +-
 3 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 139791e..5bc7516 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1035,6 +1035,7 @@ void __init setup_arch(char **cmdline_p)
early_paging_init(mdesc);
 #endif
setup_dma_zone(mdesc);
+   xen_early_init();
efi_init();
sanity_check_meminfo();
arm_memblock_init(mdesc);
@@ -1051,7 +1052,6 @@ void __init setup_arch(char **cmdline_p)
 
arm_dt_init_cpu_maps();
psci_dt_init();
-   xen_early_init();
 #ifdef CONFIG_SMP
if (is_smp()) {
if (!mdesc->smp_init || !mdesc->smp_init()) {
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 06bd61a..13e3e9f 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -53,8 +54,6 @@ struct xen_memory_region 
xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
 
 static __read_mostly unsigned int xen_events_irq;
 
-static __initdata struct device_node *xen_node;
-
 int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
   unsigned long addr,
   xen_pfn_t *gfn, int nr,
@@ -238,6 +237,33 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
return IRQ_HANDLED;
 }
 
+static __initdata struct {
+   const char *compat;
+   const char *prefix;
+   const char *version;
+   bool found;
+} hyper_node = {"xen,xen", "xen,xen-", NULL, false};
+
+static int __init fdt_find_hyper_node(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+   const void *s = NULL;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
+
+   if (of_flat_dt_is_compatible(node, hyper_node.compat))
+   hyper_node.found = true;
+
+   s = of_get_flat_dt_prop(node, "compatible", );
+   if (strlen(hyper_node.prefix) + 3  < len &&
+   !strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
+   hyper_node.version = s + strlen(hyper_node.prefix);
+
+   return 0;
+}
+
 /*
  * see Documentation/devicetree/bindings/arm/xen.txt for the
  * documentation of the Xen Device Tree format.
@@ -245,26 +271,18 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
 #define GRANT_TABLE_PHYSADDR 0
 void __init xen_early_init(void)
 {
-   int len;
-   const char *s = NULL;
-   const char *version = NULL;
-   const char *xen_prefix = "xen,xen-";
-
-   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
-   if (!xen_node) {
+   of_scan_flat_dt(fdt_find_hyper_node, NULL);
+   if (!hyper_node.found) {
pr_debug("No Xen support\n");
return;
}
-   s = of_get_property(xen_node, "compatible", );
-   if (strlen(xen_prefix) + 3  < len &&
-   !strncmp(xen_prefix, s, strlen(xen_prefix)))
-   version = s + strlen(xen_prefix);
-   if (version == NULL) {
+
+   if (hyper_node.version == NULL) {
pr_debug("Xen version not found\n");
return;
}
 
-   pr_info("Xen %s support found\n", version);
+   pr_info("Xen %s support found\n", hyper_node.version);
 
xen_domain_type = XEN_HVM_DOMAIN;
 
@@ -305,6 +323,14 @@ static void __init xen_acpi_guest_init(void)
 
 static void __init xen_dt_guest_init(void)
 {
+   struct device_node *xen_node;
+
+   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
+   if (!xen_node) {
+   pr_err("Xen support was detected before, but it has 
disappeared\n");
+   return;
+   }
+
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
 }
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 9dc6776..7cf992f 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -320,6 +320,7 @@ void __init setup_arch(char **cmdline_p)
 */
cpu_uninstall_idmap();
 
+   xen_early_init();
efi_init();
arm64_memblock_init();
 
@@ -341,7 +342,6 @@ void __init setup_arch(char **cmdline_p)
} else {
psci_acpi_init();
}
-   xen_early_init();
 
cpu_read_bootcpu_ops();
smp_init_cpus();
-- 
2.0.4




[PATCH v11 10/17] arm/xen: Get event-channel irq through HVM_PARAM when booting with ACPI

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

The kernel will get the event-channel IRQ through
HVM_PARAM_CALLBACK_IRQ.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Julien Grall 
---
 arch/arm/xen/enlighten.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index d94f726..06bd61a 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -278,6 +279,35 @@ void __init xen_early_init(void)
add_preferred_console("hvc", 0, NULL);
 }
 
+static void __init xen_acpi_guest_init(void)
+{
+#ifdef CONFIG_ACPI
+   struct xen_hvm_param a;
+   int interrupt, trigger, polarity;
+
+   a.domid = DOMID_SELF;
+   a.index = HVM_PARAM_CALLBACK_IRQ;
+
+   if (HYPERVISOR_hvm_op(HVMOP_get_param, )
+   || (a.value >> 56) != HVM_PARAM_CALLBACK_TYPE_PPI) {
+   xen_events_irq = 0;
+   return;
+   }
+
+   interrupt = a.value & 0xff;
+   trigger = ((a.value >> 8) & 0x1) ? ACPI_EDGE_SENSITIVE
+: ACPI_LEVEL_SENSITIVE;
+   polarity = ((a.value >> 8) & 0x2) ? ACPI_ACTIVE_LOW
+ : ACPI_ACTIVE_HIGH;
+   xen_events_irq = acpi_register_gsi(NULL, interrupt, trigger, polarity);
+#endif
+}
+
+static void __init xen_dt_guest_init(void)
+{
+   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+}
+
 static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
@@ -286,7 +316,11 @@ static int __init xen_guest_init(void)
if (!xen_domain())
return 0;
 
-   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+   if (!acpi_disabled)
+   xen_acpi_guest_init();
+   else
+   xen_dt_guest_init();
+
if (!xen_events_irq) {
pr_err("Xen event channel interrupt not found\n");
return -ENODEV;
-- 
2.0.4




[PATCH v11 17/17] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

Add a new function to parse DT parameters for Xen specific UEFI just
like the way for normal UEFI. Then it could reuse the existing codes.

If Xen supports EFI, initialize runtime services.

CC: Matt Fleming <m...@codeblueprint.co.uk>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Matt Fleming <m...@codeblueprint.co.uk>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/arm/xen/enlighten.c   |  6 +
 drivers/firmware/efi/arm-runtime.c | 17 +-
 drivers/firmware/efi/efi.c | 45 --
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..e130562 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -261,6 +261,12 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   /* Check if Xen supports EFI */
+   if (of_get_flat_dt_subnode_by_name(node, "uefi") > 0)
+   set_bit(EFI_PARAVIRT, );
+   }
+
return 0;
 }
 
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 6ae21e4..ac609b9 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern u64 efi_system_table;
 
@@ -107,13 +108,19 @@ static int __init arm_enable_runtime_services(void)
}
set_bit(EFI_SYSTEM_TABLES, );
 
-   if (!efi_virtmap_init()) {
-   pr_err("No UEFI virtual mapping was installed -- runtime 
services will not be available\n");
-   return -ENOMEM;
+   if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_PARAVIRT)) {
+   /* Set up runtime services function pointers for Xen Dom0 */
+   xen_efi_runtime_setup();
+   } else {
+   if (!efi_virtmap_init()) {
+   pr_err("No UEFI virtual mapping was installed -- 
runtime services will not be available\n");
+   return -ENOMEM;
+   }
+
+   /* Set up runtime services function pointers */
+   efi_native_runtime_setup();
}
 
-   /* Set up runtime services function pointers */
-   efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, );
 
efi.runtime_version = efi.systab->hdr.revision;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 3a69ed5..519c096 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -469,12 +469,14 @@ device_initcall(efi_load_efivars);
FIELD_SIZEOF(struct efi_fdt_params, field) \
}
 
-static __initdata struct {
+struct params {
const char name[32];
const char propname[32];
int offset;
int size;
-} dt_params[] = {
+};
+
+static struct params fdt_params[] __initdata = {
UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
@@ -482,24 +484,45 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
+static struct params xen_fdt_params[] __initdata = {
+   UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
+   UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
+   UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
+   UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
+   UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
+};
+
 struct param_info {
int found;
void *params;
+   struct params *dt_params;
+   int size;
 };
 
 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
   int depth, void *data)
 {
struct param_info *info = data;
+   struct params *dt_params = info->dt_params;
const void *prop;
void *dest;
u64 val;
-   int i, len;
+   int i, len, offset;
 
-   if (depth != 1 || strcmp(uname, "chosen") != 0)
-   return 0;
+   if (efi_enabled(EFI_PARAVIRT)) {
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
 
-   for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+

[PATCH v11 15/17] ARM64: XEN: Add a function to initialize Xen specific UEFI runtime services

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

When running on Xen hypervisor, runtime services are supported through
hypercall. Add a Xen specific function to initialize runtime services.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/arm/include/asm/xen/xen-ops.h   |  6 ++
 arch/arm/xen/Makefile|  1 +
 arch/arm/xen/efi.c   | 40 
 arch/arm64/include/asm/xen/xen-ops.h |  6 ++
 arch/arm64/xen/Makefile  |  1 +
 drivers/xen/Kconfig  |  2 +-
 6 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/xen/xen-ops.h
 create mode 100644 arch/arm/xen/efi.c
 create mode 100644 arch/arm64/include/asm/xen/xen-ops.h

diff --git a/arch/arm/include/asm/xen/xen-ops.h 
b/arch/arm/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
index 1296952..2279521 100644
--- a/arch/arm/xen/Makefile
+++ b/arch/arm/xen/Makefile
@@ -1 +1,2 @@
 obj-y  := enlighten.o hypercall.o grant-table.o p2m.o mm.o
+obj-$(CONFIG_XEN_EFI) += efi.o
diff --git a/arch/arm/xen/efi.c b/arch/arm/xen/efi.c
new file mode 100644
index 000..16db419
--- /dev/null
+++ b/arch/arm/xen/efi.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Linaro Limited, Shannon Zhao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+
+/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
+ * e.g. efi.systab, will be set like normal EFI.
+ */
+void __init xen_efi_runtime_setup(void)
+{
+   efi.get_time = xen_efi_get_time;
+   efi.set_time = xen_efi_set_time;
+   efi.get_wakeup_time  = xen_efi_get_wakeup_time;
+   efi.set_wakeup_time  = xen_efi_set_wakeup_time;
+   efi.get_variable = xen_efi_get_variable;
+   efi.get_next_variable= xen_efi_get_next_variable;
+   efi.set_variable = xen_efi_set_variable;
+   efi.query_variable_info  = xen_efi_query_variable_info;
+   efi.update_capsule   = xen_efi_update_capsule;
+   efi.query_capsule_caps   = xen_efi_query_capsule_caps;
+   efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
+   efi.reset_system = NULL; /* Functionality provided by Xen. 
*/
+}
+EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
diff --git a/arch/arm64/include/asm/xen/xen-ops.h 
b/arch/arm64/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm64/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm64/xen/Makefile b/arch/arm64/xen/Makefile
index 74a8d87..8ff8aa9 100644
--- a/arch/arm64/xen/Makefile
+++ b/arch/arm64/xen/Makefile
@@ -1,2 +1,3 @@
 xen-arm-y  += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o 
mm.o)
 obj-y  := xen-arm.o hypercall.o
+obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 979a831..f15bb3b7 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -275,7 +275,7 @@ config XEN_HAVE_PVMMU
 
 config XEN_EFI
def_bool y
-   depends on X86_64 && EFI
+   depends on (ARM || ARM64 || X86_64) && EFI
 
 config XEN_AUTO_XLATE
def_bool y
-- 
2.0.4




[PATCH v11 00/17] Add ACPI support for Xen Dom0 on ARM64

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao <shannon.z...@linaro.org>

This patch set adds ACPI support for Xen Dom0 on ARM64. The relevant Xen
ACPI on ARM64 design document could be found from [1].

This patch set adds a new FDT node "uefi" under /hypervisor to pass UEFI
information. Introduce a bus notifier of AMBA and Platform bus to map
the new added device's MMIO space. Make Xen domain use
xlated_setup_gnttab_pages to setup grant table and a new hypercall to
get event-channel irq.

Regarding the initialization flow of Linux kernel, it needs to move
xen_early_init() before efi_init(). Then xen_early_init() will check
whether it runs on Xen through the /hypervisor node and efi_init() will
call a new function fdt_find_xen_uefi_params(), to parse those
xen,uefi-* parameters just like the existing efi_get_fdt_params().

And in arm64_enable_runtime_services() it will check whether it runs on
Xen and call another new function xen_efi_runtime_setup() to setup
runtime service instead of efi_native_runtime_setup(). The
xen_efi_runtime_setup() will assign the runtime function pointers with
the functions of driver/xen/efi.c.

And since we pass a /hypervisor node and a /chosen node to Dom0, it
needs to check whether the DTS only contains a /hypervisor node and a
/chosen node in acpi_boot_table_init().

Patches are tested on FVP base model.

Thanks,
Shannon

[1] http://lists.xen.org/archives/html/xen-devel/2015-11/msg00488.html

Changes since v10:
* address Rafael's comments on patch 1
* undo the device mmio mappings if it fails in patch 6

Changes since v9:
* address Rafael's comments on patch 1
* check the compatible string of hypervisor node in patch 12

Changes since v8:
* rebased on v4.6-rc1
* print UART device address (PATCH 1)
* use xen_for_each_gfn (PATCH 3)
* reduce indentation by inverting the condition (PATCH 10)
* move xen_early_init() before efi_init() as well for ARM (PATCH 11)
* sync the document with Xen (PATCH 13)

Changes since v7:
* add __init prefix for acpi_get_spcr_uart_addr (PATCH 1)

Changes since v6:
* rebase on linux master
* refactor codes as acpi_get_spcr_uart_addr (PATCH 1)
* sync with Xen (patch 9)

Changes since v5:
* rebase on linux master
* use acpi_dev_resource_memory to parse the device memory info(patch 1)
* sync with Xen (patch 9)

Changes since v4:
* rebase on linux master
* move the check acpi_device_should_be_hidden into
  acpi_bus_type_and_status (patch 1)
* use existing function fdt_subnode_offset (patch 16)

Changes since v3:
* rebase on linux master
* print a warning when there is no SPCR table
* rephase the commit message of PATCH 3
* rephase the words of PATCH 13
* use strcmp and factor the function in PATCH 16
* Add several ACKs and RBs, thanks a lot


Changes since v2:
* Use 0 to check if it should ignore the UART
* Fix the use of page_to_xen_pfn
* Factor ACPI and DT parts in xen_guest_init
* Check "uefi" node by full path
* Fix the statement of Documentation/devicetree/bindings/arm/xen.txt

Changes since v1:
* Rebase on linux mainline and wallclock patch from Stefano
* Refactor AMBA and platform device MMIO map to one file
* Use EFI_PARAVIRT to check if it supports XEN EFI
* Refactor Xen EFI codes
* Address other comments

Shannon Zhao (17):
  Xen: ACPI: Hide UART used by Xen
  xen/grant-table: Move xlated_setup_gnttab_pages to common place
  Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn
  arm/xen: Use xen_xlate_map_ballooned_pages to setup grant table
  xen: memory : Add new XENMAPSPACE type XENMAPSPACE_dev_mmio
  Xen: ARM: Add support for mapping platform device mmio
  Xen: ARM: Add support for mapping AMBA device mmio
  Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen
  xen/hvm/params: Add a new delivery type for event-channel in
HVM_PARAM_CALLBACK_IRQ
  arm/xen: Get event-channel irq through HVM_PARAM when booting with
ACPI
  ARM: XEN: Move xen_early_init() before efi_init()
  ARM64: ACPI: Check if it runs on Xen to enable or disable ACPI
  ARM: Xen: Document UEFI support on Xen ARM virtual platforms
  XEN: EFI: Move x86 specific codes to architecture directory
  ARM64: XEN: Add a function to initialize Xen specific UEFI runtime
services
  FDT: Add a helper to get the subnode by given name
  Xen: EFI: Parse DT parameters for Xen specific UEFI

 Documentation/devicetree/bindings/arm/xen.txt |  35 +
 arch/arm/include/asm/xen/xen-ops.h|   6 +
 arch/arm/kernel/setup.c   |   2 +-
 arch/arm/xen/Makefile |   1 +
 arch/arm/xen/efi.c|  40 ++
 arch/arm/xen/enlighten.c  | 109 ++
 arch/arm64/include/asm/xen/xen-ops.h  |   6 +
 arch/arm64/kernel/acpi.c  |  14 +-
 arch/arm64/kernel/setup.c |   2 +-
 arch/arm64/xen/Makefile   |   1 +
 arch/x86/xen/efi.c| 112 +++
 arch/x86/xen/grant-table.c 

[PATCH v11 17/17] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

Add a new function to parse DT parameters for Xen specific UEFI just
like the way for normal UEFI. Then it could reuse the existing codes.

If Xen supports EFI, initialize runtime services.

CC: Matt Fleming 
Signed-off-by: Shannon Zhao 
Reviewed-by: Matt Fleming 
Reviewed-by: Stefano Stabellini 
---
 arch/arm/xen/enlighten.c   |  6 +
 drivers/firmware/efi/arm-runtime.c | 17 +-
 drivers/firmware/efi/efi.c | 45 --
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..e130562 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -261,6 +261,12 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   /* Check if Xen supports EFI */
+   if (of_get_flat_dt_subnode_by_name(node, "uefi") > 0)
+   set_bit(EFI_PARAVIRT, );
+   }
+
return 0;
 }
 
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 6ae21e4..ac609b9 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern u64 efi_system_table;
 
@@ -107,13 +108,19 @@ static int __init arm_enable_runtime_services(void)
}
set_bit(EFI_SYSTEM_TABLES, );
 
-   if (!efi_virtmap_init()) {
-   pr_err("No UEFI virtual mapping was installed -- runtime 
services will not be available\n");
-   return -ENOMEM;
+   if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_PARAVIRT)) {
+   /* Set up runtime services function pointers for Xen Dom0 */
+   xen_efi_runtime_setup();
+   } else {
+   if (!efi_virtmap_init()) {
+   pr_err("No UEFI virtual mapping was installed -- 
runtime services will not be available\n");
+   return -ENOMEM;
+   }
+
+   /* Set up runtime services function pointers */
+   efi_native_runtime_setup();
}
 
-   /* Set up runtime services function pointers */
-   efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, );
 
efi.runtime_version = efi.systab->hdr.revision;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 3a69ed5..519c096 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -469,12 +469,14 @@ device_initcall(efi_load_efivars);
FIELD_SIZEOF(struct efi_fdt_params, field) \
}
 
-static __initdata struct {
+struct params {
const char name[32];
const char propname[32];
int offset;
int size;
-} dt_params[] = {
+};
+
+static struct params fdt_params[] __initdata = {
UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
@@ -482,24 +484,45 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
+static struct params xen_fdt_params[] __initdata = {
+   UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
+   UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
+   UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
+   UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
+   UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
+};
+
 struct param_info {
int found;
void *params;
+   struct params *dt_params;
+   int size;
 };
 
 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
   int depth, void *data)
 {
struct param_info *info = data;
+   struct params *dt_params = info->dt_params;
const void *prop;
void *dest;
u64 val;
-   int i, len;
+   int i, len, offset;
 
-   if (depth != 1 || strcmp(uname, "chosen") != 0)
-   return 0;
+   if (efi_enabled(EFI_PARAVIRT)) {
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
 
-   for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+   offset = of_get_flat_dt_subnode_by_name(node, "uefi");
+   if (offset < 0)
+   return 0;
+   

[PATCH v11 15/17] ARM64: XEN: Add a function to initialize Xen specific UEFI runtime services

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

When running on Xen hypervisor, runtime services are supported through
hypercall. Add a Xen specific function to initialize runtime services.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 arch/arm/include/asm/xen/xen-ops.h   |  6 ++
 arch/arm/xen/Makefile|  1 +
 arch/arm/xen/efi.c   | 40 
 arch/arm64/include/asm/xen/xen-ops.h |  6 ++
 arch/arm64/xen/Makefile  |  1 +
 drivers/xen/Kconfig  |  2 +-
 6 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/xen/xen-ops.h
 create mode 100644 arch/arm/xen/efi.c
 create mode 100644 arch/arm64/include/asm/xen/xen-ops.h

diff --git a/arch/arm/include/asm/xen/xen-ops.h 
b/arch/arm/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
index 1296952..2279521 100644
--- a/arch/arm/xen/Makefile
+++ b/arch/arm/xen/Makefile
@@ -1 +1,2 @@
 obj-y  := enlighten.o hypercall.o grant-table.o p2m.o mm.o
+obj-$(CONFIG_XEN_EFI) += efi.o
diff --git a/arch/arm/xen/efi.c b/arch/arm/xen/efi.c
new file mode 100644
index 000..16db419
--- /dev/null
+++ b/arch/arm/xen/efi.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Linaro Limited, Shannon Zhao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+
+/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
+ * e.g. efi.systab, will be set like normal EFI.
+ */
+void __init xen_efi_runtime_setup(void)
+{
+   efi.get_time = xen_efi_get_time;
+   efi.set_time = xen_efi_set_time;
+   efi.get_wakeup_time  = xen_efi_get_wakeup_time;
+   efi.set_wakeup_time  = xen_efi_set_wakeup_time;
+   efi.get_variable = xen_efi_get_variable;
+   efi.get_next_variable= xen_efi_get_next_variable;
+   efi.set_variable = xen_efi_set_variable;
+   efi.query_variable_info  = xen_efi_query_variable_info;
+   efi.update_capsule   = xen_efi_update_capsule;
+   efi.query_capsule_caps   = xen_efi_query_capsule_caps;
+   efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
+   efi.reset_system = NULL; /* Functionality provided by Xen. 
*/
+}
+EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
diff --git a/arch/arm64/include/asm/xen/xen-ops.h 
b/arch/arm64/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm64/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm64/xen/Makefile b/arch/arm64/xen/Makefile
index 74a8d87..8ff8aa9 100644
--- a/arch/arm64/xen/Makefile
+++ b/arch/arm64/xen/Makefile
@@ -1,2 +1,3 @@
 xen-arm-y  += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o 
mm.o)
 obj-y  := xen-arm.o hypercall.o
+obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 979a831..f15bb3b7 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -275,7 +275,7 @@ config XEN_HAVE_PVMMU
 
 config XEN_EFI
def_bool y
-   depends on X86_64 && EFI
+   depends on (ARM || ARM64 || X86_64) && EFI
 
 config XEN_AUTO_XLATE
def_bool y
-- 
2.0.4




[PATCH v11 00/17] Add ACPI support for Xen Dom0 on ARM64

2016-04-07 Thread Shannon Zhao
From: Shannon Zhao 

This patch set adds ACPI support for Xen Dom0 on ARM64. The relevant Xen
ACPI on ARM64 design document could be found from [1].

This patch set adds a new FDT node "uefi" under /hypervisor to pass UEFI
information. Introduce a bus notifier of AMBA and Platform bus to map
the new added device's MMIO space. Make Xen domain use
xlated_setup_gnttab_pages to setup grant table and a new hypercall to
get event-channel irq.

Regarding the initialization flow of Linux kernel, it needs to move
xen_early_init() before efi_init(). Then xen_early_init() will check
whether it runs on Xen through the /hypervisor node and efi_init() will
call a new function fdt_find_xen_uefi_params(), to parse those
xen,uefi-* parameters just like the existing efi_get_fdt_params().

And in arm64_enable_runtime_services() it will check whether it runs on
Xen and call another new function xen_efi_runtime_setup() to setup
runtime service instead of efi_native_runtime_setup(). The
xen_efi_runtime_setup() will assign the runtime function pointers with
the functions of driver/xen/efi.c.

And since we pass a /hypervisor node and a /chosen node to Dom0, it
needs to check whether the DTS only contains a /hypervisor node and a
/chosen node in acpi_boot_table_init().

Patches are tested on FVP base model.

Thanks,
Shannon

[1] http://lists.xen.org/archives/html/xen-devel/2015-11/msg00488.html

Changes since v10:
* address Rafael's comments on patch 1
* undo the device mmio mappings if it fails in patch 6

Changes since v9:
* address Rafael's comments on patch 1
* check the compatible string of hypervisor node in patch 12

Changes since v8:
* rebased on v4.6-rc1
* print UART device address (PATCH 1)
* use xen_for_each_gfn (PATCH 3)
* reduce indentation by inverting the condition (PATCH 10)
* move xen_early_init() before efi_init() as well for ARM (PATCH 11)
* sync the document with Xen (PATCH 13)

Changes since v7:
* add __init prefix for acpi_get_spcr_uart_addr (PATCH 1)

Changes since v6:
* rebase on linux master
* refactor codes as acpi_get_spcr_uart_addr (PATCH 1)
* sync with Xen (patch 9)

Changes since v5:
* rebase on linux master
* use acpi_dev_resource_memory to parse the device memory info(patch 1)
* sync with Xen (patch 9)

Changes since v4:
* rebase on linux master
* move the check acpi_device_should_be_hidden into
  acpi_bus_type_and_status (patch 1)
* use existing function fdt_subnode_offset (patch 16)

Changes since v3:
* rebase on linux master
* print a warning when there is no SPCR table
* rephase the commit message of PATCH 3
* rephase the words of PATCH 13
* use strcmp and factor the function in PATCH 16
* Add several ACKs and RBs, thanks a lot


Changes since v2:
* Use 0 to check if it should ignore the UART
* Fix the use of page_to_xen_pfn
* Factor ACPI and DT parts in xen_guest_init
* Check "uefi" node by full path
* Fix the statement of Documentation/devicetree/bindings/arm/xen.txt

Changes since v1:
* Rebase on linux mainline and wallclock patch from Stefano
* Refactor AMBA and platform device MMIO map to one file
* Use EFI_PARAVIRT to check if it supports XEN EFI
* Refactor Xen EFI codes
* Address other comments

Shannon Zhao (17):
  Xen: ACPI: Hide UART used by Xen
  xen/grant-table: Move xlated_setup_gnttab_pages to common place
  Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn
  arm/xen: Use xen_xlate_map_ballooned_pages to setup grant table
  xen: memory : Add new XENMAPSPACE type XENMAPSPACE_dev_mmio
  Xen: ARM: Add support for mapping platform device mmio
  Xen: ARM: Add support for mapping AMBA device mmio
  Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen
  xen/hvm/params: Add a new delivery type for event-channel in
HVM_PARAM_CALLBACK_IRQ
  arm/xen: Get event-channel irq through HVM_PARAM when booting with
ACPI
  ARM: XEN: Move xen_early_init() before efi_init()
  ARM64: ACPI: Check if it runs on Xen to enable or disable ACPI
  ARM: Xen: Document UEFI support on Xen ARM virtual platforms
  XEN: EFI: Move x86 specific codes to architecture directory
  ARM64: XEN: Add a function to initialize Xen specific UEFI runtime
services
  FDT: Add a helper to get the subnode by given name
  Xen: EFI: Parse DT parameters for Xen specific UEFI

 Documentation/devicetree/bindings/arm/xen.txt |  35 +
 arch/arm/include/asm/xen/xen-ops.h|   6 +
 arch/arm/kernel/setup.c   |   2 +-
 arch/arm/xen/Makefile |   1 +
 arch/arm/xen/efi.c|  40 ++
 arch/arm/xen/enlighten.c  | 109 ++
 arch/arm64/include/asm/xen/xen-ops.h  |   6 +
 arch/arm64/kernel/acpi.c  |  14 +-
 arch/arm64/kernel/setup.c |   2 +-
 arch/arm64/xen/Makefile   |   1 +
 arch/x86/xen/efi.c| 112 +++
 arch/x86/xen/grant-table.c|  57 +---

Re: [PATCH v10 06/17] Xen: ARM: Add support for mapping platform device mmio

2016-04-07 Thread Shannon Zhao


On 2016/4/7 18:32, Julien Grall wrote:
> Hi Shannon,
> 
> On 07/04/16 02:37, Shannon Zhao wrote:
>>
>>
>> On 2016/4/6 20:16, Julien Grall wrote:
>>>> +gpfns[j] = XEN_PFN_DOWN(r->start) + j;
>>>> +idxs[j] = XEN_PFN_DOWN(r->start) + j;
>>>> +}
>>>> +
>>>> +xatp.domid = DOMID_SELF;
>>>> +xatp.size = nr;
>>>> +xatp.space = XENMAPSPACE_dev_mmio;
>>>> +
>>>> +set_xen_guest_handle(xatp.gpfns, gpfns);
>>>> +set_xen_guest_handle(xatp.idxs, idxs);
>>>> +set_xen_guest_handle(xatp.errs, errs);
>>>> +
>>>> +rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, );
>>>> +kfree(gpfns);
>>>> +kfree(idxs);
>>>> +kfree(errs);
>>>> +if (rc)
>>>> +return rc;
>>>
>>> Shouldn't we redo the mapping if the hypercall fails?
>> Hmm, why? If it fails again when we redo the mapping, what should we do
>> then? Redo again?
> 
> Because the device MMIO region is left half mapped in DOM0 address space.
> 
> After having another look to your patch, if an error occurs, the
> notifier will still return NOTIFY_OK. This will lead to random data
> abort when the driver is accessing the MMIO regions as the device will
> be considered fully functional.
> 
> However, even if the notifier return NOTIFY_BAD, the function device_add
> doesn't care about the return value of blocking_notifier_call_chain. I
> think this need to be fixed.
> 
>> I think if it fails at the first time it will always fail no matter how
>> many times we do.
> 
> I was speaking about the mappings that succeeded. They will unlikely
> fail during removal. If they ever fail you can just ignore the error.
Ok, I see. I thought you mean that it needs to map the regions again.
But what you really mean is undoing the mappings.

Thanks,
-- 
Shannon



Re: [PATCH v10 06/17] Xen: ARM: Add support for mapping platform device mmio

2016-04-07 Thread Shannon Zhao


On 2016/4/7 18:32, Julien Grall wrote:
> Hi Shannon,
> 
> On 07/04/16 02:37, Shannon Zhao wrote:
>>
>>
>> On 2016/4/6 20:16, Julien Grall wrote:
>>>> +gpfns[j] = XEN_PFN_DOWN(r->start) + j;
>>>> +idxs[j] = XEN_PFN_DOWN(r->start) + j;
>>>> +}
>>>> +
>>>> +xatp.domid = DOMID_SELF;
>>>> +xatp.size = nr;
>>>> +xatp.space = XENMAPSPACE_dev_mmio;
>>>> +
>>>> +set_xen_guest_handle(xatp.gpfns, gpfns);
>>>> +set_xen_guest_handle(xatp.idxs, idxs);
>>>> +set_xen_guest_handle(xatp.errs, errs);
>>>> +
>>>> +rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, );
>>>> +kfree(gpfns);
>>>> +kfree(idxs);
>>>> +kfree(errs);
>>>> +if (rc)
>>>> +return rc;
>>>
>>> Shouldn't we redo the mapping if the hypercall fails?
>> Hmm, why? If it fails again when we redo the mapping, what should we do
>> then? Redo again?
> 
> Because the device MMIO region is left half mapped in DOM0 address space.
> 
> After having another look to your patch, if an error occurs, the
> notifier will still return NOTIFY_OK. This will lead to random data
> abort when the driver is accessing the MMIO regions as the device will
> be considered fully functional.
> 
> However, even if the notifier return NOTIFY_BAD, the function device_add
> doesn't care about the return value of blocking_notifier_call_chain. I
> think this need to be fixed.
> 
>> I think if it fails at the first time it will always fail no matter how
>> many times we do.
> 
> I was speaking about the mappings that succeeded. They will unlikely
> fail during removal. If they ever fail you can just ignore the error.
Ok, I see. I thought you mean that it needs to map the regions again.
But what you really mean is undoing the mappings.

Thanks,
-- 
Shannon



Re: [PATCH v10 00/17] Add ACPI support for Xen Dom0 on ARM64

2016-04-06 Thread Shannon Zhao
Hi Julien,

On 2016/4/6 19:32, Julien Grall wrote:
> Hi Shannon,
> 
> On 01/04/2016 16:48, Shannon Zhao wrote:
>> This patch set adds ACPI support for Xen Dom0 on ARM64. The relevant Xen
>> ACPI on ARM64 design document could be found from [1].
>>
>> This patch set adds a new FDT node "uefi" under /hypervisor to pass UEFI
>> information. Introduce a bus notifier of AMBA and Platform bus to map
>> the new added device's MMIO space. Make Xen domain use
>> xlated_setup_gnttab_pages to setup grant table and a new hypercall to
>> get event-channel irq.
>>
>> Regarding the initialization flow of Linux kernel, it needs to move
>> xen_early_init() before efi_init(). Then xen_early_init() will check
>> whether it runs on Xen through the /hypervisor node and efi_init() will
>> call a new function fdt_find_xen_uefi_params(), to parse those
>> xen,uefi-* parameters just like the existing efi_get_fdt_params().
>>
>> And in arm64_enable_runtime_services() it will check whether it runs on
>> Xen and call another new function xen_efi_runtime_setup() to setup
>> runtime service instead of efi_native_runtime_setup(). The
>> xen_efi_runtime_setup() will assign the runtime function pointers with
>> the functions of driver/xen/efi.c.
>>
>> And since we pass a /hypervisor node and a /chosen node to Dom0, it
>> needs to check whether the DTS only contains a /hypervisor node and a
>> /chosen node in acpi_boot_table_init().
>>
>> Patches are tested on FVP base model. They can be fetched from[2].
> 
> I have tested this series and Linux is booting up to the prompt:
> 
> Tested-by: Julien Grall <julien.gr...@arm.com>
Thanks a lot. There are several patches which you didn't give your
comments. So I assume you will review them. If so, I'll wait and update
this series later.

Thanks,
-- 
Shannon



Re: [PATCH v10 00/17] Add ACPI support for Xen Dom0 on ARM64

2016-04-06 Thread Shannon Zhao
Hi Julien,

On 2016/4/6 19:32, Julien Grall wrote:
> Hi Shannon,
> 
> On 01/04/2016 16:48, Shannon Zhao wrote:
>> This patch set adds ACPI support for Xen Dom0 on ARM64. The relevant Xen
>> ACPI on ARM64 design document could be found from [1].
>>
>> This patch set adds a new FDT node "uefi" under /hypervisor to pass UEFI
>> information. Introduce a bus notifier of AMBA and Platform bus to map
>> the new added device's MMIO space. Make Xen domain use
>> xlated_setup_gnttab_pages to setup grant table and a new hypercall to
>> get event-channel irq.
>>
>> Regarding the initialization flow of Linux kernel, it needs to move
>> xen_early_init() before efi_init(). Then xen_early_init() will check
>> whether it runs on Xen through the /hypervisor node and efi_init() will
>> call a new function fdt_find_xen_uefi_params(), to parse those
>> xen,uefi-* parameters just like the existing efi_get_fdt_params().
>>
>> And in arm64_enable_runtime_services() it will check whether it runs on
>> Xen and call another new function xen_efi_runtime_setup() to setup
>> runtime service instead of efi_native_runtime_setup(). The
>> xen_efi_runtime_setup() will assign the runtime function pointers with
>> the functions of driver/xen/efi.c.
>>
>> And since we pass a /hypervisor node and a /chosen node to Dom0, it
>> needs to check whether the DTS only contains a /hypervisor node and a
>> /chosen node in acpi_boot_table_init().
>>
>> Patches are tested on FVP base model. They can be fetched from[2].
> 
> I have tested this series and Linux is booting up to the prompt:
> 
> Tested-by: Julien Grall 
Thanks a lot. There are several patches which you didn't give your
comments. So I assume you will review them. If so, I'll wait and update
this series later.

Thanks,
-- 
Shannon



Re: [PATCH v10 06/17] Xen: ARM: Add support for mapping platform device mmio

2016-04-06 Thread Shannon Zhao


On 2016/4/6 20:16, Julien Grall wrote:
>> +gpfns[j] = XEN_PFN_DOWN(r->start) + j;
>> +idxs[j] = XEN_PFN_DOWN(r->start) + j;
>> +}
>> +
>> +xatp.domid = DOMID_SELF;
>> +xatp.size = nr;
>> +xatp.space = XENMAPSPACE_dev_mmio;
>> +
>> +set_xen_guest_handle(xatp.gpfns, gpfns);
>> +set_xen_guest_handle(xatp.idxs, idxs);
>> +set_xen_guest_handle(xatp.errs, errs);
>> +
>> +rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, );
>> +kfree(gpfns);
>> +kfree(idxs);
>> +kfree(errs);
>> +if (rc)
>> +return rc;
> 
> Shouldn't we redo the mapping if the hypercall fails?
Hmm, why? If it fails again when we redo the mapping, what should we do
then? Redo again?
I think if it fails at the first time it will always fail no matter how
many times we do.

Thanks,
-- 
Shannon



Re: [PATCH v10 06/17] Xen: ARM: Add support for mapping platform device mmio

2016-04-06 Thread Shannon Zhao


On 2016/4/6 20:16, Julien Grall wrote:
>> +gpfns[j] = XEN_PFN_DOWN(r->start) + j;
>> +idxs[j] = XEN_PFN_DOWN(r->start) + j;
>> +}
>> +
>> +xatp.domid = DOMID_SELF;
>> +xatp.size = nr;
>> +xatp.space = XENMAPSPACE_dev_mmio;
>> +
>> +set_xen_guest_handle(xatp.gpfns, gpfns);
>> +set_xen_guest_handle(xatp.idxs, idxs);
>> +set_xen_guest_handle(xatp.errs, errs);
>> +
>> +rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, );
>> +kfree(gpfns);
>> +kfree(idxs);
>> +kfree(errs);
>> +if (rc)
>> +return rc;
> 
> Shouldn't we redo the mapping if the hypercall fails?
Hmm, why? If it fails again when we redo the mapping, what should we do
then? Redo again?
I think if it fails at the first time it will always fail no matter how
many times we do.

Thanks,
-- 
Shannon



[PATCH v10 07/17] Xen: ARM: Add support for mapping AMBA device mmio

2016-04-01 Thread Shannon Zhao
Add a bus_notifier for AMBA bus device in order to map the device
mmio regions when DOM0 booting with ACPI.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 drivers/xen/arm-device.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
index 76e26e5..3854043 100644
--- a/drivers/xen/arm-device.c
+++ b/drivers/xen/arm-device.c
@@ -139,3 +139,46 @@ static int __init register_xen_platform_notifier(void)
 }
 
 arch_initcall(register_xen_platform_notifier);
+
+#ifdef CONFIG_ARM_AMBA
+#include 
+
+static int xen_amba_notifier(struct notifier_block *nb,
+unsigned long action, void *data)
+{
+   struct amba_device *adev = to_amba_device(data);
+   int r = 0;
+
+   switch (action) {
+   case BUS_NOTIFY_ADD_DEVICE:
+   r = xen_map_device_mmio(>res, 1);
+   break;
+   case BUS_NOTIFY_DEL_DEVICE:
+   r = xen_unmap_device_mmio(>res, 1);
+   break;
+   default:
+   return NOTIFY_DONE;
+   }
+   if (r)
+   dev_err(>dev, "AMBA: Failed to %s device %s MMIO!\n",
+   action == BUS_NOTIFY_ADD_DEVICE ? "map" :
+   (action == BUS_NOTIFY_DEL_DEVICE ? "unmap" : "?"),
+   adev->dev.init_name);
+
+   return NOTIFY_OK;
+}
+
+static struct notifier_block amba_device_nb = {
+   .notifier_call = xen_amba_notifier,
+};
+
+static int __init register_xen_amba_notifier(void)
+{
+   if (!xen_initial_domain() || acpi_disabled)
+   return 0;
+
+   return bus_register_notifier(_bustype, _device_nb);
+}
+
+arch_initcall(register_xen_amba_notifier);
+#endif
-- 
2.1.4



[PATCH v10 07/17] Xen: ARM: Add support for mapping AMBA device mmio

2016-04-01 Thread Shannon Zhao
Add a bus_notifier for AMBA bus device in order to map the device
mmio regions when DOM0 booting with ACPI.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 drivers/xen/arm-device.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
index 76e26e5..3854043 100644
--- a/drivers/xen/arm-device.c
+++ b/drivers/xen/arm-device.c
@@ -139,3 +139,46 @@ static int __init register_xen_platform_notifier(void)
 }
 
 arch_initcall(register_xen_platform_notifier);
+
+#ifdef CONFIG_ARM_AMBA
+#include 
+
+static int xen_amba_notifier(struct notifier_block *nb,
+unsigned long action, void *data)
+{
+   struct amba_device *adev = to_amba_device(data);
+   int r = 0;
+
+   switch (action) {
+   case BUS_NOTIFY_ADD_DEVICE:
+   r = xen_map_device_mmio(>res, 1);
+   break;
+   case BUS_NOTIFY_DEL_DEVICE:
+   r = xen_unmap_device_mmio(>res, 1);
+   break;
+   default:
+   return NOTIFY_DONE;
+   }
+   if (r)
+   dev_err(>dev, "AMBA: Failed to %s device %s MMIO!\n",
+   action == BUS_NOTIFY_ADD_DEVICE ? "map" :
+   (action == BUS_NOTIFY_DEL_DEVICE ? "unmap" : "?"),
+   adev->dev.init_name);
+
+   return NOTIFY_OK;
+}
+
+static struct notifier_block amba_device_nb = {
+   .notifier_call = xen_amba_notifier,
+};
+
+static int __init register_xen_amba_notifier(void)
+{
+   if (!xen_initial_domain() || acpi_disabled)
+   return 0;
+
+   return bus_register_notifier(_bustype, _device_nb);
+}
+
+arch_initcall(register_xen_amba_notifier);
+#endif
-- 
2.1.4



[PATCH v10 02/17] xen/grant-table: Move xlated_setup_gnttab_pages to common place

2016-04-01 Thread Shannon Zhao
Move xlated_setup_gnttab_pages to common place, so it can be reused by
ARM to setup grant table.

Rename it to xen_xlate_map_ballooned_pages.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/x86/xen/grant-table.c | 57 +--
 drivers/xen/xlate_mmu.c| 61 ++
 include/xen/xen-ops.h  |  2 ++
 3 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index e079500..de4144c 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -111,63 +111,18 @@ int arch_gnttab_init(unsigned long nr_shared)
 }
 
 #ifdef CONFIG_XEN_PVH
-#include 
 #include 
-#include 
-static int __init xlated_setup_gnttab_pages(void)
-{
-   struct page **pages;
-   xen_pfn_t *pfns;
-   void *vaddr;
-   int rc;
-   unsigned int i;
-   unsigned long nr_grant_frames = gnttab_max_grant_frames();
-
-   BUG_ON(nr_grant_frames == 0);
-   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
-   if (!pages)
-   return -ENOMEM;
-
-   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
-   if (!pfns) {
-   kfree(pages);
-   return -ENOMEM;
-   }
-   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
-   if (rc) {
-   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   kfree(pages);
-   kfree(pfns);
-   return rc;
-   }
-   for (i = 0; i < nr_grant_frames; i++)
-   pfns[i] = page_to_pfn(pages[i]);
-
-   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
-   if (!vaddr) {
-   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   free_xenballooned_pages(nr_grant_frames, pages);
-   kfree(pages);
-   kfree(pfns);
-   return -ENOMEM;
-   }
-   kfree(pages);
-
-   xen_auto_xlat_grant_frames.pfn = pfns;
-   xen_auto_xlat_grant_frames.count = nr_grant_frames;
-   xen_auto_xlat_grant_frames.vaddr = vaddr;
-
-   return 0;
-}
-
+#include 
 static int __init xen_pvh_gnttab_setup(void)
 {
if (!xen_pvh_domain())
return -ENODEV;
 
-   return xlated_setup_gnttab_pages();
+   xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
+
+   return xen_xlate_map_ballooned_pages(_auto_xlat_grant_frames.pfn,
+_auto_xlat_grant_frames.vaddr,
+xen_auto_xlat_grant_frames.count);
 }
 /* Call it _before_ __gnttab_init as we need to initialize the
  * xen_auto_xlat_grant_frames first. */
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 5063c5e..9692656 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -29,6 +29,8 @@
  */
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -37,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
 
@@ -185,3 +188,61 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
return 0;
 }
 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
+
+/**
+ * xen_xlate_map_ballooned_pages - map a new set of ballooned pages
+ * @gfns: returns the array of corresponding GFNs
+ * @virt: returns the virtual address of the mapped region
+ * @nr_grant_frames: number of GFNs
+ * @return 0 on success, error otherwise
+ *
+ * This allocates a set of ballooned pages and maps them into the
+ * kernel's address space.
+ */
+int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
+unsigned long nr_grant_frames)
+{
+   struct page **pages;
+   xen_pfn_t *pfns;
+   void *vaddr;
+   int rc;
+   unsigned int i;
+
+   BUG_ON(nr_grant_frames == 0);
+   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
+   if (!pages)
+   return -ENOMEM;
+
+   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
+   if (!pfns) {
+   kfree(pages);
+   return -ENOMEM;
+   }
+   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
+   if (rc) {
+   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
+   nr_grant_frames, rc);
+   kfree(pages);
+   kfree(pfns);
+   return rc;
+   }
+   for (i = 0; i < nr_grant_frames; i++)
+   pfns[i] = page_to_pfn(pages[i]);
+
+   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
+   if (!vaddr) {
+   pr_warn("%s Couldn't map %ld pfns rc:%d\

[PATCH v10 02/17] xen/grant-table: Move xlated_setup_gnttab_pages to common place

2016-04-01 Thread Shannon Zhao
Move xlated_setup_gnttab_pages to common place, so it can be reused by
ARM to setup grant table.

Rename it to xen_xlate_map_ballooned_pages.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 arch/x86/xen/grant-table.c | 57 +--
 drivers/xen/xlate_mmu.c| 61 ++
 include/xen/xen-ops.h  |  2 ++
 3 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index e079500..de4144c 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -111,63 +111,18 @@ int arch_gnttab_init(unsigned long nr_shared)
 }
 
 #ifdef CONFIG_XEN_PVH
-#include 
 #include 
-#include 
-static int __init xlated_setup_gnttab_pages(void)
-{
-   struct page **pages;
-   xen_pfn_t *pfns;
-   void *vaddr;
-   int rc;
-   unsigned int i;
-   unsigned long nr_grant_frames = gnttab_max_grant_frames();
-
-   BUG_ON(nr_grant_frames == 0);
-   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
-   if (!pages)
-   return -ENOMEM;
-
-   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
-   if (!pfns) {
-   kfree(pages);
-   return -ENOMEM;
-   }
-   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
-   if (rc) {
-   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   kfree(pages);
-   kfree(pfns);
-   return rc;
-   }
-   for (i = 0; i < nr_grant_frames; i++)
-   pfns[i] = page_to_pfn(pages[i]);
-
-   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
-   if (!vaddr) {
-   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
-   nr_grant_frames, rc);
-   free_xenballooned_pages(nr_grant_frames, pages);
-   kfree(pages);
-   kfree(pfns);
-   return -ENOMEM;
-   }
-   kfree(pages);
-
-   xen_auto_xlat_grant_frames.pfn = pfns;
-   xen_auto_xlat_grant_frames.count = nr_grant_frames;
-   xen_auto_xlat_grant_frames.vaddr = vaddr;
-
-   return 0;
-}
-
+#include 
 static int __init xen_pvh_gnttab_setup(void)
 {
if (!xen_pvh_domain())
return -ENODEV;
 
-   return xlated_setup_gnttab_pages();
+   xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
+
+   return xen_xlate_map_ballooned_pages(_auto_xlat_grant_frames.pfn,
+_auto_xlat_grant_frames.vaddr,
+xen_auto_xlat_grant_frames.count);
 }
 /* Call it _before_ __gnttab_init as we need to initialize the
  * xen_auto_xlat_grant_frames first. */
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 5063c5e..9692656 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -29,6 +29,8 @@
  */
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -37,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
 
@@ -185,3 +188,61 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
return 0;
 }
 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
+
+/**
+ * xen_xlate_map_ballooned_pages - map a new set of ballooned pages
+ * @gfns: returns the array of corresponding GFNs
+ * @virt: returns the virtual address of the mapped region
+ * @nr_grant_frames: number of GFNs
+ * @return 0 on success, error otherwise
+ *
+ * This allocates a set of ballooned pages and maps them into the
+ * kernel's address space.
+ */
+int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
+unsigned long nr_grant_frames)
+{
+   struct page **pages;
+   xen_pfn_t *pfns;
+   void *vaddr;
+   int rc;
+   unsigned int i;
+
+   BUG_ON(nr_grant_frames == 0);
+   pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
+   if (!pages)
+   return -ENOMEM;
+
+   pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
+   if (!pfns) {
+   kfree(pages);
+   return -ENOMEM;
+   }
+   rc = alloc_xenballooned_pages(nr_grant_frames, pages);
+   if (rc) {
+   pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
+   nr_grant_frames, rc);
+   kfree(pages);
+   kfree(pfns);
+   return rc;
+   }
+   for (i = 0; i < nr_grant_frames; i++)
+   pfns[i] = page_to_pfn(pages[i]);
+
+   vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
+   if (!vaddr) {
+   pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
+   nr_grant_frames

[PATCH v10 13/17] ARM: Xen: Document UEFI support on Xen ARM virtual platforms

2016-04-01 Thread Shannon Zhao
Add a "uefi" node under /hypervisor node in FDT, then Linux kernel could
scan this to get the UEFI information.

CC: Rob Herring <r...@kernel.org>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Rob Herring <r...@kernel.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 Documentation/devicetree/bindings/arm/xen.txt | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/xen.txt 
b/Documentation/devicetree/bindings/arm/xen.txt
index 0f7b9c2..c9b9321 100644
--- a/Documentation/devicetree/bindings/arm/xen.txt
+++ b/Documentation/devicetree/bindings/arm/xen.txt
@@ -11,10 +11,32 @@ the following properties:
   memory where the grant table should be mapped to, using an
   HYPERVISOR_memory_op hypercall. The memory region is large enough to map
   the whole grant table (it is larger or equal to gnttab_max_grant_frames()).
+  This property is unnecessary when booting Dom0 using ACPI.
 
 - interrupts: the interrupt used by Xen to inject event notifications.
   A GIC node is also required.
+  This property is unnecessary when booting Dom0 using ACPI.
 
+To support UEFI on Xen ARM virtual platforms, Xen populates the FDT "uefi" node
+under /hypervisor with following parameters:
+
+
+Name  | Size   | Description
+
+xen,uefi-system-table | 64-bit | Guest physical address of the UEFI System
+ || Table.
+
+xen,uefi-mmap-start   | 64-bit | Guest physical address of the UEFI memory
+ || map.
+
+xen,uefi-mmap-size| 32-bit | Size in bytes of the UEFI memory map
+  || pointed to in previous entry.
+
+xen,uefi-mmap-desc-size   | 32-bit | Size in bytes of each entry in the UEFI
+  || memory map.
+
+xen,uefi-mmap-desc-ver| 32-bit | Version of the mmap descriptor format.
+
 
 Example (assuming #address-cells = <2> and #size-cells = <2>):
 
@@ -22,4 +44,17 @@ hypervisor {
compatible = "xen,xen-4.3", "xen,xen";
reg = <0 0xb000 0 0x2>;
interrupts = <1 15 0xf08>;
+   uefi {
+   xen,uefi-system-table = <0x>;
+   xen,uefi-mmap-start = <0x>;
+   xen,uefi-mmap-size = <0x>;
+   xen,uefi-mmap-desc-size = <0x>;
+   xen,uefi-mmap-desc-ver = <0x>;
+};
 };
+
+The format and meaning of the "xen,uefi-*" parameters are similar to those in
+Documentation/arm/uefi.txt, which are provided by the regular UEFI stub. 
However
+they differ because they are provided by the Xen hypervisor, together with a 
set
+of UEFI runtime services implemented via hypercalls, see
+http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
-- 
2.1.4



[PATCH v10 10/17] arm/xen: Get event-channel irq through HVM_PARAM when booting with ACPI

2016-04-01 Thread Shannon Zhao
The kernel will get the event-channel IRQ through
HVM_PARAM_CALLBACK_IRQ.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/arm/xen/enlighten.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index d94f726..06bd61a 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -278,6 +279,35 @@ void __init xen_early_init(void)
add_preferred_console("hvc", 0, NULL);
 }
 
+static void __init xen_acpi_guest_init(void)
+{
+#ifdef CONFIG_ACPI
+   struct xen_hvm_param a;
+   int interrupt, trigger, polarity;
+
+   a.domid = DOMID_SELF;
+   a.index = HVM_PARAM_CALLBACK_IRQ;
+
+   if (HYPERVISOR_hvm_op(HVMOP_get_param, )
+   || (a.value >> 56) != HVM_PARAM_CALLBACK_TYPE_PPI) {
+   xen_events_irq = 0;
+   return;
+   }
+
+   interrupt = a.value & 0xff;
+   trigger = ((a.value >> 8) & 0x1) ? ACPI_EDGE_SENSITIVE
+: ACPI_LEVEL_SENSITIVE;
+   polarity = ((a.value >> 8) & 0x2) ? ACPI_ACTIVE_LOW
+ : ACPI_ACTIVE_HIGH;
+   xen_events_irq = acpi_register_gsi(NULL, interrupt, trigger, polarity);
+#endif
+}
+
+static void __init xen_dt_guest_init(void)
+{
+   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+}
+
 static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
@@ -286,7 +316,11 @@ static int __init xen_guest_init(void)
if (!xen_domain())
return 0;
 
-   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+   if (!acpi_disabled)
+   xen_acpi_guest_init();
+   else
+   xen_dt_guest_init();
+
if (!xen_events_irq) {
pr_err("Xen event channel interrupt not found\n");
return -ENODEV;
-- 
2.1.4



[PATCH v10 11/17] ARM: XEN: Move xen_early_init() before efi_init()

2016-04-01 Thread Shannon Zhao
Move xen_early_init() before efi_init(), then when calling efi_init()
could initialize Xen specific UEFI.

Check if it runs on Xen hypervisor through the flat dts.

Cc: Russell King <li...@arm.linux.org.uk>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/arm/kernel/setup.c   |  2 +-
 arch/arm/xen/enlighten.c  | 56 ++-
 arch/arm64/kernel/setup.c |  2 +-
 3 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 139791e..5bc7516 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1035,6 +1035,7 @@ void __init setup_arch(char **cmdline_p)
early_paging_init(mdesc);
 #endif
setup_dma_zone(mdesc);
+   xen_early_init();
efi_init();
sanity_check_meminfo();
arm_memblock_init(mdesc);
@@ -1051,7 +1052,6 @@ void __init setup_arch(char **cmdline_p)
 
arm_dt_init_cpu_maps();
psci_dt_init();
-   xen_early_init();
 #ifdef CONFIG_SMP
if (is_smp()) {
if (!mdesc->smp_init || !mdesc->smp_init()) {
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 06bd61a..13e3e9f 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -53,8 +54,6 @@ struct xen_memory_region 
xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
 
 static __read_mostly unsigned int xen_events_irq;
 
-static __initdata struct device_node *xen_node;
-
 int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
   unsigned long addr,
   xen_pfn_t *gfn, int nr,
@@ -238,6 +237,33 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
return IRQ_HANDLED;
 }
 
+static __initdata struct {
+   const char *compat;
+   const char *prefix;
+   const char *version;
+   bool found;
+} hyper_node = {"xen,xen", "xen,xen-", NULL, false};
+
+static int __init fdt_find_hyper_node(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+   const void *s = NULL;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
+
+   if (of_flat_dt_is_compatible(node, hyper_node.compat))
+   hyper_node.found = true;
+
+   s = of_get_flat_dt_prop(node, "compatible", );
+   if (strlen(hyper_node.prefix) + 3  < len &&
+   !strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
+   hyper_node.version = s + strlen(hyper_node.prefix);
+
+   return 0;
+}
+
 /*
  * see Documentation/devicetree/bindings/arm/xen.txt for the
  * documentation of the Xen Device Tree format.
@@ -245,26 +271,18 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
 #define GRANT_TABLE_PHYSADDR 0
 void __init xen_early_init(void)
 {
-   int len;
-   const char *s = NULL;
-   const char *version = NULL;
-   const char *xen_prefix = "xen,xen-";
-
-   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
-   if (!xen_node) {
+   of_scan_flat_dt(fdt_find_hyper_node, NULL);
+   if (!hyper_node.found) {
pr_debug("No Xen support\n");
return;
}
-   s = of_get_property(xen_node, "compatible", );
-   if (strlen(xen_prefix) + 3  < len &&
-   !strncmp(xen_prefix, s, strlen(xen_prefix)))
-   version = s + strlen(xen_prefix);
-   if (version == NULL) {
+
+   if (hyper_node.version == NULL) {
pr_debug("Xen version not found\n");
return;
}
 
-   pr_info("Xen %s support found\n", version);
+   pr_info("Xen %s support found\n", hyper_node.version);
 
xen_domain_type = XEN_HVM_DOMAIN;
 
@@ -305,6 +323,14 @@ static void __init xen_acpi_guest_init(void)
 
 static void __init xen_dt_guest_init(void)
 {
+   struct device_node *xen_node;
+
+   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
+   if (!xen_node) {
+   pr_err("Xen support was detected before, but it has 
disappeared\n");
+   return;
+   }
+
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
 }
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 9dc6776..7cf992f 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -320,6 +320,7 @@ void __init setup_arch(char **cmdline_p)
 */
cpu_uninstall_idmap();
 
+   xen_early_init();
efi_init();
arm64_memblock_init();
 
@@ -341,7 +342,6 @@ void __init setup_arch(char **cmdline_p)
} else {
psci_acpi_init();
}
-   xen_early_init();
 
cpu_read_bootcpu_ops();
smp_init_cpus();
-- 
2.1.4



[PATCH v10 17/17] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-04-01 Thread Shannon Zhao
Add a new function to parse DT parameters for Xen specific UEFI just
like the way for normal UEFI. Then it could reuse the existing codes.

If Xen supports EFI, initialize runtime services.

CC: Matt Fleming <m...@codeblueprint.co.uk>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Matt Fleming <m...@codeblueprint.co.uk>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/arm/xen/enlighten.c   |  6 +
 drivers/firmware/efi/arm-runtime.c | 17 +-
 drivers/firmware/efi/efi.c | 45 --
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..e130562 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -261,6 +261,12 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   /* Check if Xen supports EFI */
+   if (of_get_flat_dt_subnode_by_name(node, "uefi") > 0)
+   set_bit(EFI_PARAVIRT, );
+   }
+
return 0;
 }
 
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 6ae21e4..ac609b9 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern u64 efi_system_table;
 
@@ -107,13 +108,19 @@ static int __init arm_enable_runtime_services(void)
}
set_bit(EFI_SYSTEM_TABLES, );
 
-   if (!efi_virtmap_init()) {
-   pr_err("No UEFI virtual mapping was installed -- runtime 
services will not be available\n");
-   return -ENOMEM;
+   if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_PARAVIRT)) {
+   /* Set up runtime services function pointers for Xen Dom0 */
+   xen_efi_runtime_setup();
+   } else {
+   if (!efi_virtmap_init()) {
+   pr_err("No UEFI virtual mapping was installed -- 
runtime services will not be available\n");
+   return -ENOMEM;
+   }
+
+   /* Set up runtime services function pointers */
+   efi_native_runtime_setup();
}
 
-   /* Set up runtime services function pointers */
-   efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, );
 
efi.runtime_version = efi.systab->hdr.revision;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 3a69ed5..519c096 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -469,12 +469,14 @@ device_initcall(efi_load_efivars);
FIELD_SIZEOF(struct efi_fdt_params, field) \
}
 
-static __initdata struct {
+struct params {
const char name[32];
const char propname[32];
int offset;
int size;
-} dt_params[] = {
+};
+
+static struct params fdt_params[] __initdata = {
UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
@@ -482,24 +484,45 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
+static struct params xen_fdt_params[] __initdata = {
+   UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
+   UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
+   UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
+   UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
+   UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
+};
+
 struct param_info {
int found;
void *params;
+   struct params *dt_params;
+   int size;
 };
 
 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
   int depth, void *data)
 {
struct param_info *info = data;
+   struct params *dt_params = info->dt_params;
const void *prop;
void *dest;
u64 val;
-   int i, len;
+   int i, len, offset;
 
-   if (depth != 1 || strcmp(uname, "chosen") != 0)
-   return 0;
+   if (efi_enabled(EFI_PARAVIRT)) {
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
 
-   for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+   offset = of_get_flat_dt_subnode_by_name

[PATCH v10 14/17] XEN: EFI: Move x86 specific codes to architecture directory

2016-04-01 Thread Shannon Zhao
Move x86 specific codes to architecture directory and export those EFI
runtime service functions. This will be useful for initializing runtime
service on ARM later.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/x86/xen/efi.c| 112 
 drivers/xen/efi.c | 174 ++
 include/xen/xen-ops.h |  30 ++---
 3 files changed, 168 insertions(+), 148 deletions(-)

diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c
index be14cc3..86527f1 100644
--- a/arch/x86/xen/efi.c
+++ b/arch/x86/xen/efi.c
@@ -20,10 +20,122 @@
 #include 
 #include 
 
+#include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
+
+static efi_char16_t vendor[100] __initdata;
+
+static efi_system_table_t efi_systab_xen __initdata = {
+   .hdr = {
+   .signature  = EFI_SYSTEM_TABLE_SIGNATURE,
+   .revision   = 0, /* Initialized later. */
+   .headersize = 0, /* Ignored by Linux Kernel. */
+   .crc32  = 0, /* Ignored by Linux Kernel. */
+   .reserved   = 0
+   },
+   .fw_vendor  = EFI_INVALID_TABLE_ADDR, /* Initialized later. */
+   .fw_revision= 0,  /* Initialized later. */
+   .con_in_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_in = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .runtime= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .boottime   = (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .nr_tables  = 0,  /* Initialized later. */
+   .tables = EFI_INVALID_TABLE_ADDR  /* Initialized later. */
+};
+
+static const struct efi efi_xen __initconst = {
+   .systab   = NULL, /* Initialized later. */
+   .runtime_version  = 0,/* Initialized later. */
+   .mps  = EFI_INVALID_TABLE_ADDR,
+   .acpi = EFI_INVALID_TABLE_ADDR,
+   .acpi20   = EFI_INVALID_TABLE_ADDR,
+   .smbios   = EFI_INVALID_TABLE_ADDR,
+   .smbios3  = EFI_INVALID_TABLE_ADDR,
+   .sal_systab   = EFI_INVALID_TABLE_ADDR,
+   .boot_info= EFI_INVALID_TABLE_ADDR,
+   .hcdp = EFI_INVALID_TABLE_ADDR,
+   .uga  = EFI_INVALID_TABLE_ADDR,
+   .uv_systab= EFI_INVALID_TABLE_ADDR,
+   .fw_vendor= EFI_INVALID_TABLE_ADDR,
+   .runtime  = EFI_INVALID_TABLE_ADDR,
+   .config_table = EFI_INVALID_TABLE_ADDR,
+   .get_time = xen_efi_get_time,
+   .set_time = xen_efi_set_time,
+   .get_wakeup_time  = xen_efi_get_wakeup_time,
+   .set_wakeup_time  = xen_efi_set_wakeup_time,
+   .get_variable = xen_efi_get_variable,
+   .get_next_variable= xen_efi_get_next_variable,
+   .set_variable = xen_efi_set_variable,
+   .query_variable_info  = xen_efi_query_variable_info,
+   .update_capsule   = xen_efi_update_capsule,
+   .query_capsule_caps   = xen_efi_query_capsule_caps,
+   .get_next_high_mono_count = xen_efi_get_next_high_mono_count,
+   .reset_system = NULL, /* Functionality provided by Xen. */
+   .set_virtual_address_map  = NULL, /* Not used under Xen. */
+   .memmap   = NULL, /* Not used under Xen. */
+   .flags= 0 /* Initialized later. */
+};
+
+static efi_system_table_t __init *xen_efi_probe(void)
+{
+   struct xen_platform_op op = {
+   .cmd = XENPF_firmware_info,
+   .u.firmware_info = {
+   .type = XEN_FW_EFI_INFO,
+   .index = XEN_FW_EFI_CONFIG_TABLE
+   }
+   };
+   union xenpf_efi_info *info = _info.u.efi_info;
+
+   if (!xen_initial_domain() || HYPERVISOR_platform_op() < 0)
+   return NULL;
+
+   /* Here we know that Xen runs on EFI platform. */
+
+   efi = efi_xen;
+
+   efi_systab_xen.tables = info->cfg.addr;
+   efi_systab_xen.nr_tables = info->cfg.nent;
+
+   op.cmd = XENPF_firmware_info;
+   op.u.firmware_info.type = XEN_FW_EFI_INFO;
+   op.u.firmware_info.index = XEN_FW_EFI

[PATCH v10 16/17] FDT: Add a helper to get the subnode by given name

2016-04-01 Thread Shannon Zhao
Sometimes it needs to check if there is a subnode of given node in FDT
by given name. Introduce this helper to get the subnode if it exists.

CC: Rob Herring <r...@kernel.org>
Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 drivers/of/fdt.c   | 13 +
 include/linux/of_fdt.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 3349d2a..5c8b2f2 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -645,6 +645,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
 }
 
 /**
+ * of_get_flat_dt_subnode_by_name - get the subnode by given name
+ *
+ * @node: the parent node
+ * @uname: the name of subnode
+ * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+
+int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
+{
+   return fdt_subnode_offset(initial_boot_params, node, uname);
+}
+
+/**
  * of_get_flat_dt_root - find the root node in the flat blob
  */
 unsigned long __init of_get_flat_dt_root(void)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 2fbe868..2c3707e 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -52,6 +52,8 @@ extern char __dtb_end[];
 extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
 int depth, void *data),
   void *data);
+extern int of_get_flat_dt_subnode_by_name(unsigned long node,
+ const char *uname);
 extern const void *of_get_flat_dt_prop(unsigned long node, const char *name,
   int *size);
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
-- 
2.1.4



[PATCH v10 13/17] ARM: Xen: Document UEFI support on Xen ARM virtual platforms

2016-04-01 Thread Shannon Zhao
Add a "uefi" node under /hypervisor node in FDT, then Linux kernel could
scan this to get the UEFI information.

CC: Rob Herring 
Signed-off-by: Shannon Zhao 
Acked-by: Rob Herring 
Reviewed-by: Stefano Stabellini 
---
 Documentation/devicetree/bindings/arm/xen.txt | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/xen.txt 
b/Documentation/devicetree/bindings/arm/xen.txt
index 0f7b9c2..c9b9321 100644
--- a/Documentation/devicetree/bindings/arm/xen.txt
+++ b/Documentation/devicetree/bindings/arm/xen.txt
@@ -11,10 +11,32 @@ the following properties:
   memory where the grant table should be mapped to, using an
   HYPERVISOR_memory_op hypercall. The memory region is large enough to map
   the whole grant table (it is larger or equal to gnttab_max_grant_frames()).
+  This property is unnecessary when booting Dom0 using ACPI.
 
 - interrupts: the interrupt used by Xen to inject event notifications.
   A GIC node is also required.
+  This property is unnecessary when booting Dom0 using ACPI.
 
+To support UEFI on Xen ARM virtual platforms, Xen populates the FDT "uefi" node
+under /hypervisor with following parameters:
+
+
+Name  | Size   | Description
+
+xen,uefi-system-table | 64-bit | Guest physical address of the UEFI System
+ || Table.
+
+xen,uefi-mmap-start   | 64-bit | Guest physical address of the UEFI memory
+ || map.
+
+xen,uefi-mmap-size| 32-bit | Size in bytes of the UEFI memory map
+  || pointed to in previous entry.
+
+xen,uefi-mmap-desc-size   | 32-bit | Size in bytes of each entry in the UEFI
+  || memory map.
+
+xen,uefi-mmap-desc-ver| 32-bit | Version of the mmap descriptor format.
+
 
 Example (assuming #address-cells = <2> and #size-cells = <2>):
 
@@ -22,4 +44,17 @@ hypervisor {
compatible = "xen,xen-4.3", "xen,xen";
reg = <0 0xb000 0 0x2>;
interrupts = <1 15 0xf08>;
+   uefi {
+   xen,uefi-system-table = <0x>;
+   xen,uefi-mmap-start = <0x>;
+   xen,uefi-mmap-size = <0x>;
+   xen,uefi-mmap-desc-size = <0x>;
+   xen,uefi-mmap-desc-ver = <0x>;
+};
 };
+
+The format and meaning of the "xen,uefi-*" parameters are similar to those in
+Documentation/arm/uefi.txt, which are provided by the regular UEFI stub. 
However
+they differ because they are provided by the Xen hypervisor, together with a 
set
+of UEFI runtime services implemented via hypercalls, see
+http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
-- 
2.1.4



[PATCH v10 10/17] arm/xen: Get event-channel irq through HVM_PARAM when booting with ACPI

2016-04-01 Thread Shannon Zhao
The kernel will get the event-channel IRQ through
HVM_PARAM_CALLBACK_IRQ.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 arch/arm/xen/enlighten.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index d94f726..06bd61a 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -278,6 +279,35 @@ void __init xen_early_init(void)
add_preferred_console("hvc", 0, NULL);
 }
 
+static void __init xen_acpi_guest_init(void)
+{
+#ifdef CONFIG_ACPI
+   struct xen_hvm_param a;
+   int interrupt, trigger, polarity;
+
+   a.domid = DOMID_SELF;
+   a.index = HVM_PARAM_CALLBACK_IRQ;
+
+   if (HYPERVISOR_hvm_op(HVMOP_get_param, )
+   || (a.value >> 56) != HVM_PARAM_CALLBACK_TYPE_PPI) {
+   xen_events_irq = 0;
+   return;
+   }
+
+   interrupt = a.value & 0xff;
+   trigger = ((a.value >> 8) & 0x1) ? ACPI_EDGE_SENSITIVE
+: ACPI_LEVEL_SENSITIVE;
+   polarity = ((a.value >> 8) & 0x2) ? ACPI_ACTIVE_LOW
+ : ACPI_ACTIVE_HIGH;
+   xen_events_irq = acpi_register_gsi(NULL, interrupt, trigger, polarity);
+#endif
+}
+
+static void __init xen_dt_guest_init(void)
+{
+   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+}
+
 static int __init xen_guest_init(void)
 {
struct xen_add_to_physmap xatp;
@@ -286,7 +316,11 @@ static int __init xen_guest_init(void)
if (!xen_domain())
return 0;
 
-   xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+   if (!acpi_disabled)
+   xen_acpi_guest_init();
+   else
+   xen_dt_guest_init();
+
if (!xen_events_irq) {
pr_err("Xen event channel interrupt not found\n");
return -ENODEV;
-- 
2.1.4



[PATCH v10 11/17] ARM: XEN: Move xen_early_init() before efi_init()

2016-04-01 Thread Shannon Zhao
Move xen_early_init() before efi_init(), then when calling efi_init()
could initialize Xen specific UEFI.

Check if it runs on Xen hypervisor through the flat dts.

Cc: Russell King 
Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 arch/arm/kernel/setup.c   |  2 +-
 arch/arm/xen/enlighten.c  | 56 ++-
 arch/arm64/kernel/setup.c |  2 +-
 3 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 139791e..5bc7516 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1035,6 +1035,7 @@ void __init setup_arch(char **cmdline_p)
early_paging_init(mdesc);
 #endif
setup_dma_zone(mdesc);
+   xen_early_init();
efi_init();
sanity_check_meminfo();
arm_memblock_init(mdesc);
@@ -1051,7 +1052,6 @@ void __init setup_arch(char **cmdline_p)
 
arm_dt_init_cpu_maps();
psci_dt_init();
-   xen_early_init();
 #ifdef CONFIG_SMP
if (is_smp()) {
if (!mdesc->smp_init || !mdesc->smp_init()) {
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 06bd61a..13e3e9f 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -53,8 +54,6 @@ struct xen_memory_region 
xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
 
 static __read_mostly unsigned int xen_events_irq;
 
-static __initdata struct device_node *xen_node;
-
 int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
   unsigned long addr,
   xen_pfn_t *gfn, int nr,
@@ -238,6 +237,33 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
return IRQ_HANDLED;
 }
 
+static __initdata struct {
+   const char *compat;
+   const char *prefix;
+   const char *version;
+   bool found;
+} hyper_node = {"xen,xen", "xen,xen-", NULL, false};
+
+static int __init fdt_find_hyper_node(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+   const void *s = NULL;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
+
+   if (of_flat_dt_is_compatible(node, hyper_node.compat))
+   hyper_node.found = true;
+
+   s = of_get_flat_dt_prop(node, "compatible", );
+   if (strlen(hyper_node.prefix) + 3  < len &&
+   !strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
+   hyper_node.version = s + strlen(hyper_node.prefix);
+
+   return 0;
+}
+
 /*
  * see Documentation/devicetree/bindings/arm/xen.txt for the
  * documentation of the Xen Device Tree format.
@@ -245,26 +271,18 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
 #define GRANT_TABLE_PHYSADDR 0
 void __init xen_early_init(void)
 {
-   int len;
-   const char *s = NULL;
-   const char *version = NULL;
-   const char *xen_prefix = "xen,xen-";
-
-   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
-   if (!xen_node) {
+   of_scan_flat_dt(fdt_find_hyper_node, NULL);
+   if (!hyper_node.found) {
pr_debug("No Xen support\n");
return;
}
-   s = of_get_property(xen_node, "compatible", );
-   if (strlen(xen_prefix) + 3  < len &&
-   !strncmp(xen_prefix, s, strlen(xen_prefix)))
-   version = s + strlen(xen_prefix);
-   if (version == NULL) {
+
+   if (hyper_node.version == NULL) {
pr_debug("Xen version not found\n");
return;
}
 
-   pr_info("Xen %s support found\n", version);
+   pr_info("Xen %s support found\n", hyper_node.version);
 
xen_domain_type = XEN_HVM_DOMAIN;
 
@@ -305,6 +323,14 @@ static void __init xen_acpi_guest_init(void)
 
 static void __init xen_dt_guest_init(void)
 {
+   struct device_node *xen_node;
+
+   xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
+   if (!xen_node) {
+   pr_err("Xen support was detected before, but it has 
disappeared\n");
+   return;
+   }
+
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
 }
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 9dc6776..7cf992f 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -320,6 +320,7 @@ void __init setup_arch(char **cmdline_p)
 */
cpu_uninstall_idmap();
 
+   xen_early_init();
efi_init();
arm64_memblock_init();
 
@@ -341,7 +342,6 @@ void __init setup_arch(char **cmdline_p)
} else {
psci_acpi_init();
}
-   xen_early_init();
 
cpu_read_bootcpu_ops();
smp_init_cpus();
-- 
2.1.4



[PATCH v10 17/17] Xen: EFI: Parse DT parameters for Xen specific UEFI

2016-04-01 Thread Shannon Zhao
Add a new function to parse DT parameters for Xen specific UEFI just
like the way for normal UEFI. Then it could reuse the existing codes.

If Xen supports EFI, initialize runtime services.

CC: Matt Fleming 
Signed-off-by: Shannon Zhao 
Reviewed-by: Matt Fleming 
Reviewed-by: Stefano Stabellini 
---
 arch/arm/xen/enlighten.c   |  6 +
 drivers/firmware/efi/arm-runtime.c | 17 +-
 drivers/firmware/efi/efi.c | 45 --
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 13e3e9f..e130562 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -261,6 +261,12 @@ static int __init fdt_find_hyper_node(unsigned long node, 
const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
 
+   if (IS_ENABLED(CONFIG_XEN_EFI)) {
+   /* Check if Xen supports EFI */
+   if (of_get_flat_dt_subnode_by_name(node, "uefi") > 0)
+   set_bit(EFI_PARAVIRT, );
+   }
+
return 0;
 }
 
diff --git a/drivers/firmware/efi/arm-runtime.c 
b/drivers/firmware/efi/arm-runtime.c
index 6ae21e4..ac609b9 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern u64 efi_system_table;
 
@@ -107,13 +108,19 @@ static int __init arm_enable_runtime_services(void)
}
set_bit(EFI_SYSTEM_TABLES, );
 
-   if (!efi_virtmap_init()) {
-   pr_err("No UEFI virtual mapping was installed -- runtime 
services will not be available\n");
-   return -ENOMEM;
+   if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_PARAVIRT)) {
+   /* Set up runtime services function pointers for Xen Dom0 */
+   xen_efi_runtime_setup();
+   } else {
+   if (!efi_virtmap_init()) {
+   pr_err("No UEFI virtual mapping was installed -- 
runtime services will not be available\n");
+   return -ENOMEM;
+   }
+
+   /* Set up runtime services function pointers */
+   efi_native_runtime_setup();
}
 
-   /* Set up runtime services function pointers */
-   efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, );
 
efi.runtime_version = efi.systab->hdr.revision;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 3a69ed5..519c096 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -469,12 +469,14 @@ device_initcall(efi_load_efivars);
FIELD_SIZEOF(struct efi_fdt_params, field) \
}
 
-static __initdata struct {
+struct params {
const char name[32];
const char propname[32];
int offset;
int size;
-} dt_params[] = {
+};
+
+static struct params fdt_params[] __initdata = {
UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
@@ -482,24 +484,45 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
+static struct params xen_fdt_params[] __initdata = {
+   UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
+   UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
+   UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
+   UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
+   UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
+};
+
 struct param_info {
int found;
void *params;
+   struct params *dt_params;
+   int size;
 };
 
 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
   int depth, void *data)
 {
struct param_info *info = data;
+   struct params *dt_params = info->dt_params;
const void *prop;
void *dest;
u64 val;
-   int i, len;
+   int i, len, offset;
 
-   if (depth != 1 || strcmp(uname, "chosen") != 0)
-   return 0;
+   if (efi_enabled(EFI_PARAVIRT)) {
+   if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+   return 0;
 
-   for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+   offset = of_get_flat_dt_subnode_by_name(node, "uefi");
+   if (offset < 0)
+   return 0;
+   node = offset;
+  

[PATCH v10 14/17] XEN: EFI: Move x86 specific codes to architecture directory

2016-04-01 Thread Shannon Zhao
Move x86 specific codes to architecture directory and export those EFI
runtime service functions. This will be useful for initializing runtime
service on ARM later.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 arch/x86/xen/efi.c| 112 
 drivers/xen/efi.c | 174 ++
 include/xen/xen-ops.h |  30 ++---
 3 files changed, 168 insertions(+), 148 deletions(-)

diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c
index be14cc3..86527f1 100644
--- a/arch/x86/xen/efi.c
+++ b/arch/x86/xen/efi.c
@@ -20,10 +20,122 @@
 #include 
 #include 
 
+#include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
+
+static efi_char16_t vendor[100] __initdata;
+
+static efi_system_table_t efi_systab_xen __initdata = {
+   .hdr = {
+   .signature  = EFI_SYSTEM_TABLE_SIGNATURE,
+   .revision   = 0, /* Initialized later. */
+   .headersize = 0, /* Ignored by Linux Kernel. */
+   .crc32  = 0, /* Ignored by Linux Kernel. */
+   .reserved   = 0
+   },
+   .fw_vendor  = EFI_INVALID_TABLE_ADDR, /* Initialized later. */
+   .fw_revision= 0,  /* Initialized later. */
+   .con_in_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_in = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .con_out= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr_handle  = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .stderr = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+   .runtime= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .boottime   = (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+   .nr_tables  = 0,  /* Initialized later. */
+   .tables = EFI_INVALID_TABLE_ADDR  /* Initialized later. */
+};
+
+static const struct efi efi_xen __initconst = {
+   .systab   = NULL, /* Initialized later. */
+   .runtime_version  = 0,/* Initialized later. */
+   .mps  = EFI_INVALID_TABLE_ADDR,
+   .acpi = EFI_INVALID_TABLE_ADDR,
+   .acpi20   = EFI_INVALID_TABLE_ADDR,
+   .smbios   = EFI_INVALID_TABLE_ADDR,
+   .smbios3  = EFI_INVALID_TABLE_ADDR,
+   .sal_systab   = EFI_INVALID_TABLE_ADDR,
+   .boot_info= EFI_INVALID_TABLE_ADDR,
+   .hcdp = EFI_INVALID_TABLE_ADDR,
+   .uga  = EFI_INVALID_TABLE_ADDR,
+   .uv_systab= EFI_INVALID_TABLE_ADDR,
+   .fw_vendor= EFI_INVALID_TABLE_ADDR,
+   .runtime  = EFI_INVALID_TABLE_ADDR,
+   .config_table = EFI_INVALID_TABLE_ADDR,
+   .get_time = xen_efi_get_time,
+   .set_time = xen_efi_set_time,
+   .get_wakeup_time  = xen_efi_get_wakeup_time,
+   .set_wakeup_time  = xen_efi_set_wakeup_time,
+   .get_variable = xen_efi_get_variable,
+   .get_next_variable= xen_efi_get_next_variable,
+   .set_variable = xen_efi_set_variable,
+   .query_variable_info  = xen_efi_query_variable_info,
+   .update_capsule   = xen_efi_update_capsule,
+   .query_capsule_caps   = xen_efi_query_capsule_caps,
+   .get_next_high_mono_count = xen_efi_get_next_high_mono_count,
+   .reset_system = NULL, /* Functionality provided by Xen. */
+   .set_virtual_address_map  = NULL, /* Not used under Xen. */
+   .memmap   = NULL, /* Not used under Xen. */
+   .flags= 0 /* Initialized later. */
+};
+
+static efi_system_table_t __init *xen_efi_probe(void)
+{
+   struct xen_platform_op op = {
+   .cmd = XENPF_firmware_info,
+   .u.firmware_info = {
+   .type = XEN_FW_EFI_INFO,
+   .index = XEN_FW_EFI_CONFIG_TABLE
+   }
+   };
+   union xenpf_efi_info *info = _info.u.efi_info;
+
+   if (!xen_initial_domain() || HYPERVISOR_platform_op() < 0)
+   return NULL;
+
+   /* Here we know that Xen runs on EFI platform. */
+
+   efi = efi_xen;
+
+   efi_systab_xen.tables = info->cfg.addr;
+   efi_systab_xen.nr_tables = info->cfg.nent;
+
+   op.cmd = XENPF_firmware_info;
+   op.u.firmware_info.type = XEN_FW_EFI_INFO;
+   op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
+   info->vendor.bufsz = sizeof(vendor);
+   set_xen_

[PATCH v10 16/17] FDT: Add a helper to get the subnode by given name

2016-04-01 Thread Shannon Zhao
Sometimes it needs to check if there is a subnode of given node in FDT
by given name. Introduce this helper to get the subnode if it exists.

CC: Rob Herring 
Signed-off-by: Shannon Zhao 
Acked-by: Stefano Stabellini 
Acked-by: Rob Herring 
---
 drivers/of/fdt.c   | 13 +
 include/linux/of_fdt.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 3349d2a..5c8b2f2 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -645,6 +645,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
 }
 
 /**
+ * of_get_flat_dt_subnode_by_name - get the subnode by given name
+ *
+ * @node: the parent node
+ * @uname: the name of subnode
+ * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+
+int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
+{
+   return fdt_subnode_offset(initial_boot_params, node, uname);
+}
+
+/**
  * of_get_flat_dt_root - find the root node in the flat blob
  */
 unsigned long __init of_get_flat_dt_root(void)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 2fbe868..2c3707e 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -52,6 +52,8 @@ extern char __dtb_end[];
 extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
 int depth, void *data),
   void *data);
+extern int of_get_flat_dt_subnode_by_name(unsigned long node,
+ const char *uname);
 extern const void *of_get_flat_dt_prop(unsigned long node, const char *name,
   int *size);
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
-- 
2.1.4



[PATCH v10 15/17] ARM64: XEN: Add a function to initialize Xen specific UEFI runtime services

2016-04-01 Thread Shannon Zhao
When running on Xen hypervisor, runtime services are supported through
hypercall. Add a Xen specific function to initialize runtime services.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 arch/arm/include/asm/xen/xen-ops.h   |  6 ++
 arch/arm/xen/Makefile|  1 +
 arch/arm/xen/efi.c   | 40 
 arch/arm64/include/asm/xen/xen-ops.h |  6 ++
 arch/arm64/xen/Makefile  |  1 +
 drivers/xen/Kconfig  |  2 +-
 6 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/xen/xen-ops.h
 create mode 100644 arch/arm/xen/efi.c
 create mode 100644 arch/arm64/include/asm/xen/xen-ops.h

diff --git a/arch/arm/include/asm/xen/xen-ops.h 
b/arch/arm/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
index 1296952..2279521 100644
--- a/arch/arm/xen/Makefile
+++ b/arch/arm/xen/Makefile
@@ -1 +1,2 @@
 obj-y  := enlighten.o hypercall.o grant-table.o p2m.o mm.o
+obj-$(CONFIG_XEN_EFI) += efi.o
diff --git a/arch/arm/xen/efi.c b/arch/arm/xen/efi.c
new file mode 100644
index 000..16db419
--- /dev/null
+++ b/arch/arm/xen/efi.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Linaro Limited, Shannon Zhao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+
+/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
+ * e.g. efi.systab, will be set like normal EFI.
+ */
+void __init xen_efi_runtime_setup(void)
+{
+   efi.get_time = xen_efi_get_time;
+   efi.set_time = xen_efi_set_time;
+   efi.get_wakeup_time  = xen_efi_get_wakeup_time;
+   efi.set_wakeup_time  = xen_efi_set_wakeup_time;
+   efi.get_variable = xen_efi_get_variable;
+   efi.get_next_variable= xen_efi_get_next_variable;
+   efi.set_variable = xen_efi_set_variable;
+   efi.query_variable_info  = xen_efi_query_variable_info;
+   efi.update_capsule   = xen_efi_update_capsule;
+   efi.query_capsule_caps   = xen_efi_query_capsule_caps;
+   efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
+   efi.reset_system = NULL; /* Functionality provided by Xen. 
*/
+}
+EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
diff --git a/arch/arm64/include/asm/xen/xen-ops.h 
b/arch/arm64/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm64/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm64/xen/Makefile b/arch/arm64/xen/Makefile
index 74a8d87..8ff8aa9 100644
--- a/arch/arm64/xen/Makefile
+++ b/arch/arm64/xen/Makefile
@@ -1,2 +1,3 @@
 xen-arm-y  += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o 
mm.o)
 obj-y  := xen-arm.o hypercall.o
+obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 979a8317..f15bb3b7 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -275,7 +275,7 @@ config XEN_HAVE_PVMMU
 
 config XEN_EFI
def_bool y
-   depends on X86_64 && EFI
+   depends on (ARM || ARM64 || X86_64) && EFI
 
 config XEN_AUTO_XLATE
def_bool y
-- 
2.1.4



[PATCH v10 12/17] ARM64: ACPI: Check if it runs on Xen to enable or disable ACPI

2016-04-01 Thread Shannon Zhao
When it's a Xen domain0 booting with ACPI, it will supply a /chosen and
a /hypervisor node in DT. So check if it needs to enable ACPI.

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
Acked-by: Hanjun Guo <hanjun@linaro.org>
---
 arch/arm64/kernel/acpi.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index d1ce8e2..57ee317 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -67,10 +67,15 @@ static int __init dt_scan_depth1_nodes(unsigned long node,
 {
/*
 * Return 1 as soon as we encounter a node at depth 1 that is
-* not the /chosen node.
+* not the /chosen node, or /hypervisor node with compatible
+* string "xen,xen".
 */
-   if (depth == 1 && (strcmp(uname, "chosen") != 0))
-   return 1;
+   if (depth == 1 && (strcmp(uname, "chosen") != 0)) {
+   if (strcmp(uname, "hypervisor") != 0 ||
+   !of_flat_dt_is_compatible(node, "xen,xen"))
+   return 1;
+   }
+
return 0;
 }
 
@@ -184,7 +189,8 @@ void __init acpi_boot_table_init(void)
/*
 * Enable ACPI instead of device tree unless
 * - ACPI has been disabled explicitly (acpi=off), or
-* - the device tree is not empty (it has more than just a /chosen node)
+* - the device tree is not empty (it has more than just a /chosen node,
+*   and a /hypervisor node when running on Xen)
 *   and ACPI has not been force enabled (acpi=force)
 */
if (param_acpi_off ||
-- 
2.1.4



[PATCH v10 09/17] xen/hvm/params: Add a new delivery type for event-channel in HVM_PARAM_CALLBACK_IRQ

2016-04-01 Thread Shannon Zhao
This new delivery type which is for ARM shares the same value with
HVM_PARAM_CALLBACK_TYPE_VECTOR which is for x86.

val[15:8] is flag: val[7:0] is a PPI.
To the flag, bit 8 stands the interrupt mode is edge(1) or level(0) and
bit 9 stands the interrupt polarity is active low(1) or high(0).

Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabell...@eu.citrix.com>
---
 include/xen/interface/hvm/params.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/xen/interface/hvm/params.h 
b/include/xen/interface/hvm/params.h
index 70ad208..4d61fc5 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -47,11 +47,24 @@
  * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
  */
 
+#if defined(__i386__) || defined(__x86_64__)
 #define HVM_PARAM_CALLBACK_TYPE_VECTOR   2
 /*
  * val[7:0] is a vector number.  Check for XENFEAT_hvm_callback_vector to know
  * if this delivery method is available.
  */
+#elif defined(__arm__) || defined(__aarch64__)
+#define HVM_PARAM_CALLBACK_TYPE_PPI  2
+/*
+ * val[55:16] needs to be zero.
+ * val[15:8] is interrupt flag of the PPI used by event-channel:
+ *  bit 8: the PPI is edge(1) or level(0) triggered
+ *  bit 9: the PPI is active low(1) or high(0)
+ * val[7:0] is a PPI number used by event-channel.
+ * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to
+ * the notification is handled by the interrupt controller.
+ */
+#endif
 
 #define HVM_PARAM_STORE_PFN1
 #define HVM_PARAM_STORE_EVTCHN 2
-- 
2.1.4



[PATCH v10 12/17] ARM64: ACPI: Check if it runs on Xen to enable or disable ACPI

2016-04-01 Thread Shannon Zhao
When it's a Xen domain0 booting with ACPI, it will supply a /chosen and
a /hypervisor node in DT. So check if it needs to enable ACPI.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
Acked-by: Hanjun Guo 
---
 arch/arm64/kernel/acpi.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index d1ce8e2..57ee317 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -67,10 +67,15 @@ static int __init dt_scan_depth1_nodes(unsigned long node,
 {
/*
 * Return 1 as soon as we encounter a node at depth 1 that is
-* not the /chosen node.
+* not the /chosen node, or /hypervisor node with compatible
+* string "xen,xen".
 */
-   if (depth == 1 && (strcmp(uname, "chosen") != 0))
-   return 1;
+   if (depth == 1 && (strcmp(uname, "chosen") != 0)) {
+   if (strcmp(uname, "hypervisor") != 0 ||
+   !of_flat_dt_is_compatible(node, "xen,xen"))
+   return 1;
+   }
+
return 0;
 }
 
@@ -184,7 +189,8 @@ void __init acpi_boot_table_init(void)
/*
 * Enable ACPI instead of device tree unless
 * - ACPI has been disabled explicitly (acpi=off), or
-* - the device tree is not empty (it has more than just a /chosen node)
+* - the device tree is not empty (it has more than just a /chosen node,
+*   and a /hypervisor node when running on Xen)
 *   and ACPI has not been force enabled (acpi=force)
 */
if (param_acpi_off ||
-- 
2.1.4



[PATCH v10 09/17] xen/hvm/params: Add a new delivery type for event-channel in HVM_PARAM_CALLBACK_IRQ

2016-04-01 Thread Shannon Zhao
This new delivery type which is for ARM shares the same value with
HVM_PARAM_CALLBACK_TYPE_VECTOR which is for x86.

val[15:8] is flag: val[7:0] is a PPI.
To the flag, bit 8 stands the interrupt mode is edge(1) or level(0) and
bit 9 stands the interrupt polarity is active low(1) or high(0).

Signed-off-by: Shannon Zhao 
Acked-by: Stefano Stabellini 
---
 include/xen/interface/hvm/params.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/xen/interface/hvm/params.h 
b/include/xen/interface/hvm/params.h
index 70ad208..4d61fc5 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -47,11 +47,24 @@
  * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
  */
 
+#if defined(__i386__) || defined(__x86_64__)
 #define HVM_PARAM_CALLBACK_TYPE_VECTOR   2
 /*
  * val[7:0] is a vector number.  Check for XENFEAT_hvm_callback_vector to know
  * if this delivery method is available.
  */
+#elif defined(__arm__) || defined(__aarch64__)
+#define HVM_PARAM_CALLBACK_TYPE_PPI  2
+/*
+ * val[55:16] needs to be zero.
+ * val[15:8] is interrupt flag of the PPI used by event-channel:
+ *  bit 8: the PPI is edge(1) or level(0) triggered
+ *  bit 9: the PPI is active low(1) or high(0)
+ * val[7:0] is a PPI number used by event-channel.
+ * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to
+ * the notification is handled by the interrupt controller.
+ */
+#endif
 
 #define HVM_PARAM_STORE_PFN1
 #define HVM_PARAM_STORE_EVTCHN 2
-- 
2.1.4



[PATCH v10 15/17] ARM64: XEN: Add a function to initialize Xen specific UEFI runtime services

2016-04-01 Thread Shannon Zhao
When running on Xen hypervisor, runtime services are supported through
hypercall. Add a Xen specific function to initialize runtime services.

Signed-off-by: Shannon Zhao 
Reviewed-by: Stefano Stabellini 
---
 arch/arm/include/asm/xen/xen-ops.h   |  6 ++
 arch/arm/xen/Makefile|  1 +
 arch/arm/xen/efi.c   | 40 
 arch/arm64/include/asm/xen/xen-ops.h |  6 ++
 arch/arm64/xen/Makefile  |  1 +
 drivers/xen/Kconfig  |  2 +-
 6 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/xen/xen-ops.h
 create mode 100644 arch/arm/xen/efi.c
 create mode 100644 arch/arm64/include/asm/xen/xen-ops.h

diff --git a/arch/arm/include/asm/xen/xen-ops.h 
b/arch/arm/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
index 1296952..2279521 100644
--- a/arch/arm/xen/Makefile
+++ b/arch/arm/xen/Makefile
@@ -1 +1,2 @@
 obj-y  := enlighten.o hypercall.o grant-table.o p2m.o mm.o
+obj-$(CONFIG_XEN_EFI) += efi.o
diff --git a/arch/arm/xen/efi.c b/arch/arm/xen/efi.c
new file mode 100644
index 000..16db419
--- /dev/null
+++ b/arch/arm/xen/efi.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Linaro Limited, Shannon Zhao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+
+/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
+ * e.g. efi.systab, will be set like normal EFI.
+ */
+void __init xen_efi_runtime_setup(void)
+{
+   efi.get_time = xen_efi_get_time;
+   efi.set_time = xen_efi_set_time;
+   efi.get_wakeup_time  = xen_efi_get_wakeup_time;
+   efi.set_wakeup_time  = xen_efi_set_wakeup_time;
+   efi.get_variable = xen_efi_get_variable;
+   efi.get_next_variable= xen_efi_get_next_variable;
+   efi.set_variable = xen_efi_set_variable;
+   efi.query_variable_info  = xen_efi_query_variable_info;
+   efi.update_capsule   = xen_efi_update_capsule;
+   efi.query_capsule_caps   = xen_efi_query_capsule_caps;
+   efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
+   efi.reset_system = NULL; /* Functionality provided by Xen. 
*/
+}
+EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
diff --git a/arch/arm64/include/asm/xen/xen-ops.h 
b/arch/arm64/include/asm/xen/xen-ops.h
new file mode 100644
index 000..ec154e7
--- /dev/null
+++ b/arch/arm64/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm64/xen/Makefile b/arch/arm64/xen/Makefile
index 74a8d87..8ff8aa9 100644
--- a/arch/arm64/xen/Makefile
+++ b/arch/arm64/xen/Makefile
@@ -1,2 +1,3 @@
 xen-arm-y  += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o 
mm.o)
 obj-y  := xen-arm.o hypercall.o
+obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 979a8317..f15bb3b7 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -275,7 +275,7 @@ config XEN_HAVE_PVMMU
 
 config XEN_EFI
def_bool y
-   depends on X86_64 && EFI
+   depends on (ARM || ARM64 || X86_64) && EFI
 
 config XEN_AUTO_XLATE
def_bool y
-- 
2.1.4



  1   2   3   4   5   >