summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel-arm64.patch2435
-rw-r--r--kernel.spec5
2 files changed, 78 insertions, 2362 deletions
diff --git a/kernel-arm64.patch b/kernel-arm64.patch
index 6fb01f64c..0a8b9ea91 100644
--- a/kernel-arm64.patch
+++ b/kernel-arm64.patch
@@ -1,107 +1,49 @@
-diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
-index 85af34d..f3c05b5 100644
---- a/Documentation/arm64/booting.txt
-+++ b/Documentation/arm64/booting.txt
-@@ -168,6 +168,14 @@ Before jumping into the kernel, the following conditions must be met:
- the kernel image will be entered must be initialised by software at a
- higher exception level to prevent execution in an UNKNOWN state.
-
-+ For systems with a GICv3 interrupt controller:
-+ - If EL3 is present:
-+ ICC_SRE_EL3.Enable (bit 3) must be initialiased to 0b1.
-+ ICC_SRE_EL3.SRE (bit 0) must be initialised to 0b1.
-+ - If the kernel is entered at EL1:
-+ ICC.SRE_EL2.Enable (bit 3) must be initialised to 0b1
-+ ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b1.
-+
- The requirements described above for CPU mode, caches, MMUs, architected
- timers, coherency and system registers apply to all CPUs. All CPUs must
- enter the kernel in the same exception level.
-diff --git a/Documentation/devicetree/bindings/arm/gic-v3.txt b/Documentation/devicetree/bindings/arm/gic-v3.txt
-new file mode 100644
-index 0000000..33cd05e
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/gic-v3.txt
-@@ -0,0 +1,79 @@
-+* ARM Generic Interrupt Controller, version 3
-+
-+AArch64 SMP cores are often associated with a GICv3, providing Private
-+Peripheral Interrupts (PPI), Shared Peripheral Interrupts (SPI),
-+Software Generated Interrupts (SGI), and Locality-specific Peripheral
-+Interrupts (LPI).
-+
-+Main node required properties:
-+
-+- compatible : should at least contain "arm,gic-v3".
-+- interrupt-controller : Identifies the node as an interrupt controller
-+- #interrupt-cells : Specifies the number of cells needed to encode an
-+ interrupt source. Must be a single cell with a value of at least 3.
-+
-+ The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
-+ interrupts. Other values are reserved for future use.
-+
-+ The 2nd cell contains the interrupt number for the interrupt type.
-+ SPI interrupts are in the range [0-987]. PPI interrupts are in the
-+ range [0-15].
-+
-+ The 3rd cell is the flags, encoded as follows:
-+ bits[3:0] trigger type and level flags.
-+ 1 = edge triggered
-+ 4 = level triggered
-+
-+ Cells 4 and beyond are reserved for future use. When the 1st cell
-+ has a value of 0 or 1, cells 4 and beyond act as padding, and may be
-+ ignored. It is recommended that padding cells have a value of 0.
-+
-+- reg : Specifies base physical address(s) and size of the GIC
-+ registers, in the following order:
-+ - GIC Distributor interface (GICD)
-+ - GIC Redistributors (GICR), one range per redistributor region
-+ - GIC CPU interface (GICC)
-+ - GIC Hypervisor interface (GICH)
-+ - GIC Virtual CPU interface (GICV)
-+
-+ GICC, GICH and GICV are optional.
-+
-+- interrupts : Interrupt source of the VGIC maintenance interrupt.
-+
-+Optional
-+
-+- redistributor-stride : If using padding pages, specifies the stride
-+ of consecutive redistributors. Must be a multiple of 64kB.
-+
-+- #redistributor-regions: The number of independent contiguous regions
-+ occupied by the redistributors. Required if more than one such
-+ region is present.
-+
-+Examples:
-+
-+ gic: interrupt-controller@2cf00000 {
-+ compatible = "arm,gic-v3";
-+ #interrupt-cells = <3>;
-+ interrupt-controller;
-+ reg = <0x0 0x2f000000 0 0x10000>, // GICD
-+ <0x0 0x2f100000 0 0x200000>, // GICR
-+ <0x0 0x2c000000 0 0x2000>, // GICC
-+ <0x0 0x2c010000 0 0x2000>, // GICH
-+ <0x0 0x2c020000 0 0x2000>; // GICV
-+ interrupts = <1 9 4>;
-+ };
-+
-+ gic: interrupt-controller@2c010000 {
-+ compatible = "arm,gic-v3";
-+ #interrupt-cells = <3>;
-+ interrupt-controller;
-+ redistributor-stride = <0x0 0x40000>; // 256kB stride
-+ #redistributor-regions = <2>;
-+ reg = <0x0 0x2c010000 0 0x10000>, // GICD
-+ <0x0 0x2d000000 0 0x800000>, // GICR 1: CPUs 0-31
-+ <0x0 0x2e000000 0 0x800000>; // GICR 2: CPUs 32-63
-+ <0x0 0x2c040000 0 0x2000>, // GICC
-+ <0x0 0x2c060000 0 0x2000>, // GICH
-+ <0x0 0x2c080000 0 0x2000>; // GICV
-+ interrupts = <1 9 4>;
-+ };
+ .../devicetree/bindings/net/apm-xgene-enet.txt | 72 ++
+ .../devicetree/bindings/pci/xgene-pci.txt | 52 ++
+ MAINTAINERS | 15 +
+ arch/arm64/Kconfig | 19 +-
+ arch/arm64/boot/dts/apm-mustang.dts | 12 +
+ arch/arm64/boot/dts/apm-storm.dtsi | 208 ++++-
+ arch/arm64/include/asm/Kbuild | 1 +
+ arch/arm64/include/asm/elf.h | 3 +-
+ arch/arm64/include/asm/io.h | 3 +-
+ arch/arm64/include/asm/kvm_mmu.h | 12 +-
+ arch/arm64/include/asm/pci.h | 49 ++
+ arch/arm64/kernel/Makefile | 1 +
+ arch/arm64/kernel/efi-stub.c | 16 +-
+ arch/arm64/kernel/efi.c | 11 +
+ arch/arm64/kernel/head.S | 6 +-
+ arch/arm64/kernel/pci.c | 38 +
+ arch/arm64/kernel/process.c | 6 +
+ arch/arm64/kernel/smp_spin_table.c | 21 +-
+ drivers/ata/ahci_xgene.c | 3 +-
+ drivers/irqchip/irq-gic.c | 32 +-
+ drivers/net/ethernet/Kconfig | 1 +
+ drivers/net/ethernet/Makefile | 1 +
+ drivers/net/ethernet/apm/Kconfig | 1 +
+ drivers/net/ethernet/apm/Makefile | 5 +
+ drivers/net/ethernet/apm/xgene/Kconfig | 9 +
+ drivers/net/ethernet/apm/xgene/Makefile | 6 +
+ .../net/ethernet/apm/xgene/xgene_enet_ethtool.c | 125 +++
+ drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 747 ++++++++++++++++
+ drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 375 ++++++++
+ drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 962 +++++++++++++++++++++
+ drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 107 +++
+ drivers/of/address.c | 108 +++
+ drivers/of/of_pci.c | 136 +++
+ drivers/pci/host-bridge.c | 18 +-
+ drivers/pci/host/Kconfig | 10 +
+ drivers/pci/host/Makefile | 1 +
+ drivers/pci/host/pci-xgene.c | 725 ++++++++++++++++
+ drivers/pci/pci.c | 37 +
+ drivers/pci/probe.c | 68 +-
+ include/asm-generic/io.h | 2 +-
+ include/linux/of_address.h | 14 +-
+ include/linux/of_pci.h | 10 +
+ include/linux/pci.h | 15 +
+ tools/perf/arch/arm64/include/perf_regs.h | 2 +
+ 44 files changed, 3992 insertions(+), 73 deletions(-)
+
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
new file mode 100644
index 0000000..3e2a295
@@ -239,10 +181,10 @@ index 0000000..e19fdb8
+ status = "ok";
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
-index 0f066dd..5a10717 100644
+index 7e2eb4c..7bf051dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -701,6 +701,14 @@ S: Maintained
+@@ -719,6 +719,14 @@ S: Maintained
F: drivers/net/appletalk/
F: net/appletalk/
@@ -257,7 +199,7 @@ index 0f066dd..5a10717 100644
APTINA CAMERA SENSOR PLL
M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
-@@ -6861,6 +6869,13 @@ S: Maintained
+@@ -6880,6 +6888,13 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/host-generic-pci.txt
F: drivers/pci/host/pci-host-generic.c
@@ -268,123 +210,14 @@ index 0f066dd..5a10717 100644
+S: Maintained
+F: drivers/pci/host/pci-xgene.c
+
- PCMCIA SUBSYSTEM
- P: Linux PCMCIA Team
- L: linux-pcmcia@lists.infradead.org
-diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
-index 193ceaf..d6d5227 100644
---- a/arch/arm/include/asm/kvm_host.h
-+++ b/arch/arm/include/asm/kvm_host.h
-@@ -225,6 +225,11 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext)
- return 0;
- }
-
-+static inline void vgic_arch_setup(const struct vgic_params *vgic)
-+{
-+ BUG_ON(vgic->type != VGIC_V2);
-+}
-+
- int kvm_perf_init(void);
- int kvm_perf_teardown(void);
-
-diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
-index 85598b5..713e807 100644
---- a/arch/arm/kernel/asm-offsets.c
-+++ b/arch/arm/kernel/asm-offsets.c
-@@ -182,13 +182,13 @@ int main(void)
- DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc));
- #ifdef CONFIG_KVM_ARM_VGIC
- DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu));
-- DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr));
-- DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr));
-- DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr));
-- DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr));
-- DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr));
-- DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr));
-- DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr));
-+ DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr));
-+ DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr));
-+ DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr));
-+ DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr));
-+ DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr));
-+ DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr));
-+ DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr));
- DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr));
- #ifdef CONFIG_KVM_ARM_TIMER
- DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
-diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
-index 789bca9..f7057ed 100644
---- a/arch/arm/kvm/Makefile
-+++ b/arch/arm/kvm/Makefile
-@@ -21,4 +21,5 @@ obj-y += kvm-arm.o init.o interrupts.o
- obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
- obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
- obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
-+obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o
- obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
-diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
-index 76af9302..e4eaf30 100644
---- a/arch/arm/kvm/interrupts_head.S
-+++ b/arch/arm/kvm/interrupts_head.S
-@@ -421,14 +421,14 @@ vcpu .req r0 @ vcpu pointer always in r0
- ldr r9, [r2, #GICH_ELRSR1]
- ldr r10, [r2, #GICH_APR]
-
-- str r3, [r11, #VGIC_CPU_HCR]
-- str r4, [r11, #VGIC_CPU_VMCR]
-- str r5, [r11, #VGIC_CPU_MISR]
-- str r6, [r11, #VGIC_CPU_EISR]
-- str r7, [r11, #(VGIC_CPU_EISR + 4)]
-- str r8, [r11, #VGIC_CPU_ELRSR]
-- str r9, [r11, #(VGIC_CPU_ELRSR + 4)]
-- str r10, [r11, #VGIC_CPU_APR]
-+ str r3, [r11, #VGIC_V2_CPU_HCR]
-+ str r4, [r11, #VGIC_V2_CPU_VMCR]
-+ str r5, [r11, #VGIC_V2_CPU_MISR]
-+ str r6, [r11, #VGIC_V2_CPU_EISR]
-+ str r7, [r11, #(VGIC_V2_CPU_EISR + 4)]
-+ str r8, [r11, #VGIC_V2_CPU_ELRSR]
-+ str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)]
-+ str r10, [r11, #VGIC_V2_CPU_APR]
-
- /* Clear GICH_HCR */
- mov r5, #0
-@@ -436,7 +436,7 @@ vcpu .req r0 @ vcpu pointer always in r0
-
- /* Save list registers */
- add r2, r2, #GICH_LR0
-- add r3, r11, #VGIC_CPU_LR
-+ add r3, r11, #VGIC_V2_CPU_LR
- ldr r4, [r11, #VGIC_CPU_NR_LR]
- 1: ldr r6, [r2], #4
- str r6, [r3], #4
-@@ -463,9 +463,9 @@ vcpu .req r0 @ vcpu pointer always in r0
- add r11, vcpu, #VCPU_VGIC_CPU
-
- /* We only restore a minimal set of registers */
-- ldr r3, [r11, #VGIC_CPU_HCR]
-- ldr r4, [r11, #VGIC_CPU_VMCR]
-- ldr r8, [r11, #VGIC_CPU_APR]
-+ ldr r3, [r11, #VGIC_V2_CPU_HCR]
-+ ldr r4, [r11, #VGIC_V2_CPU_VMCR]
-+ ldr r8, [r11, #VGIC_V2_CPU_APR]
-
- str r3, [r2, #GICH_HCR]
- str r4, [r2, #GICH_VMCR]
-@@ -473,7 +473,7 @@ vcpu .req r0 @ vcpu pointer always in r0
-
- /* Restore list registers */
- add r2, r2, #GICH_LR0
-- add r3, r11, #VGIC_CPU_LR
-+ add r3, r11, #VGIC_V2_CPU_LR
- ldr r4, [r11, #VGIC_CPU_NR_LR]
- 1: ldr r6, [r3], #4
- str r6, [r2], #4
+ PCIE DRIVER FOR ST SPEAR13XX
+ M: Mohit Kumar <mohit.kumar@st.com>
+ L: linux-pci@vger.kernel.org
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index b0f9c9d..be54ce2 100644
+index fd4e81a..e8559bb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
-@@ -80,7 +80,7 @@ config MMU
+@@ -81,7 +81,7 @@ config MMU
def_bool y
config NO_IOPORT_MAP
@@ -393,7 +226,7 @@ index b0f9c9d..be54ce2 100644
config STACKTRACE_SUPPORT
def_bool y
-@@ -155,6 +155,23 @@ menu "Bus support"
+@@ -156,6 +156,23 @@ menu "Bus support"
config ARM_AMBA
bool
@@ -777,99 +610,8 @@ index e0ecdcf..dc34039 100644
#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M))
static inline u8 inb(unsigned long addr)
-diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
-index 3d69030..cc83520 100644
---- a/arch/arm64/include/asm/kvm_arm.h
-+++ b/arch/arm64/include/asm/kvm_arm.h
-@@ -76,9 +76,10 @@
- */
- #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
- HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \
-- HCR_AMO | HCR_IMO | HCR_FMO | \
-- HCR_SWIO | HCR_TIDCP | HCR_RW)
-+ HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW)
- #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF)
-+#define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO)
-+
-
- /* Hyp System Control Register (SCTLR_EL2) bits */
- #define SCTLR_EL2_EE (1 << 25)
-diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
-index 9fcd54b..a28c35b 100644
---- a/arch/arm64/include/asm/kvm_asm.h
-+++ b/arch/arm64/include/asm/kvm_asm.h
-@@ -18,6 +18,8 @@
- #ifndef __ARM_KVM_ASM_H__
- #define __ARM_KVM_ASM_H__
-
-+#include <asm/virt.h>
-+
- /*
- * 0 is reserved as an invalid value.
- * Order *must* be kept in sync with the hyp switch code.
-@@ -96,13 +98,21 @@ extern char __kvm_hyp_init_end[];
-
- extern char __kvm_hyp_vector[];
-
--extern char __kvm_hyp_code_start[];
--extern char __kvm_hyp_code_end[];
-+#define __kvm_hyp_code_start __hyp_text_start
-+#define __kvm_hyp_code_end __hyp_text_end
-
- extern void __kvm_flush_vm_context(void);
- extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
-
- extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
-+
-+extern u64 __vgic_v3_get_ich_vtr_el2(void);
-+
-+extern char __save_vgic_v2_state[];
-+extern char __restore_vgic_v2_state[];
-+extern char __save_vgic_v3_state[];
-+extern char __restore_vgic_v3_state[];
-+
- #endif
-
- #endif /* __ARM_KVM_ASM_H__ */
-diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
-index 92242ce..4ae9213 100644
---- a/arch/arm64/include/asm/kvm_host.h
-+++ b/arch/arm64/include/asm/kvm_host.h
-@@ -200,4 +200,32 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
- hyp_stack_ptr, vector_ptr);
- }
-
-+struct vgic_sr_vectors {
-+ void *save_vgic;
-+ void *restore_vgic;
-+};
-+
-+static inline void vgic_arch_setup(const struct vgic_params *vgic)
-+{
-+ extern struct vgic_sr_vectors __vgic_sr_vectors;
-+
-+ switch(vgic->type)
-+ {
-+ case VGIC_V2:
-+ __vgic_sr_vectors.save_vgic = __save_vgic_v2_state;
-+ __vgic_sr_vectors.restore_vgic = __restore_vgic_v2_state;
-+ break;
-+
-+#ifdef CONFIG_ARM_GIC_V3
-+ case VGIC_V3:
-+ __vgic_sr_vectors.save_vgic = __save_vgic_v3_state;
-+ __vgic_sr_vectors.restore_vgic = __restore_vgic_v3_state;
-+ break;
-+#endif
-+
-+ default:
-+ BUG();
-+ }
-+}
-+
- #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
-index 7d29847..d7f77ff 100644
+index 8e138c7..f8c9385 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -122,8 +122,16 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd)
@@ -889,8 +631,8 @@ index 7d29847..d7f77ff 100644
+ (__boundary - 1 < (end) - 1)? __boundary: (end); \
+})
- struct kvm;
-
+ static inline bool kvm_page_empty(void *ptr)
+ {
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
new file mode 100644
index 0000000..3f7856e
@@ -946,21 +688,6 @@ index 0000000..3f7856e
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_PCI_H */
-diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
-index 215ad46..7a5df52 100644
---- a/arch/arm64/include/asm/virt.h
-+++ b/arch/arm64/include/asm/virt.h
-@@ -50,6 +50,10 @@ static inline bool is_hyp_mode_mismatched(void)
- return __boot_cpu_mode[0] != __boot_cpu_mode[1];
- }
-
-+/* The section containing the hypervisor text */
-+extern char __hyp_text_start[];
-+extern char __hyp_text_end[];
-+
- #endif /* __ASSEMBLY__ */
-
- #endif /* ! __ASM__VIRT_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index df7ef87..1ed5a06 100644
--- a/arch/arm64/kernel/Makefile
@@ -973,42 +700,6 @@ index df7ef87..1ed5a06 100644
obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
-diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
-index 646f888..e74654c 100644
---- a/arch/arm64/kernel/asm-offsets.c
-+++ b/arch/arm64/kernel/asm-offsets.c
-@@ -129,13 +129,24 @@ int main(void)
- DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled));
- DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
- DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu));
-- DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr));
-- DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr));
-- DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr));
-- DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr));
-- DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr));
-- DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr));
-- DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr));
-+ DEFINE(VGIC_SAVE_FN, offsetof(struct vgic_sr_vectors, save_vgic));
-+ DEFINE(VGIC_RESTORE_FN, offsetof(struct vgic_sr_vectors, restore_vgic));
-+ DEFINE(VGIC_SR_VECTOR_SZ, sizeof(struct vgic_sr_vectors));
-+ DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr));
-+ DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr));
-+ DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr));
-+ DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr));
-+ DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr));
-+ DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr));
-+ DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr));
-+ DEFINE(VGIC_V3_CPU_HCR, offsetof(struct vgic_cpu, vgic_v3.vgic_hcr));
-+ DEFINE(VGIC_V3_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v3.vgic_vmcr));
-+ DEFINE(VGIC_V3_CPU_MISR, offsetof(struct vgic_cpu, vgic_v3.vgic_misr));
-+ DEFINE(VGIC_V3_CPU_EISR, offsetof(struct vgic_cpu, vgic_v3.vgic_eisr));
-+ DEFINE(VGIC_V3_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v3.vgic_elrsr));
-+ DEFINE(VGIC_V3_CPU_AP0R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap0r));
-+ DEFINE(VGIC_V3_CPU_AP1R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap1r));
-+ DEFINE(VGIC_V3_CPU_LR, offsetof(struct vgic_cpu, vgic_v3.vgic_lr));
- DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr));
- DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
- DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
index 1317fef..d27dd98 100644
--- a/arch/arm64/kernel/efi-stub.c
@@ -1214,635 +905,6 @@ index 0347d38..70181c1 100644
return 0;
}
-diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
-index 72a9fd5..32a0961 100644
---- a/arch/arm64/kvm/Makefile
-+++ b/arch/arm64/kvm/Makefile
-@@ -20,4 +20,8 @@ kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
- kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o
-
- kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
-+kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o
-+kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v2-switch.o
-+kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3.o
-+kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v3-switch.o
- kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
-diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
-index b0d1512..5945f3b 100644
---- a/arch/arm64/kvm/hyp.S
-+++ b/arch/arm64/kvm/hyp.S
-@@ -16,7 +16,6 @@
- */
-
- #include <linux/linkage.h>
--#include <linux/irqchip/arm-gic.h>
-
- #include <asm/assembler.h>
- #include <asm/memory.h>
-@@ -36,9 +35,6 @@
- .pushsection .hyp.text, "ax"
- .align PAGE_SHIFT
-
--__kvm_hyp_code_start:
-- .globl __kvm_hyp_code_start
--
- .macro save_common_regs
- // x2: base address for cpu context
- // x3: tmp register
-@@ -339,11 +335,8 @@ __kvm_hyp_code_start:
- .endm
-
- .macro activate_traps
-- ldr x2, [x0, #VCPU_IRQ_LINES]
-- ldr x1, [x0, #VCPU_HCR_EL2]
-- orr x2, x2, x1
-- msr hcr_el2, x2
--
-+ ldr x2, [x0, #VCPU_HCR_EL2]
-+ msr hcr_el2, x2
- ldr x2, =(CPTR_EL2_TTA)
- msr cptr_el2, x2
-
-@@ -379,100 +372,33 @@ __kvm_hyp_code_start:
- .endm
-
- /*
-- * Save the VGIC CPU state into memory
-- * x0: Register pointing to VCPU struct
-- * Do not corrupt x1!!!
-+ * Call into the vgic backend for state saving
- */
- .macro save_vgic_state
-- /* Get VGIC VCTRL base into x2 */
-- ldr x2, [x0, #VCPU_KVM]
-- kern_hyp_va x2
-- ldr x2, [x2, #KVM_VGIC_VCTRL]
-- kern_hyp_va x2
-- cbz x2, 2f // disabled
--
-- /* Compute the address of struct vgic_cpu */
-- add x3, x0, #VCPU_VGIC_CPU
--
-- /* Save all interesting registers */
-- ldr w4, [x2, #GICH_HCR]
-- ldr w5, [x2, #GICH_VMCR]
-- ldr w6, [x2, #GICH_MISR]
-- ldr w7, [x2, #GICH_EISR0]
-- ldr w8, [x2, #GICH_EISR1]
-- ldr w9, [x2, #GICH_ELRSR0]
-- ldr w10, [x2, #GICH_ELRSR1]
-- ldr w11, [x2, #GICH_APR]
--CPU_BE( rev w4, w4 )
--CPU_BE( rev w5, w5 )
--CPU_BE( rev w6, w6 )
--CPU_BE( rev w7, w7 )
--CPU_BE( rev w8, w8 )
--CPU_BE( rev w9, w9 )
--CPU_BE( rev w10, w10 )
--CPU_BE( rev w11, w11 )
--
-- str w4, [x3, #VGIC_CPU_HCR]
-- str w5, [x3, #VGIC_CPU_VMCR]
-- str w6, [x3, #VGIC_CPU_MISR]
-- str w7, [x3, #VGIC_CPU_EISR]
-- str w8, [x3, #(VGIC_CPU_EISR + 4)]
-- str w9, [x3, #VGIC_CPU_ELRSR]
-- str w10, [x3, #(VGIC_CPU_ELRSR + 4)]
-- str w11, [x3, #VGIC_CPU_APR]
--
-- /* Clear GICH_HCR */
-- str wzr, [x2, #GICH_HCR]
--
-- /* Save list registers */
-- add x2, x2, #GICH_LR0
-- ldr w4, [x3, #VGIC_CPU_NR_LR]
-- add x3, x3, #VGIC_CPU_LR
--1: ldr w5, [x2], #4
--CPU_BE( rev w5, w5 )
-- str w5, [x3], #4
-- sub w4, w4, #1
-- cbnz w4, 1b
--2:
-+ adr x24, __vgic_sr_vectors
-+ ldr x24, [x24, VGIC_SAVE_FN]
-+ kern_hyp_va x24
-+ blr x24
-+ mrs x24, hcr_el2
-+ mov x25, #HCR_INT_OVERRIDE
-+ neg x25, x25
-+ and x24, x24, x25
-+ msr hcr_el2, x24
- .endm
-
- /*
-- * Restore the VGIC CPU state from memory
-- * x0: Register pointing to VCPU struct
-+ * Call into the vgic backend for state restoring
- */
- .macro restore_vgic_state
-- /* Get VGIC VCTRL base into x2 */
-- ldr x2, [x0, #VCPU_KVM]
-- kern_hyp_va x2
-- ldr x2, [x2, #KVM_VGIC_VCTRL]
-- kern_hyp_va x2
-- cbz x2, 2f // disabled
--
-- /* Compute the address of struct vgic_cpu */
-- add x3, x0, #VCPU_VGIC_CPU
--
-- /* We only restore a minimal set of registers */
-- ldr w4, [x3, #VGIC_CPU_HCR]
-- ldr w5, [x3, #VGIC_CPU_VMCR]
-- ldr w6, [x3, #VGIC_CPU_APR]
--CPU_BE( rev w4, w4 )
--CPU_BE( rev w5, w5 )
--CPU_BE( rev w6, w6 )
--
-- str w4, [x2, #GICH_HCR]
-- str w5, [x2, #GICH_VMCR]
-- str w6, [x2, #GICH_APR]
--
-- /* Restore list registers */
-- add x2, x2, #GICH_LR0
-- ldr w4, [x3, #VGIC_CPU_NR_LR]
-- add x3, x3, #VGIC_CPU_LR
--1: ldr w5, [x3], #4
--CPU_BE( rev w5, w5 )
-- str w5, [x2], #4
-- sub w4, w4, #1
-- cbnz w4, 1b
--2:
-+ mrs x24, hcr_el2
-+ ldr x25, [x0, #VCPU_IRQ_LINES]
-+ orr x24, x24, #HCR_INT_OVERRIDE
-+ orr x24, x24, x25
-+ msr hcr_el2, x24
-+ adr x24, __vgic_sr_vectors
-+ ldr x24, [x24, #VGIC_RESTORE_FN]
-+ kern_hyp_va x24
-+ blr x24
- .endm
-
- .macro save_timer_state
-@@ -653,6 +579,12 @@ ENTRY(__kvm_flush_vm_context)
- ret
- ENDPROC(__kvm_flush_vm_context)
-
-+ // struct vgic_sr_vectors __vgi_sr_vectors;
-+ .align 3
-+ENTRY(__vgic_sr_vectors)
-+ .skip VGIC_SR_VECTOR_SZ
-+ENDPROC(__vgic_sr_vectors)
-+
- __kvm_hyp_panic:
- // Guess the context by looking at VTTBR:
- // If zero, then we're already a host.
-@@ -880,7 +812,4 @@ ENTRY(__kvm_hyp_vector)
- ventry el1_error_invalid // Error 32-bit EL1
- ENDPROC(__kvm_hyp_vector)
-
--__kvm_hyp_code_end:
-- .globl __kvm_hyp_code_end
--
- .popsection
-diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S
-new file mode 100644
-index 0000000..ae21177
---- /dev/null
-+++ b/arch/arm64/kvm/vgic-v2-switch.S
-@@ -0,0 +1,133 @@
-+/*
-+ * Copyright (C) 2012,2013 - ARM Ltd
-+ * Author: Marc Zyngier <marc.zyngier@arm.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 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 <linux/linkage.h>
-+#include <linux/irqchip/arm-gic.h>
-+
-+#include <asm/assembler.h>
-+#include <asm/memory.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/kvm.h>
-+#include <asm/kvm_asm.h>
-+#include <asm/kvm_arm.h>
-+#include <asm/kvm_mmu.h>
-+
-+ .text
-+ .pushsection .hyp.text, "ax"
-+
-+/*
-+ * Save the VGIC CPU state into memory
-+ * x0: Register pointing to VCPU struct
-+ * Do not corrupt x1!!!
-+ */
-+ENTRY(__save_vgic_v2_state)
-+__save_vgic_v2_state:
-+ /* Get VGIC VCTRL base into x2 */
-+ ldr x2, [x0, #VCPU_KVM]
-+ kern_hyp_va x2
-+ ldr x2, [x2, #KVM_VGIC_VCTRL]
-+ kern_hyp_va x2
-+ cbz x2, 2f // disabled
-+
-+ /* Compute the address of struct vgic_cpu */
-+ add x3, x0, #VCPU_VGIC_CPU
-+
-+ /* Save all interesting registers */
-+ ldr w4, [x2, #GICH_HCR]
-+ ldr w5, [x2, #GICH_VMCR]
-+ ldr w6, [x2, #GICH_MISR]
-+ ldr w7, [x2, #GICH_EISR0]
-+ ldr w8, [x2, #GICH_EISR1]
-+ ldr w9, [x2, #GICH_ELRSR0]
-+ ldr w10, [x2, #GICH_ELRSR1]
-+ ldr w11, [x2, #GICH_APR]
-+CPU_BE( rev w4, w4 )
-+CPU_BE( rev w5, w5 )
-+CPU_BE( rev w6, w6 )
-+CPU_BE( rev w7, w7 )
-+CPU_BE( rev w8, w8 )
-+CPU_BE( rev w9, w9 )
-+CPU_BE( rev w10, w10 )
-+CPU_BE( rev w11, w11 )
-+
-+ str w4, [x3, #VGIC_V2_CPU_HCR]
-+ str w5, [x3, #VGIC_V2_CPU_VMCR]
-+ str w6, [x3, #VGIC_V2_CPU_MISR]
-+ str w7, [x3, #VGIC_V2_CPU_EISR]
-+ str w8, [x3, #(VGIC_V2_CPU_EISR + 4)]
-+ str w9, [x3, #VGIC_V2_CPU_ELRSR]
-+ str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)]
-+ str w11, [x3, #VGIC_V2_CPU_APR]
-+
-+ /* Clear GICH_HCR */
-+ str wzr, [x2, #GICH_HCR]
-+
-+ /* Save list registers */
-+ add x2, x2, #GICH_LR0
-+ ldr w4, [x3, #VGIC_CPU_NR_LR]
-+ add x3, x3, #VGIC_V2_CPU_LR
-+1: ldr w5, [x2], #4
-+CPU_BE( rev w5, w5 )
-+ str w5, [x3], #4
-+ sub w4, w4, #1
-+ cbnz w4, 1b
-+2:
-+ ret
-+ENDPROC(__save_vgic_v2_state)
-+
-+/*
-+ * Restore the VGIC CPU state from memory
-+ * x0: Register pointing to VCPU struct
-+ */
-+ENTRY(__restore_vgic_v2_state)
-+__restore_vgic_v2_state:
-+ /* Get VGIC VCTRL base into x2 */
-+ ldr x2, [x0, #VCPU_KVM]
-+ kern_hyp_va x2
-+ ldr x2, [x2, #KVM_VGIC_VCTRL]
-+ kern_hyp_va x2
-+ cbz x2, 2f // disabled
-+
-+ /* Compute the address of struct vgic_cpu */
-+ add x3, x0, #VCPU_VGIC_CPU
-+
-+ /* We only restore a minimal set of registers */
-+ ldr w4, [x3, #VGIC_V2_CPU_HCR]
-+ ldr w5, [x3, #VGIC_V2_CPU_VMCR]
-+ ldr w6, [x3, #VGIC_V2_CPU_APR]
-+CPU_BE( rev w4, w4 )
-+CPU_BE( rev w5, w5 )
-+CPU_BE( rev w6, w6 )
-+
-+ str w4, [x2, #GICH_HCR]
-+ str w5, [x2, #GICH_VMCR]
-+ str w6, [x2, #GICH_APR]
-+
-+ /* Restore list registers */
-+ add x2, x2, #GICH_LR0
-+ ldr w4, [x3, #VGIC_CPU_NR_LR]
-+ add x3, x3, #VGIC_V2_CPU_LR
-+1: ldr w5, [x3], #4
-+CPU_BE( rev w5, w5 )
-+ str w5, [x2], #4
-+ sub w4, w4, #1
-+ cbnz w4, 1b
-+2:
-+ ret
-+ENDPROC(__restore_vgic_v2_state)
-+
-+ .popsection
-diff --git a/arch/arm64/kvm/vgic-v3-switch.S b/arch/arm64/kvm/vgic-v3-switch.S
-new file mode 100644
-index 0000000..d160469
---- /dev/null
-+++ b/arch/arm64/kvm/vgic-v3-switch.S
-@@ -0,0 +1,267 @@
-+/*
-+ * Copyright (C) 2012,2013 - ARM Ltd
-+ * Author: Marc Zyngier <marc.zyngier@arm.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 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 <linux/linkage.h>
-+#include <linux/irqchip/arm-gic-v3.h>
-+
-+#include <asm/assembler.h>
-+#include <asm/memory.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/kvm.h>
-+#include <asm/kvm_asm.h>
-+#include <asm/kvm_arm.h>
-+
-+ .text
-+ .pushsection .hyp.text, "ax"
-+
-+/*
-+ * We store LRs in reverse order to let the CPU deal with streaming
-+ * access. Use this macro to make it look saner...
-+ */
-+#define LR_OFFSET(n) (VGIC_V3_CPU_LR + (15 - n) * 8)
-+
-+/*
-+ * Save the VGIC CPU state into memory
-+ * x0: Register pointing to VCPU struct
-+ * Do not corrupt x1!!!
-+ */
-+.macro save_vgic_v3_state
-+ // Compute the address of struct vgic_cpu
-+ add x3, x0, #VCPU_VGIC_CPU
-+
-+ // Make sure stores to the GIC via the memory mapped interface
-+ // are now visible to the system register interface
-+ dsb st
-+
-+ // Save all interesting registers
-+ mrs_s x4, ICH_HCR_EL2
-+ mrs_s x5, ICH_VMCR_EL2
-+ mrs_s x6, ICH_MISR_EL2
-+ mrs_s x7, ICH_EISR_EL2
-+ mrs_s x8, ICH_ELSR_EL2
-+
-+ str w4, [x3, #VGIC_V3_CPU_HCR]
-+ str w5, [x3, #VGIC_V3_CPU_VMCR]
-+ str w6, [x3, #VGIC_V3_CPU_MISR]
-+ str w7, [x3, #VGIC_V3_CPU_EISR]
-+ str w8, [x3, #VGIC_V3_CPU_ELRSR]
-+
-+ msr_s ICH_HCR_EL2, xzr
-+
-+ mrs_s x21, ICH_VTR_EL2
-+ mvn w22, w21
-+ ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4
-+
-+ adr x24, 1f
-+ add x24, x24, x23
-+ br x24
-+
-+1:
-+ mrs_s x20, ICH_LR15_EL2
-+ mrs_s x19, ICH_LR14_EL2
-+ mrs_s x18, ICH_LR13_EL2
-+ mrs_s x17, ICH_LR12_EL2
-+ mrs_s x16, ICH_LR11_EL2
-+ mrs_s x15, ICH_LR10_EL2
-+ mrs_s x14, ICH_LR9_EL2
-+ mrs_s x13, ICH_LR8_EL2
-+ mrs_s x12, ICH_LR7_EL2
-+ mrs_s x11, ICH_LR6_EL2
-+ mrs_s x10, ICH_LR5_EL2
-+ mrs_s x9, ICH_LR4_EL2
-+ mrs_s x8, ICH_LR3_EL2
-+ mrs_s x7, ICH_LR2_EL2
-+ mrs_s x6, ICH_LR1_EL2
-+ mrs_s x5, ICH_LR0_EL2
-+
-+ adr x24, 1f
-+ add x24, x24, x23
-+ br x24
-+
-+1:
-+ str x20, [x3, #LR_OFFSET(15)]
-+ str x19, [x3, #LR_OFFSET(14)]
-+ str x18, [x3, #LR_OFFSET(13)]
-+ str x17, [x3, #LR_OFFSET(12)]
-+ str x16, [x3, #LR_OFFSET(11)]
-+ str x15, [x3, #LR_OFFSET(10)]
-+ str x14, [x3, #LR_OFFSET(9)]
-+ str x13, [x3, #LR_OFFSET(8)]
-+ str x12, [x3, #LR_OFFSET(7)]
-+ str x11, [x3, #LR_OFFSET(6)]
-+ str x10, [x3, #LR_OFFSET(5)]
-+ str x9, [x3, #LR_OFFSET(4)]
-+ str x8, [x3, #LR_OFFSET(3)]
-+ str x7, [x3, #LR_OFFSET(2)]
-+ str x6, [x3, #LR_OFFSET(1)]
-+ str x5, [x3, #LR_OFFSET(0)]
-+
-+ tbnz w21, #29, 6f // 6 bits
-+ tbz w21, #30, 5f // 5 bits
-+ // 7 bits
-+ mrs_s x20, ICH_AP0R3_EL2
-+ str w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)]
-+ mrs_s x19, ICH_AP0R2_EL2
-+ str w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)]
-+6: mrs_s x18, ICH_AP0R1_EL2
-+ str w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)]
-+5: mrs_s x17, ICH_AP0R0_EL2
-+ str w17, [x3, #VGIC_V3_CPU_AP0R]
-+
-+ tbnz w21, #29, 6f // 6 bits
-+ tbz w21, #30, 5f // 5 bits
-+ // 7 bits
-+ mrs_s x20, ICH_AP1R3_EL2
-+ str w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)]
-+ mrs_s x19, ICH_AP1R2_EL2
-+ str w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)]
-+6: mrs_s x18, ICH_AP1R1_EL2
-+ str w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)]
-+5: mrs_s x17, ICH_AP1R0_EL2
-+ str w17, [x3, #VGIC_V3_CPU_AP1R]
-+
-+ // Restore SRE_EL1 access and re-enable SRE at EL1.
-+ mrs_s x5, ICC_SRE_EL2
-+ orr x5, x5, #ICC_SRE_EL2_ENABLE
-+ msr_s ICC_SRE_EL2, x5
-+ isb
-+ mov x5, #1
-+ msr_s ICC_SRE_EL1, x5
-+.endm
-+
-+/*
-+ * Restore the VGIC CPU state from memory
-+ * x0: Register pointing to VCPU struct
-+ */
-+.macro restore_vgic_v3_state
-+ // Disable SRE_EL1 access. Necessary, otherwise
-+ // ICH_VMCR_EL2.VFIQEn becomes one, and FIQ happens...
-+ msr_s ICC_SRE_EL1, xzr
-+ isb
-+
-+ // Compute the address of struct vgic_cpu
-+ add x3, x0, #VCPU_VGIC_CPU
-+
-+ // Restore all interesting registers
-+ ldr w4, [x3, #VGIC_V3_CPU_HCR]
-+ ldr w5, [x3, #VGIC_V3_CPU_VMCR]
-+
-+ msr_s ICH_HCR_EL2, x4
-+ msr_s ICH_VMCR_EL2, x5
-+
-+ mrs_s x21, ICH_VTR_EL2
-+
-+ tbnz w21, #29, 6f // 6 bits
-+ tbz w21, #30, 5f // 5 bits
-+ // 7 bits
-+ ldr w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)]
-+ msr_s ICH_AP1R3_EL2, x20
-+ ldr w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)]
-+ msr_s ICH_AP1R2_EL2, x19
-+6: ldr w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)]
-+ msr_s ICH_AP1R1_EL2, x18
-+5: ldr w17, [x3, #VGIC_V3_CPU_AP1R]
-+ msr_s ICH_AP1R0_EL2, x17
-+
-+ tbnz w21, #29, 6f // 6 bits
-+ tbz w21, #30, 5f // 5 bits
-+ // 7 bits
-+ ldr w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)]
-+ msr_s ICH_AP0R3_EL2, x20
-+ ldr w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)]
-+ msr_s ICH_AP0R2_EL2, x19
-+6: ldr w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)]
-+ msr_s ICH_AP0R1_EL2, x18
-+5: ldr w17, [x3, #VGIC_V3_CPU_AP0R]
-+ msr_s ICH_AP0R0_EL2, x17
-+
-+ and w22, w21, #0xf
-+ mvn w22, w21
-+ ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4
-+
-+ adr x24, 1f
-+ add x24, x24, x23
-+ br x24
-+
-+1:
-+ ldr x20, [x3, #LR_OFFSET(15)]
-+ ldr x19, [x3, #LR_OFFSET(14)]
-+ ldr x18, [x3, #LR_OFFSET(13)]
-+ ldr x17, [x3, #LR_OFFSET(12)]
-+ ldr x16, [x3, #LR_OFFSET(11)]
-+ ldr x15, [x3, #LR_OFFSET(10)]
-+ ldr x14, [x3, #LR_OFFSET(9)]
-+ ldr x13, [x3, #LR_OFFSET(8)]
-+ ldr x12, [x3, #LR_OFFSET(7)]
-+ ldr x11, [x3, #LR_OFFSET(6)]
-+ ldr x10, [x3, #LR_OFFSET(5)]
-+ ldr x9, [x3, #LR_OFFSET(4)]
-+ ldr x8, [x3, #LR_OFFSET(3)]
-+ ldr x7, [x3, #LR_OFFSET(2)]
-+ ldr x6, [x3, #LR_OFFSET(1)]
-+ ldr x5, [x3, #LR_OFFSET(0)]
-+
-+ adr x24, 1f
-+ add x24, x24, x23
-+ br x24
-+
-+1:
-+ msr_s ICH_LR15_EL2, x20
-+ msr_s ICH_LR14_EL2, x19
-+ msr_s ICH_LR13_EL2, x18
-+ msr_s ICH_LR12_EL2, x17
-+ msr_s ICH_LR11_EL2, x16
-+ msr_s ICH_LR10_EL2, x15
-+ msr_s ICH_LR9_EL2, x14
-+ msr_s ICH_LR8_EL2, x13
-+ msr_s ICH_LR7_EL2, x12
-+ msr_s ICH_LR6_EL2, x11
-+ msr_s ICH_LR5_EL2, x10
-+ msr_s ICH_LR4_EL2, x9
-+ msr_s ICH_LR3_EL2, x8
-+ msr_s ICH_LR2_EL2, x7
-+ msr_s ICH_LR1_EL2, x6
-+ msr_s ICH_LR0_EL2, x5
-+
-+ // Ensure that the above will have reached the
-+ // (re)distributors. This ensure the guest will read
-+ // the correct values from the memory-mapped interface.
-+ isb
-+ dsb sy
-+
-+ // Prevent the guest from touching the GIC system registers
-+ mrs_s x5, ICC_SRE_EL2
-+ and x5, x5, #~ICC_SRE_EL2_ENABLE
-+ msr_s ICC_SRE_EL2, x5
-+.endm
-+
-+ENTRY(__save_vgic_v3_state)
-+ save_vgic_v3_state
-+ ret
-+ENDPROC(__save_vgic_v3_state)
-+
-+ENTRY(__restore_vgic_v3_state)
-+ restore_vgic_v3_state
-+ ret
-+ENDPROC(__restore_vgic_v3_state)
-+
-+ENTRY(__vgic_v3_get_ich_vtr_el2)
-+ mrs_s x0, ICH_VTR_EL2
-+ ret
-+ENDPROC(__vgic_v3_get_ich_vtr_el2)
-+
-+ .popsection
-diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
-index 71c52bc..a149c67 100644
---- a/arch/ia64/kernel/time.c
-+++ b/arch/ia64/kernel/time.c
-@@ -384,21 +384,6 @@ static struct irqaction timer_irqaction = {
- .name = "timer"
- };
-
--static struct platform_device rtc_efi_dev = {
-- .name = "rtc-efi",
-- .id = -1,
--};
--
--static int __init rtc_init(void)
--{
-- if (platform_device_register(&rtc_efi_dev) < 0)
-- printk(KERN_ERR "unable to register rtc device...\n");
--
-- /* not necessarily an error */
-- return 0;
--}
--module_init(rtc_init);
--
- void read_persistent_clock(struct timespec *ts)
- {
- efi_gettimeofday(ts);
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index bc28111..00e5a0c 100644
--- a/drivers/ata/ahci_xgene.c
@@ -1858,10 +920,10 @@ index bc28111..00e5a0c 100644
rc = ahci_qc_issue(qc);
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
-index 9c1f883..1ddfdde 100644
+index 4b959e6..c36c7ab55 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
-@@ -383,6 +383,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)
+@@ -381,6 +381,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)
void __iomem *dist_base = gic_data_dist_base(gic);
void __iomem *base = gic_data_cpu_base(gic);
unsigned int cpu_mask, cpu = smp_processor_id();
@@ -1869,7 +931,7 @@ index 9c1f883..1ddfdde 100644
int i;
/*
-@@ -403,13 +404,29 @@ static void gic_cpu_init(struct gic_chip_data *gic)
+@@ -401,13 +402,29 @@ static void gic_cpu_init(struct gic_chip_data *gic)
gic_cpu_config(dist_base, NULL);
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
@@ -1901,7 +963,7 @@ index 9c1f883..1ddfdde 100644
}
#ifdef CONFIG_CPU_PM
-@@ -520,6 +537,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
+@@ -518,6 +535,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
{
int i;
u32 *ptr;
@@ -1909,7 +971,7 @@ index 9c1f883..1ddfdde 100644
void __iomem *dist_base;
void __iomem *cpu_base;
-@@ -544,7 +562,15 @@ static void gic_cpu_restore(unsigned int gic_nr)
+@@ -542,7 +560,15 @@ static void gic_cpu_restore(unsigned int gic_nr)
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
@@ -4342,7 +3404,7 @@ index 0000000..f4f7e4a
+
+#endif /* __XGENE_ENET_MAIN_H__ */
diff --git a/drivers/of/address.c b/drivers/of/address.c
-index 5edfcb0..cbbaed2 100644
+index e371825..5eaadae 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -5,6 +5,7 @@
@@ -4426,7 +3488,7 @@ index 5edfcb0..cbbaed2 100644
}
static int __of_address_to_resource(struct device_node *dev,
-@@ -811,3 +872,50 @@ bool of_dma_is_coherent(struct device_node *np)
+@@ -847,3 +908,50 @@ bool of_dma_is_coherent(struct device_node *np)
return false;
}
EXPORT_SYMBOL_GPL(of_dma_is_coherent);
@@ -4670,10 +3732,10 @@ index 0e5f3c9..54ceafd 100644
+ return 0;
+}
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
-index 21df477..3b988a2 100644
+index 2d8a4d0..76daa18 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
-@@ -46,4 +46,14 @@ config PCI_HOST_GENERIC
+@@ -46,6 +46,16 @@ config PCI_HOST_GENERIC
Say Y here if you want to support a simple generic PCI host
controller, such as the one emulated by kvmtool.
@@ -4687,16 +3749,19 @@ index 21df477..3b988a2 100644
+ There are 5 internal PCIe ports available. Each port is GEN3 capable
+ and have varied lanes from x1 to x8.
+
- endmenu
+ config PCIE_SPEAR13XX
+ tristate "STMicroelectronics SPEAr PCIe controller"
+ depends on ARCH_SPEAR13XX
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
-index 611ba4b..0801606 100644
+index 0daec79..6990412 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
-@@ -6,3 +6,4 @@ obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
+@@ -6,4 +6,5 @@ obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o
obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
+obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
+ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
new file mode 100644
index 0000000..7bf4ac7
@@ -5622,71 +4687,6 @@ index e3cf8a2..abf5e82 100644
}
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
-diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
-index 0754f5c..4478a59 100644
---- a/drivers/rtc/Kconfig
-+++ b/drivers/rtc/Kconfig
-@@ -789,7 +789,7 @@ config RTC_DRV_DA9063
-
- config RTC_DRV_EFI
- tristate "EFI RTC"
-- depends on IA64
-+ depends on EFI
- help
- If you say yes here you will get support for the EFI
- Real Time Clock.
-diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
-index 70347d0..f1dfc36 100644
---- a/drivers/rtc/Makefile
-+++ b/drivers/rtc/Makefile
-@@ -10,6 +10,10 @@ obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
- obj-$(CONFIG_RTC_CLASS) += rtc-core.o
- rtc-core-y := class.o interface.o
-
-+ifdef CONFIG_RTC_DRV_EFI
-+rtc-core-y += rtc-efi-platform.o
-+endif
-+
- rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
- rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
- rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
-diff --git a/drivers/rtc/rtc-efi-platform.c b/drivers/rtc/rtc-efi-platform.c
-new file mode 100644
-index 0000000..b40fbe3
---- /dev/null
-+++ b/drivers/rtc/rtc-efi-platform.c
-@@ -0,0 +1,31 @@
-+/*
-+ * Moved from arch/ia64/kernel/time.c
-+ *
-+ * Copyright (C) 1998-2003 Hewlett-Packard Co
-+ * Stephane Eranian <eranian@hpl.hp.com>
-+ * David Mosberger <davidm@hpl.hp.com>
-+ * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
-+ * Copyright (C) 1999-2000 VA Linux Systems
-+ * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com>
-+ */
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/efi.h>
-+#include <linux/platform_device.h>
-+
-+static struct platform_device rtc_efi_dev = {
-+ .name = "rtc-efi",
-+ .id = -1,
-+};
-+
-+static int __init rtc_init(void)
-+{
-+ if (efi_enabled(EFI_RUNTIME_SERVICES))
-+ if (platform_device_register(&rtc_efi_dev) < 0)
-+ pr_err("unable to register rtc device...\n");
-+
-+ /* not necessarily an error */
-+ return 0;
-+}
-+module_init(rtc_init);
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 975e1cc..2e2161b 100644
--- a/include/asm-generic/io.h
@@ -5700,184 +4700,8 @@ index 975e1cc..2e2161b 100644
}
static inline void ioport_unmap(void __iomem *p)
-diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
-index f27000f..35b0c12 100644
---- a/include/kvm/arm_vgic.h
-+++ b/include/kvm/arm_vgic.h
-@@ -24,7 +24,6 @@
- #include <linux/irqreturn.h>
- #include <linux/spinlock.h>
- #include <linux/types.h>
--#include <linux/irqchip/arm-gic.h>
-
- #define VGIC_NR_IRQS 256
- #define VGIC_NR_SGIS 16
-@@ -32,7 +31,9 @@
- #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS)
- #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS)
- #define VGIC_MAX_CPUS KVM_MAX_VCPUS
--#define VGIC_MAX_LRS (1 << 6)
-+
-+#define VGIC_V2_MAX_LRS (1 << 6)
-+#define VGIC_V3_MAX_LRS 16
-
- /* Sanity checks... */
- #if (VGIC_MAX_CPUS > 8)
-@@ -68,9 +69,62 @@ struct vgic_bytemap {
- u32 shared[VGIC_NR_SHARED_IRQS / 4];
- };
-
-+struct kvm_vcpu;
-+
-+enum vgic_type {
-+ VGIC_V2, /* Good ol' GICv2 */
-+ VGIC_V3, /* New fancy GICv3 */
-+};
-+
-+#define LR_STATE_PENDING (1 << 0)
-+#define LR_STATE_ACTIVE (1 << 1)
-+#define LR_STATE_MASK (3 << 0)
-+#define LR_EOI_INT (1 << 2)
-+
-+struct vgic_lr {
-+ u16 irq;
-+ u8 source;
-+ u8 state;
-+};
-+
-+struct vgic_vmcr {
-+ u32 ctlr;
-+ u32 abpr;
-+ u32 bpr;
-+ u32 pmr;
-+};
-+
-+struct vgic_ops {
-+ struct vgic_lr (*get_lr)(const struct kvm_vcpu *, int);
-+ void (*set_lr)(struct kvm_vcpu *, int, struct vgic_lr);
-+ void (*sync_lr_elrsr)(struct kvm_vcpu *, int, struct vgic_lr);
-+ u64 (*get_elrsr)(const struct kvm_vcpu *vcpu);
-+ u64 (*get_eisr)(const struct kvm_vcpu *vcpu);
-+ u32 (*get_interrupt_status)(const struct kvm_vcpu *vcpu);
-+ void (*enable_underflow)(struct kvm_vcpu *vcpu);
-+ void (*disable_underflow)(struct kvm_vcpu *vcpu);
-+ void (*get_vmcr)(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
-+ void (*set_vmcr)(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
-+ void (*enable)(struct kvm_vcpu *vcpu);
-+};
-+
-+struct vgic_params {
-+ /* vgic type */
-+ enum vgic_type type;
-+ /* Physical address of vgic virtual cpu interface */
-+ phys_addr_t vcpu_base;
-+ /* Number of list registers */
-+ u32 nr_lr;
-+ /* Interrupt number */
-+ unsigned int maint_irq;
-+ /* Virtual control interface base address */
-+ void __iomem *vctrl_base;
-+};
-+
- struct vgic_dist {
- #ifdef CONFIG_KVM_ARM_VGIC
- spinlock_t lock;
-+ bool in_kernel;
- bool ready;
-
- /* Virtual control interface mapping */
-@@ -110,6 +164,29 @@ struct vgic_dist {
- #endif
- };
-
-+struct vgic_v2_cpu_if {
-+ u32 vgic_hcr;
-+ u32 vgic_vmcr;
-+ u32 vgic_misr; /* Saved only */
-+ u32 vgic_eisr[2]; /* Saved only */
-+ u32 vgic_elrsr[2]; /* Saved only */
-+ u32 vgic_apr;
-+ u32 vgic_lr[VGIC_V2_MAX_LRS];
-+};
-+
-+struct vgic_v3_cpu_if {
-+#ifdef CONFIG_ARM_GIC_V3
-+ u32 vgic_hcr;
-+ u32 vgic_vmcr;
-+ u32 vgic_misr; /* Saved only */
-+ u32 vgic_eisr; /* Saved only */
-+ u32 vgic_elrsr; /* Saved only */
-+ u32 vgic_ap0r[4];
-+ u32 vgic_ap1r[4];
-+ u64 vgic_lr[VGIC_V3_MAX_LRS];
-+#endif
-+};
-+
- struct vgic_cpu {
- #ifdef CONFIG_KVM_ARM_VGIC
- /* per IRQ to LR mapping */
-@@ -120,24 +197,24 @@ struct vgic_cpu {
- DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS);
-
- /* Bitmap of used/free list registers */
-- DECLARE_BITMAP( lr_used, VGIC_MAX_LRS);
-+ DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS);
-
- /* Number of list registers on this CPU */
- int nr_lr;
-
- /* CPU vif control registers for world switch */
-- u32 vgic_hcr;
-- u32 vgic_vmcr;
-- u32 vgic_misr; /* Saved only */
-- u32 vgic_eisr[2]; /* Saved only */
-- u32 vgic_elrsr[2]; /* Saved only */
-- u32 vgic_apr;
-- u32 vgic_lr[VGIC_MAX_LRS];
-+ union {
-+ struct vgic_v2_cpu_if vgic_v2;
-+ struct vgic_v3_cpu_if vgic_v3;
-+ };
- #endif
- };
-
- #define LR_EMPTY 0xff
-
-+#define INT_STATUS_EOI (1 << 0)
-+#define INT_STATUS_UNDERFLOW (1 << 1)
-+
- struct kvm;
- struct kvm_vcpu;
- struct kvm_run;
-@@ -157,9 +234,25 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
- bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
- struct kvm_exit_mmio *mmio);
-
--#define irqchip_in_kernel(k) (!!((k)->arch.vgic.vctrl_base))
-+#define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel))
- #define vgic_initialized(k) ((k)->arch.vgic.ready)
-
-+int vgic_v2_probe(struct device_node *vgic_node,
-+ const struct vgic_ops **ops,
-+ const struct vgic_params **params);
-+#ifdef CONFIG_ARM_GIC_V3
-+int vgic_v3_probe(struct device_node *vgic_node,
-+ const struct vgic_ops **ops,
-+ const struct vgic_params **params);
-+#else
-+static inline int vgic_v3_probe(struct device_node *vgic_node,
-+ const struct vgic_ops **ops,
-+ const struct vgic_params **params)
-+{
-+ return -ENODEV;
-+}
-+#endif
-+
- #else
- static inline int kvm_vgic_hyp_init(void)
- {
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
-index c13b878..33c0420 100644
+index fb7b722..cb9479e4 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -23,17 +23,8 @@ struct of_pci_range {
@@ -5998,1114 +4822,3 @@ index e9441b9..1d3f39c 100644
#define PERF_REG_IP PERF_REG_ARM64_PC
#define PERF_REG_SP PERF_REG_ARM64_SP
-diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
-new file mode 100644
-index 0000000..ff597d8
---- /dev/null
-+++ b/virt/kvm/arm/vgic-v2.c
-@@ -0,0 +1,259 @@
-+/*
-+ * Copyright (C) 2012,2013 ARM Limited, All Rights Reserved.
-+ * Author: Marc Zyngier <marc.zyngier@arm.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 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 <linux/cpu.h>
-+#include <linux/kvm.h>
-+#include <linux/kvm_host.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+
-+#include <linux/irqchip/arm-gic.h>
-+
-+#include <asm/kvm_emulate.h>
-+#include <asm/kvm_arm.h>
-+#include <asm/kvm_mmu.h>
-+
-+static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
-+{
-+ struct vgic_lr lr_desc;
-+ u32 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr];
-+
-+ lr_desc.irq = val & GICH_LR_VIRTUALID;
-+ if (lr_desc.irq <= 15)
-+ lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7;
-+ else
-+ lr_desc.source = 0;
-+ lr_desc.state = 0;
-+
-+ if (val & GICH_LR_PENDING_BIT)
-+ lr_desc.state |= LR_STATE_PENDING;
-+ if (val & GICH_LR_ACTIVE_BIT)
-+ lr_desc.state |= LR_STATE_ACTIVE;
-+ if (val & GICH_LR_EOI)
-+ lr_desc.state |= LR_EOI_INT;
-+
-+ return lr_desc;
-+}
-+
-+static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
-+ struct vgic_lr lr_desc)
-+{
-+ u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq;
-+
-+ if (lr_desc.state & LR_STATE_PENDING)
-+ lr_val |= GICH_LR_PENDING_BIT;
-+ if (lr_desc.state & LR_STATE_ACTIVE)
-+ lr_val |= GICH_LR_ACTIVE_BIT;
-+ if (lr_desc.state & LR_EOI_INT)
-+ lr_val |= GICH_LR_EOI;
-+
-+ vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
-+}
-+
-+static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
-+ struct vgic_lr lr_desc)
-+{
-+ if (!(lr_desc.state & LR_STATE_MASK))
-+ set_bit(lr, (unsigned long *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr);
-+}
-+
-+static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu)
-+{
-+ u64 val;
-+
-+ val = vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[1];
-+ val <<= 32;
-+ val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[0];
-+
-+ return val;
-+}
-+
-+static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu)
-+{
-+ u64 val;
-+
-+ val = vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[1];
-+ val <<= 32;
-+ val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[0];
-+
-+ return val;
-+}
-+
-+static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu)
-+{
-+ u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr;
-+ u32 ret = 0;
-+
-+ if (misr & GICH_MISR_EOI)
-+ ret |= INT_STATUS_EOI;
-+ if (misr & GICH_MISR_U)
-+ ret |= INT_STATUS_UNDERFLOW;
-+
-+ return ret;
-+}
-+
-+static void vgic_v2_enable_underflow(struct kvm_vcpu *vcpu)
-+{
-+ vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr |= GICH_HCR_UIE;
-+}
-+
-+static void vgic_v2_disable_underflow(struct kvm_vcpu *vcpu)
-+{
-+ vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr &= ~GICH_HCR_UIE;
-+}
-+
-+static void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
-+{
-+ u32 vmcr = vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr;
-+
-+ vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >> GICH_VMCR_CTRL_SHIFT;
-+ vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> GICH_VMCR_ALIAS_BINPOINT_SHIFT;
-+ vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> GICH_VMCR_BINPOINT_SHIFT;
-+ vmcrp->pmr = (vmcr & GICH_VMCR_PRIMASK_MASK) >> GICH_VMCR_PRIMASK_SHIFT;
-+}
-+
-+static void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
-+{
-+ u32 vmcr;
-+
-+ vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK;
-+ vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & GICH_VMCR_ALIAS_BINPOINT_MASK;
-+ vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & GICH_VMCR_BINPOINT_MASK;
-+ vmcr |= (vmcrp->pmr << GICH_VMCR_PRIMASK_SHIFT) & GICH_VMCR_PRIMASK_MASK;
-+
-+ vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = vmcr;
-+}
-+
-+static void vgic_v2_enable(struct kvm_vcpu *vcpu)
-+{
-+ /*
-+ * By forcing VMCR to zero, the GIC will restore the binary
-+ * points to their reset values. Anything else resets to zero
-+ * anyway.
-+ */
-+ vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
-+
-+ /* Get the show on the road... */
-+ vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
-+}
-+
-+static const struct vgic_ops vgic_v2_ops = {
-+ .get_lr = vgic_v2_get_lr,
-+ .set_lr = vgic_v2_set_lr,
-+ .sync_lr_elrsr = vgic_v2_sync_lr_elrsr,
-+ .get_elrsr = vgic_v2_get_elrsr,
-+ .get_eisr = vgic_v2_get_eisr,
-+ .get_interrupt_status = vgic_v2_get_interrupt_status,
-+ .enable_underflow = vgic_v2_enable_underflow,
-+ .disable_underflow = vgic_v2_disable_underflow,
-+ .get_vmcr = vgic_v2_get_vmcr,
-+ .set_vmcr = vgic_v2_set_vmcr,
-+ .enable = vgic_v2_enable,
-+};
-+
-+static struct vgic_params vgic_v2_params;
-+
-+/**
-+ * vgic_v2_probe - probe for a GICv2 compatible interrupt controller in DT
-+ * @node: pointer to the DT node
-+ * @ops: address of a pointer to the GICv2 operations
-+ * @params: address of a pointer to HW-specific parameters
-+ *
-+ * Returns 0 if a GICv2 has been found, with the low level operations
-+ * in *ops and the HW parameters in *params. Returns an error code
-+ * otherwise.
-+ */
-+int vgic_v2_probe(struct device_node *vgic_node,
-+ const struct vgic_ops **ops,
-+ const struct vgic_params **params)
-+{
-+ int ret;
-+ struct resource vctrl_res;
-+ struct resource vcpu_res;
-+ struct vgic_params *vgic = &vgic_v2_params;
-+
-+ vgic->maint_irq = irq_of_parse_and_map(vgic_node, 0);
-+ if (!vgic->maint_irq) {
-+ kvm_err("error getting vgic maintenance irq from DT\n");
-+ ret = -ENXIO;
-+ goto out;
-+ }
-+
-+ ret = of_address_to_resource(vgic_node, 2, &vctrl_res);
-+ if (ret) {
-+ kvm_err("Cannot obtain GICH resource\n");
-+ goto out;
-+ }
-+
-+ vgic->vctrl_base = of_iomap(vgic_node, 2);
-+ if (!vgic->vctrl_base) {
-+ kvm_err("Cannot ioremap GICH\n");
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ vgic->nr_lr = readl_relaxed(vgic->vctrl_base + GICH_VTR);
-+ vgic->nr_lr = (vgic->nr_lr & 0x3f) + 1;
-+
-+ ret = create_hyp_io_mappings(vgic->vctrl_base,
-+ vgic->vctrl_base + resource_size(&vctrl_res),
-+ vctrl_res.start);
-+ if (ret) {
-+ kvm_err("Cannot map VCTRL into hyp\n");
-+ goto out_unmap;
-+ }
-+
-+ if (of_address_to_resource(vgic_node, 3, &vcpu_res)) {
-+ kvm_err("Cannot obtain GICV resource\n");
-+ ret = -ENXIO;
-+ goto out_unmap;
-+ }
-+
-+ if (!PAGE_ALIGNED(vcpu_res.start)) {
-+ kvm_err("GICV physical address 0x%llx not page aligned\n",
-+ (unsigned long long)vcpu_res.start);
-+ ret = -ENXIO;
-+ goto out_unmap;
-+ }
-+
-+ if (!PAGE_ALIGNED(resource_size(&vcpu_res))) {
-+ kvm_err("GICV size 0x%llx not a multiple of page size 0x%lx\n",
-+ (unsigned long long)resource_size(&vcpu_res),
-+ PAGE_SIZE);
-+ ret = -ENXIO;
-+ goto out_unmap;
-+ }
-+
-+ vgic->vcpu_base = vcpu_res.start;
-+
-+ kvm_info("%s@%llx IRQ%d\n", vgic_node->name,
-+ vgic->vctrl_base, vgic->maint_irq);
-+
-+ vgic->type = VGIC_V2;
-+ *ops = &vgic_v2_ops;
-+ *params = vgic;
-+ goto out;
-+
-+out_unmap:
-+ iounmap(vgic->vctrl_base);
-+out:
-+ of_node_put(vgic_node);
-+ return ret;
-+}
-diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
-new file mode 100644
-index 0000000..f01d446
---- /dev/null
-+++ b/virt/kvm/arm/vgic-v3.c
-@@ -0,0 +1,231 @@
-+/*
-+ * Copyright (C) 2013 ARM Limited, All Rights Reserved.
-+ * Author: Marc Zyngier <marc.zyngier@arm.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 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 <linux/cpu.h>
-+#include <linux/kvm.h>
-+#include <linux/kvm_host.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+
-+#include <linux/irqchip/arm-gic-v3.h>
-+
-+#include <asm/kvm_emulate.h>
-+#include <asm/kvm_arm.h>
-+#include <asm/kvm_mmu.h>
-+
-+/* These are for GICv2 emulation only */
-+#define GICH_LR_VIRTUALID (0x3ffUL << 0)
-+#define GICH_LR_PHYSID_CPUID_SHIFT (10)
-+#define GICH_LR_PHYSID_CPUID (7UL << GICH_LR_PHYSID_CPUID_SHIFT)
-+
-+/*
-+ * LRs are stored in reverse order in memory. make sure we index them
-+ * correctly.
-+ */
-+#define LR_INDEX(lr) (VGIC_V3_MAX_LRS - 1 - lr)
-+
-+static u32 ich_vtr_el2;
-+
-+static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu *vcpu, int lr)
-+{
-+ struct vgic_lr lr_desc;
-+ u64 val = vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)];
-+
-+ lr_desc.irq = val & GICH_LR_VIRTUALID;
-+ if (lr_desc.irq <= 15)
-+ lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7;
-+ else
-+ lr_desc.source = 0;
-+ lr_desc.state = 0;
-+
-+ if (val & ICH_LR_PENDING_BIT)
-+ lr_desc.state |= LR_STATE_PENDING;
-+ if (val & ICH_LR_ACTIVE_BIT)
-+ lr_desc.state |= LR_STATE_ACTIVE;
-+ if (val & ICH_LR_EOI)
-+ lr_desc.state |= LR_EOI_INT;
-+
-+ return lr_desc;
-+}
-+
-+static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
-+ struct vgic_lr lr_desc)
-+{
-+ u64 lr_val = (((u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) |
-+ lr_desc.irq);
-+
-+ if (lr_desc.state & LR_STATE_PENDING)
-+ lr_val |= ICH_LR_PENDING_BIT;
-+ if (lr_desc.state & LR_STATE_ACTIVE)
-+ lr_val |= ICH_LR_ACTIVE_BIT;
-+ if (lr_desc.state & LR_EOI_INT)
-+ lr_val |= ICH_LR_EOI;
-+
-+ vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)] = lr_val;
-+}
-+
-+static void vgic_v3_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
-+ struct vgic_lr lr_desc)
-+{
-+ if (!(lr_desc.state & LR_STATE_MASK))
-+ vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr |= (1U << lr);
-+}
-+
-+static u64 vgic_v3_get_elrsr(const struct kvm_vcpu *vcpu)
-+{
-+ return vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr;
-+}
-+
-+static u64 vgic_v3_get_eisr(const struct kvm_vcpu *vcpu)
-+{
-+ return vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr;
-+}
-+
-+static u32 vgic_v3_get_interrupt_status(const struct kvm_vcpu *vcpu)
-+{
-+ u32 misr = vcpu->arch.vgic_cpu.vgic_v3.vgic_misr;
-+ u32 ret = 0;
-+
-+ if (misr & ICH_MISR_EOI)
-+ ret |= INT_STATUS_EOI;
-+ if (misr & ICH_MISR_U)
-+ ret |= INT_STATUS_UNDERFLOW;
-+
-+ return ret;
-+}
-+
-+static void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
-+{
-+ u32 vmcr = vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr;
-+
-+ vmcrp->ctlr = (vmcr & ICH_VMCR_CTLR_MASK) >> ICH_VMCR_CTLR_SHIFT;
-+ vmcrp->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT;
-+ vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT;
-+ vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT;
-+}
-+
-+static void vgic_v3_enable_underflow(struct kvm_vcpu *vcpu)
-+{
-+ vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr |= ICH_HCR_UIE;
-+}
-+
-+static void vgic_v3_disable_underflow(struct kvm_vcpu *vcpu)
-+{
-+ vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr &= ~ICH_HCR_UIE;
-+}
-+
-+static void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
-+{
-+ u32 vmcr;
-+
-+ vmcr = (vmcrp->ctlr << ICH_VMCR_CTLR_SHIFT) & ICH_VMCR_CTLR_MASK;
-+ vmcr |= (vmcrp->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK;
-+ vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_MASK;
-+ vmcr |= (vmcrp->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK;
-+
-+ vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr = vmcr;
-+}
-+
-+static void vgic_v3_enable(struct kvm_vcpu *vcpu)
-+{
-+ /*
-+ * By forcing VMCR to zero, the GIC will restore the binary
-+ * points to their reset values. Anything else resets to zero
-+ * anyway.
-+ */
-+ vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr = 0;
-+
-+ /* Get the show on the road... */
-+ vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr = ICH_HCR_EN;
-+}
-+
-+static const struct vgic_ops vgic_v3_ops = {
-+ .get_lr = vgic_v3_get_lr,
-+ .set_lr = vgic_v3_set_lr,
-+ .sync_lr_elrsr = vgic_v3_sync_lr_elrsr,
-+ .get_elrsr = vgic_v3_get_elrsr,
-+ .get_eisr = vgic_v3_get_eisr,
-+ .get_interrupt_status = vgic_v3_get_interrupt_status,
-+ .enable_underflow = vgic_v3_enable_underflow,
-+ .disable_underflow = vgic_v3_disable_underflow,
-+ .get_vmcr = vgic_v3_get_vmcr,
-+ .set_vmcr = vgic_v3_set_vmcr,
-+ .enable = vgic_v3_enable,
-+};
-+
-+static struct vgic_params vgic_v3_params;
-+
-+/**
-+ * vgic_v3_probe - probe for a GICv3 compatible interrupt controller in DT
-+ * @node: pointer to the DT node
-+ * @ops: address of a pointer to the GICv3 operations
-+ * @params: address of a pointer to HW-specific parameters
-+ *
-+ * Returns 0 if a GICv3 has been found, with the low level operations
-+ * in *ops and the HW parameters in *params. Returns an error code
-+ * otherwise.
-+ */
-+int vgic_v3_probe(struct device_node *vgic_node,
-+ const struct vgic_ops **ops,
-+ const struct vgic_params **params)
-+{
-+ int ret = 0;
-+ u32 gicv_idx;
-+ struct resource vcpu_res;
-+ struct vgic_params *vgic = &vgic_v3_params;
-+
-+ vgic->maint_irq = irq_of_parse_and_map(vgic_node, 0);
-+ if (!vgic->maint_irq) {
-+ kvm_err("error getting vgic maintenance irq from DT\n");
-+ ret = -ENXIO;
-+ goto out;
-+ }
-+
-+ ich_vtr_el2 = kvm_call_hyp(__vgic_v3_get_ich_vtr_el2);
-+
-+ /*
-+ * The ListRegs field is 5 bits, but there is a architectural
-+ * maximum of 16 list registers. Just ignore bit 4...
-+ */
-+ vgic->nr_lr = (ich_vtr_el2 & 0xf) + 1;
-+
-+ if (of_property_read_u32(vgic_node, "#redistributor-regions", &gicv_idx))
-+ gicv_idx = 1;
-+
-+ gicv_idx += 3; /* Also skip GICD, GICC, GICH */
-+ if (of_address_to_resource(vgic_node, gicv_idx, &vcpu_res)) {
-+ kvm_err("Cannot obtain GICV region\n");
-+ ret = -ENXIO;
-+ goto out;
-+ }
-+ vgic->vcpu_base = vcpu_res.start;
-+ vgic->vctrl_base = NULL;
-+ vgic->type = VGIC_V3;
-+
-+ kvm_info("%s@%llx IRQ%d\n", vgic_node->name,
-+ vcpu_res.start, vgic->maint_irq);
-+
-+ *ops = &vgic_v3_ops;
-+ *params = vgic;
-+
-+out:
-+ of_node_put(vgic_node);
-+ return ret;
-+}
-diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
-index 476d3bf..795ab48 100644
---- a/virt/kvm/arm/vgic.c
-+++ b/virt/kvm/arm/vgic.c
-@@ -76,14 +76,6 @@
- #define IMPLEMENTER_ARM 0x43b
- #define GICC_ARCH_VERSION_V2 0x2
-
--/* Physical address of vgic virtual cpu interface */
--static phys_addr_t vgic_vcpu_base;
--
--/* Virtual control interface base address */
--static void __iomem *vgic_vctrl_base;
--
--static struct device_node *vgic_node;
--
- #define ACCESS_READ_VALUE (1 << 0)
- #define ACCESS_READ_RAZ (0 << 0)
- #define ACCESS_READ_MASK(x) ((x) & (1 << 0))
-@@ -94,12 +86,17 @@ static struct device_node *vgic_node;
- #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1))
-
- static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
-+static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
- static void vgic_update_state(struct kvm *kvm);
- static void vgic_kick_vcpus(struct kvm *kvm);
- static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg);
--static u32 vgic_nr_lr;
-+static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
-+static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
-+static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
-+static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
-
--static unsigned int vgic_maint_irq;
-+static const struct vgic_ops *vgic_ops;
-+static const struct vgic_params *vgic;
-
- static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x,
- int cpuid, u32 offset)
-@@ -593,18 +590,6 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu,
- return false;
- }
-
--#define LR_CPUID(lr) \
-- (((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT)
--#define LR_IRQID(lr) \
-- ((lr) & GICH_LR_VIRTUALID)
--
--static void vgic_retire_lr(int lr_nr, int irq, struct vgic_cpu *vgic_cpu)
--{
-- clear_bit(lr_nr, vgic_cpu->lr_used);
-- vgic_cpu->vgic_lr[lr_nr] &= ~GICH_LR_STATE;
-- vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
--}
--
- /**
- * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor
- * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
-@@ -622,13 +607,10 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
- struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
- int vcpu_id = vcpu->vcpu_id;
-- int i, irq, source_cpu;
-- u32 *lr;
-+ int i;
-
- for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
-- lr = &vgic_cpu->vgic_lr[i];
-- irq = LR_IRQID(*lr);
-- source_cpu = LR_CPUID(*lr);
-+ struct vgic_lr lr = vgic_get_lr(vcpu, i);
-
- /*
- * There are three options for the state bits:
-@@ -640,7 +622,7 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
- * If the LR holds only an active interrupt (not pending) then
- * just leave it alone.
- */
-- if ((*lr & GICH_LR_STATE) == GICH_LR_ACTIVE_BIT)
-+ if ((lr.state & LR_STATE_MASK) == LR_STATE_ACTIVE)
- continue;
-
- /*
-@@ -649,18 +631,19 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
- * is fine, then we are only setting a few bits that were
- * already set.
- */
-- vgic_dist_irq_set(vcpu, irq);
-- if (irq < VGIC_NR_SGIS)
-- dist->irq_sgi_sources[vcpu_id][irq] |= 1 << source_cpu;
-- *lr &= ~GICH_LR_PENDING_BIT;
-+ vgic_dist_irq_set(vcpu, lr.irq);
-+ if (lr.irq < VGIC_NR_SGIS)
-+ dist->irq_sgi_sources[vcpu_id][lr.irq] |= 1 << lr.source;
-+ lr.state &= ~LR_STATE_PENDING;
-+ vgic_set_lr(vcpu, i, lr);
-
- /*
- * If there's no state left on the LR (it could still be
- * active), then the LR does not hold any useful info and can
- * be marked as free for other use.
- */
-- if (!(*lr & GICH_LR_STATE))
-- vgic_retire_lr(i, irq, vgic_cpu);
-+ if (!(lr.state & LR_STATE_MASK))
-+ vgic_retire_lr(i, lr.irq, vcpu);
-
- /* Finally update the VGIC state. */
- vgic_update_state(vcpu->kvm);
-@@ -989,8 +972,73 @@ static void vgic_update_state(struct kvm *kvm)
- }
- }
-
--#define MK_LR_PEND(src, irq) \
-- (GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq))
-+static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr)
-+{
-+ return vgic_ops->get_lr(vcpu, lr);
-+}
-+
-+static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr,
-+ struct vgic_lr vlr)
-+{
-+ vgic_ops->set_lr(vcpu, lr, vlr);
-+}
-+
-+static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
-+ struct vgic_lr vlr)
-+{
-+ vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
-+}
-+
-+static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
-+{
-+ return vgic_ops->get_elrsr(vcpu);
-+}
-+
-+static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu)
-+{
-+ return vgic_ops->get_eisr(vcpu);
-+}
-+
-+static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu)
-+{
-+ return vgic_ops->get_interrupt_status(vcpu);
-+}
-+
-+static inline void vgic_enable_underflow(struct kvm_vcpu *vcpu)
-+{
-+ vgic_ops->enable_underflow(vcpu);
-+}
-+
-+static inline void vgic_disable_underflow(struct kvm_vcpu *vcpu)
-+{
-+ vgic_ops->disable_underflow(vcpu);
-+}
-+
-+static inline void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-+{
-+ vgic_ops->get_vmcr(vcpu, vmcr);
-+}
-+
-+static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-+{
-+ vgic_ops->set_vmcr(vcpu, vmcr);
-+}
-+
-+static inline void vgic_enable(struct kvm_vcpu *vcpu)
-+{
-+ vgic_ops->enable(vcpu);
-+}
-+
-+static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
-+{
-+ struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-+ struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
-+
-+ vlr.state = 0;
-+ vgic_set_lr(vcpu, lr_nr, vlr);
-+ clear_bit(lr_nr, vgic_cpu->lr_used);
-+ vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
-+}
-
- /*
- * An interrupt may have been disabled after being made pending on the
-@@ -1006,13 +1054,13 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
- int lr;
-
-- for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
-- int irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
-+ for_each_set_bit(lr, vgic_cpu->lr_used, vgic->nr_lr) {
-+ struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
-
-- if (!vgic_irq_is_enabled(vcpu, irq)) {
-- vgic_retire_lr(lr, irq, vgic_cpu);
-- if (vgic_irq_is_active(vcpu, irq))
-- vgic_irq_clear_active(vcpu, irq);
-+ if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
-+ vgic_retire_lr(lr, vlr.irq, vcpu);
-+ if (vgic_irq_is_active(vcpu, vlr.irq))
-+ vgic_irq_clear_active(vcpu, vlr.irq);
- }
- }
- }
-@@ -1024,6 +1072,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
- static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
- {
- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-+ struct vgic_lr vlr;
- int lr;
-
- /* Sanitize the input... */
-@@ -1036,28 +1085,34 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
- lr = vgic_cpu->vgic_irq_lr_map[irq];
-
- /* Do we have an active interrupt for the same CPUID? */
-- if (lr != LR_EMPTY &&
-- (LR_CPUID(vgic_cpu->vgic_lr[lr]) == sgi_source_id)) {
-- kvm_debug("LR%d piggyback for IRQ%d %x\n",
-- lr, irq, vgic_cpu->vgic_lr[lr]);
-- BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
-- vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT;
-- return true;
-+ if (lr != LR_EMPTY) {
-+ vlr = vgic_get_lr(vcpu, lr);
-+ if (vlr.source == sgi_source_id) {
-+ kvm_debug("LR%d piggyback for IRQ%d\n", lr, vlr.irq);
-+ BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
-+ vlr.state |= LR_STATE_PENDING;
-+ vgic_set_lr(vcpu, lr, vlr);
-+ return true;
-+ }
- }
-
- /* Try to use another LR for this interrupt */
- lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used,
-- vgic_cpu->nr_lr);
-- if (lr >= vgic_cpu->nr_lr)
-+ vgic->nr_lr);
-+ if (lr >= vgic->nr_lr)
- return false;
-
- kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
-- vgic_cpu->vgic_lr[lr] = MK_LR_PEND(sgi_source_id, irq);
- vgic_cpu->vgic_irq_lr_map[irq] = lr;
- set_bit(lr, vgic_cpu->lr_used);
-
-+ vlr.irq = irq;
-+ vlr.source = sgi_source_id;
-+ vlr.state = LR_STATE_PENDING;
- if (!vgic_irq_is_edge(vcpu, irq))
-- vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI;
-+ vlr.state |= LR_EOI_INT;
-+
-+ vgic_set_lr(vcpu, lr, vlr);
-
- return true;
- }
-@@ -1155,9 +1210,9 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
-
- epilog:
- if (overflow) {
-- vgic_cpu->vgic_hcr |= GICH_HCR_UIE;
-+ vgic_enable_underflow(vcpu);
- } else {
-- vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE;
-+ vgic_disable_underflow(vcpu);
- /*
- * We're about to run this VCPU, and we've consumed
- * everything the distributor had in store for
-@@ -1170,44 +1225,46 @@ epilog:
-
- static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
- {
-- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-+ u32 status = vgic_get_interrupt_status(vcpu);
- bool level_pending = false;
-
-- kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr);
-+ kvm_debug("STATUS = %08x\n", status);
-
-- if (vgic_cpu->vgic_misr & GICH_MISR_EOI) {
-+ if (status & INT_STATUS_EOI) {
- /*
- * Some level interrupts have been EOIed. Clear their
- * active bit.
- */
-- int lr, irq;
-+ u64 eisr = vgic_get_eisr(vcpu);
-+ unsigned long *eisr_ptr = (unsigned long *)&eisr;
-+ int lr;
-
-- for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_eisr,
-- vgic_cpu->nr_lr) {
-- irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
-+ for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) {
-+ struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
-
-- vgic_irq_clear_active(vcpu, irq);
-- vgic_cpu->vgic_lr[lr] &= ~GICH_LR_EOI;
-+ vgic_irq_clear_active(vcpu, vlr.irq);
-+ WARN_ON(vlr.state & LR_STATE_MASK);
-+ vlr.state = 0;
-+ vgic_set_lr(vcpu, lr, vlr);
-
- /* Any additional pending interrupt? */
-- if (vgic_dist_irq_is_pending(vcpu, irq)) {
-- vgic_cpu_irq_set(vcpu, irq);
-+ if (vgic_dist_irq_is_pending(vcpu, vlr.irq)) {
-+ vgic_cpu_irq_set(vcpu, vlr.irq);
- level_pending = true;
- } else {
-- vgic_cpu_irq_clear(vcpu, irq);
-+ vgic_cpu_irq_clear(vcpu, vlr.irq);
- }
-
- /*
- * Despite being EOIed, the LR may not have
- * been marked as empty.
- */
-- set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr);
-- vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT;
-+ vgic_sync_lr_elrsr(vcpu, lr, vlr);
- }
- }
-
-- if (vgic_cpu->vgic_misr & GICH_MISR_U)
-- vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE;
-+ if (status & INT_STATUS_UNDERFLOW)
-+ vgic_disable_underflow(vcpu);
-
- return level_pending;
- }
-@@ -1220,29 +1277,31 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
- {
- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
- struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-+ u64 elrsr;
-+ unsigned long *elrsr_ptr;
- int lr, pending;
- bool level_pending;
-
- level_pending = vgic_process_maintenance(vcpu);
-+ elrsr = vgic_get_elrsr(vcpu);
-+ elrsr_ptr = (unsigned long *)&elrsr;
-
- /* Clear mappings for empty LRs */
-- for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr,
-- vgic_cpu->nr_lr) {
-- int irq;
-+ for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) {
-+ struct vgic_lr vlr;
-
- if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
- continue;
-
-- irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
-+ vlr = vgic_get_lr(vcpu, lr);
-
-- BUG_ON(irq >= VGIC_NR_IRQS);
-- vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
-+ BUG_ON(vlr.irq >= VGIC_NR_IRQS);
-+ vgic_cpu->vgic_irq_lr_map[vlr.irq] = LR_EMPTY;
- }
-
- /* Check if we still have something up our sleeve... */
-- pending = find_first_zero_bit((unsigned long *)vgic_cpu->vgic_elrsr,
-- vgic_cpu->nr_lr);
-- if (level_pending || pending < vgic_cpu->nr_lr)
-+ pending = find_first_zero_bit(elrsr_ptr, vgic->nr_lr);
-+ if (level_pending || pending < vgic->nr_lr)
- set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu);
- }
-
-@@ -1432,21 +1491,20 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
- }
-
- /*
-- * By forcing VMCR to zero, the GIC will restore the binary
-- * points to their reset values. Anything else resets to zero
-- * anyway.
-+ * Store the number of LRs per vcpu, so we don't have to go
-+ * all the way to the distributor structure to find out. Only
-+ * assembly code should use this one.
- */
-- vgic_cpu->vgic_vmcr = 0;
-+ vgic_cpu->nr_lr = vgic->nr_lr;
-
-- vgic_cpu->nr_lr = vgic_nr_lr;
-- vgic_cpu->vgic_hcr = GICH_HCR_EN; /* Get the show on the road... */
-+ vgic_enable(vcpu);
-
- return 0;
- }
-
- static void vgic_init_maintenance_interrupt(void *info)
- {
-- enable_percpu_irq(vgic_maint_irq, 0);
-+ enable_percpu_irq(vgic->maint_irq, 0);
- }
-
- static int vgic_cpu_notify(struct notifier_block *self,
-@@ -1459,7 +1517,7 @@ static int vgic_cpu_notify(struct notifier_block *self,
- break;
- case CPU_DYING:
- case CPU_DYING_FROZEN:
-- disable_percpu_irq(vgic_maint_irq);
-+ disable_percpu_irq(vgic->maint_irq);
- break;
- }
-
-@@ -1470,30 +1528,37 @@ static struct notifier_block vgic_cpu_nb = {
- .notifier_call = vgic_cpu_notify,
- };
-
-+static const struct of_device_id vgic_ids[] = {
-+ { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, },
-+ { .compatible = "arm,gic-v3", .data = vgic_v3_probe, },
-+ {},
-+};
-+
- int kvm_vgic_hyp_init(void)
- {
-+ const struct of_device_id *matched_id;
-+ int (*vgic_probe)(struct device_node *,const struct vgic_ops **,
-+ const struct vgic_params **);
-+ struct device_node *vgic_node;
- int ret;
-- struct resource vctrl_res;
-- struct resource vcpu_res;
-
-- vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic");
-+ vgic_node = of_find_matching_node_and_match(NULL,
-+ vgic_ids, &matched_id);
- if (!vgic_node) {
-- kvm_err("error: no compatible vgic node in DT\n");
-+ kvm_err("error: no compatible GIC node found\n");
- return -ENODEV;
- }
-
-- vgic_maint_irq = irq_of_parse_and_map(vgic_node, 0);
-- if (!vgic_maint_irq) {
-- kvm_err("error getting vgic maintenance irq from DT\n");
-- ret = -ENXIO;
-- goto out;
-- }
-+ vgic_probe = matched_id->data;
-+ ret = vgic_probe(vgic_node, &vgic_ops, &vgic);
-+ if (ret)
-+ return ret;
-
-- ret = request_percpu_irq(vgic_maint_irq, vgic_maintenance_handler,
-+ ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler,
- "vgic", kvm_get_running_vcpus());
- if (ret) {
-- kvm_err("Cannot register interrupt %d\n", vgic_maint_irq);
-- goto out;
-+ kvm_err("Cannot register interrupt %d\n", vgic->maint_irq);
-+ return ret;
- }
-
- ret = __register_cpu_notifier(&vgic_cpu_nb);
-@@ -1502,65 +1567,15 @@ int kvm_vgic_hyp_init(void)
- goto out_free_irq;
- }
-
-- ret = of_address_to_resource(vgic_node, 2, &vctrl_res);
-- if (ret) {
-- kvm_err("Cannot obtain VCTRL resource\n");
-- goto out_free_irq;
-- }
--
-- vgic_vctrl_base = of_iomap(vgic_node, 2);
-- if (!vgic_vctrl_base) {
-- kvm_err("Cannot ioremap VCTRL\n");
-- ret = -ENOMEM;
-- goto out_free_irq;
-- }
--
-- vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR);
-- vgic_nr_lr = (vgic_nr_lr & 0x3f) + 1;
--
-- ret = create_hyp_io_mappings(vgic_vctrl_base,
-- vgic_vctrl_base + resource_size(&vctrl_res),
-- vctrl_res.start);
-- if (ret) {
-- kvm_err("Cannot map VCTRL into hyp\n");
-- goto out_unmap;
-- }
--
-- if (of_address_to_resource(vgic_node, 3, &vcpu_res)) {
-- kvm_err("Cannot obtain VCPU resource\n");
-- ret = -ENXIO;
-- goto out_unmap;
-- }
--
-- if (!PAGE_ALIGNED(vcpu_res.start)) {
-- kvm_err("GICV physical address 0x%llx not page aligned\n",
-- (unsigned long long)vcpu_res.start);
-- ret = -ENXIO;
-- goto out_unmap;
-- }
--
-- if (!PAGE_ALIGNED(resource_size(&vcpu_res))) {
-- kvm_err("GICV size 0x%llx not a multiple of page size 0x%lx\n",
-- (unsigned long long)resource_size(&vcpu_res),
-- PAGE_SIZE);
-- ret = -ENXIO;
-- goto out_unmap;
-- }
--
-- vgic_vcpu_base = vcpu_res.start;
--
-- kvm_info("%s@%llx IRQ%d\n", vgic_node->name,
-- vctrl_res.start, vgic_maint_irq);
- on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1);
-
-- goto out;
-+ /* Callback into for arch code for setup */
-+ vgic_arch_setup(vgic);
-+
-+ return 0;
-
--out_unmap:
-- iounmap(vgic_vctrl_base);
- out_free_irq:
-- free_percpu_irq(vgic_maint_irq, kvm_get_running_vcpus());
--out:
-- of_node_put(vgic_node);
-+ free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus());
- return ret;
- }
-
-@@ -1593,7 +1608,7 @@ int kvm_vgic_init(struct kvm *kvm)
- }
-
- ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base,
-- vgic_vcpu_base, KVM_VGIC_V2_CPU_SIZE);
-+ vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE);
- if (ret) {
- kvm_err("Unable to remap VGIC CPU to VCPU\n");
- goto out;
-@@ -1639,7 +1654,8 @@ int kvm_vgic_create(struct kvm *kvm)
- }
-
- spin_lock_init(&kvm->arch.vgic.lock);
-- kvm->arch.vgic.vctrl_base = vgic_vctrl_base;
-+ kvm->arch.vgic.in_kernel = true;
-+ kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
- kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
- kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
-
-@@ -1738,39 +1754,40 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
- static bool handle_cpu_mmio_misc(struct kvm_vcpu *vcpu,
- struct kvm_exit_mmio *mmio, phys_addr_t offset)
- {
-- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-- u32 reg, mask = 0, shift = 0;
- bool updated = false;
-+ struct vgic_vmcr vmcr;
-+ u32 *vmcr_field;
-+ u32 reg;
-+
-+ vgic_get_vmcr(vcpu, &vmcr);
-
- switch (offset & ~0x3) {
- case GIC_CPU_CTRL:
-- mask = GICH_VMCR_CTRL_MASK;
-- shift = GICH_VMCR_CTRL_SHIFT;
-+ vmcr_field = &vmcr.ctlr;
- break;
- case GIC_CPU_PRIMASK:
-- mask = GICH_VMCR_PRIMASK_MASK;
-- shift = GICH_VMCR_PRIMASK_SHIFT;
-+ vmcr_field = &vmcr.pmr;
- break;
- case GIC_CPU_BINPOINT:
-- mask = GICH_VMCR_BINPOINT_MASK;
-- shift = GICH_VMCR_BINPOINT_SHIFT;
-+ vmcr_field = &vmcr.bpr;
- break;
- case GIC_CPU_ALIAS_BINPOINT:
-- mask = GICH_VMCR_ALIAS_BINPOINT_MASK;
-- shift = GICH_VMCR_ALIAS_BINPOINT_SHIFT;
-+ vmcr_field = &vmcr.abpr;
- break;
-+ default:
-+ BUG();
- }
-
- if (!mmio->is_write) {
-- reg = (vgic_cpu->vgic_vmcr & mask) >> shift;
-+ reg = *vmcr_field;
- mmio_data_write(mmio, ~0, reg);
- } else {
- reg = mmio_data_read(mmio, ~0);
-- reg = (reg << shift) & mask;
-- if (reg != (vgic_cpu->vgic_vmcr & mask))
-+ if (reg != *vmcr_field) {
-+ *vmcr_field = reg;
-+ vgic_set_vmcr(vcpu, &vmcr);
- updated = true;
-- vgic_cpu->vgic_vmcr &= ~mask;
-- vgic_cpu->vgic_vmcr |= reg;
-+ }
- }
- return updated;
- }
diff --git a/kernel.spec b/kernel.spec
index 6396d15df..087058fb4 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -8,7 +8,7 @@ Summary: The Linux kernel
# be 0.
%global released_kernel 0
-%global aarch64patches 0
+%global aarch64patches 1
# Sign modules on x86. Make sure the config files match this setting if more
# architectures are added.
@@ -2240,6 +2240,9 @@ fi
# ||----w |
# || ||
%changelog
+* Tue Aug 12 2014 Kyle McMartin <kyle@fedoraproject.org>
+- kernel-arm64.patch: fix up merge conflict and re-enable
+
* Tue Aug 12 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.17.0-0.rc0.git4.1
- Linux v3.16-10473-gc8d6637d0497