linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: cdall@cs.columbia.edu (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 19/32] arm64: KVM: Plug the VGIC
Date: Tue, 23 Apr 2013 16:00:12 -0700	[thread overview]
Message-ID: <20130423230012.GG20569@gmail.com> (raw)
In-Reply-To: <1365437854-30214-20-git-send-email-marc.zyngier@arm.com>

On Mon, Apr 08, 2013 at 05:17:21PM +0100, Marc Zyngier wrote:
> Add support for the in-kernel GIC emulation. The include file
> is a complete duplicate of the 32bit one - something to fix
> at one point.

seems like something that should be fixed sooner as opposed to later...
Is it hard?

> 
> Reviewed-by: Christopher Covington <cov@codeaurora.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/include/asm/kvm_vgic.h | 156 ++++++++++++++++++++++++++++++++++++++
>  arch/arm64/kvm/hyp.S              |  88 +++++++++++++++++++++
>  2 files changed, 244 insertions(+)
>  create mode 100644 arch/arm64/include/asm/kvm_vgic.h
> 
> diff --git a/arch/arm64/include/asm/kvm_vgic.h b/arch/arm64/include/asm/kvm_vgic.h
> new file mode 100644
> index 0000000..f353f22
> --- /dev/null
> +++ b/arch/arm64/include/asm/kvm_vgic.h
> @@ -0,0 +1,156 @@
> +/*
> + * Copyright (C) 2012 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/>.
> + */
> +
> +#ifndef __ARM64_KVM_VGIC_H
> +#define __ARM64_KVM_VGIC_H
> +
> +#include <linux/kernel.h>
> +#include <linux/kvm.h>
> +#include <linux/irqreturn.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>
> +#include <linux/irqchip/arm-gic.h>
> +
> +#define VGIC_NR_IRQS		128
> +#define VGIC_NR_SGIS		16
> +#define VGIC_NR_PPIS		16
> +#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
> +
> +/* Sanity checks... */
> +#if (VGIC_MAX_CPUS > 8)
> +#error	Invalid number of CPU interfaces
> +#endif
> +
> +#if (VGIC_NR_IRQS & 31)
> +#error "VGIC_NR_IRQS must be a multiple of 32"
> +#endif
> +
> +#if (VGIC_NR_IRQS > 1024)
> +#error "VGIC_NR_IRQS must be <= 1024"
> +#endif
> +
> +/*
> + * The GIC distributor registers describing interrupts have two parts:
> + * - 32 per-CPU interrupts (SGI + PPI)
> + * - a bunch of shared interrupts (SPI)
> + */
> +struct vgic_bitmap {
> +	union {
> +		u32 reg[VGIC_NR_PRIVATE_IRQS / 32];
> +		DECLARE_BITMAP(reg_ul, VGIC_NR_PRIVATE_IRQS);
> +	} percpu[VGIC_MAX_CPUS];
> +	union {
> +		u32 reg[VGIC_NR_SHARED_IRQS / 32];
> +		DECLARE_BITMAP(reg_ul, VGIC_NR_SHARED_IRQS);
> +	} shared;
> +};
> +
> +struct vgic_bytemap {
> +	u32 percpu[VGIC_MAX_CPUS][VGIC_NR_PRIVATE_IRQS / 4];
> +	u32 shared[VGIC_NR_SHARED_IRQS  / 4];
> +};
> +
> +struct vgic_dist {
> +	spinlock_t		lock;
> +	bool			ready;
> +
> +	/* Virtual control interface mapping */
> +	void __iomem		*vctrl_base;
> +
> +	/* Distributor and vcpu interface mapping in the guest */
> +	phys_addr_t		vgic_dist_base;
> +	phys_addr_t		vgic_cpu_base;
> +
> +	/* Distributor enabled */
> +	u32			enabled;
> +
> +	/* Interrupt enabled (one bit per IRQ) */
> +	struct vgic_bitmap	irq_enabled;
> +
> +	/* Interrupt 'pin' level */
> +	struct vgic_bitmap	irq_state;
> +
> +	/* Level-triggered interrupt in progress */
> +	struct vgic_bitmap	irq_active;
> +
> +	/* Interrupt priority. Not used yet. */
> +	struct vgic_bytemap	irq_priority;
> +
> +	/* Level/edge triggered */
> +	struct vgic_bitmap	irq_cfg;
> +
> +	/* Source CPU per SGI and target CPU */
> +	u8			irq_sgi_sources[VGIC_MAX_CPUS][16];
> +
> +	/* Target CPU for each IRQ */
> +	u8			irq_spi_cpu[VGIC_NR_SHARED_IRQS];
> +	struct vgic_bitmap	irq_spi_target[VGIC_MAX_CPUS];
> +
> +	/* Bitmap indicating which CPU has something pending */
> +	unsigned long		irq_pending_on_cpu;
> +};
> +
> +struct vgic_cpu {
> +	/* per IRQ to LR mapping */
> +	u8		vgic_irq_lr_map[VGIC_NR_IRQS];
> +
> +	/* Pending interrupts on this VCPU */
> +	DECLARE_BITMAP(	pending_percpu, VGIC_NR_PRIVATE_IRQS);
> +	DECLARE_BITMAP(	pending_shared, VGIC_NR_SHARED_IRQS);
> +
> +	/* Bitmap of used/free list registers */
> +	DECLARE_BITMAP(	lr_used, 64);
> +
> +	/* 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[64];	/* A15 has only 4... */
> +};
> +
> +#define LR_EMPTY	0xff
> +
> +struct kvm;
> +struct kvm_vcpu;
> +struct kvm_run;
> +struct kvm_exit_mmio;
> +
> +int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr);
> +int kvm_vgic_hyp_init(void);
> +int kvm_vgic_init(struct kvm *kvm);
> +int kvm_vgic_create(struct kvm *kvm);
> +int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu);
> +void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
> +void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
> +int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
> +			bool level);
> +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 vgic_initialized(k)	((k)->arch.vgic.ready)
> +
> +#endif
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index c745d20..cc3192e 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -306,6 +306,90 @@ __kvm_hyp_code_start:
>  	msr	vttbr_el2, xzr
>  .endm
>  
> +/*
> + * Save the VGIC CPU state into memory
> + * x0: Register pointing to VCPU struct
> + * Do not corrupt x1!!!
> + */
> +.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]
> +
> +	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
> +	str	w5, [x3], #4
> +	sub	w4, w4, #1
> +	cbnz	w4, 1b
> +2:
> +.endm
> +
> +/*
> + * Restore the VGIC CPU state from memory
> + * x0: Register pointing to VCPU struct
> + */
> +.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]
> +
> +	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
> +	str	w5, [x2], #4
> +	sub	w4, w4, #1
> +	cbnz	w4, 1b
> +2:
> +.endm
> +
>  __save_sysregs:
>  	save_sysregs
>  	ret
> @@ -348,6 +432,8 @@ ENTRY(__kvm_vcpu_run)
>  	activate_traps
>  	activate_vm
>  
> +	restore_vgic_state
> +
>  	// Guest context
>  	add	x2, x0, #VCPU_CONTEXT
>  
> @@ -370,6 +456,8 @@ __kvm_vcpu_return:
>  	bl __save_fpsimd
>  	bl __save_sysregs
>  
> +	save_vgic_state
> +
>  	deactivate_traps
>  	deactivate_vm
>  
> -- 
> 1.8.1.4
> 
> 
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm

  reply	other threads:[~2013-04-23 23:00 UTC|newest]

