From: eric.auger@linaro.org (Eric Auger)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 12/19] arm/arm64: KVM: add vgic.h header file
Date: Tue, 18 Nov 2014 15:07:22 +0100 [thread overview]
Message-ID: <546B529A.7030901@linaro.org> (raw)
In-Reply-To: <1415959683-26027-13-git-send-email-andre.przywara@arm.com>
On 11/14/2014 11:07 AM, Andre Przywara wrote:
> vgic.c is currently a mixture of generic vGIC emulation code and
> functions specific to emulating a GICv2. To ease the addition of
> GICv3 later, we create new header file vgic.h, which holds constants
> and prototypes of commonly used functions.
> Rename some identifiers to avoid name space clutter.
> I removed the long-standing comment about using the kvm_io_bus API
> to tackle the GIC register ranges, as it wouldn't be a win for us
> anymore.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>
> -------
> As the diff isn't always obvious here (and to aid eventual rebases),
> here is a list of high-level changes done to the code:
> * moved definitions and prototypes from vgic.c to vgic.h:
> - VGIC_ADDR_UNDEF
> - ACCESS_{READ,WRITE}_*
> - vgic_update_state()
> - vgic_kick_vcpus()
> - vgic_get_vmcr()
> - vgic_set_vmcr()
> - struct mmio_range {} (renamed to struct kvm_mmio_range)
> * removed static keyword and exported prototype in vgic.h:
> - vgic_bitmap_get_reg()
> - vgic_bitmap_set_irq_val()
> - vgic_bitmap_get_shared_map()
> - vgic_bytemap_get_reg()
> - vgic_dist_irq_set()
> - vgic_dist_irq_clear()
> - vgic_cpu_irq_clear()
> - vgic_reg_access()
> - handle_mmio_raz_wi()
> - vgic_handle_enable_reg()
> - vgic_handle_pending_reg()
> - vgic_handle_cfg_reg()
> - vgic_unqueue_irqs()
> - find_matching_range() (renamed to vgic_find_range)
> - vgic_handle_mmio_range()
> - vgic_update_state()
> - vgic_get_vmcr()
> - vgic_set_vmcr()
> - vgic_queue_irq()
> - vgic_kick_vcpus()
> - vgic_init_maps()
> - vgic_has_attr_regs()
> - vgic_set_common_attr()
> - vgic_get_common_attr()
> * moved functions to vgic.h (static inline):
> - mmio_data_read()
> - mmio_data_write()
> - is_in_range()
> ---
> Changelog v3...v4:
> - rename struct mmio_range to struct kvm_mmio_range
> - rename find_matching_range() to vgic_find_range()
Hi Andre,
It might have helped here to split the patch into 2: first renamings (
mmio_range, find_matching_range ...) in anticipation and then the move.
I would rather use kvm_*vgic*_mmio_range to emphasize it is not kvm wide.
> - remove vgic_create() and vgic_destroy() from header
>
> virt/kvm/arm/vgic.c | 150 +++++++++++++++++----------------------------------
> virt/kvm/arm/vgic.h | 119 ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 169 insertions(+), 100 deletions(-)
> create mode 100644 virt/kvm/arm/vgic.h
>
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index ea71cd0..4fa58c9 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -75,32 +75,16 @@
> * inactive as long as the external input line is held high.
> */
>
> -#define VGIC_ADDR_UNDEF (-1)
> -#define IS_VGIC_ADDR_UNDEF(_x) ((_x) == VGIC_ADDR_UNDEF)
> +#include "vgic.h"
>
> -#define PRODUCT_ID_KVM 0x4b /* ASCII code K */
> -#define IMPLEMENTER_ARM 0x43b
> #define GICC_ARCH_VERSION_V2 0x2
>
> -#define ACCESS_READ_VALUE (1 << 0)
> -#define ACCESS_READ_RAZ (0 << 0)
> -#define ACCESS_READ_MASK(x) ((x) & (1 << 0))
> -#define ACCESS_WRITE_IGNORED (0 << 1)
> -#define ACCESS_WRITE_SETBIT (1 << 1)
> -#define ACCESS_WRITE_CLEARBIT (2 << 1)
> -#define ACCESS_WRITE_VALUE (3 << 1)
> -#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 u8 *vgic_get_sgi_sources(struct vgic_dist *dist, int vcpu_id, int sgi);
> static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg);
> 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 const struct vgic_ops *vgic_ops;
> static const struct vgic_params *vgic;
> @@ -174,8 +158,7 @@ static unsigned long *u64_to_bitmask(u64 *val)
> return (unsigned long *)val;
> }
>
> -static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x,
> - int cpuid, u32 offset)
> +u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, int cpuid, u32 offset)
> {
> offset >>= 2;
> if (!offset)
> @@ -193,8 +176,8 @@ static int vgic_bitmap_get_irq_val(struct vgic_bitmap *x,
> return test_bit(irq - VGIC_NR_PRIVATE_IRQS, x->shared);
> }
>
> -static void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid,
> - int irq, int val)
> +void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid,
> + int irq, int val)
> {
> unsigned long *reg;
>
> @@ -216,7 +199,7 @@ static unsigned long *vgic_bitmap_get_cpu_map(struct vgic_bitmap *x, int cpuid)
> return x->private + cpuid;
> }
>
> -static unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x)
> +unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x)
> {
> return x->shared;
> }
> @@ -243,7 +226,7 @@ static void vgic_free_bytemap(struct vgic_bytemap *b)
> b->shared = NULL;
> }
>
> -static u32 *vgic_bytemap_get_reg(struct vgic_bytemap *x, int cpuid, u32 offset)
> +u32 *vgic_bytemap_get_reg(struct vgic_bytemap *x, int cpuid, u32 offset)
> {
> u32 *reg;
>
> @@ -340,14 +323,14 @@ static int vgic_dist_irq_is_pending(struct kvm_vcpu *vcpu, int irq)
> return vgic_bitmap_get_irq_val(&dist->irq_pending, vcpu->vcpu_id, irq);
> }
>
> -static void vgic_dist_irq_set_pending(struct kvm_vcpu *vcpu, int irq)
> +void vgic_dist_irq_set_pending(struct kvm_vcpu *vcpu, int irq)
> {
> struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>
> vgic_bitmap_set_irq_val(&dist->irq_pending, vcpu->vcpu_id, irq, 1);
> }
>
> -static void vgic_dist_irq_clear_pending(struct kvm_vcpu *vcpu, int irq)
> +void vgic_dist_irq_clear_pending(struct kvm_vcpu *vcpu, int irq)
> {
> struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>
> @@ -363,7 +346,7 @@ static void vgic_cpu_irq_set(struct kvm_vcpu *vcpu, int irq)
> vcpu->arch.vgic_cpu.pending_shared);
> }
>
> -static void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
> +void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
> {
> if (irq < VGIC_NR_PRIVATE_IRQS)
> clear_bit(irq, vcpu->arch.vgic_cpu.pending_percpu);
> @@ -377,16 +360,6 @@ static bool vgic_can_sample_irq(struct kvm_vcpu *vcpu, int irq)
> return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq);
> }
>
> -static u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask)
> -{
> - return le32_to_cpu(*((u32 *)mmio->data)) & mask;
> -}
> -
> -static void mmio_data_write(struct kvm_exit_mmio *mmio, u32 mask, u32 value)
> -{
> - *((u32 *)mmio->data) = cpu_to_le32(value) & mask;
> -}
> -
> /**
> * vgic_reg_access - access vgic register
> * @mmio: pointer to the data describing the mmio access
> @@ -398,8 +371,8 @@ static void mmio_data_write(struct kvm_exit_mmio *mmio, u32 mask, u32 value)
> * modes defined for vgic register access
> * (read,raz,write-ignored,setbit,clearbit,write)
> */
> -static void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
> - phys_addr_t offset, int mode)
> +void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
> + phys_addr_t offset, int mode)
> {
> int word_offset = (offset & 3) * 8;
> u32 mask = (1UL << (mmio->len * 8)) - 1;
> @@ -483,16 +456,16 @@ static bool handle_mmio_misc(struct kvm_vcpu *vcpu,
> return false;
> }
>
> -static bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu,
> - struct kvm_exit_mmio *mmio, phys_addr_t offset)
> +bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset)
> {
> vgic_reg_access(mmio, NULL, offset,
> ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
> return false;
> }
>
> -static bool vgic_handle_enable_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio,
> - phys_addr_t offset, int vcpu_id, int access)
> +bool vgic_handle_enable_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset, int vcpu_id, int access)
> {
> u32 *reg;
> int mode = ACCESS_READ_VALUE | access;
> @@ -529,9 +502,9 @@ static bool handle_mmio_clear_enable_reg(struct kvm_vcpu *vcpu,
> vcpu->vcpu_id, ACCESS_WRITE_CLEARBIT);
> }
>
> -static bool vgic_handle_set_pending_reg(struct kvm *kvm,
> - struct kvm_exit_mmio *mmio,
> - phys_addr_t offset, int vcpu_id)
> +bool vgic_handle_set_pending_reg(struct kvm *kvm,
> + struct kvm_exit_mmio *mmio,
> + phys_addr_t offset, int vcpu_id)
> {
> u32 *reg, orig;
> u32 level_mask;
> @@ -566,9 +539,9 @@ static bool vgic_handle_set_pending_reg(struct kvm *kvm,
> return false;
> }
>
> -static bool vgic_handle_clear_pending_reg(struct kvm *kvm,
> - struct kvm_exit_mmio *mmio,
> - phys_addr_t offset, int vcpu_id)
> +bool vgic_handle_clear_pending_reg(struct kvm *kvm,
> + struct kvm_exit_mmio *mmio,
> + phys_addr_t offset, int vcpu_id)
> {
> u32 *level_active;
> u32 *reg, orig;
> @@ -740,8 +713,8 @@ static u16 vgic_cfg_compress(u32 val)
> * LSB is always 0. As such, we only keep the upper bit, and use the
> * two above functions to compress/expand the bits
> */
> -static bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
> - phys_addr_t offset)
> +bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset)
> {
> u32 val;
>
> @@ -817,7 +790,7 @@ static void vgic_v2_add_sgi_source(struct kvm_vcpu *vcpu, int irq, int source)
> * to the distributor but the active state stays in the LRs, because we don't
> * track the active state on the distributor side.
> */
> -static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
> +void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
> {
> struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> int i;
> @@ -942,21 +915,7 @@ static bool handle_mmio_sgi_clear(struct kvm_vcpu *vcpu,
> return write_set_clear_sgi_pend_reg(vcpu, mmio, offset, false);
> }
>
> -/*
> - * I would have liked to use the kvm_bus_io_*() API instead, but it
> - * cannot cope with banked registers (only the VM pointer is passed
> - * around, and we need the vcpu). One of these days, someone please
> - * fix it!
> - */
> -struct mmio_range {
> - phys_addr_t base;
> - unsigned long len;
> - int bits_per_irq;
> - bool (*handle_mmio)(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
> - phys_addr_t offset);
> -};
> -
> -static const struct mmio_range vgic_dist_ranges[] = {
> +static const struct kvm_mmio_range vgic_dist_ranges[] = {
> {
> .base = GIC_DIST_CTRL,
> .len = 12,
> @@ -1041,12 +1000,12 @@ static const struct mmio_range vgic_dist_ranges[] = {
> {}
> };
>
> -static const
> -struct mmio_range *find_matching_range(const struct mmio_range *ranges,
> +const
> +struct kvm_mmio_range *vgic_find_range(const struct kvm_mmio_range *ranges,
> struct kvm_exit_mmio *mmio,
> phys_addr_t offset)
> {
> - const struct mmio_range *r = ranges;
> + const struct kvm_mmio_range *r = ranges;
>
> while (r->len) {
> if (offset >= r->base &&
> @@ -1059,7 +1018,7 @@ struct mmio_range *find_matching_range(const struct mmio_range *ranges,
> }
>
> static bool vgic_validate_access(const struct vgic_dist *dist,
> - const struct mmio_range *range,
> + const struct kvm_mmio_range *range,
> unsigned long offset)
> {
> int irq;
> @@ -1085,7 +1044,7 @@ static bool vgic_validate_access(const struct vgic_dist *dist,
> static bool call_range_handler(struct kvm_vcpu *vcpu,
> struct kvm_exit_mmio *mmio,
> unsigned long offset,
> - const struct mmio_range *range)
> + const struct kvm_mmio_range *range)
> {
> u32 *data32 = (void *)mmio->data;
> struct kvm_exit_mmio mmio32;
> @@ -1129,18 +1088,18 @@ static bool call_range_handler(struct kvm_vcpu *vcpu,
> *
> * returns true if the MMIO access could be performed
> */
> -static bool vgic_handle_mmio_range(struct kvm_vcpu *vcpu, struct kvm_run *run,
> +bool vgic_handle_mmio_range(struct kvm_vcpu *vcpu, struct kvm_run *run,
> struct kvm_exit_mmio *mmio,
> - const struct mmio_range *ranges,
> + const struct kvm_mmio_range *ranges,
> unsigned long mmio_base)
> {
> - const struct mmio_range *range;
> + const struct kvm_mmio_range *range;
> struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> bool updated_state;
> unsigned long offset;
>
> offset = mmio->phys_addr - mmio_base;
> - range = find_matching_range(ranges, mmio, offset);
> + range = vgic_find_range(ranges, mmio, offset);
> if (unlikely(!range || !range->handle_mmio)) {
> pr_warn("Unhandled access %d %08llx %d\n",
> mmio->is_write, mmio->phys_addr, mmio->len);
> @@ -1166,12 +1125,6 @@ static bool vgic_handle_mmio_range(struct kvm_vcpu *vcpu, struct kvm_run *run,
> return true;
> }
>
> -static inline bool is_in_range(phys_addr_t addr, unsigned long len,
> - phys_addr_t baseaddr, unsigned long size)
> -{
> - return (addr >= baseaddr) && (addr + len <= baseaddr + size);
> -}
> -
> static bool vgic_v2_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
> struct kvm_exit_mmio *mmio)
> {
> @@ -1298,7 +1251,7 @@ static int compute_pending_for_cpu(struct kvm_vcpu *vcpu)
> * Update the interrupt state and determine which CPUs have pending
> * interrupts. Must be called with distributor lock held.
> */
> -static void vgic_update_state(struct kvm *kvm)
> +void vgic_update_state(struct kvm *kvm)
> {
> struct vgic_dist *dist = &kvm->arch.vgic;
> struct kvm_vcpu *vcpu;
> @@ -1359,12 +1312,12 @@ 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)
> +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)
> +void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
> {
> vgic_ops->set_vmcr(vcpu, vmcr);
> }
> @@ -1414,7 +1367,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
> * Queue an interrupt to a CPU virtual interface. Return true on success,
> * or false if it wasn't possible to queue it.
> */
> -static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
> +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_dist *dist = &vcpu->kvm->arch.vgic;
> @@ -1700,7 +1653,7 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
> return test_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
> }
>
> -static void vgic_kick_vcpus(struct kvm *kvm)
> +void vgic_kick_vcpus(struct kvm *kvm)
> {
> struct kvm_vcpu *vcpu;
> int c;
> @@ -1941,7 +1894,7 @@ void kvm_vgic_destroy(struct kvm *kvm)
> * Allocate and initialize the various data structures. Must be called
> * with kvm->lock held!
> */
> -static int vgic_init_maps(struct kvm *kvm)
> +int vgic_init_maps(struct kvm *kvm)
> {
> struct vgic_dist *dist = &kvm->arch.vgic;
> struct kvm_vcpu *vcpu;
> @@ -2080,7 +2033,7 @@ out:
> return ret;
> }
>
> -static int vgic_v2_init_emulation(struct kvm *kvm)
> +int vgic_v2_init_emulation(struct kvm *kvm)
> {
> struct vgic_dist *dist = &kvm->arch.vgic;
>
> @@ -2320,7 +2273,7 @@ static bool handle_cpu_mmio_ident(struct kvm_vcpu *vcpu,
> * CPU Interface Register accesses - these are not accessed by the VM, but by
> * user space for saving and restoring VGIC state.
> */
> -static const struct mmio_range vgic_cpu_ranges[] = {
> +static const struct kvm_mmio_range vgic_cpu_ranges[] = {
> {
> .base = GIC_CPU_CTRL,
> .len = 12,
> @@ -2347,7 +2300,7 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
> struct kvm_device_attr *attr,
> u32 *reg, bool is_write)
> {
> - const struct mmio_range *r = NULL, *ranges;
> + const struct kvm_mmio_range *r = NULL, *ranges;
> phys_addr_t offset;
> int ret, cpuid, c;
> struct kvm_vcpu *vcpu, *tmp_vcpu;
> @@ -2388,7 +2341,7 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
> default:
> BUG();
> }
> - r = find_matching_range(ranges, &mmio, offset);
> + r = vgic_find_range(ranges, &mmio, offset);
>
> if (unlikely(!r || !r->handle_mmio)) {
> ret = -ENXIO;
> @@ -2434,8 +2387,7 @@ out:
> return ret;
> }
>
> -static int vgic_set_common_attr(struct kvm_device *dev,
> - struct kvm_device_attr *attr)
> +int vgic_set_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
> {
> int r;
>
> @@ -2512,8 +2464,7 @@ static int vgic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
> return -ENXIO;
> }
>
> -static int vgic_get_common_attr(struct kvm_device *dev,
> - struct kvm_device_attr *attr)
> +int vgic_get_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
> {
> int r = -ENXIO;
>
> @@ -2568,13 +2519,12 @@ static int vgic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
> return -ENXIO;
> }
>
> -static int vgic_has_attr_regs(const struct mmio_range *ranges,
> - phys_addr_t offset)
> +int vgic_has_attr_regs(const struct kvm_mmio_range *ranges, phys_addr_t offset)
> {
> struct kvm_exit_mmio dev_attr_mmio;
>
> dev_attr_mmio.len = 4;
> - if (find_matching_range(ranges, &dev_attr_mmio, offset))
> + if (vgic_find_range(ranges, &dev_attr_mmio, offset))
> return 0;
> else
> return -ENXIO;
> @@ -2604,12 +2554,12 @@ static int vgic_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
> return -ENXIO;
> }
>
> -static void vgic_destroy(struct kvm_device *dev)
> +void vgic_destroy(struct kvm_device *dev)
> {
> kfree(dev);
> }
>
> -static int vgic_create(struct kvm_device *dev, u32 type)
> +int vgic_create(struct kvm_device *dev, u32 type)
> {
> return kvm_vgic_create(dev->kvm, type);
> }
> diff --git a/virt/kvm/arm/vgic.h b/virt/kvm/arm/vgic.h
> new file mode 100644
> index 0000000..ff3171a
> --- /dev/null
> +++ b/virt/kvm/arm/vgic.h
> @@ -0,0 +1,119 @@
> +/*
> + * Copyright (C) 2012-2014 ARM Ltd.
> + * Author: Marc Zyngier <marc.zyngier@arm.com>
> + *
> + * Derived from virt/kvm/arm/vgic.c
> + *
> + * 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 __KVM_VGIC_H__
> +#define __KVM_VGIC_H__
> +
> +#define VGIC_ADDR_UNDEF (-1)
> +#define IS_VGIC_ADDR_UNDEF(_x) ((_x) == VGIC_ADDR_UNDEF)
> +
> +#define PRODUCT_ID_KVM 0x4b /* ASCII code K */
> +#define IMPLEMENTER_ARM 0x43b
> +
> +#define ACCESS_READ_VALUE (1 << 0)
> +#define ACCESS_READ_RAZ (0 << 0)
> +#define ACCESS_READ_MASK(x) ((x) & (1 << 0))
> +#define ACCESS_WRITE_IGNORED (0 << 1)
> +#define ACCESS_WRITE_SETBIT (1 << 1)
> +#define ACCESS_WRITE_CLEARBIT (2 << 1)
> +#define ACCESS_WRITE_VALUE (3 << 1)
> +#define ACCESS_WRITE_MASK(x) ((x) & (3 << 1))
> +
> +unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x);
> +
> +void vgic_update_state(struct kvm *kvm);
> +int vgic_init_maps(struct kvm *kvm);
> +
> +u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, int cpuid, u32 offset);
> +u32 *vgic_bytemap_get_reg(struct vgic_bytemap *x, int cpuid, u32 offset);
> +
> +void vgic_dist_irq_set_pending(struct kvm_vcpu *vcpu, int irq);
> +void vgic_dist_irq_clear_pending(struct kvm_vcpu *vcpu, int irq);
> +void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq);
> +void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid,
> + int irq, int val);
> +
> +void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
> +void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
> +
> +bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq);
> +void vgic_unqueue_irqs(struct kvm_vcpu *vcpu);
> +
> +void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
> + phys_addr_t offset, int mode);
> +bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset);
> +
> +static inline
> +u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask)
> +{
> + return le32_to_cpu(*((u32 *)mmio->data)) & mask;
> +}
> +
> +static inline
> +void mmio_data_write(struct kvm_exit_mmio *mmio, u32 mask, u32 value)
> +{
> + *((u32 *)mmio->data) = cpu_to_le32(value) & mask;
> +}
> +
> +struct kvm_mmio_range {
> + phys_addr_t base;
> + unsigned long len;
> + int bits_per_irq;
> + bool (*handle_mmio)(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset);
> +};
> +
> +static inline bool is_in_range(phys_addr_t addr, unsigned long len,
> + phys_addr_t baseaddr, unsigned long size)
> +{
> + return (addr >= baseaddr) && (addr + len <= baseaddr + size);
> +}
don't it deserve a renaming too?
same for mmio_data_write/read? defines?
Best Regards
Eric
> +
> +const
> +struct kvm_mmio_range *vgic_find_range(const struct kvm_mmio_range *ranges,
> + struct kvm_exit_mmio *mmio,
> + phys_addr_t offset);
> +
> +bool vgic_handle_mmio_range(struct kvm_vcpu *vcpu, struct kvm_run *run,
> + struct kvm_exit_mmio *mmio,
> + const struct kvm_mmio_range *ranges,
> + unsigned long mmio_base);
> +
> +bool vgic_handle_enable_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset, int vcpu_id, int access);
> +
> +bool vgic_handle_set_pending_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset, int vcpu_id);
> +
> +bool vgic_handle_clear_pending_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset, int vcpu_id);
> +
> +bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
> + phys_addr_t offset);
> +
> +void vgic_kick_vcpus(struct kvm *kvm);
> +
> +int vgic_has_attr_regs(const struct kvm_mmio_range *ranges, phys_addr_t offset);
> +int vgic_set_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr);
> +int vgic_get_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr);
> +
> +int vgic_v2_init_emulation(struct kvm *kvm);
> +
> +#endif
>
next prev parent reply other threads:[~2014-11-18 14:07 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-14 10:07 [PATCH v4 00/19] KVM GICv3 emulation Andre Przywara
2014-11-14 10:07 ` [PATCH v4 01/19] arm/arm64: KVM: rework MPIDR assignment and add accessors Andre Przywara
2014-11-18 10:35 ` Eric Auger
2014-11-23 9:34 ` Christoffer Dall
2014-11-14 10:07 ` [PATCH v4 02/19] arm/arm64: KVM: pass down user space provided GIC type into vGIC code Andre Przywara
2014-11-18 10:36 ` Eric Auger
2014-11-14 10:07 ` [PATCH v4 03/19] arm/arm64: KVM: refactor vgic_handle_mmio() function Andre Przywara
2014-11-18 10:35 ` Eric Auger
2014-11-14 10:07 ` [PATCH v4 04/19] arm/arm64: KVM: wrap 64 bit MMIO accesses with two 32 bit ones Andre Przywara
2014-11-18 10:36 ` Eric Auger
2014-11-23 9:42 ` Christoffer Dall
2014-11-24 13:50 ` Andre Przywara
2014-11-24 14:40 ` Christoffer Dall
2014-11-14 10:07 ` [PATCH v4 05/19] arm/arm64: KVM: introduce per-VM ops Andre Przywara
2014-11-23 9:58 ` Christoffer Dall
2014-11-14 10:07 ` [PATCH v4 06/19] arm/arm64: KVM: move kvm_register_device_ops() into vGIC probing Andre Przywara
2014-11-18 10:43 ` Eric Auger
2014-11-18 10:58 ` Eric Auger
2014-11-18 11:03 ` Andre Przywara
2014-11-14 10:07 ` [PATCH v4 07/19] arm/arm64: KVM: dont rely on a valid GICH base address Andre Przywara
2014-11-14 10:07 ` [PATCH v4 08/19] arm/arm64: KVM: make the maximum number of vCPUs a per-VM value Andre Przywara
2014-11-23 13:21 ` Christoffer Dall
2014-12-08 14:10 ` Andre Przywara
2014-11-14 10:07 ` [PATCH v4 09/19] arm/arm64: KVM: make the value of ICC_SRE_EL1 a per-VM variable Andre Przywara
2014-11-14 10:07 ` [PATCH v4 10/19] arm/arm64: KVM: refactor MMIO accessors Andre Przywara
2014-11-14 10:07 ` [PATCH v4 11/19] arm/arm64: KVM: refactor/wrap vgic_set/get_attr() Andre Przywara
2014-11-23 13:27 ` Christoffer Dall
2014-11-14 10:07 ` [PATCH v4 12/19] arm/arm64: KVM: add vgic.h header file Andre Przywara
2014-11-18 14:07 ` Eric Auger [this message]
2014-11-18 15:24 ` Andre Przywara
2014-11-23 13:29 ` Christoffer Dall
2014-11-14 10:07 ` [PATCH v4 13/19] arm/arm64: KVM: split GICv2 specific emulation code from vgic.c Andre Przywara
2014-11-23 13:32 ` Christoffer Dall
2014-11-14 10:07 ` [PATCH v4 14/19] arm/arm64: KVM: add opaque private pointer to MMIO data Andre Przywara
2014-11-23 13:33 ` Christoffer Dall
2014-11-14 10:07 ` [PATCH v4 15/19] arm/arm64: KVM: add virtual GICv3 distributor emulation Andre Przywara
2014-11-14 11:07 ` Christoffer Dall
2014-11-17 13:58 ` Andre Przywara
2014-11-17 23:46 ` Christoffer Dall
2014-11-18 15:57 ` Eric Auger
2014-11-23 14:38 ` Christoffer Dall
2014-11-24 16:00 ` Andre Przywara
2014-11-25 10:41 ` Christoffer Dall
2014-11-28 15:24 ` Andre Przywara
2014-11-30 8:30 ` Christoffer Dall
2014-12-02 16:24 ` Andre Przywara
2014-12-02 17:06 ` Marc Zyngier
2014-12-02 17:32 ` Andre Przywara
2014-12-03 10:30 ` Christoffer Dall
2014-12-03 10:47 ` Andre Przywara
2014-12-03 11:06 ` Christoffer Dall
2014-12-03 10:29 ` Christoffer Dall
2014-12-03 10:44 ` Marc Zyngier
2014-12-03 11:07 ` Christoffer Dall
2014-12-03 10:28 ` Christoffer Dall
2014-12-03 11:10 ` Andre Przywara
2014-12-03 11:28 ` Arnd Bergmann
2014-12-03 11:39 ` Peter Maydell
2014-12-03 12:03 ` Andre Przywara
2014-12-03 13:14 ` Arnd Bergmann
2014-12-04 9:34 ` Christoffer Dall
2014-12-04 10:02 ` Eric Auger
2014-11-14 10:08 ` [PATCH v4 16/19] arm64: GICv3: introduce symbolic names for GICv3 ICC_SGI1R_EL1 fields Andre Przywara
2014-11-23 14:43 ` Christoffer Dall
2014-11-14 10:08 ` [PATCH v4 17/19] arm64: KVM: add SGI generation register emulation Andre Przywara
2014-11-23 15:08 ` Christoffer Dall
2014-11-24 16:37 ` Andre Przywara
2014-11-25 11:03 ` Christoffer Dall
2014-11-28 15:40 ` Andre Przywara
2014-11-30 8:45 ` Christoffer Dall
2014-12-03 17:50 ` Andre Przywara
2014-12-03 20:22 ` Christoffer Dall
2014-11-14 10:08 ` [PATCH v4 18/19] arm/arm64: KVM: enable kernel side of GICv3 emulation Andre Przywara
2014-11-24 9:09 ` Christoffer Dall
2014-11-24 17:41 ` Andre Przywara
2014-11-25 11:08 ` Christoffer Dall
2014-11-14 10:08 ` [PATCH v4 19/19] arm/arm64: KVM: allow userland to request a virtual GICv3 Andre Przywara
2014-11-24 9:39 ` Christoffer Dall
2014-11-24 9:33 ` [PATCH v4 00/19] KVM GICv3 emulation Eric Auger
2014-11-24 17:46 ` Andre Przywara
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=546B529A.7030901@linaro.org \
--to=eric.auger@linaro.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.