From 4f551a3d96a2de85a041ee60e806bda1d5b06255 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 13 Apr 2016 09:48:02 +0100 Subject: KVM: arm/arm64: vgic: avoid map in kvm_vgic_inject_mapped_irq() When we want to inject a hardware mapped IRQ into a guest, we actually only need the virtual IRQ number from the irq_phys_map. So let's pass this number directly from the arch timer to the VGIC to avoid using the map as a parameter. Signed-off-by: Andre Przywara Reviewed-by: Eric Auger Reviewed-by: Christoffer Dall --- include/kvm/arm_vgic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index be6037aa703d..e22f01507e2b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -342,7 +342,7 @@ 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_inject_mapped_irq(struct kvm *kvm, int cpuid, - struct irq_phys_map *map, bool level); + unsigned int virt_irq, bool level); void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, -- cgit From e262f4193638fff2de458f0c70284f0cb50926a7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 13 Apr 2016 10:03:49 +0100 Subject: KVM: arm/arm64: vgic: avoid map in kvm_vgic_map_is_active() For getting the active state of a mapped IRQ, we actually only need the virtual IRQ number, not the pointer to the mapping entry. Pass the virtual IRQ number from the arch timer to the VGIC directly. Signed-off-by: Andre Przywara Reviewed-by: Eric Auger Reviewed-by: Christoffer Dall --- include/kvm/arm_vgic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index e22f01507e2b..9830232c453b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -348,7 +348,7 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int irq); int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map); -bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map); +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) #define vgic_initialized(k) (!!((k)->arch.vgic.nr_cpus)) -- cgit From 63306c28ac92bdf9e41aef367708d762f9f725f2 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 13 Apr 2016 10:04:06 +0100 Subject: KVM: arm/arm64: vgic: avoid map in kvm_vgic_unmap_phys_irq() kvm_vgic_unmap_phys_irq() only needs the virtual IRQ number, so let's just pass that between the arch timer and the VGIC to get rid of the irq_phys_map pointer. Signed-off-by: Andre Przywara Reviewed-by: Eric Auger Reviewed-by: Christoffer Dall --- include/kvm/arm_vgic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 9830232c453b..c7bb184c79eb 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -347,7 +347,7 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int irq); -int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map); +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq); bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) -- cgit From b452cb52072d21f026e38ac7af36a969bab2ed22 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Sat, 4 Jun 2016 15:41:00 +0100 Subject: KVM: arm/arm64: Remove the IRQ field from struct irq_phys_map The communication of a Linux IRQ number from outside the VGIC to the vgic was a leftover from the day when the vgic code cared about how a particular device injects virtual interrupts mapped to a physical interrupt. We can safely remove this notion, leaving all physical IRQ handling to be done in the device driver (the arch timer in this case), which makes room for a saner API for the new VGIC. Signed-off-by: Christoffer Dall Signed-off-by: Andre Przywara Reviewed-by: Eric Auger --- include/kvm/arm_vgic.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index c7bb184c79eb..9ad7625c0e79 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -158,7 +158,6 @@ struct vgic_io_device { struct irq_phys_map { u32 virt_irq; u32 phys_irq; - u32 irq; }; struct irq_phys_map_entry { @@ -346,7 +345,7 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, - int virt_irq, int irq); + int virt_irq, int phys_irq); int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq); bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); -- cgit From a7e33ad9b25552b75a2523cc598db8bcd218ede5 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 13 Apr 2016 11:03:02 +0100 Subject: KVM: arm/arm64: arch_timer: Remove irq_phys_map Now that the interface between the arch timer and the VGIC does not require passing the irq_phys_map entry pointer anymore, let's remove it from the virtual arch timer and use the virtual IRQ number instead directly. The remaining pointer returned by kvm_vgic_map_phys_irq() will be removed in the following patch. Signed-off-by: Andre Przywara Reviewed-by: Eric Auger Reviewed-by: Christoffer Dall --- include/kvm/arm_arch_timer.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index b651aed9dc6b..a47b7dee434d 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -53,9 +53,6 @@ struct arch_timer_cpu { /* Timer IRQ */ struct kvm_irq_level irq; - /* VGIC mapping */ - struct irq_phys_map *map; - /* Active IRQ state caching */ bool active_cleared_last; }; -- cgit From c8eb3f6b9bc31abc0ab3230737fde1639c8b1ea6 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 13 Apr 2016 11:49:07 +0100 Subject: KVM: arm/arm64: vgic: Remove irq_phys_map from interface Now that the virtual arch timer does not care about the irq_phys_map anymore, let's rework kvm_vgic_map_phys_irq() to return an error value instead. Any reference to that mapping can later be done by passing the correct combination of VCPU and virtual IRQ number. This makes the irq_phys_map handling completely private to the VGIC code. Signed-off-by: Andre Przywara Reviewed-by: Eric Auger Reviewed-by: Christoffer Dall --- include/kvm/arm_vgic.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 9ad7625c0e79..3e17fb4e64b7 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -344,8 +344,7 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, unsigned int virt_irq, bool level); void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); -struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, - int virt_irq, int phys_irq); +int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int phys_irq); int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq); bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); -- cgit From 41a54482c010d8806cf56e1501bb3b61fac14cf9 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Wed, 18 May 2016 16:26:00 +0100 Subject: KVM: arm/arm64: Move timer IRQ map to latest possible time We are about to modify the VGIC to allocate all data structures dynamically and store mapped IRQ information on a per-IRQ struct, which is indeed allocated dynamically at init time. Therefore, we cannot record the mapped IRQ info from the timer at timer reset time like it's done now, because VCPU reset happens before timer init. A possible later time to do this is on the first run of a per VCPU, it just requires us to move the enable state to be a per-VCPU state and do the lookup of the physical IRQ number when we are about to run the VCPU. Signed-off-by: Christoffer Dall Signed-off-by: Andre Przywara --- include/kvm/arm_arch_timer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index a47b7dee434d..dda39d8fa189 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -24,9 +24,6 @@ #include struct arch_timer_kvm { - /* Is the timer enabled */ - bool enabled; - /* Virtual offset */ cycle_t cntvoff; }; @@ -55,10 +52,13 @@ struct arch_timer_cpu { /* Active IRQ state caching */ bool active_cleared_last; + + /* Is the timer enabled */ + bool enabled; }; int kvm_timer_hyp_init(void); -void kvm_timer_enable(struct kvm *kvm); +int kvm_timer_enable(struct kvm_vcpu *vcpu); void kvm_timer_init(struct kvm *kvm); int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, const struct kvm_irq_level *irq); -- cgit From 2db4c104fa2a9af12c07433642e2e4fee37fe2fd Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Wed, 6 Apr 2016 14:48:53 +0200 Subject: KVM: arm/arm64: Get rid of vgic_cpu->nr_lr The number of list registers is a property of the underlying system, not of emulated VGIC CPU interface. As we are about to move this variable to global state in the new vgic for clarity, move it from the legacy implementation as well to make the merge of the new code easier. Signed-off-by: Christoffer Dall Signed-off-by: Andre Przywara Reviewed-by: Andre Przywara --- include/kvm/arm_vgic.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 3e17fb4e64b7..67a66371356d 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -304,9 +304,6 @@ struct vgic_cpu { unsigned long *active_shared; unsigned long *pend_act_shared; - /* Number of list registers on this CPU */ - int nr_lr; - /* CPU vif control registers for world switch */ union { struct vgic_v2_cpu_if vgic_v2; -- cgit From 2defaff48aaf16072a6eac4cf8234917197dfa72 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 7 Mar 2016 17:32:29 +0700 Subject: KVM: arm/arm64: pmu: abstract access to number of SPIs Currently the PMU uses a member of the struct vgic_dist directly, which not only breaks abstraction, but will fail with the new VGIC. Abstract this access in the VGIC header file and refactor the validity check in the PMU code. Signed-off-by: Andre Przywara --- include/kvm/arm_vgic.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 67a66371356d..ade70056cbd6 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -348,6 +348,8 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) #define vgic_initialized(k) (!!((k)->arch.vgic.nr_cpus)) #define vgic_ready(k) ((k)->arch.vgic.ready) +#define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ + ((i) < (k)->arch.vgic.nr_irqs)) int vgic_v2_probe(const struct gic_kvm_info *gic_kvm_info, const struct vgic_ops **ops, -- cgit From 44bfc42e94cd76a0bd44f3fce98d4a7b76f31bc0 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 4 May 2016 14:35:48 +0100 Subject: KVM: arm/arm64: move GICv2 emulation defines into arm-gic-v3.h As (some) GICv3 hosts can emulate a GICv2, some GICv2 specific masks for the list register definition also apply to GICv3 LRs. At the moment we have those definitions in the KVM VGICv3 implementation, so let's move them into the GICv3 header file to have them automatically defined. Signed-off-by: Andre Przywara Acked-by: Marc Zyngier --- include/linux/irqchip/arm-gic-v3.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index d5d798b35c1f..ec938d14da5d 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -276,6 +276,11 @@ #define ICH_LR_PHYS_ID_SHIFT 32 #define ICH_LR_PHYS_ID_MASK (0x3ffULL << ICH_LR_PHYS_ID_SHIFT) +/* 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) + #define ICH_MISR_EOI (1 << 0) #define ICH_MISR_U (1 << 1) -- cgit From b18b57787f5e469b2825784ae3c522fc14472e97 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Mon, 23 Nov 2015 07:20:05 -0800 Subject: KVM: arm/arm64: vgic-new: Add data structure definitions Add a new header file for the new and improved GIC implementation. The big change is that we now have a struct vgic_irq per IRQ instead of spreading all the information over various bitmaps. We include this new header conditionally from within the old header file for the time being to avoid touching all the users. Signed-off-by: Christoffer Dall Signed-off-by: Andre Przywara Reviewed-by: Marc Zyngier --- include/kvm/arm_vgic.h | 5 ++ include/kvm/vgic/vgic.h | 201 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 include/kvm/vgic/vgic.h (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index ade70056cbd6..da0a524802cb 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -19,6 +19,10 @@ #ifndef __ASM_ARM_KVM_VGIC_H #define __ASM_ARM_KVM_VGIC_H +#ifdef CONFIG_KVM_NEW_VGIC +#include +#else + #include #include #include @@ -367,4 +371,5 @@ static inline int vgic_v3_probe(const struct gic_kvm_info *gic_kvm_info, } #endif +#endif /* old VGIC include */ #endif diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h new file mode 100644 index 000000000000..6ca0781ac2cc --- /dev/null +++ b/include/kvm/vgic/vgic.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2015, 2016 ARM Ltd. + * + * 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 . + */ +#ifndef __ASM_ARM_KVM_VGIC_VGIC_H +#define __ASM_ARM_KVM_VGIC_VGIC_H + +#include +#include +#include +#include +#include +#include + +#define VGIC_V3_MAX_CPUS 255 +#define VGIC_V2_MAX_CPUS 8 +#define VGIC_NR_IRQS_LEGACY 256 +#define VGIC_NR_SGIS 16 +#define VGIC_NR_PPIS 16 +#define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) +#define VGIC_MAX_PRIVATE (VGIC_NR_PRIVATE_IRQS - 1) +#define VGIC_MAX_SPI 1019 +#define VGIC_MAX_RESERVED 1023 +#define VGIC_MIN_LPI 8192 + +enum vgic_type { + VGIC_V2, /* Good ol' GICv2 */ + VGIC_V3, /* New fancy GICv3 */ +}; + +/* same for all guests, as depending only on the _host's_ GIC model */ +struct vgic_global { + /* type of the host GIC */ + enum vgic_type type; + + /* Physical address of vgic virtual cpu interface */ + phys_addr_t vcpu_base; + + /* virtual control interface mapping */ + void __iomem *vctrl_base; + + /* Number of implemented list registers */ + int nr_lr; + + /* Maintenance IRQ number */ + unsigned int maint_irq; + + /* maximum number of VCPUs allowed (GICv2 limits us to 8) */ + int max_gic_vcpus; + + /* Only needed for the legacy KVM_CREATE_IRQCHIP */ + bool can_emulate_gicv2; +}; + +extern struct vgic_global kvm_vgic_global_state; + +#define VGIC_V2_MAX_LRS (1 << 6) +#define VGIC_V3_MAX_LRS 16 +#define VGIC_V3_LR_INDEX(lr) (VGIC_V3_MAX_LRS - 1 - lr) + +enum vgic_irq_config { + VGIC_CONFIG_EDGE = 0, + VGIC_CONFIG_LEVEL +}; + +struct vgic_irq { + spinlock_t irq_lock; /* Protects the content of the struct */ + struct list_head ap_list; + + struct kvm_vcpu *vcpu; /* SGIs and PPIs: The VCPU + * SPIs and LPIs: The VCPU whose ap_list + * this is queued on. + */ + + struct kvm_vcpu *target_vcpu; /* The VCPU that this interrupt should + * be sent to, as a result of the + * targets reg (v2) or the + * affinity reg (v3). + */ + + u32 intid; /* Guest visible INTID */ + bool pending; + bool line_level; /* Level only */ + bool soft_pending; /* Level only */ + bool active; /* not used for LPIs */ + bool enabled; + bool hw; /* Tied to HW IRQ */ + u32 hwintid; /* HW INTID number */ + union { + u8 targets; /* GICv2 target VCPUs mask */ + u32 mpidr; /* GICv3 target VCPU */ + }; + u8 source; /* GICv2 SGIs only */ + u8 priority; + enum vgic_irq_config config; /* Level or edge */ +}; + +struct vgic_dist { + bool in_kernel; + bool ready; + + /* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */ + u32 vgic_model; + + int nr_spis; + + /* TODO: Consider moving to global state */ + /* Virtual control interface mapping */ + void __iomem *vctrl_base; + + /* base addresses in guest physical address space: */ + gpa_t vgic_dist_base; /* distributor */ + union { + /* either a GICv2 CPU interface */ + gpa_t vgic_cpu_base; + /* or a number of GICv3 redistributor regions */ + gpa_t vgic_redist_base; + }; + + /* distributor enabled */ + bool enabled; + + struct vgic_irq *spis; +}; + +struct vgic_v2_cpu_if { + u32 vgic_hcr; + u32 vgic_vmcr; + u32 vgic_misr; /* Saved only */ + u64 vgic_eisr; /* Saved only */ + u64 vgic_elrsr; /* Saved only */ + u32 vgic_apr; + u32 vgic_lr[VGIC_V2_MAX_LRS]; +}; + +struct vgic_v3_cpu_if { +#ifdef CONFIG_KVM_ARM_VGIC_V3 + u32 vgic_hcr; + u32 vgic_vmcr; + u32 vgic_sre; /* Restored only, change ignored */ + 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 { + /* CPU vif control registers for world switch */ + union { + struct vgic_v2_cpu_if vgic_v2; + struct vgic_v3_cpu_if vgic_v3; + }; + + unsigned int used_lrs; + struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS]; + + spinlock_t ap_list_lock; /* Protects the ap_list */ + + /* + * List of IRQs that this VCPU should consider because they are either + * Active or Pending (hence the name; AP list), or because they recently + * were one of the two and need to be migrated off this list to another + * VCPU. + */ + struct list_head ap_list_head; + + u64 live_lrs; +}; + +#define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) +#define vgic_initialized(k) (false) +#define vgic_ready(k) ((k)->arch.vgic.ready) +#define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ + ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) + +/** + * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW + * + * The host's GIC naturally limits the maximum amount of VCPUs a guest + * can use. + */ +static inline int kvm_vgic_get_max_vcpus(void) +{ + return kvm_vgic_global_state.max_gic_vcpus; +} + +#endif /* __ASM_ARM_KVM_VGIC_VGIC_H */ -- cgit From 81eeb95ddbabbb998a6b39f762bc7edaa2a979b4 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Wed, 25 Nov 2015 10:02:16 -0800 Subject: KVM: arm/arm64: vgic-new: Implement virtual IRQ injection Provide a vgic_queue_irq_unlock() function which decides whether a given IRQ needs to be queued to a VCPU's ap_list. This should be called whenever an IRQ becomes pending or enabled, either as a result of userspace injection, from in-kernel emulated devices like the architected timer or from MMIO accesses to the distributor emulation. Also provides the necessary functions to allow userland to inject an IRQ to a guest. Since this is the first code that starts using our locking mechanism, we add some (hopefully) clear documentation of our locking strategy and requirements along with this patch. Signed-off-by: Christoffer Dall Signed-off-by: Andre Przywara --- include/kvm/vgic/vgic.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 6ca0781ac2cc..7b6ca90861b8 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -181,6 +181,9 @@ struct vgic_cpu { u64 live_lrs; }; +int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, + bool level); + #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) #define vgic_initialized(k) (false) #define vgic_ready(k) ((k)->arch.vgic.ready) -- cgit From 0919e84c0fc1fc73525fdcedefab89ea8460f697 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 26 Nov 2015 17:19:25 +0000 Subject: KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework Implement the framework for syncing IRQs between our emulation and the list registers, which represent the guest's view of IRQs. This is done in kvm_vgic_flush_hwstate and kvm_vgic_sync_hwstate, which gets called on guest entry and exit. The code talking to the actual GICv2/v3 hardware is added in the following patches. Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Eric Auger Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 7b6ca90861b8..9506267498e5 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -190,6 +190,10 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) +bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu); +void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); +void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); + /** * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW * -- cgit From 140b086dd19771410915a924db2e635c2b51a0f4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 26 Nov 2015 17:19:25 +0000 Subject: KVM: arm/arm64: vgic-new: Add GICv2 world switch backend Processing maintenance interrupts and accessing the list registers are dependent on the host's GIC version. Introduce vgic-v2.c to contain GICv2 specific functions. Implement the GICv2 specific code for syncing the emulation state into the VGIC registers. Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Eric Auger Reviewed-by: Christoffer Dall --- include/linux/irqchip/arm-gic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 9c940263ca23..be0d26f940af 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -76,6 +76,7 @@ #define GICH_LR_VIRTUALID (0x3ff << 0) #define GICH_LR_PHYSID_CPUID_SHIFT (10) #define GICH_LR_PHYSID_CPUID (0x3ff << GICH_LR_PHYSID_CPUID_SHIFT) +#define GICH_LR_PRIORITY_SHIFT 23 #define GICH_LR_STATE (3 << 28) #define GICH_LR_PENDING_BIT (1 << 28) #define GICH_LR_ACTIVE_BIT (1 << 29) -- cgit From 59529f69f5048e50dcde3434661981c01f8208b4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 30 Nov 2015 13:09:53 +0000 Subject: KVM: arm/arm64: vgic-new: Add GICv3 world switch backend As the GICv3 virtual interface registers differ from their GICv2 siblings, we need different handlers for processing maintenance interrupts and reading/writing to the LRs. Implement the respective handler functions and connect them to existing code to be called if the host is using a GICv3. Signed-off-by: Marc Zyngier Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/linux/irqchip/arm-gic-v3.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index ec938d14da5d..35e93cfa1742 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -275,6 +275,7 @@ #define ICH_LR_ACTIVE_BIT (1ULL << 63) #define ICH_LR_PHYS_ID_SHIFT 32 #define ICH_LR_PHYS_ID_MASK (0x3ffULL << ICH_LR_PHYS_ID_SHIFT) +#define ICH_LR_PRIORITY_SHIFT 48 /* These are for GICv2 emulation only */ #define GICH_LR_VIRTUALID (0x3ffUL << 0) -- cgit From 90eee56c5f9081686035972dfcddfd6c85cafdf9 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Mon, 7 Dec 2015 15:30:38 +0000 Subject: KVM: arm/arm64: vgic-new: Implement kvm_vgic_vcpu_pending_irq Tell KVM whether a particular VCPU has an IRQ that needs handling in the guest. This is used to decide whether a VCPU is runnable. Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall Reviewed-by: Marc Zyngier --- include/kvm/vgic/vgic.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 9506267498e5..f6632880870f 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -184,6 +184,8 @@ struct vgic_cpu { int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, bool level); +int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); + #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) #define vgic_initialized(k) (false) #define vgic_ready(k) ((k)->arch.vgic.ready) -- cgit From 4493b1c4866a03963a35be7d157c911a617a3694 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Apr 2016 11:06:12 +0100 Subject: KVM: arm/arm64: vgic-new: Add MMIO handling framework Add an MMIO handling framework to the VGIC emulation: Each register is described by its offset, size (or number of bits per IRQ, if applicable) and the read/write handler functions. We provide initialization macros to describe each GIC register later easily. Separate dispatch functions for read and write accesses are connected to the kvm_io_bus framework and binary-search for the responsible register handler based on the offset address within the region. We convert the incoming data (referenced by a pointer) to the host's endianess and use pass-by-value to hand the data over to the actual handler functions. The register handler prototype and the endianess conversion are courtesy of Christoffer Dall. Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index f6632880870f..ff3f9c2abd95 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -106,6 +106,16 @@ struct vgic_irq { enum vgic_irq_config config; /* Level or edge */ }; +struct vgic_register_region; + +struct vgic_io_device { + gpa_t base_addr; + struct kvm_vcpu *redist_vcpu; + const struct vgic_register_region *regions; + int nr_regions; + struct kvm_io_device dev; +}; + struct vgic_dist { bool in_kernel; bool ready; @@ -132,6 +142,9 @@ struct vgic_dist { bool enabled; struct vgic_irq *spis; + + struct vgic_io_device dist_iodev; + struct vgic_io_device *redist_iodevs; }; struct vgic_v2_cpu_if { -- cgit From 2b0cda8789654bfcebca397daebc37aff081bd75 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Apr 2016 11:06:47 +0100 Subject: KVM: arm/arm64: vgic-new: Add CTLR, TYPER and IIDR handlers Those three registers are v2 emulation specific, so their implementation lives entirely in vgic-mmio-v2.c. Also they are handled in one function, as their implementation is pretty simple. When the guest enables the distributor, we kick all VCPUs to get potentially pending interrupts serviced. Signed-off-by: Marc Zyngier Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/linux/irqchip/arm-gic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index be0d26f940af..fd051855539b 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -33,6 +33,7 @@ #define GIC_DIST_CTRL 0x000 #define GIC_DIST_CTR 0x004 +#define GIC_DIST_IIDR 0x008 #define GIC_DIST_IGROUP 0x080 #define GIC_DIST_ENABLE_SET 0x100 #define GIC_DIST_ENABLE_CLEAR 0x180 -- cgit From 621ecd8d2123bc13e140b519e01a18200aeb614c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 26 Jan 2016 15:31:15 +0000 Subject: KVM: arm/arm64: vgic-new: Add GICv3 SGI system register trap handler In contrast to GICv2 SGIs in a GICv3 implementation are not triggered by a MMIO write, but with a system register write. KVM knows about that register already, we just need to implement the handler and wire it up to the core KVM/ARM code. Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index ff3f9c2abd95..00e3dca10a63 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -209,6 +209,14 @@ bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu); void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); +#ifdef CONFIG_KVM_ARM_VGIC_V3 +void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg); +#else +static inline void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg) +{ +} +#endif + /** * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW * -- cgit From e2c1f9abff83ee0ad0f78e03918c7edf070edb39 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Mon, 21 Dec 2015 16:36:04 +0100 Subject: KVM: arm/arm64: vgic-new: vgic_kvm_device: implement kvm_vgic_addr kvm_vgic_addr is used by the userspace to set the base address of the following register regions, as seen by the guest: - distributor(v2 and v3), - re-distributors (v3), - CPU interface (v2). Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 00e3dca10a63..3689b9bf3af7 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -194,6 +194,8 @@ struct vgic_cpu { u64 live_lrs; }; +int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); + int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, bool level); -- cgit From 909777324588b40d431e6e3af0911ee62e0d00e3 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Tue, 1 Dec 2015 15:02:35 +0100 Subject: KVM: arm/arm64: vgic-new: vgic_init: implement kvm_vgic_hyp_init Implements kvm_vgic_hyp_init and vgic_probe function. This uses the new firmware independent VGIC probing to support both ACPI and DT based systems (code from Marc Zyngier). The vgic_global struct is enriched with new fields populated by those functions. Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 3689b9bf3af7..393489fdc480 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -195,6 +195,7 @@ struct vgic_cpu { }; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); +int kvm_vgic_hyp_init(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, bool level); -- cgit From 5e6431da8f3a04759ac8d77b7c98eec0de580343 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Mon, 21 Dec 2015 14:50:50 +0100 Subject: KVM: arm/arm64: vgic-new: vgic_init: implement vgic_create This patch implements the vgic_creation function which is called on CREATE_IRQCHIP VM IOCTL (v2 only) or KVM_CREATE_DEVICE Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 393489fdc480..0634d895007a 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -195,6 +195,7 @@ struct vgic_cpu { }; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); +int kvm_vgic_create(struct kvm *kvm, u32 type); int kvm_vgic_hyp_init(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, -- cgit From ad275b8bb1e659b14120174d87e3c1fdc22e9978 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Mon, 21 Dec 2015 18:09:38 +0100 Subject: KVM: arm/arm64: vgic-new: vgic_init: implement vgic_init This patch allocates and initializes the data structures used to model the vgic distributor and virtual cpu interfaces. At that stage the number of IRQs and number of virtual CPUs is frozen. Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 0634d895007a..e7ae36b9bffa 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -119,6 +119,7 @@ struct vgic_io_device { struct vgic_dist { bool in_kernel; bool ready; + bool initialized; /* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */ u32 vgic_model; @@ -195,7 +196,11 @@ struct vgic_cpu { }; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); +void kvm_vgic_early_init(struct kvm *kvm); int kvm_vgic_create(struct kvm *kvm, u32 type); +void kvm_vgic_destroy(struct kvm *kvm); +void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu); +void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); int kvm_vgic_hyp_init(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, @@ -204,7 +209,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) -#define vgic_initialized(k) (false) +#define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_ready(k) ((k)->arch.vgic.ready) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) -- cgit From b0442ee227e826afc4df16cdfb8bd6eef6a8f425 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Mon, 21 Dec 2015 15:04:42 +0100 Subject: KVM: arm/arm64: vgic-new: vgic_init: implement map_resources map_resources is the last initialization step. It is executed on first VCPU run. At that stage the code checks that userspace has provided the base addresses for the relevant VGIC regions, which depend on the type of VGIC that is exposed to the guest. Also we check if the two regions overlap. If the checks succeeded, we register the respective register frames with the kvm_io_bus framework. If we emulate a GICv2, the function also forces vgic_init execution if it has not been executed yet. Also we map the virtual GIC CPU interface onto the guest's CPU interface. Signed-off-by: Eric Auger Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index e7ae36b9bffa..17b2a73cca96 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -201,6 +201,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type); void kvm_vgic_destroy(struct kvm *kvm); void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu); void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); +int kvm_vgic_map_resources(struct kvm *kvm); int kvm_vgic_hyp_init(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, -- cgit From 568e8c901eaa62004640cad8b9773819f27461a0 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 22 Dec 2015 00:52:33 +0000 Subject: KVM: arm/arm64: vgic-new: implement mapped IRQ handling We now store the mapped hardware IRQ number in our struct, so we don't need the irq_phys_map for the new VGIC. Implement the hardware IRQ mapping on top of the reworked arch timer interface. Signed-off-by: Andre Przywara Reviewed-by: Christoffer Dall --- include/kvm/vgic/vgic.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index 17b2a73cca96..3fbd175265ae 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -206,6 +206,11 @@ int kvm_vgic_hyp_init(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, bool level); +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, unsigned int intid, + bool level); +int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq); +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq); +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); -- cgit From cfc5abbcd043752c426740e61700010abfcc71e1 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 23 May 2016 08:43:33 +0200 Subject: KVM: Unify traced vector format Specifically the change from hex to decimal helps correlating events. Signed-off-by: Jan Kiszka Signed-off-by: Paolo Bonzini --- include/trace/events/kvm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 526fb3d2e43a..f28292d73ddb 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -108,7 +108,7 @@ TRACE_EVENT(kvm_ioapic_set_irq, __entry->coalesced = coalesced; ), - TP_printk("pin %u dst %x vec=%u (%s|%s|%s%s)%s", + TP_printk("pin %u dst %x vec %u (%s|%s|%s%s)%s", __entry->pin, (u8)(__entry->e >> 56), (u8)__entry->e, __print_symbolic((__entry->e >> 8 & 0x7), kvm_deliver_mode), (__entry->e & (1<<11)) ? "logical" : "physical", @@ -129,7 +129,7 @@ TRACE_EVENT(kvm_ioapic_delayed_eoi_inj, __entry->e = e; ), - TP_printk("dst %x vec=%u (%s|%s|%s%s)", + TP_printk("dst %x vec %u (%s|%s|%s%s)", (u8)(__entry->e >> 56), (u8)__entry->e, __print_symbolic((__entry->e >> 8 & 0x7), kvm_deliver_mode), (__entry->e & (1<<11)) ? "logical" : "physical", @@ -151,7 +151,7 @@ TRACE_EVENT(kvm_msi_set_irq, __entry->data = data; ), - TP_printk("dst %u vec %x (%s|%s|%s%s)", + TP_printk("dst %u vec %u (%s|%s|%s%s)", (u8)(__entry->address >> 12), (u8)__entry->data, __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode), (__entry->address & (1<<2)) ? "logical" : "physical", -- cgit From 536a6f88c49dd739961ffd53774775afed852c83 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Wed, 18 May 2016 13:26:23 +0200 Subject: KVM: Create debugfs dir and stat files for each VM This patch adds a kvm debugfs subdirectory for each VM, which is named after its pid and file descriptor. The directories contain the same kind of files that are already in the kvm debugfs directory, but the data exported through them is now VM specific. This makes the debugfs kvm data a convenient alternative to the tracepoints which already have per VM data. The debugfs data is easy to read and low overhead. CC: Dan Carpenter [includes fixes by Dan Carpenter] Signed-off-by: Janosch Frank Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b1fa8f11c95b..1c9c973a7dd9 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -412,6 +412,8 @@ struct kvm { #endif long tlbs_dirty; struct list_head devices; + struct dentry *debugfs_dentry; + struct kvm_stat_data **debugfs_stat_data; }; #define kvm_err(fmt, ...) \ @@ -991,6 +993,11 @@ enum kvm_stat_kind { KVM_STAT_VCPU, }; +struct kvm_stat_data { + int offset; + struct kvm *kvm; +}; + struct kvm_stats_debugfs_item { const char *name; int offset; -- cgit