Thread overview: 116+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-08 16:17 [PATCH v3 00/32] Port of KVM to arm64 Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 01/32] arm64: add explicit symbols to ESR_EL1 decoding Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 02/32] arm64: KVM: define HYP and Stage-2 translation page flags Marc Zyngier
2013-04-10 14:07   ` Will Deacon
2013-04-12 15:22     ` Marc Zyngier
2013-04-26 17:01   ` Catalin Marinas
2013-04-26 17:11     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 03/32] arm64: KVM: HYP mode idmap support Marc Zyngier
2013-04-23 22:57   ` Christoffer Dall
2013-04-24  9:36     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 04/32] arm64: KVM: EL2 register definitions Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 05/32] arm64: KVM: system register definitions for 64bit guests Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 06/32] arm64: KVM: Basic ESR_EL2 helpers and vcpu register access Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 07/32] arm64: KVM: fault injection into a guest Marc Zyngier
2013-04-10 16:40   ` Will Deacon
2013-04-12 15:29     ` Marc Zyngier
2013-04-23 22:57   ` Christoffer Dall
2013-04-24 10:04     ` Marc Zyngier
2013-04-24 16:46       ` Christoffer Dall
2013-04-29 16:26   ` Catalin Marinas
2013-05-07 16:29     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 08/32] arm64: KVM: architecture specific MMU backend Marc Zyngier
2013-04-23 22:58   ` Christoffer Dall
2013-04-24 11:03     ` Marc Zyngier
2013-04-24 11:10       ` Will Deacon
2013-04-24 16:50         ` Christoffer Dall
2013-04-24 16:55       ` Christoffer Dall
2013-04-25 12:59         ` Marc Zyngier
2013-04-25 15:13           ` Christoffer Dall
2013-04-29 17:35   ` Catalin Marinas
2013-04-30 10:23     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 09/32] arm64: KVM: user space interface Marc Zyngier
2013-04-10 16:45   ` Will Deacon
2013-04-12 15:31     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 10/32] arm64: KVM: system register handling Marc Zyngier
2013-04-10 17:04   ` Will Deacon
2013-04-12 15:48     ` Marc Zyngier
2013-04-23 23:01   ` Christoffer Dall
2013-04-24 13:37     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 11/32] arm64: KVM: CPU specific system registers handling Marc Zyngier
2013-04-10 17:06   ` Will Deacon
2013-04-12 16:04     ` Marc Zyngier
2013-04-23 22:59       ` Christoffer Dall
2013-04-24  9:33         ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 12/32] arm64: KVM: virtual CPU reset Marc Zyngier
2013-04-10 17:07   ` Will Deacon
2013-04-12 16:04     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 13/32] arm64: KVM: kvm_arch and kvm_vcpu_arch definitions Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 14/32] arm64: KVM: MMIO access backend Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 15/32] arm64: KVM: guest one-reg interface Marc Zyngier
2013-04-10 17:13   ` Will Deacon
2013-04-12 16:35     ` Marc Zyngier
2013-04-23 22:59   ` Christoffer Dall
2013-04-24 11:27     ` Marc Zyngier
2013-04-24 17:05       ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 16/32] arm64: KVM: hypervisor initialization code Marc Zyngier
2013-05-02 11:03   ` Catalin Marinas
2013-05-02 13:28     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 17/32] arm64: KVM: HYP mode world switch implementation Marc Zyngier
2013-04-23 22:59   ` Christoffer Dall
2013-04-24 11:39     ` Marc Zyngier
2013-04-24 17:08       ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 18/32] arm64: KVM: Exit handling Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 19/32] arm64: KVM: Plug the VGIC Marc Zyngier
2013-04-23 23:00   ` Christoffer Dall [this message]
2013-04-24 11:43     ` Marc Zyngier
2013-05-02 14:38       ` Catalin Marinas
2013-04-08 16:17 ` [PATCH v3 20/32] arm64: KVM: Plug the arch timer Marc Zyngier
2013-04-23 23:00   ` Christoffer Dall
2013-04-24 11:43     ` Marc Zyngier
2013-05-02 15:31       ` Catalin Marinas
2013-04-08 16:17 ` [PATCH v3 21/32] arm64: KVM: PSCI implementation Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 22/32] arm64: KVM: Build system integration Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 23/32] arm64: KVM: define 32bit specific registers Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 24/32] arm64: KVM: 32bit GP register access Marc Zyngier
2013-04-23 23:00   ` Christoffer Dall
2013-04-24 13:06     ` Marc Zyngier
2013-04-24 17:09       ` Christoffer Dall
2013-05-02 16:09   ` Catalin Marinas
2013-05-07 16:28     ` Marc Zyngier
2013-05-07 16:33       ` Catalin Marinas
2013-05-11  0:36         ` Christoffer Dall
2013-05-11  7:51           ` Peter Maydell
2013-05-11  9:43           ` Catalin Marinas
2013-05-12 18:51             ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 25/32] arm64: KVM: 32bit conditional execution emulation Marc Zyngier
2013-04-23 23:00   ` Christoffer Dall
2013-04-24 13:13     ` Marc Zyngier
2013-04-24 17:11       ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 26/32] arm64: KVM: 32bit handling of coprocessor traps Marc Zyngier
2013-04-23 23:01   ` Christoffer Dall
2013-04-24 13:42     ` Marc Zyngier
2013-04-24 17:14       ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 27/32] arm64: KVM: CPU specific 32bit coprocessor access Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 28/32] arm64: KVM: 32bit specific register world switch Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 29/32] arm64: KVM: 32bit guest fault injection Marc Zyngier
2013-04-23 23:02   ` Christoffer Dall
2013-04-24 13:46     ` Marc Zyngier
2013-04-24 17:15       ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 30/32] arm64: KVM: enable initialization of a 32bit vcpu Marc Zyngier
2013-04-23 23:02   ` Christoffer Dall
2013-04-24 13:49     ` Marc Zyngier
2013-04-24 17:17       ` Christoffer Dall
2013-05-07 16:36         ` Marc Zyngier
2013-05-11  0:38           ` Christoffer Dall
2013-05-11  8:04             ` Peter Maydell
2013-05-11 16:26               ` Christoffer Dall
2013-05-11 16:31                 ` Peter Maydell
2013-05-13  9:01             ` Marc Zyngier
2013-05-13 15:46               ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 31/32] arm64: KVM: userspace API documentation Marc Zyngier
2013-04-23 23:02   ` Christoffer Dall
2013-04-24 13:52     ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 32/32] arm64: KVM: MAINTAINERS update Marc Zyngier
2013-04-23 23:04 ` [PATCH v3 00/32] Port of KVM to arm64 Christoffer Dall
2013-05-03 13:17 ` Catalin Marinas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130423230012.GG20569@gmail.com \
    --to=cdall@cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).