[PATCH] ppc: initialize GPRs as per epapr
ePAPR defines the initial values of cpu registers. This patch initialize the GPRs as per ePAPR specification. This resolves the issue of guest reboot/reset (guest hang on reboot). Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com Signed-off-by: Stuart Yoder stuart.yo...@freescale.com --- hw/ppc/e500.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index c1bdb6b..a47f976 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -37,6 +37,7 @@ #include qemu/host-utils.h #include hw/pci-host/ppce500.h +#define EPAPR_MAGIC(0x45504150) #define BINARY_DEVICE_TREE_FILEmpc8544ds.dtb #define UIMAGE_LOAD_BASE 0 #define DTC_LOAD_PAD 0x180 @@ -444,6 +445,12 @@ static void ppce500_cpu_reset(void *opaque) cs-halted = 0; env-gpr[1] = (1620) - 8; env-gpr[3] = bi-dt_base; +env-gpr[4] = 0; +env-gpr[5] = 0; +env-gpr[6] = EPAPR_MAGIC; +env-gpr[7] = (64 * 1024 * 1024); +env-gpr[8] = 0; +env-gpr[9] = 0; env-nip = bi-entry; mmubooke_create_initial_mapping(env); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] ppc: initialize GPRs as per epapr
This was supposed to go to qemu-devel. Please Ignore this patch: Thanks -Bharat -Original Message- From: Bhushan Bharat-R65777 Sent: Friday, April 26, 2013 11:44 AM To: kvm-ppc@vger.kernel.org; k...@vger.kernel.org; ag...@suse.de; Wood Scott- B07421 Cc: Bhushan Bharat-R65777; Bhushan Bharat-R65777; Yoder Stuart-B08248 Subject: [PATCH] ppc: initialize GPRs as per epapr ePAPR defines the initial values of cpu registers. This patch initialize the GPRs as per ePAPR specification. This resolves the issue of guest reboot/reset (guest hang on reboot). Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com Signed-off-by: Stuart Yoder stuart.yo...@freescale.com --- hw/ppc/e500.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index c1bdb6b..a47f976 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -37,6 +37,7 @@ #include qemu/host-utils.h #include hw/pci-host/ppce500.h +#define EPAPR_MAGIC(0x45504150) #define BINARY_DEVICE_TREE_FILEmpc8544ds.dtb #define UIMAGE_LOAD_BASE 0 #define DTC_LOAD_PAD 0x180 @@ -444,6 +445,12 @@ static void ppce500_cpu_reset(void *opaque) cs-halted = 0; env-gpr[1] = (1620) - 8; env-gpr[3] = bi-dt_base; +env-gpr[4] = 0; +env-gpr[5] = 0; +env-gpr[6] = EPAPR_MAGIC; +env-gpr[7] = (64 * 1024 * 1024); +env-gpr[8] = 0; +env-gpr[9] = 0; env-nip = bi-entry; mmubooke_create_initial_mapping(env); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] kvm: destroy emulated devices on VM exit
On 26.04.2013, at 02:11, Scott Wood wrote: The hassle of getting refcounting right was greater than the hassle of keeping a list of devices to destroy on VM exit. Signed-off-by: Scott Wood scottw...@freescale.com Thanks, applied both to my irqfd mpic queue. Alex --- arch/powerpc/kvm/mpic.c |2 -- include/linux/kvm_host.h |3 ++- virt/kvm/kvm_main.c | 29 - 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index d137df8..4ac98d1 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1788,7 +1788,6 @@ int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, if (opp-mpic_mode_mask == GCR_MODE_PROXY) vcpu-arch.epr_flags |= KVMPPC_EPR_KERNEL; - kvm_device_get(dev); out: spin_unlock_irq(opp-lock); return ret; @@ -1804,7 +1803,6 @@ void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu) BUG_ON(!opp-dst[vcpu-arch.irq_cpu_id].vcpu); opp-dst[vcpu-arch.irq_cpu_id].vcpu = NULL; - kvm_device_put(opp-dev); } /* diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index feffbda..36c9776 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -393,6 +393,7 @@ struct kvm { long mmu_notifier_count; #endif long tlbs_dirty; + struct list_head devices; }; #define kvm_err(fmt, ...) \ @@ -1069,8 +1070,8 @@ struct kvm_device_ops; struct kvm_device { struct kvm_device_ops *ops; struct kvm *kvm; - atomic_t users; void *private; + struct list_head vm_node; }; /* create, destroy, and name are mandatory */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f6cd14d..5da9f02 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -504,6 +504,7 @@ static struct kvm *kvm_create_vm(unsigned long type) mutex_init(kvm-irq_lock); mutex_init(kvm-slots_lock); atomic_set(kvm-users_count, 1); + INIT_LIST_HEAD(kvm-devices); r = kvm_init_mmu_notifier(kvm); if (r) @@ -581,6 +582,19 @@ void kvm_free_physmem(struct kvm *kvm) kfree(kvm-memslots); } +static void kvm_destroy_devices(struct kvm *kvm) +{ + struct list_head *node, *tmp; + + list_for_each_safe(node, tmp, kvm-devices) { + struct kvm_device *dev = + list_entry(node, struct kvm_device, vm_node); + + list_del(node); + dev-ops-destroy(dev); + } +} + static void kvm_destroy_vm(struct kvm *kvm) { int i; @@ -600,6 +614,7 @@ static void kvm_destroy_vm(struct kvm *kvm) kvm_arch_flush_shadow_all(kvm); #endif kvm_arch_destroy_vm(kvm); + kvm_destroy_devices(kvm); kvm_free_physmem(kvm); cleanup_srcu_struct(kvm-srcu); kvm_arch_free_vm(kvm); @@ -2195,23 +2210,11 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl, } } -void kvm_device_get(struct kvm_device *dev) -{ - atomic_inc(dev-users); -} - -void kvm_device_put(struct kvm_device *dev) -{ - if (atomic_dec_and_test(dev-users)) - dev-ops-destroy(dev); -} - static int kvm_device_release(struct inode *inode, struct file *filp) { struct kvm_device *dev = filp-private_data; struct kvm *kvm = dev-kvm; - kvm_device_put(dev); kvm_put_kvm(kvm); return 0; } @@ -2257,7 +2260,6 @@ static int kvm_ioctl_create_device(struct kvm *kvm, dev-ops = ops; dev-kvm = kvm; - atomic_set(dev-users, 1); ret = ops-create(dev, cd-type); if (ret 0) { @@ -2271,6 +2273,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, return ret; } + list_add(dev-vm_node, kvm-devices); kvm_get_kvm(kvm); cd-fd = ret; return 0; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] kvm/powerpc/e500mc: fix tlb invalidation on cpu migration
On 25.04.2013, at 11:04, Caraman Mihai Claudiu-B02008 wrote: On 08.03.2013, at 21:25, Scott Wood wrote: The existing check handles the case where we've migrated to a different core than we last ran on, but it doesn't handle the case where we're still on the same cpu we last ran on, but some other vcpu has run on this cpu in the meantime. Without this, guest segfaults (and other misbehavior) have been seen in smp guests. Cc: sta...@vger.kernel.org # 3.8.x Signed-off-by: Scott Wood scottw...@freescale.com Thanks, applied to kvm-ppc-3.9. Alex Can you pull it into kvm-ppc-queue? It's not in kvm/next, so it'd potentially screw things up again when I create a new pull request. Please just do a manual git merge of kvm/master or linus/master into kvm-ppc-queue. Alex -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] KVM: PPC: cache flush for kernel managed pages
On 25.04.2013, at 18:33, Bharat Bhushan wrote: From: Bharat Bhushan bharat.bhus...@freescale.com Kernel can only access pages which maps as memory. So flush only the valid kernel pages. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com Thanks, applied to kvm-ppc-queue. Alex --- v1-v2 - move pfn_valid() check in kvmppc_mmu_flush_icache - Added comment to describe why this is needed arch/powerpc/include/asm/kvm_ppc.h |9 - 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index f589307..4794de6 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -282,8 +282,15 @@ void kvmppc_init_lpid(unsigned long nr_lpids); static inline void kvmppc_mmu_flush_icache(pfn_t pfn) { - /* Clear i-cache for new pages */ struct page *page; + /* + * We can only access pages that the kernel maps + * as memory. Bail out for unmapped ones. + */ + if (!pfn_valid(pfn)) + return; + + /* Clear i-cache for new pages */ page = pfn_to_page(pfn); if (!test_bit(PG_arch_1, page-flags)) { flush_dcache_icache_page(page); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/20] KVM: Drop __KVM_HAVE_IOAPIC condition on irq routing
We have a capability enquire system that allows user space to ask kvm whether a feature is available. The point behind this system is that we can have different kernel configurations with different capabilities and user space can adjust accordingly. Because features can always be non existent, we can drop any #ifdefs on CAP defines that could be used generically, like the irq routing bits. These can be easily reused for non-IOAPIC systems as well. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/uapi/linux/kvm.h |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 74d0ff3..c741902 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -579,9 +579,7 @@ struct kvm_ppc_smmu_info { #ifdef __KVM_HAVE_PIT #define KVM_CAP_REINJECT_CONTROL 24 #endif -#ifdef __KVM_HAVE_IOAPIC #define KVM_CAP_IRQ_ROUTING 25 -#endif #define KVM_CAP_IRQ_INJECT_STATUS 26 #ifdef __KVM_HAVE_DEVICE_ASSIGNMENT #define KVM_CAP_DEVICE_DEASSIGNMENT 27 -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/20] KVM: Remove kvm_get_intr_delivery_bitmask
The prototype has been stale for a while, I can't spot any real function define behind it. Let's just remove it. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/linux/kvm_host.h |5 - 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4215d4f..a7bfe9d 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -719,11 +719,6 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, bool mask); -#ifdef __KVM_HAVE_IOAPIC -void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, - union kvm_ioapic_redirect_entry *entry, - unsigned long *deliver_bitmask); -#endif int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, bool line_status); int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level); -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/20] KVM: Introduce CONFIG_HAVE_KVM_IRQ_ROUTING
Quite a bit of code in KVM has been conditionalized on availability of IOAPIC emulation. However, most of it is generically applicable to platforms that don't have an IOPIC, but a different type of irq chip. Make code that only relies on IRQ routing, not an APIC itself, on CONFIG_HAVE_KVM_IRQ_ROUTING, so that we can reuse it later. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/Kconfig |1 + include/linux/kvm_host.h |6 +++--- virt/kvm/Kconfig |3 +++ virt/kvm/eventfd.c |6 +++--- virt/kvm/kvm_main.c |2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 586f000..9d50efd 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -29,6 +29,7 @@ config KVM select MMU_NOTIFIER select ANON_INODES select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING select HAVE_KVM_EVENTFD select KVM_APIC_ARCHITECTURE select KVM_ASYNC_PF diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bf3b1dc..4215d4f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -304,7 +304,7 @@ struct kvm_kernel_irq_routing_entry { struct hlist_node link; }; -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING struct kvm_irq_routing_table { int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; @@ -432,7 +432,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); int __must_check vcpu_load(struct kvm_vcpu *vcpu); void vcpu_put(struct kvm_vcpu *vcpu); -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING int kvm_irqfd_init(void); void kvm_irqfd_exit(void); #else @@ -957,7 +957,7 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq) } #endif -#ifdef KVM_CAP_IRQ_ROUTING +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING #define KVM_MAX_IRQ_ROUTES 1024 diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index d01b24b..779262f 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -6,6 +6,9 @@ config HAVE_KVM config HAVE_KVM_IRQCHIP bool +config HAVE_KVM_IRQ_ROUTING + bool + config HAVE_KVM_EVENTFD bool select EVENTFD diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index c5d43ff..64ee720 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -35,7 +35,7 @@ #include iodev.h -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING /* * * irqfd: Allows an fd to be used to inject an interrupt to the guest @@ -433,7 +433,7 @@ fail: void kvm_eventfd_init(struct kvm *kvm) { -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING spin_lock_init(kvm-irqfds.lock); INIT_LIST_HEAD(kvm-irqfds.items); INIT_LIST_HEAD(kvm-irqfds.resampler_list); @@ -442,7 +442,7 @@ kvm_eventfd_init(struct kvm *kvm) INIT_LIST_HEAD(kvm-ioeventfds); } -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING /* * shutdown any irqfd's that match fd+gsi */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index aaac1a7..2c3b226 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2404,7 +2404,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) case KVM_CAP_SIGNAL_MSI: #endif return 1; -#ifdef KVM_CAP_IRQ_ROUTING +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING case KVM_CAP_IRQ_ROUTING: return KVM_MAX_IRQ_ROUTES; #endif -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/20] KVM: PPC: In-kernel MPIC support with irqfd v4
Hi, This patch set contains a fully working implementation of the in-kernel MPIC from Scott with a few fixups and a new version of my irqfd generalization patch set. v1 - v2: - depend on CONFIG_ defines rather than __KVM defines - fix compile issues - fix the kvm_irqchip{,s} typo v2 - v3: - make mpic pointer type safe - add wmb before setting global mpic variable - make eoi notification happen unlockedly - add IRQ routing documentation - announce mpic availability after its creation - fix pr_debug again v3 - v4: - update documentation - fix spin locks - remove default routing map - move eoi notify code into eoi register handler - fix header - new: KVM: IA64: Carry non-ia64 changes into ia64 - new: kvm: destroy emulated devices on VM exit - new: kvm/ppc/mpic: Eliminate mmio_mapped Alex Alexander Graf (12): KVM: Add KVM_IRQCHIP_NUM_PINS in addition to KVM_IOAPIC_NUM_PINS KVM: Introduce CONFIG_HAVE_KVM_IRQ_ROUTING KVM: Drop __KVM_HAVE_IOAPIC condition on irq routing KVM: Remove kvm_get_intr_delivery_bitmask KVM: Move irq routing to generic code KVM: Extract generic irqchip logic into irqchip.c KVM: Move irq routing setup to irqchip.c KVM: Move irqfd resample cap handling to generic code KVM: PPC: Support irq routing and irqfd for in-kernel MPIC KVM: PPC: MPIC: Add support for KVM_IRQ_LINE KVM: PPC: MPIC: Restrict to e500 platforms KVM: IA64: Carry non-ia64 changes into ia64 Scott Wood (8): kvm: add device control API kvm/ppc/mpic: import hw/openpic.c from QEMU kvm/ppc/mpic: remove some obviously unneeded code kvm/ppc/mpic: adapt to kernel style and environment kvm/ppc/mpic: in-kernel MPIC emulation kvm/ppc/mpic: add KVM_CAP_IRQ_MPIC kvm: destroy emulated devices on VM exit kvm/ppc/mpic: Eliminate mmio_mapped Documentation/virtual/kvm/api.txt | 78 ++ Documentation/virtual/kvm/devices/README |1 + Documentation/virtual/kvm/devices/mpic.txt | 56 + arch/ia64/include/asm/kvm_host.h |1 + arch/ia64/kvm/Kconfig |1 + arch/ia64/kvm/Makefile |2 +- arch/powerpc/include/asm/kvm_host.h| 24 +- arch/powerpc/include/asm/kvm_ppc.h | 30 + arch/powerpc/include/uapi/asm/kvm.h|9 + arch/powerpc/kvm/Kconfig | 12 + arch/powerpc/kvm/Makefile |3 + arch/powerpc/kvm/booke.c | 12 +- arch/powerpc/kvm/irq.h | 17 + arch/powerpc/kvm/mpic.c| 1843 arch/powerpc/kvm/powerpc.c | 55 +- arch/x86/include/asm/kvm_host.h|2 + arch/x86/kvm/Kconfig |1 + arch/x86/kvm/Makefile |2 +- arch/x86/kvm/x86.c |1 - include/linux/kvm_host.h | 54 +- include/trace/events/kvm.h | 12 +- include/uapi/linux/kvm.h | 33 +- virt/kvm/Kconfig |3 + virt/kvm/assigned-dev.c| 30 - virt/kvm/eventfd.c |6 +- virt/kvm/irq_comm.c| 194 +--- virt/kvm/irqchip.c | 237 virt/kvm/kvm_main.c| 173 +++- 28 files changed, 2641 insertions(+), 251 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/README create mode 100644 Documentation/virtual/kvm/devices/mpic.txt create mode 100644 arch/powerpc/kvm/irq.h create mode 100644 arch/powerpc/kvm/mpic.c create mode 100644 virt/kvm/irqchip.c -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/20] KVM: Move irqfd resample cap handling to generic code
Now that we have most irqfd code completely platform agnostic, let's move irqfd's resample capability return to generic code as well. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/x86.c |1 - virt/kvm/kvm_main.c |3 +++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 50e2e10..888d892 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2513,7 +2513,6 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PCI_2_3: case KVM_CAP_KVMCLOCK_CTRL: case KVM_CAP_READONLY_MEM: - case KVM_CAP_IRQFD_RESAMPLE: r = 1; break; case KVM_CAP_COALESCED_MMIO: diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b6f3354..f9492f3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2433,6 +2433,9 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) #ifdef CONFIG_HAVE_KVM_MSI case KVM_CAP_SIGNAL_MSI: #endif +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING + case KVM_CAP_IRQFD_RESAMPLE: +#endif return 1; #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING case KVM_CAP_IRQ_ROUTING: -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 19/20] kvm: destroy emulated devices on VM exit
From: Scott Wood scottw...@freescale.com The hassle of getting refcounting right was greater than the hassle of keeping a list of devices to destroy on VM exit. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c |2 -- include/linux/kvm_host.h |3 ++- virt/kvm/kvm_main.c | 29 - 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 89fe1d6..795ca0c 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1781,7 +1781,6 @@ int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, if (opp-mpic_mode_mask == GCR_MODE_PROXY) vcpu-arch.epr_flags |= KVMPPC_EPR_KERNEL; - kvm_device_get(dev); out: spin_unlock_irq(opp-lock); return ret; @@ -1797,7 +1796,6 @@ void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu) BUG_ON(!opp-dst[vcpu-arch.irq_cpu_id].vcpu); opp-dst[vcpu-arch.irq_cpu_id].vcpu = NULL; - kvm_device_put(opp-dev); } /* diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index feffbda..36c9776 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -393,6 +393,7 @@ struct kvm { long mmu_notifier_count; #endif long tlbs_dirty; + struct list_head devices; }; #define kvm_err(fmt, ...) \ @@ -1069,8 +1070,8 @@ struct kvm_device_ops; struct kvm_device { struct kvm_device_ops *ops; struct kvm *kvm; - atomic_t users; void *private; + struct list_head vm_node; }; /* create, destroy, and name are mandatory */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f6cd14d..5da9f02 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -504,6 +504,7 @@ static struct kvm *kvm_create_vm(unsigned long type) mutex_init(kvm-irq_lock); mutex_init(kvm-slots_lock); atomic_set(kvm-users_count, 1); + INIT_LIST_HEAD(kvm-devices); r = kvm_init_mmu_notifier(kvm); if (r) @@ -581,6 +582,19 @@ void kvm_free_physmem(struct kvm *kvm) kfree(kvm-memslots); } +static void kvm_destroy_devices(struct kvm *kvm) +{ + struct list_head *node, *tmp; + + list_for_each_safe(node, tmp, kvm-devices) { + struct kvm_device *dev = + list_entry(node, struct kvm_device, vm_node); + + list_del(node); + dev-ops-destroy(dev); + } +} + static void kvm_destroy_vm(struct kvm *kvm) { int i; @@ -600,6 +614,7 @@ static void kvm_destroy_vm(struct kvm *kvm) kvm_arch_flush_shadow_all(kvm); #endif kvm_arch_destroy_vm(kvm); + kvm_destroy_devices(kvm); kvm_free_physmem(kvm); cleanup_srcu_struct(kvm-srcu); kvm_arch_free_vm(kvm); @@ -2195,23 +2210,11 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl, } } -void kvm_device_get(struct kvm_device *dev) -{ - atomic_inc(dev-users); -} - -void kvm_device_put(struct kvm_device *dev) -{ - if (atomic_dec_and_test(dev-users)) - dev-ops-destroy(dev); -} - static int kvm_device_release(struct inode *inode, struct file *filp) { struct kvm_device *dev = filp-private_data; struct kvm *kvm = dev-kvm; - kvm_device_put(dev); kvm_put_kvm(kvm); return 0; } @@ -2257,7 +2260,6 @@ static int kvm_ioctl_create_device(struct kvm *kvm, dev-ops = ops; dev-kvm = kvm; - atomic_set(dev-users, 1); ret = ops-create(dev, cd-type); if (ret 0) { @@ -2271,6 +2273,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, return ret; } + list_add(dev-vm_node, kvm-devices); kvm_get_kvm(kvm); cd-fd = ret; return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 20/20] kvm/ppc/mpic: Eliminate mmio_mapped
From: Scott Wood scottw...@freescale.com We no longer need to keep track of this now that MPIC destruction always happens either during VM destruction (after MMIO has been destroyed) or during a failed creation (before the fd has been exposed to userspace, and thus before the MMIO region could have been registered). Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 29 + 1 files changed, 1 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 795ca0c..f3148f8 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -190,7 +190,6 @@ struct openpic { struct kvm_io_device mmio; struct list_head mmio_regions; atomic_t users; - bool mmio_mapped; gpa_t reg_base; spinlock_t lock; @@ -1428,24 +1427,13 @@ static int kvm_mpic_write(struct kvm_io_device *this, gpa_t addr, return ret; } -static void kvm_mpic_dtor(struct kvm_io_device *this) -{ - struct openpic *opp = container_of(this, struct openpic, mmio); - - opp-mmio_mapped = false; -} - static const struct kvm_io_device_ops mpic_mmio_ops = { .read = kvm_mpic_read, .write = kvm_mpic_write, - .destructor = kvm_mpic_dtor, }; static void map_mmio(struct openpic *opp) { - BUG_ON(opp-mmio_mapped); - opp-mmio_mapped = true; - kvm_iodevice_init(opp-mmio, mpic_mmio_ops); kvm_io_bus_register_dev(opp-kvm, KVM_MMIO_BUS, @@ -1455,10 +1443,7 @@ static void map_mmio(struct openpic *opp) static void unmap_mmio(struct openpic *opp) { - if (opp-mmio_mapped) { - opp-mmio_mapped = false; - kvm_io_bus_unregister_dev(opp-kvm, KVM_MMIO_BUS, opp-mmio); - } + kvm_io_bus_unregister_dev(opp-kvm, KVM_MMIO_BUS, opp-mmio); } static int set_base_addr(struct openpic *opp, struct kvm_device_attr *attr) @@ -1637,18 +1622,6 @@ static void mpic_destroy(struct kvm_device *dev) { struct openpic *opp = dev-private; - if (opp-mmio_mapped) { - /* -* Normally we get unmapped by kvm_io_bus_destroy(), -* which happens before the VCPUs release their references. -* -* Thus, we should only get here if no VCPUs took a reference -* to us in the first place. -*/ - WARN_ON(opp-nb_cpus != 0); - unmap_mmio(opp); - } - dev-kvm-arch.mpic = NULL; kfree(opp); } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/20] KVM: PPC: MPIC: Restrict to e500 platforms
The code as is doesn't make any sense on non-e500 platforms. Restrict it there, so that people don't get wrong ideas on what would actually work. This patch should get reverted as soon as it's possible to either run e500 guests on non-e500 hosts or the MPIC emulation gains support for non-e500 modes. Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index a608570..e88b1da 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -153,7 +153,7 @@ config KVM_E500MC config KVM_MPIC bool KVM in-kernel MPIC emulation - depends on KVM + depends on KVM E500 select HAVE_KVM_IRQCHIP select HAVE_KVM_IRQ_ROUTING select HAVE_KVM_MSI -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 18/20] KVM: IA64: Carry non-ia64 changes into ia64
We changed a few things in non-ia64 code paths. This patch blindly applies the changes to the ia64 code as well, hoping it proves useful in case anyone revives the ia64 kvm code. Signed-off-by: Alexander Graf ag...@suse.de --- arch/ia64/include/asm/kvm_host.h |1 + arch/ia64/kvm/Kconfig|1 + arch/ia64/kvm/Makefile |2 +- 3 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index cfa7498..989dd3f 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h @@ -26,6 +26,7 @@ #define KVM_USER_MEM_SLOTS 32 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 +#define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS /* define exit reasons from vmm to kvm*/ #define EXIT_REASON_VM_PANIC 0 diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 2cd225f..043183a 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig @@ -27,6 +27,7 @@ config KVM select PREEMPT_NOTIFIERS select ANON_INODES select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING select KVM_APIC_ARCHITECTURE select KVM_MMIO ---help--- diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index db3d7c5..511f64a 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile @@ -49,7 +49,7 @@ ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ - coalesced_mmio.o irq_comm.o assigned-dev.o) + coalesced_mmio.o irq_comm.o assigned-dev.o irqchip.o) ifeq ($(CONFIG_IOMMU_API),y) common-objs += $(addprefix ../../../virt/kvm/, iommu.o) -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 16/20] KVM: PPC: MPIC: Add support for KVM_IRQ_LINE
Now that all pieces are in place for reusing generic irq infrastructure, we can copy x86's implementation of KVM_IRQ_LINE irq injection and simply reuse it for PPC, as it will work there just as well. Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/uapi/asm/kvm.h |1 + arch/powerpc/kvm/powerpc.c | 13 + 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 3537bf3..dbb2ac2 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -26,6 +26,7 @@ #define __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT #define __KVM_HAVE_IRQCHIP +#define __KVM_HAVE_IRQ_LINE struct kvm_regs { __u64 pc; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index c431fea..874c106 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -33,6 +33,7 @@ #include asm/cputhreads.h #include asm/irqflags.h #include timing.h +#include irq.h #include ../mm/mmu_decl.h #define CREATE_TRACE_POINTS @@ -945,6 +946,18 @@ static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) return 0; } +int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, + bool line_status) +{ + if (!irqchip_in_kernel(kvm)) + return -ENXIO; + + irq_event-status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, + irq_event-irq, irq_event-level, + line_status); + return 0; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/20] kvm/ppc/mpic: remove some obviously unneeded code
From: Scott Wood scottw...@freescale.com Remove some parts of the code that are obviously QEMU or Raven specific before fixing style issues, to reduce the style issues that need to be fixed. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 344 --- 1 files changed, 0 insertions(+), 344 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 57655b9..d6d70a4 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -22,39 +22,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -/* - * - * Based on OpenPic implementations: - * - Intel GW80314 I/O companion chip developer's manual - * - Motorola MPC8245 MPC8540 user manuals. - * - Motorola MCP750 (aka Raven) programmer manual. - * - Motorola Harrier programmer manuel - * - * Serial interrupts, as implemented in Raven chipset are not supported yet. - * - */ -#include hw.h -#include ppc/mac.h -#include pci/pci.h -#include openpic.h -#include sysbus.h -#include pci/msi.h -#include qemu/bitops.h -#include ppc.h - -//#define DEBUG_OPENPIC - -#ifdef DEBUG_OPENPIC -static const int debug_openpic = 1; -#else -static const int debug_openpic = 0; -#endif - -#define DPRINTF(fmt, ...) do { \ -if (debug_openpic) { \ -printf(fmt , ## __VA_ARGS__); \ -} \ -} while (0) #define MAX_CPU 32 #define MAX_SRC 256 @@ -82,21 +49,6 @@ static const int debug_openpic = 0; #define OPENPIC_CPU_REG_START0x2 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) -/* Raven */ -#define RAVEN_MAX_CPU 2 -#define RAVEN_MAX_EXT 48 -#define RAVEN_MAX_IRQ 64 -#define RAVEN_MAX_TMR MAX_TMR -#define RAVEN_MAX_IPI MAX_IPI - -/* Interrupt definitions */ -#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */ -#define RAVEN_ERR_IRQ(RAVEN_MAX_EXT + 1) /* Error IRQ */ -#define RAVEN_TMR_IRQ(RAVEN_MAX_EXT + 2) /* First timer IRQ */ -#define RAVEN_IPI_IRQ(RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */ -/* First doorbell IRQ */ -#define RAVEN_DBL_IRQ(RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI)) - typedef struct FslMpicInfo { int max_ext; } FslMpicInfo; @@ -138,44 +90,6 @@ static FslMpicInfo fsl_mpic_42 = { #define ILR_INTTGT_CINT 0x01 /* critical */ #define ILR_INTTGT_MCP0x02 /* machine check */ -/* The currently supported INTTGT values happen to be the same as QEMU's - * openpic output codes, but don't depend on this. The output codes - * could change (unlikely, but...) or support could be added for - * more INTTGT values. - */ -static const int inttgt_output[][2] = { - {ILR_INTTGT_INT, OPENPIC_OUTPUT_INT}, - {ILR_INTTGT_CINT, OPENPIC_OUTPUT_CINT}, - {ILR_INTTGT_MCP, OPENPIC_OUTPUT_MCK}, -}; - -static int inttgt_to_output(int inttgt) -{ - int i; - - for (i = 0; i ARRAY_SIZE(inttgt_output); i++) { - if (inttgt_output[i][0] == inttgt) { - return inttgt_output[i][1]; - } - } - - fprintf(stderr, %s: unsupported inttgt %d\n, __func__, inttgt); - return OPENPIC_OUTPUT_INT; -} - -static int output_to_inttgt(int output) -{ - int i; - - for (i = 0; i ARRAY_SIZE(inttgt_output); i++) { - if (inttgt_output[i][1] == output) { - return inttgt_output[i][0]; - } - } - - abort(); -} - #define MSIIR_OFFSET 0x140 #define MSIIR_SRS_SHIFT29 #define MSIIR_SRS_MASK (0x7 MSIIR_SRS_SHIFT) @@ -1265,228 +1179,36 @@ static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len) return openpic_cpu_read_internal(opaque, addr, (addr 0x1f000) 12); } -static const MemoryRegionOps openpic_glb_ops_le = { - .write = openpic_gbl_write, - .read = openpic_gbl_read, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, -}; - static const MemoryRegionOps openpic_glb_ops_be = { .write = openpic_gbl_write, .read = openpic_gbl_read, - .endianness = DEVICE_BIG_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, -}; - -static const MemoryRegionOps openpic_tmr_ops_le = { - .write = openpic_tmr_write, - .read = openpic_tmr_read, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, }; static const MemoryRegionOps openpic_tmr_ops_be = { .write = openpic_tmr_write, .read = openpic_tmr_read, - .endianness = DEVICE_BIG_ENDIAN, - .impl = { -.min_access_size = 4, -
[PATCH 15/20] KVM: PPC: Support irq routing and irqfd for in-kernel MPIC
Now that all the irq routing and irqfd pieces are generic, we can expose real irqchip support to all of KVM's internal helpers. This allows us to use irqfd with the in-kernel MPIC. Signed-off-by: Alexander Graf ag...@suse.de --- v2 - v3: - make mpic pointer type safe - add wmb before setting global mpic variable - make eoi notification happen unlockedly - add IRQ routing documentation - announce mpic availability after its creation v3 - v4: - update documentation - fix spin locks - remove default routing map - move eoi notify code into eoi register handler --- Documentation/virtual/kvm/devices/mpic.txt | 19 + arch/powerpc/include/asm/kvm_host.h|7 ++ arch/powerpc/include/uapi/asm/kvm.h|1 + arch/powerpc/kvm/Kconfig |3 + arch/powerpc/kvm/Makefile |1 + arch/powerpc/kvm/irq.h | 17 arch/powerpc/kvm/mpic.c| 111 +++- 7 files changed, 158 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/kvm/irq.h diff --git a/Documentation/virtual/kvm/devices/mpic.txt b/Documentation/virtual/kvm/devices/mpic.txt index ce98e32..ad0ac77 100644 --- a/Documentation/virtual/kvm/devices/mpic.txt +++ b/Documentation/virtual/kvm/devices/mpic.txt @@ -35,3 +35,22 @@ Groups: attr is the IRQ number. IRQ numbers for standard sources are the byte offset of the relevant IVPR from EIVPR0, divided by 32. + +IRQ Routing: + + The MPIC emulation supports IRQ routing. Only a single MPIC device can + be instantiated. Once that device has been created, it's available as + irqchip id 0. + + This irqchip 0 has 256 interrupt pins, which expose the interrupts in + the main array of interrupt sources (a.k.a. SRC interrupts). + + The numbering is the same as the MPIC device tree binding -- based on + the register offset from the beginning of the sources array, without + regard to any subdivisions in chip documentation such as internal + or external interrupts. + + Default routes are established for these pins, with the GSI being equal + to the pin number. + + Access to non-SRC interrupts is not implemented through IRQ routing mechanisms. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 36368c9..80f2004 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -44,6 +44,10 @@ #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #endif +/* These values are internal and can be increased later */ +#define KVM_NR_IRQCHIPS 1 +#define KVM_IRQCHIP_NUM_PINS 256 + #if !defined(CONFIG_KVM_440) #include linux/mmu_notifier.h @@ -256,6 +260,9 @@ struct kvm_arch { #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; #endif +#ifdef CONFIG_KVM_MPIC + struct openpic *mpic; +#endif }; /* diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 36be2fe..3537bf3 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -25,6 +25,7 @@ /* Select powerpc specific features in linux/kvm.h */ #define __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT +#define __KVM_HAVE_IRQCHIP struct kvm_regs { __u64 pc; diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 938a729..a608570 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -154,6 +154,9 @@ config KVM_E500MC config KVM_MPIC bool KVM in-kernel MPIC emulation depends on KVM + select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING + select HAVE_KVM_MSI help Enable support for emulating MPIC devices inside the host kernel, rather than relying on userspace to emulate. diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 4a2277a..4eada0c 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -104,6 +104,7 @@ kvm-book3s_32-objs := \ kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o +kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(addprefix ../../../virt/kvm/, irqchip.o) kvm-objs := $(kvm-objs-m) $(kvm-objs-y) diff --git a/arch/powerpc/kvm/irq.h b/arch/powerpc/kvm/irq.h new file mode 100644 index 000..f1e27fd --- /dev/null +++ b/arch/powerpc/kvm/irq.h @@ -0,0 +1,17 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#include linux/kvm_host.h + +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + int ret = 0; + +#ifdef CONFIG_KVM_MPIC + ret = ret || (kvm-arch.mpic != NULL); +#endif + smp_rmb(); + return ret; +} + +#endif diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 10bc08a..89fe1d6 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1076,7 +1076,9 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr, case 0xA0: /* IACK */ /*
[PATCH 13/20] kvm/ppc/mpic: in-kernel MPIC emulation
From: Scott Wood scottw...@freescale.com Hook the MPIC code up to the KVM interfaces, add locking, etc. Signed-off-by: Scott Wood scottw...@freescale.com [agraf: add stub function for kvmppc_mpic_set_epr, non-booke, 64bit] Signed-off-by: Alexander Graf ag...@suse.de --- v2 - v3: - fix pr_debug again --- Documentation/virtual/kvm/devices/mpic.txt | 37 ++ arch/powerpc/include/asm/kvm_host.h|8 +- arch/powerpc/include/asm/kvm_ppc.h | 17 + arch/powerpc/include/uapi/asm/kvm.h|7 + arch/powerpc/kvm/Kconfig |9 + arch/powerpc/kvm/Makefile |2 + arch/powerpc/kvm/booke.c |8 +- arch/powerpc/kvm/mpic.c| 762 +--- arch/powerpc/kvm/powerpc.c | 12 +- include/linux/kvm_host.h |2 + include/uapi/linux/kvm.h |3 + virt/kvm/kvm_main.c|6 + 12 files changed, 673 insertions(+), 200 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/mpic.txt diff --git a/Documentation/virtual/kvm/devices/mpic.txt b/Documentation/virtual/kvm/devices/mpic.txt new file mode 100644 index 000..ce98e32 --- /dev/null +++ b/Documentation/virtual/kvm/devices/mpic.txt @@ -0,0 +1,37 @@ +MPIC interrupt controller += + +Device types supported: + KVM_DEV_TYPE_FSL_MPIC_20 Freescale MPIC v2.0 + KVM_DEV_TYPE_FSL_MPIC_42 Freescale MPIC v4.2 + +Only one MPIC instance, of any type, may be instantiated. The created +MPIC will act as the system interrupt controller, connecting to each +vcpu's interrupt inputs. + +Groups: + KVM_DEV_MPIC_GRP_MISC + Attributes: +KVM_DEV_MPIC_BASE_ADDR (rw, 64-bit) + Base address of the 256 KiB MPIC register space. Must be + naturally aligned. A value of zero disables the mapping. + Reset value is zero. + + KVM_DEV_MPIC_GRP_REGISTER (rw, 32-bit) +Access an MPIC register, as if the access were made from the guest. +attr is the byte offset into the MPIC register space. Accesses +must be 4-byte aligned. + +MSIs may be signaled by using this attribute group to write +to the relevant MSIIR. + + KVM_DEV_MPIC_GRP_IRQ_ACTIVE (rw, 32-bit) +IRQ input line for each standard openpic source. 0 is inactive and 1 +is active, regardless of interrupt sense. + +For edge-triggered interrupts: Writing 1 is considered an activating +edge, and writing 0 is ignored. Reading returns 1 if a previously +signaled edge has not been acknowledged, and 0 otherwise. + +attr is the IRQ number. IRQ numbers for standard sources are the +byte offset of the relevant IVPR from EIVPR0, divided by 32. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index e34f8fe..7e7aef9 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -359,6 +359,11 @@ struct kvmppc_slb { #define KVMPPC_BOOKE_MAX_IAC 4 #define KVMPPC_BOOKE_MAX_DAC 2 +/* KVMPPC_EPR_USER takes precedence over KVMPPC_EPR_KERNEL */ +#define KVMPPC_EPR_NONE0 /* EPR not supported */ +#define KVMPPC_EPR_USER1 /* exit to userspace to fill EPR */ +#define KVMPPC_EPR_KERNEL 2 /* in-kernel irqchip */ + struct kvmppc_booke_debug_reg { u32 dbcr0; u32 dbcr1; @@ -522,7 +527,7 @@ struct kvm_vcpu_arch { u8 sane; u8 cpu_type; u8 hcall_needed; - u8 epr_enabled; + u8 epr_flags; /* KVMPPC_EPR_xxx */ u8 epr_needed; u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ @@ -589,5 +594,6 @@ struct kvm_vcpu_arch { #define KVM_MMIO_REG_FQPR 0x0060 #define __KVM_HAVE_ARCH_WQP +#define __KVM_HAVE_CREATE_DEVICE #endif /* __POWERPC_KVM_HOST_H__ */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 4794de6..da43e5f 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -164,6 +164,8 @@ extern int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu); extern int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *); +int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); + /* * Cuts out inst bits with ordering according to spec. * That means the leftmost bit is zero. All given bits are included. @@ -245,6 +247,9 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *); void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); +struct openpic; +void kvmppc_mpic_put(struct openpic *opp); + #ifdef CONFIG_KVM_BOOK3S_64_HV static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) { @@ -270,6 +275,18 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) #endif } +#ifdef CONFIG_KVM_MPIC + +void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu); + +#else + +static inline void kvmppc_mpic_set_epr(struct
[PATCH 10/20] kvm/ppc/mpic: import hw/openpic.c from QEMU
From: Scott Wood scottw...@freescale.com This is QEMU's hw/openpic.c from commit abd8d4a4d6dfea7ddea72f095f993e1de941614e (Update version for 1.4.0-rc0), run through Lindent with no other changes to ease merging future changes between Linux and QEMU. Remaining style issues (including those introduced by Lindent) will be fixed in a later patch. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 1686 +++ 1 files changed, 1686 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/kvm/mpic.c diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c new file mode 100644 index 000..57655b9 --- /dev/null +++ b/arch/powerpc/kvm/mpic.c @@ -0,0 +1,1686 @@ +/* + * OpenPIC emulation + * + * Copyright (c) 2004 Jocelyn Mayer + * 2011 Alexander Graf + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* + * + * Based on OpenPic implementations: + * - Intel GW80314 I/O companion chip developer's manual + * - Motorola MPC8245 MPC8540 user manuals. + * - Motorola MCP750 (aka Raven) programmer manual. + * - Motorola Harrier programmer manuel + * + * Serial interrupts, as implemented in Raven chipset are not supported yet. + * + */ +#include hw.h +#include ppc/mac.h +#include pci/pci.h +#include openpic.h +#include sysbus.h +#include pci/msi.h +#include qemu/bitops.h +#include ppc.h + +//#define DEBUG_OPENPIC + +#ifdef DEBUG_OPENPIC +static const int debug_openpic = 1; +#else +static const int debug_openpic = 0; +#endif + +#define DPRINTF(fmt, ...) do { \ +if (debug_openpic) { \ +printf(fmt , ## __VA_ARGS__); \ +} \ +} while (0) + +#define MAX_CPU 32 +#define MAX_SRC 256 +#define MAX_TMR 4 +#define MAX_IPI 4 +#define MAX_MSI 8 +#define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR) +#define VID 0x03 /* MPIC version ID */ + +/* OpenPIC capability flags */ +#define OPENPIC_FLAG_IDR_CRIT (1 0) +#define OPENPIC_FLAG_ILR (2 0) + +/* OpenPIC address map */ +#define OPENPIC_GLB_REG_START0x0 +#define OPENPIC_GLB_REG_SIZE 0x10F0 +#define OPENPIC_TMR_REG_START0x10F0 +#define OPENPIC_TMR_REG_SIZE 0x220 +#define OPENPIC_MSI_REG_START0x1600 +#define OPENPIC_MSI_REG_SIZE 0x200 +#define OPENPIC_SUMMARY_REG_START 0x3800 +#define OPENPIC_SUMMARY_REG_SIZE0x800 +#define OPENPIC_SRC_REG_START0x1 +#define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20) +#define OPENPIC_CPU_REG_START0x2 +#define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) + +/* Raven */ +#define RAVEN_MAX_CPU 2 +#define RAVEN_MAX_EXT 48 +#define RAVEN_MAX_IRQ 64 +#define RAVEN_MAX_TMR MAX_TMR +#define RAVEN_MAX_IPI MAX_IPI + +/* Interrupt definitions */ +#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */ +#define RAVEN_ERR_IRQ(RAVEN_MAX_EXT + 1) /* Error IRQ */ +#define RAVEN_TMR_IRQ(RAVEN_MAX_EXT + 2) /* First timer IRQ */ +#define RAVEN_IPI_IRQ(RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */ +/* First doorbell IRQ */ +#define RAVEN_DBL_IRQ(RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI)) + +typedef struct FslMpicInfo { + int max_ext; +} FslMpicInfo; + +static FslMpicInfo fsl_mpic_20 = { + .max_ext = 12, +}; + +static FslMpicInfo fsl_mpic_42 = { + .max_ext = 12, +}; + +#define FRR_NIRQ_SHIFT16 +#define FRR_NCPU_SHIFT 8 +#define FRR_VID_SHIFT 0 + +#define VID_REVISION_1_2 2 +#define VID_REVISION_1_3 3 + +#define VIR_GENERIC 0x/* Generic Vendor ID */ + +#define GCR_RESET0x8000 +#define GCR_MODE_PASS0x +#define GCR_MODE_MIXED 0x2000 +#define GCR_MODE_PROXY 0x6000 + +#define TBCR_CI 0x8000 /* count inhibit */ +#define TCCR_TOG 0x8000 /* toggles
[PATCH 12/20] kvm/ppc/mpic: adapt to kernel style and environment
From: Scott Wood scottw...@freescale.com Remove braces that Linux style doesn't permit, remove space after '*' that Lindent added, keep error/debug strings contiguous, etc. Substitute type names, debug prints, etc. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 445 ++- 1 files changed, 208 insertions(+), 237 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index d6d70a4..1df67ae 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -42,22 +42,22 @@ #define OPENPIC_TMR_REG_SIZE 0x220 #define OPENPIC_MSI_REG_START0x1600 #define OPENPIC_MSI_REG_SIZE 0x200 -#define OPENPIC_SUMMARY_REG_START 0x3800 -#define OPENPIC_SUMMARY_REG_SIZE0x800 +#define OPENPIC_SUMMARY_REG_START0x3800 +#define OPENPIC_SUMMARY_REG_SIZE 0x800 #define OPENPIC_SRC_REG_START0x1 #define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20) #define OPENPIC_CPU_REG_START0x2 -#define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) +#define OPENPIC_CPU_REG_SIZE (0x100 + ((MAX_CPU - 1) * 0x1000)) -typedef struct FslMpicInfo { +struct fsl_mpic_info { int max_ext; -} FslMpicInfo; +}; -static FslMpicInfo fsl_mpic_20 = { +static struct fsl_mpic_info fsl_mpic_20 = { .max_ext = 12, }; -static FslMpicInfo fsl_mpic_42 = { +static struct fsl_mpic_info fsl_mpic_42 = { .max_ext = 12, }; @@ -100,44 +100,43 @@ static int get_current_cpu(void) { CPUState *cpu_single_cpu; - if (!cpu_single_env) { + if (!cpu_single_env) return -1; - } cpu_single_cpu = ENV_GET_CPU(cpu_single_env); return cpu_single_cpu-cpu_index; } -static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, int idx); -static void openpic_cpu_write_internal(void *opaque, hwaddr addr, +static uint32_t openpic_cpu_read_internal(void *opaque, gpa_t addr, int idx); +static void openpic_cpu_write_internal(void *opaque, gpa_t addr, uint32_t val, int idx); -typedef enum IRQType { +enum irq_type { IRQ_TYPE_NORMAL = 0, IRQ_TYPE_FSLINT,/* FSL internal interrupt -- level only */ IRQ_TYPE_FSLSPECIAL,/* FSL timer/IPI interrupt, edge, no polarity */ -} IRQType; +}; -typedef struct IRQQueue { +struct irq_queue { /* Round up to the nearest 64 IRQs so that the queue length * won't change when moving between 32 and 64 bit hosts. */ unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) ~63)]; int next; int priority; -} IRQQueue; +}; -typedef struct IRQSource { +struct irq_source { uint32_t ivpr; /* IRQ vector/priority register */ uint32_t idr; /* IRQ destination register */ uint32_t destmask; /* bitmap of CPU destinations */ int last_cpu; int output; /* IRQ level, e.g. OPENPIC_OUTPUT_INT */ int pending;/* TRUE if IRQ is pending */ - IRQType type; + enum irq_type type; bool level:1; /* level-triggered */ - bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ -} IRQSource; + bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ +}; #define IVPR_MASK_SHIFT 31 #define IVPR_MASK_MASK(1 IVPR_MASK_SHIFT) @@ -158,22 +157,19 @@ typedef struct IRQSource { #define IDR_EP 0x8000 /* external pin */ #define IDR_CI 0x4000 /* critical interrupt */ -typedef struct IRQDest { +struct irq_dest { int32_t ctpr; /* CPU current task priority */ - IRQQueue raised; - IRQQueue servicing; + struct irq_queue raised; + struct irq_queue servicing; qemu_irq *irqs; /* Count of IRQ sources asserting on non-INT outputs */ uint32_t outputs_active[OPENPIC_OUTPUT_NB]; -} IRQDest; - -typedef struct OpenPICState { - SysBusDevice busdev; - MemoryRegion mem; +}; +struct openpic { /* Behavior control */ - FslMpicInfo *fsl; + struct fsl_mpic_info *fsl; uint32_t model; uint32_t flags; uint32_t nb_irqs; @@ -186,9 +182,6 @@ typedef struct OpenPICState { uint32_t brr1; uint32_t mpic_mode_mask; - /* Sub-regions */ - MemoryRegion sub_io_mem[6]; - /* Global registers */ uint32_t frr; /* Feature reporting register */ uint32_t gcr; /* Global configuration register */ @@ -196,9 +189,9 @@ typedef struct OpenPICState { uint32_t spve; /* Spurious vector register */ uint32_t tfrr; /* Timer frequency reporting register */ /* Source registers */ - IRQSource src[MAX_IRQ]; + struct irq_source src[MAX_IRQ]; /* Local
[PATCH 06/20] KVM: Extract generic irqchip logic into irqchip.c
The current irq_comm.c file contains pieces of code that are generic across different irqchip implementations, as well as code that is fully IOAPIC specific. Split the generic bits out into irqchip.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/Makefile |2 +- include/trace/events/kvm.h | 12 +++- virt/kvm/irq_comm.c| 118 -- virt/kvm/irqchip.c | 152 4 files changed, 163 insertions(+), 121 deletions(-) create mode 100644 virt/kvm/irqchip.c diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 04d3040..a797b8e 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -7,7 +7,7 @@ CFLAGS_vmx.o := -I. kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ coalesced_mmio.o irq_comm.o eventfd.o \ - assigned-dev.o) + assigned-dev.o irqchip.o) kvm-$(CONFIG_IOMMU_API)+= $(addprefix ../../../virt/kvm/, iommu.o) kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 19911dd..7005d11 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -37,7 +37,7 @@ TRACE_EVENT(kvm_userspace_exit, __entry-errno 0 ? -__entry-errno : __entry-reason) ); -#if defined(__KVM_HAVE_IRQ_LINE) +#if defined(CONFIG_HAVE_KVM_IRQCHIP) TRACE_EVENT(kvm_set_irq, TP_PROTO(unsigned int gsi, int level, int irq_source_id), TP_ARGS(gsi, level, irq_source_id), @@ -122,6 +122,10 @@ TRACE_EVENT(kvm_msi_set_irq, {KVM_IRQCHIP_PIC_SLAVE, PIC slave}, \ {KVM_IRQCHIP_IOAPIC,IOAPIC} +#endif /* defined(__KVM_HAVE_IOAPIC) */ + +#if defined(CONFIG_HAVE_KVM_IRQCHIP) + TRACE_EVENT(kvm_ack_irq, TP_PROTO(unsigned int irqchip, unsigned int pin), TP_ARGS(irqchip, pin), @@ -136,14 +140,18 @@ TRACE_EVENT(kvm_ack_irq, __entry-pin= pin; ), +#ifdef kvm_irqchips TP_printk(irqchip %s pin %u, __print_symbolic(__entry-irqchip, kvm_irqchips), __entry-pin) +#else + TP_printk(irqchip %d pin %u, __entry-irqchip, __entry-pin) +#endif ); +#endif /* defined(CONFIG_HAVE_KVM_IRQCHIP) */ -#endif /* defined(__KVM_HAVE_IOAPIC) */ #define KVM_TRACE_MMIO_READ_UNSATISFIED 0 #define KVM_TRACE_MMIO_READ 1 diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 7c0071d..d5008f4 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -151,59 +151,6 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e, return -EWOULDBLOCK; } -int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) -{ - struct kvm_kernel_irq_routing_entry route; - - if (!irqchip_in_kernel(kvm) || msi-flags != 0) - return -EINVAL; - - route.msi.address_lo = msi-address_lo; - route.msi.address_hi = msi-address_hi; - route.msi.data = msi-data; - - return kvm_set_msi(route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); -} - -/* - * Return value: - * 0 Interrupt was ignored (masked or not delivered for other reasons) - * = 0 Interrupt was coalesced (previous irq is still pending) - * 0 Number of CPUs interrupt was delivered to - */ -int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, - bool line_status) -{ - struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; - int ret = -1, i = 0; - struct kvm_irq_routing_table *irq_rt; - - trace_kvm_set_irq(irq, level, irq_source_id); - - /* Not possible to detect if the guest uses the PIC or the -* IOAPIC. So set the bit in both. The guest will ignore -* writes to the unused one. -*/ - rcu_read_lock(); - irq_rt = rcu_dereference(kvm-irq_routing); - if (irq irq_rt-nr_rt_entries) - hlist_for_each_entry(e, irq_rt-map[irq], link) - irq_set[i++] = *e; - rcu_read_unlock(); - - while(i--) { - int r; - r = irq_set[i].set(irq_set[i], kvm, irq_source_id, level, - line_status); - if (r 0) - continue; - - ret = r + ((ret 0) ? 0 : ret); - } - - return ret; -} - /* * Deliver an IRQ in an atomic context if we can, or return a failure, * user can retry in a process context. @@ -241,63 +188,6 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level) return ret; } -bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) -{ - struct kvm_irq_ack_notifier *kian; - int gsi; - - rcu_read_lock(); - gsi
[PATCH 09/20] kvm: add device control API
From: Scott Wood scottw...@freescale.com Currently, devices that are emulated inside KVM are configured in a hardcoded manner based on an assumption that any given architecture only has one way to do it. If there's any need to access device state, it is done through inflexible one-purpose-only IOCTLs (e.g. KVM_GET/SET_LAPIC). Defining new IOCTLs for every little thing is cumbersome and depletes a limited numberspace. This API provides a mechanism to instantiate a device of a certain type, returning an ID that can be used to set/get attributes of the device. Attributes may include configuration parameters (e.g. register base address), device state, operational commands, etc. It is similar to the ONE_REG API, except that it acts on devices rather than vcpus. Both device types and individual attributes can be tested without having to create the device or get/set the attribute, without the need for separately managing enumerated capabilities. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- v3 - v4: - fix header --- Documentation/virtual/kvm/api.txt| 70 Documentation/virtual/kvm/devices/README |1 + include/linux/kvm_host.h | 35 include/uapi/linux/kvm.h | 27 ++ virt/kvm/kvm_main.c | 129 ++ 5 files changed, 262 insertions(+), 0 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/README diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 976eb65..d52f3f9 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2173,6 +2173,76 @@ header; first `n_valid' valid entries with contents from the data written, then `n_invalid' invalid entries, invalidating any previously valid entries found. +4.79 KVM_CREATE_DEVICE + +Capability: KVM_CAP_DEVICE_CTRL +Type: vm ioctl +Parameters: struct kvm_create_device (in/out) +Returns: 0 on success, -1 on error +Errors: + ENODEV: The device type is unknown or unsupported + EEXIST: Device already created, and this type of device may not + be instantiated multiple times + + Other error conditions may be defined by individual device types or + have their standard meanings. + +Creates an emulated device in the kernel. The file descriptor returned +in fd can be used with KVM_SET/GET/HAS_DEVICE_ATTR. + +If the KVM_CREATE_DEVICE_TEST flag is set, only test whether the +device type is supported (not necessarily whether it can be created +in the current vm). + +Individual devices should not define flags. Attributes should be used +for specifying any behavior that is not implied by the device type +number. + +struct kvm_create_device { + __u32 type; /* in: KVM_DEV_TYPE_xxx */ + __u32 fd; /* out: device handle */ + __u32 flags; /* in: KVM_CREATE_DEVICE_xxx */ +}; + +4.80 KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR + +Capability: KVM_CAP_DEVICE_CTRL +Type: device ioctl +Parameters: struct kvm_device_attr +Returns: 0 on success, -1 on error +Errors: + ENXIO: The group or attribute is unknown/unsupported for this device + EPERM: The attribute cannot (currently) be accessed this way + (e.g. read-only attribute, or attribute that only makes + sense when the device is in a different state) + + Other error conditions may be defined by individual device types. + +Gets/sets a specified piece of device configuration and/or state. The +semantics are device-specific. See individual device documentation in +the devices directory. As with ONE_REG, the size of the data +transferred is defined by the particular attribute. + +struct kvm_device_attr { + __u32 flags; /* no flags currently defined */ + __u32 group; /* device-defined */ + __u64 attr; /* group-defined */ + __u64 addr; /* userspace address of attr data */ +}; + +4.81 KVM_HAS_DEVICE_ATTR + +Capability: KVM_CAP_DEVICE_CTRL +Type: device ioctl +Parameters: struct kvm_device_attr +Returns: 0 on success, -1 on error +Errors: + ENXIO: The group or attribute is unknown/unsupported for this device + +Tests whether a device supports a particular attribute. A successful +return indicates the attribute is implemented. It does not necessarily +indicate that the attribute can be read or written in the device's +current state. addr is ignored. 4.77 KVM_ARM_VCPU_INIT diff --git a/Documentation/virtual/kvm/devices/README b/Documentation/virtual/kvm/devices/README new file mode 100644 index 000..34a6983 --- /dev/null +++ b/Documentation/virtual/kvm/devices/README @@ -0,0 +1 @@ +This directory contains specific device bindings for KVM_CAP_DEVICE_CTRL. diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index dcef724..6dab6b5 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1064,6 +1064,41 @@
[PATCH 07/20] KVM: Move irq routing setup to irqchip.c
Setting up IRQ routes is nothing IOAPIC specific. Extract everything that really is generic code into irqchip.c and only leave the ioapic specific bits to irq_comm.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/linux/kvm_host.h |3 ++ virt/kvm/irq_comm.c | 76 ++--- virt/kvm/irqchip.c | 85 ++ 3 files changed, 91 insertions(+), 73 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a7bfe9d..dcef724 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -961,6 +961,9 @@ int kvm_set_irq_routing(struct kvm *kvm, const struct kvm_irq_routing_entry *entries, unsigned nr, unsigned flags); +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue); void kvm_free_irq_routing(struct kvm *kvm); int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index d5008f4..e2e6b44 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -271,27 +271,14 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, rcu_read_unlock(); } -static int setup_routing_entry(struct kvm_irq_routing_table *rt, - struct kvm_kernel_irq_routing_entry *e, - const struct kvm_irq_routing_entry *ue) +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue) { int r = -EINVAL; int delta; unsigned max_pin; - struct kvm_kernel_irq_routing_entry *ei; - /* -* Do not allow GSI to be mapped to the same irqchip more than once. -* Allow only one to one mapping between GSI and MSI. -*/ - hlist_for_each_entry(ei, rt-map[ue-gsi], link) - if (ei-type == KVM_IRQ_ROUTING_MSI || - ue-type == KVM_IRQ_ROUTING_MSI || - ue-u.irqchip.irqchip == ei-irqchip.irqchip) - return r; - - e-gsi = ue-gsi; - e-type = ue-type; switch (ue-type) { case KVM_IRQ_ROUTING_IRQCHIP: delta = 0; @@ -328,68 +315,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, goto out; } - hlist_add_head(e-link, rt-map[e-gsi]); r = 0; out: return r; } -int kvm_set_irq_routing(struct kvm *kvm, - const struct kvm_irq_routing_entry *ue, - unsigned nr, - unsigned flags) -{ - struct kvm_irq_routing_table *new, *old; - u32 i, j, nr_rt_entries = 0; - int r; - - for (i = 0; i nr; ++i) { - if (ue[i].gsi = KVM_MAX_IRQ_ROUTES) - return -EINVAL; - nr_rt_entries = max(nr_rt_entries, ue[i].gsi); - } - - nr_rt_entries += 1; - - new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)) - + (nr * sizeof(struct kvm_kernel_irq_routing_entry)), - GFP_KERNEL); - - if (!new) - return -ENOMEM; - - new-rt_entries = (void *)new-map[nr_rt_entries]; - - new-nr_rt_entries = nr_rt_entries; - for (i = 0; i 3; i++) - for (j = 0; j KVM_IRQCHIP_NUM_PINS; j++) - new-chip[i][j] = -1; - - for (i = 0; i nr; ++i) { - r = -EINVAL; - if (ue-flags) - goto out; - r = setup_routing_entry(new, new-rt_entries[i], ue); - if (r) - goto out; - ++ue; - } - - mutex_lock(kvm-irq_lock); - old = kvm-irq_routing; - kvm_irq_routing_update(kvm, new); - mutex_unlock(kvm-irq_lock); - - synchronize_rcu(); - - new = old; - r = 0; - -out: - kfree(new); - return r; -} - #define IOAPIC_ROUTING_ENTRY(irq) \ { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) } diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 12f7f26..20dc9e4 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -150,3 +150,88 @@ void kvm_free_irq_routing(struct kvm *kvm) at this stage */ kfree(kvm-irq_routing); } + +static int setup_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue) +{ + int r = -EINVAL; + struct
[PATCH 01/20] KVM: Add KVM_IRQCHIP_NUM_PINS in addition to KVM_IOAPIC_NUM_PINS
The concept of routing interrupt lines to an irqchip is nothing that is IOAPIC specific. Every irqchip has a maximum number of pins that can be linked to irq lines. So let's add a new define that allows us to reuse generic code for non-IOAPIC platforms. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/include/asm/kvm_host.h |2 ++ include/linux/kvm_host.h|2 +- virt/kvm/irq_comm.c |2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 599f98b..f44c3fe 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -43,6 +43,8 @@ #define KVM_PIO_PAGE_OFFSET 1 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2 +#define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS + #define CR0_RESERVED_BITS \ (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \ | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 93a5005..bf3b1dc 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -307,7 +307,7 @@ struct kvm_kernel_irq_routing_entry { #ifdef __KVM_HAVE_IOAPIC struct kvm_irq_routing_table { - int chip[KVM_NR_IRQCHIPS][KVM_IOAPIC_NUM_PINS]; + int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; struct kvm_kernel_irq_routing_entry *rt_entries; u32 nr_rt_entries; /* diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 25ab480..7c0071d 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -480,7 +480,7 @@ int kvm_set_irq_routing(struct kvm *kvm, new-nr_rt_entries = nr_rt_entries; for (i = 0; i 3; i++) - for (j = 0; j KVM_IOAPIC_NUM_PINS; j++) + for (j = 0; j KVM_IRQCHIP_NUM_PINS; j++) new-chip[i][j] = -1; for (i = 0; i nr; ++i) { -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/20] KVM: Move irq routing to generic code
The IRQ routing set ioctl lives in the hacky device assignment code inside of KVM today. This is definitely the wrong place for it. Move it to the much more natural kvm_main.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- virt/kvm/assigned-dev.c | 30 -- virt/kvm/kvm_main.c | 30 ++ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index f4c7f59..8db4370 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -983,36 +983,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, goto out; break; } -#ifdef KVM_CAP_IRQ_ROUTING - case KVM_SET_GSI_ROUTING: { - struct kvm_irq_routing routing; - struct kvm_irq_routing __user *urouting; - struct kvm_irq_routing_entry *entries; - - r = -EFAULT; - if (copy_from_user(routing, argp, sizeof(routing))) - goto out; - r = -EINVAL; - if (routing.nr = KVM_MAX_IRQ_ROUTES) - goto out; - if (routing.flags) - goto out; - r = -ENOMEM; - entries = vmalloc(routing.nr * sizeof(*entries)); - if (!entries) - goto out; - r = -EFAULT; - urouting = argp; - if (copy_from_user(entries, urouting-entries, - routing.nr * sizeof(*entries))) - goto out_free_irq_routing; - r = kvm_set_irq_routing(kvm, entries, routing.nr, - routing.flags); - out_free_irq_routing: - vfree(entries); - break; - } -#endif /* KVM_CAP_IRQ_ROUTING */ #ifdef __KVM_HAVE_MSIX case KVM_ASSIGN_SET_MSIX_NR: { struct kvm_assigned_msix_nr entry_nr; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2c3b226..b6f3354 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2274,6 +2274,36 @@ static long kvm_vm_ioctl(struct file *filp, break; } #endif +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING + case KVM_SET_GSI_ROUTING: { + struct kvm_irq_routing routing; + struct kvm_irq_routing __user *urouting; + struct kvm_irq_routing_entry *entries; + + r = -EFAULT; + if (copy_from_user(routing, argp, sizeof(routing))) + goto out; + r = -EINVAL; + if (routing.nr = KVM_MAX_IRQ_ROUTES) + goto out; + if (routing.flags) + goto out; + r = -ENOMEM; + entries = vmalloc(routing.nr * sizeof(*entries)); + if (!entries) + goto out; + r = -EFAULT; + urouting = argp; + if (copy_from_user(entries, urouting-entries, + routing.nr * sizeof(*entries))) + goto out_free_irq_routing; + r = kvm_set_irq_routing(kvm, entries, routing.nr, + routing.flags); + out_free_irq_routing: + vfree(entries); + break; + } +#endif /* CONFIG_HAVE_KVM_IRQ_ROUTING */ default: r = kvm_arch_vm_ioctl(filp, ioctl, arg); if (r == -ENOTTY) -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 8/8 v3] KVM: PPC: e500: Add e6500 core to Kconfig description
On 04/26/2013 11:11 AM, tiejun.chen wrote: On 04/25/2013 07:32 PM, Caraman Mihai Claudiu-B02008 wrote: Is the flowing is fine with that generic machine, ppce500, to boot P5040DS with 64bit, ./qemu-system-ppc64 -enable-kvm -m 1048 -nographic -M ppce500 -kernel uImage -initrd ramdisk.gz -L . -append root=/dev/ram rw console=ttyS0,115200 -cpu e5500 -dtb p5040ds.dtb Thanks, Tiejun There is no need for -dtb. With your comment, I use kvm-ppc-queue which top commit is be28a27c, kvm/ppc: don't call complete_mmio_load when it's a store, in plus that patch you pointedto build one uImage based on corenet64_smp_defconfig, but we need to enable CONFIG_PPC_QEMU_E500 manually, and select CONFIG_TICK_CPU_ACCOUNTING since the default CONFIG_VIRT_CPU_ACCOUNTING_NATIVE would introduce some trace when boot VM. And perform as follows: ./qemu-system-ppc64 -enable-kvm -m 1048 -nographic -M ppce500 -kernel uImage -initrd ramdisk.gz -L . -append root=/dev/ram rw console=ttyS0,115200 -cpu e5500 But I can't see anything in the serial port. Please ignore this since e5500 is okay now. Thanks for your reply. Tiejun -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/6] kvm: add device control API
On Thu, Apr 25, 2013 at 01:59:20PM -0500, Scott Wood wrote: On 04/25/2013 01:22:04 PM, Gleb Natapov wrote: On Thu, Apr 25, 2013 at 11:51:08AM -0500, Scott Wood wrote: On 04/25/2013 05:47:39 AM, Alexander Graf wrote: On 25.04.2013, at 11:43, Gleb Natapov wrote: +void kvm_device_put(struct kvm_device *dev) +{ + if (atomic_dec_and_test(dev-users)) + dev-ops-destroy(dev); +} + +static int kvm_device_release(struct inode *inode, struct file *filp) +{ + struct kvm_device *dev = filp-private_data; + struct kvm *kvm = dev-kvm; + + kvm_device_put(dev); + kvm_put_kvm(kvm); We may put kvm only if users goes to zero, otherwise kvm can be freed while something holds a reference to a device. Why not make kvm_device_put() do it? Nice catch. I'll change the patch so it does the kvm_put_kvm inside kvm_device_put's destroy branch. No, please don't. The KVM reference being put here is associated with the file descriptor, not with the MPIC object. Is it so? Device holds a pointer to kvm, so it increments kvm reference to make sure the pointer is valid. What prevents kvm from been destroyed while device is still in use in current code? Where will that kvm pointer be used, after all the file descriptors go away and the vcpus stop running? mmio_mapped guards against unmapping the MMIO if it's already been unmapped due to KVM destruction. We don't have any timers or other delayed work. MPIC does not, but timer device will have one. Well, I do see one place, that Alex added -- the NULLing out of dev-kvm-arch.mpic, which didn't exist in my patchset. that change I think you'll have circular references and thus a memory leak, because the vcpus can hold a reference to the MPIC object. How circular reference can be created? MPIC holds reference on KVM, vcpu holds reference on MPIC, and vcpu is not destroyed until KVM is destroyed. Yes, you are right. So we need to think about how to fix it in a different way. What about holding all devices in kvm-devices[] array and destroy them during kvm destruction, like we do for vcpus? -- Gleb. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/6] kvm: add device control API
On Fri, Apr 26, 2013 at 11:55:27AM +0200, Alexander Graf wrote: On 26.04.2013, at 11:53, Gleb Natapov wrote: On Thu, Apr 25, 2013 at 01:59:20PM -0500, Scott Wood wrote: On 04/25/2013 01:22:04 PM, Gleb Natapov wrote: On Thu, Apr 25, 2013 at 11:51:08AM -0500, Scott Wood wrote: On 04/25/2013 05:47:39 AM, Alexander Graf wrote: On 25.04.2013, at 11:43, Gleb Natapov wrote: +void kvm_device_put(struct kvm_device *dev) +{ + if (atomic_dec_and_test(dev-users)) + dev-ops-destroy(dev); +} + +static int kvm_device_release(struct inode *inode, struct file *filp) +{ + struct kvm_device *dev = filp-private_data; + struct kvm *kvm = dev-kvm; + + kvm_device_put(dev); + kvm_put_kvm(kvm); We may put kvm only if users goes to zero, otherwise kvm can be freed while something holds a reference to a device. Why not make kvm_device_put() do it? Nice catch. I'll change the patch so it does the kvm_put_kvm inside kvm_device_put's destroy branch. No, please don't. The KVM reference being put here is associated with the file descriptor, not with the MPIC object. Is it so? Device holds a pointer to kvm, so it increments kvm reference to make sure the pointer is valid. What prevents kvm from been destroyed while device is still in use in current code? Where will that kvm pointer be used, after all the file descriptors go away and the vcpus stop running? mmio_mapped guards against unmapping the MMIO if it's already been unmapped due to KVM destruction. We don't have any timers or other delayed work. MPIC does not, but timer device will have one. Well, I do see one place, that Alex added -- the NULLing out of dev-kvm-arch.mpic, which didn't exist in my patchset. that change I think you'll have circular references and thus a memory leak, because the vcpus can hold a reference to the MPIC object. How circular reference can be created? MPIC holds reference on KVM, vcpu holds reference on MPIC, and vcpu is not destroyed until KVM is destroyed. Yes, you are right. So we need to think about how to fix it in a different way. What about holding all devices in kvm-devices[] array and destroy them during kvm destruction, like we do for vcpus? You should really look at your patches in LIFO order :). A patch doing that was already sent by Scott last night and is in v4 of my patch set. I tried! This causes starvation for some patches. I need better algorithm :) -- Gleb. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/7 v3] KVM: PPC: exit to user space on ehpriv instruction
On 08.04.2013, at 12:32, Bharat Bhushan wrote: From: Bharat Bhushan bharat.bhus...@freescale.com ehpriv instruction is used for setting software breakpoints by user space. This patch adds support to exit to user space with run-debug have relevant information. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/kvm/e500_emulate.c | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index e78f353..cefdd38 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -26,6 +26,7 @@ #define XOP_TLBRE 946 #define XOP_TLBWE 978 #define XOP_TLBILX 18 +#define XOP_EHPRIV 270 #ifdef CONFIG_KVM_E500MC static int dbell2prio(ulong param) @@ -130,6 +131,15 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, emulated = kvmppc_e500_emul_tlbivax(vcpu, ea); break; + case XOP_EHPRIV: This is supposed to check for oc, no? Alex + run-exit_reason = KVM_EXIT_DEBUG; + run-debug.arch.address = vcpu-arch.pc; + run-debug.arch.status = 0; + kvmppc_account_exit(vcpu, DEBUG_EXITS); + emulated = EMULATE_EXIT_USER; + *advance = 0; + break; + default: emulated = EMULATE_FAIL; } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/7 v3] KVM: PPC: exit to user space on ehpriv instruction
On 04/26/2013 06:45 PM, Alexander Graf wrote: On 08.04.2013, at 12:32, Bharat Bhushan wrote: From: Bharat Bhushan bharat.bhus...@freescale.com ehpriv instruction is used for setting software breakpoints by user space. This patch adds support to exit to user space with run-debug have relevant information. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/kvm/e500_emulate.c | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index e78f353..cefdd38 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -26,6 +26,7 @@ #define XOP_TLBRE 946 #define XOP_TLBWE 978 #define XOP_TLBILX 18 +#define XOP_EHPRIV 270 #ifdef CONFIG_KVM_E500MC static int dbell2prio(ulong param) @@ -130,6 +131,15 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, emulated = kvmppc_e500_emul_tlbivax(vcpu, ea); break; + case XOP_EHPRIV: This is supposed to check for oc, no? The other day I already sent one patch only to check OC, KVM/PPC: emulate ehpriv. But Bharat said he's waiting for other debug patches to be reviewed. Tiejun -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 7/7 v3] KVM: PPC: Add userspace debug stub support
On 08.04.2013, at 12:32, Bharat Bhushan wrote: From: Bharat Bhushan bharat.bhus...@freescale.com This patch adds the debug stub support on booke/bookehv. Now QEMU debug stub can use hw breakpoint, watchpoint and software breakpoint to debug guest. Debug registers are saved/restored on vcpu_put()/vcpu_get(). Also the debug registers are saved restored only if guest is using debug resources. Currently we do not support debug resource emulation to guest, so always exit to user space irrespective of user space is expecting the debug exception or not. This is unexpected event and let us leave the action on user space. This is similar to what it was before, only thing is that now we have proper exit state available to user space. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/include/asm/kvm_host.h |8 + arch/powerpc/include/uapi/asm/kvm.h | 22 +++- arch/powerpc/kvm/booke.c| 242 --- arch/powerpc/kvm/booke.h|5 + 4 files changed, 255 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index e34f8fe..b9ad20f 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -505,7 +505,15 @@ struct kvm_vcpu_arch { u32 mmucfg; u32 epr; u32 crit_save; + + /* Flag indicating that debug registers are used by guest */ + bool debug_active; + /* for save/restore thread-dbcr0 on vcpu run/heavyweight_exit */ + u32 saved_dbcr0; + /* guest debug registers*/ struct kvmppc_booke_debug_reg dbg_reg; + /* shadow debug registers */ + struct kvmppc_booke_debug_reg shadow_dbg_reg; #endif gpa_t paddr_accessed; gva_t vaddr_accessed; diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index c0c38ed..d7ce449 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -25,6 +25,7 @@ /* Select powerpc specific features in linux/kvm.h */ #define __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT +#define __KVM_HAVE_GUEST_DEBUG struct kvm_regs { __u64 pc; @@ -267,7 +268,24 @@ struct kvm_fpu { __u64 fpr[32]; }; +/* + * Defines for h/w breakpoint, watchpoint (read, write or both) and + * software breakpoint. + * These are used as type in KVM_SET_GUEST_DEBUG ioctl and status + * for KVM_DEBUG_EXIT. + */ +#define KVMPPC_DEBUG_NONE0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE (1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) struct kvm_debug_exit_arch { + __u64 address; + /* + * exiting to userspace because of h/w breakpoint, watchpoint + * (read, write or both) and software breakpoint. + */ + __u32 status; + __u32 reserved; }; /* for KVM_SET_GUEST_DEBUG */ @@ -279,10 +297,6 @@ struct kvm_guest_debug_arch { * Type denotes h/w breakpoint, read watchpoint, write * watchpoint or watchpoint (both read and write). */ -#define KVMPPC_DEBUG_NONE0x0 -#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) -#define KVMPPC_DEBUG_WATCH_WRITE (1UL 2) -#define KVMPPC_DEBUG_WATCH_READ (1UL 3) __u32 type; __u32 reserved; } bp[16]; diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 97ae158..0e93416 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -133,6 +133,29 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu) #endif } +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) +{ + /* Synchronize guest's desire to get debug interrupts into shadow MSR */ +#ifndef CONFIG_KVM_BOOKE_HV + vcpu-arch.shadow_msr = ~MSR_DE; + vcpu-arch.shadow_msr |= vcpu-arch.shared-msr MSR_DE; +#endif + + /* Force enable debug interrupts when user space wants to debug */ + if (vcpu-guest_debug) { +#ifdef CONFIG_KVM_BOOKE_HV + /* + * Since there is no shadow MSR, sync MSR_DE into the guest + * visible MSR. + */ + vcpu-arch.shared-msr |= MSR_DE; +#else + vcpu-arch.shadow_msr |= MSR_DE; + vcpu-arch.shared-msr = ~MSR_DE; +#endif + } +} + /* * Helper function for full MSR writes. No need to call this if only * EE/CE/ME/DE/RI are changing. @@ -150,6 +173,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr) kvmppc_mmu_msr_notify(vcpu, old_msr); kvmppc_vcpu_sync_spe(vcpu); kvmppc_vcpu_sync_fpu(vcpu); + kvmppc_vcpu_sync_debug(vcpu); } static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, @@ -646,6 +670,46 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu) return r; } +static void
Re: [PATCH 0/7 v3] KVM :PPC: Userspace Debug support
On 08.04.2013, at 12:32, Bharat Bhushan wrote: From: Bharat Bhushan bharat.bhus...@freescale.com This patchset adds the userspace debug support for booke/bookehv. this is tested on powerpc e500v2/e500mc devices. We are now assuming that debug resource will not be used by kernel for its own debugging. It will be used for only kernel user process debugging. So the kernel debug load interface during context_to is used to load debug conext for that selected process. Thanks, applied 1-4 to kvm-ppc-queue. 5 and above have comments. Alex -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/8 v3] KVM: PPC: e500: Enable FSL e6500 core
On 11.04.2013, at 12:03, Mihai Caraman wrote: Enable basic support for Freescale e6500 core, adding MAV 2.0 support. Validated on T4240QDS platfrom. Altivec, Multithreading and HW Tablewalk are not addressed by this patchset. Thanks, applied all to kvm-ppc-queue. Alex Mihai Caraman (8): KVM: PPC: Book3E: Refactor ONE_REG ioctl implementation KVM: PPC: e500: Expose MMU registers via ONE_REG KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions KVM: PPC: e500: Add support for TLBnPS registers KVM: PPC: e500: Add support for EPTCFG register KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs KVM: PPC: e500mc: Enable e6500 cores KVM: PPC: e500: Add e6500 core to Kconfig description Documentation/virtual/kvm/api.txt | 16 +++ arch/powerpc/include/asm/kvm_host.h |2 + arch/powerpc/include/uapi/asm/kvm.h | 22 arch/powerpc/kvm/44x.c | 12 ++ arch/powerpc/kvm/Kconfig|6 +- arch/powerpc/kvm/booke.c| 102 ++- arch/powerpc/kvm/e500.c | 14 +++ arch/powerpc/kvm/e500.h | 22 arch/powerpc/kvm/e500_emulate.c | 19 arch/powerpc/kvm/e500_mmu.c | 192 +++ arch/powerpc/kvm/e500mc.c | 16 +++ 11 files changed, 351 insertions(+), 72 deletions(-) -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/2] KVM: PPC: Migration bugfixes for HV KVM
On 19.04.2013, at 07:49, Paul Mackerras wrote: This series of two patches fixes a couple of bugs in live migration under HV-style KVM on PPC. They only touch PPC/HV code and add no new APIs. The patches are against Alex Graf's kvm-ppc-next branch. I would like them to go in for 3.10. Thanks, applied both to kvm-ppc-queue. Alex Paul. arch/powerpc/include/asm/kvm_book3s.h|3 +- arch/powerpc/include/asm/kvm_book3s_64.h | 13 arch/powerpc/include/asm/kvm_host.h |2 + arch/powerpc/kernel/asm-offsets.c|1 + arch/powerpc/kvm/book3s_64_mmu_hv.c | 120 +- arch/powerpc/kvm/book3s_hv.c | 30 +--- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 11 --- arch/powerpc/kvm/book3s_hv_rmhandlers.S |4 + 8 files changed, 143 insertions(+), 41 deletions(-) -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/20] KVM: Drop __KVM_HAVE_IOAPIC condition on irq routing
We have a capability enquire system that allows user space to ask kvm whether a feature is available. The point behind this system is that we can have different kernel configurations with different capabilities and user space can adjust accordingly. Because features can always be non existent, we can drop any #ifdefs on CAP defines that could be used generically, like the irq routing bits. These can be easily reused for non-IOAPIC systems as well. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/uapi/linux/kvm.h |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 74d0ff3..c741902 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -579,9 +579,7 @@ struct kvm_ppc_smmu_info { #ifdef __KVM_HAVE_PIT #define KVM_CAP_REINJECT_CONTROL 24 #endif -#ifdef __KVM_HAVE_IOAPIC #define KVM_CAP_IRQ_ROUTING 25 -#endif #define KVM_CAP_IRQ_INJECT_STATUS 26 #ifdef __KVM_HAVE_DEVICE_ASSIGNMENT #define KVM_CAP_DEVICE_DEASSIGNMENT 27 -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/20] KVM: PPC: In-kernel MPIC support with irqfd v4
Hi, This patch set contains a fully working implementation of the in-kernel MPIC from Scott with a few fixups and a new version of my irqfd generalization patch set. v1 - v2: - depend on CONFIG_ defines rather than __KVM defines - fix compile issues - fix the kvm_irqchip{,s} typo v2 - v3: - make mpic pointer type safe - add wmb before setting global mpic variable - make eoi notification happen unlockedly - add IRQ routing documentation - announce mpic availability after its creation - fix pr_debug again v3 - v4: - update documentation - fix spin locks - remove default routing map - move eoi notify code into eoi register handler - fix header - new: KVM: IA64: Carry non-ia64 changes into ia64 - new: kvm: destroy emulated devices on VM exit - new: kvm/ppc/mpic: Eliminate mmio_mapped Alex Alexander Graf (12): KVM: Add KVM_IRQCHIP_NUM_PINS in addition to KVM_IOAPIC_NUM_PINS KVM: Introduce CONFIG_HAVE_KVM_IRQ_ROUTING KVM: Drop __KVM_HAVE_IOAPIC condition on irq routing KVM: Remove kvm_get_intr_delivery_bitmask KVM: Move irq routing to generic code KVM: Extract generic irqchip logic into irqchip.c KVM: Move irq routing setup to irqchip.c KVM: Move irqfd resample cap handling to generic code KVM: PPC: Support irq routing and irqfd for in-kernel MPIC KVM: PPC: MPIC: Add support for KVM_IRQ_LINE KVM: PPC: MPIC: Restrict to e500 platforms KVM: IA64: Carry non-ia64 changes into ia64 Scott Wood (8): kvm: add device control API kvm/ppc/mpic: import hw/openpic.c from QEMU kvm/ppc/mpic: remove some obviously unneeded code kvm/ppc/mpic: adapt to kernel style and environment kvm/ppc/mpic: in-kernel MPIC emulation kvm/ppc/mpic: add KVM_CAP_IRQ_MPIC kvm: destroy emulated devices on VM exit kvm/ppc/mpic: Eliminate mmio_mapped Documentation/virtual/kvm/api.txt | 78 ++ Documentation/virtual/kvm/devices/README |1 + Documentation/virtual/kvm/devices/mpic.txt | 56 + arch/ia64/include/asm/kvm_host.h |1 + arch/ia64/kvm/Kconfig |1 + arch/ia64/kvm/Makefile |2 +- arch/powerpc/include/asm/kvm_host.h| 24 +- arch/powerpc/include/asm/kvm_ppc.h | 30 + arch/powerpc/include/uapi/asm/kvm.h|9 + arch/powerpc/kvm/Kconfig | 12 + arch/powerpc/kvm/Makefile |3 + arch/powerpc/kvm/booke.c | 12 +- arch/powerpc/kvm/irq.h | 17 + arch/powerpc/kvm/mpic.c| 1843 arch/powerpc/kvm/powerpc.c | 55 +- arch/x86/include/asm/kvm_host.h|2 + arch/x86/kvm/Kconfig |1 + arch/x86/kvm/Makefile |2 +- arch/x86/kvm/x86.c |1 - include/linux/kvm_host.h | 54 +- include/trace/events/kvm.h | 12 +- include/uapi/linux/kvm.h | 33 +- virt/kvm/Kconfig |3 + virt/kvm/assigned-dev.c| 30 - virt/kvm/eventfd.c |6 +- virt/kvm/irq_comm.c| 194 +--- virt/kvm/irqchip.c | 237 virt/kvm/kvm_main.c| 173 +++- 28 files changed, 2641 insertions(+), 251 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/README create mode 100644 Documentation/virtual/kvm/devices/mpic.txt create mode 100644 arch/powerpc/kvm/irq.h create mode 100644 arch/powerpc/kvm/mpic.c create mode 100644 virt/kvm/irqchip.c -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/20] kvm/ppc/mpic: adapt to kernel style and environment
From: Scott Wood scottw...@freescale.com Remove braces that Linux style doesn't permit, remove space after '*' that Lindent added, keep error/debug strings contiguous, etc. Substitute type names, debug prints, etc. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 445 ++- 1 files changed, 208 insertions(+), 237 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index d6d70a4..1df67ae 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -42,22 +42,22 @@ #define OPENPIC_TMR_REG_SIZE 0x220 #define OPENPIC_MSI_REG_START0x1600 #define OPENPIC_MSI_REG_SIZE 0x200 -#define OPENPIC_SUMMARY_REG_START 0x3800 -#define OPENPIC_SUMMARY_REG_SIZE0x800 +#define OPENPIC_SUMMARY_REG_START0x3800 +#define OPENPIC_SUMMARY_REG_SIZE 0x800 #define OPENPIC_SRC_REG_START0x1 #define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20) #define OPENPIC_CPU_REG_START0x2 -#define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) +#define OPENPIC_CPU_REG_SIZE (0x100 + ((MAX_CPU - 1) * 0x1000)) -typedef struct FslMpicInfo { +struct fsl_mpic_info { int max_ext; -} FslMpicInfo; +}; -static FslMpicInfo fsl_mpic_20 = { +static struct fsl_mpic_info fsl_mpic_20 = { .max_ext = 12, }; -static FslMpicInfo fsl_mpic_42 = { +static struct fsl_mpic_info fsl_mpic_42 = { .max_ext = 12, }; @@ -100,44 +100,43 @@ static int get_current_cpu(void) { CPUState *cpu_single_cpu; - if (!cpu_single_env) { + if (!cpu_single_env) return -1; - } cpu_single_cpu = ENV_GET_CPU(cpu_single_env); return cpu_single_cpu-cpu_index; } -static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, int idx); -static void openpic_cpu_write_internal(void *opaque, hwaddr addr, +static uint32_t openpic_cpu_read_internal(void *opaque, gpa_t addr, int idx); +static void openpic_cpu_write_internal(void *opaque, gpa_t addr, uint32_t val, int idx); -typedef enum IRQType { +enum irq_type { IRQ_TYPE_NORMAL = 0, IRQ_TYPE_FSLINT,/* FSL internal interrupt -- level only */ IRQ_TYPE_FSLSPECIAL,/* FSL timer/IPI interrupt, edge, no polarity */ -} IRQType; +}; -typedef struct IRQQueue { +struct irq_queue { /* Round up to the nearest 64 IRQs so that the queue length * won't change when moving between 32 and 64 bit hosts. */ unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) ~63)]; int next; int priority; -} IRQQueue; +}; -typedef struct IRQSource { +struct irq_source { uint32_t ivpr; /* IRQ vector/priority register */ uint32_t idr; /* IRQ destination register */ uint32_t destmask; /* bitmap of CPU destinations */ int last_cpu; int output; /* IRQ level, e.g. OPENPIC_OUTPUT_INT */ int pending;/* TRUE if IRQ is pending */ - IRQType type; + enum irq_type type; bool level:1; /* level-triggered */ - bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ -} IRQSource; + bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ +}; #define IVPR_MASK_SHIFT 31 #define IVPR_MASK_MASK(1 IVPR_MASK_SHIFT) @@ -158,22 +157,19 @@ typedef struct IRQSource { #define IDR_EP 0x8000 /* external pin */ #define IDR_CI 0x4000 /* critical interrupt */ -typedef struct IRQDest { +struct irq_dest { int32_t ctpr; /* CPU current task priority */ - IRQQueue raised; - IRQQueue servicing; + struct irq_queue raised; + struct irq_queue servicing; qemu_irq *irqs; /* Count of IRQ sources asserting on non-INT outputs */ uint32_t outputs_active[OPENPIC_OUTPUT_NB]; -} IRQDest; - -typedef struct OpenPICState { - SysBusDevice busdev; - MemoryRegion mem; +}; +struct openpic { /* Behavior control */ - FslMpicInfo *fsl; + struct fsl_mpic_info *fsl; uint32_t model; uint32_t flags; uint32_t nb_irqs; @@ -186,9 +182,6 @@ typedef struct OpenPICState { uint32_t brr1; uint32_t mpic_mode_mask; - /* Sub-regions */ - MemoryRegion sub_io_mem[6]; - /* Global registers */ uint32_t frr; /* Feature reporting register */ uint32_t gcr; /* Global configuration register */ @@ -196,9 +189,9 @@ typedef struct OpenPICState { uint32_t spve; /* Spurious vector register */ uint32_t tfrr; /* Timer frequency reporting register */ /* Source registers */ - IRQSource src[MAX_IRQ]; + struct irq_source src[MAX_IRQ]; /* Local
[PATCH 17/20] KVM: PPC: MPIC: Restrict to e500 platforms
The code as is doesn't make any sense on non-e500 platforms. Restrict it there, so that people don't get wrong ideas on what would actually work. This patch should get reverted as soon as it's possible to either run e500 guests on non-e500 hosts or the MPIC emulation gains support for non-e500 modes. Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index a608570..e88b1da 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -153,7 +153,7 @@ config KVM_E500MC config KVM_MPIC bool KVM in-kernel MPIC emulation - depends on KVM + depends on KVM E500 select HAVE_KVM_IRQCHIP select HAVE_KVM_IRQ_ROUTING select HAVE_KVM_MSI -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 28/42] kvm/ppc/mpic: in-kernel MPIC emulation
From: Scott Wood scottw...@freescale.com Hook the MPIC code up to the KVM interfaces, add locking, etc. Signed-off-by: Scott Wood scottw...@freescale.com [agraf: add stub function for kvmppc_mpic_set_epr, non-booke, 64bit] Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/devices/mpic.txt | 37 ++ arch/powerpc/include/asm/kvm_host.h|8 +- arch/powerpc/include/asm/kvm_ppc.h | 17 + arch/powerpc/include/uapi/asm/kvm.h|8 + arch/powerpc/kvm/Kconfig |9 + arch/powerpc/kvm/Makefile |2 + arch/powerpc/kvm/booke.c |8 +- arch/powerpc/kvm/mpic.c| 762 +--- arch/powerpc/kvm/powerpc.c | 12 +- include/linux/kvm_host.h |2 + include/uapi/linux/kvm.h |3 + virt/kvm/kvm_main.c|6 + 12 files changed, 674 insertions(+), 200 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/mpic.txt diff --git a/Documentation/virtual/kvm/devices/mpic.txt b/Documentation/virtual/kvm/devices/mpic.txt new file mode 100644 index 000..ce98e32 --- /dev/null +++ b/Documentation/virtual/kvm/devices/mpic.txt @@ -0,0 +1,37 @@ +MPIC interrupt controller += + +Device types supported: + KVM_DEV_TYPE_FSL_MPIC_20 Freescale MPIC v2.0 + KVM_DEV_TYPE_FSL_MPIC_42 Freescale MPIC v4.2 + +Only one MPIC instance, of any type, may be instantiated. The created +MPIC will act as the system interrupt controller, connecting to each +vcpu's interrupt inputs. + +Groups: + KVM_DEV_MPIC_GRP_MISC + Attributes: +KVM_DEV_MPIC_BASE_ADDR (rw, 64-bit) + Base address of the 256 KiB MPIC register space. Must be + naturally aligned. A value of zero disables the mapping. + Reset value is zero. + + KVM_DEV_MPIC_GRP_REGISTER (rw, 32-bit) +Access an MPIC register, as if the access were made from the guest. +attr is the byte offset into the MPIC register space. Accesses +must be 4-byte aligned. + +MSIs may be signaled by using this attribute group to write +to the relevant MSIIR. + + KVM_DEV_MPIC_GRP_IRQ_ACTIVE (rw, 32-bit) +IRQ input line for each standard openpic source. 0 is inactive and 1 +is active, regardless of interrupt sense. + +For edge-triggered interrupts: Writing 1 is considered an activating +edge, and writing 0 is ignored. Reading returns 1 if a previously +signaled edge has not been acknowledged, and 0 otherwise. + +attr is the IRQ number. IRQ numbers for standard sources are the +byte offset of the relevant IVPR from EIVPR0, divided by 32. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 1443768..153c8c2 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -361,6 +361,11 @@ struct kvmppc_slb { #define KVMPPC_BOOKE_MAX_IAC 4 #define KVMPPC_BOOKE_MAX_DAC 2 +/* KVMPPC_EPR_USER takes precedence over KVMPPC_EPR_KERNEL */ +#define KVMPPC_EPR_NONE0 /* EPR not supported */ +#define KVMPPC_EPR_USER1 /* exit to userspace to fill EPR */ +#define KVMPPC_EPR_KERNEL 2 /* in-kernel irqchip */ + struct kvmppc_booke_debug_reg { u32 dbcr0; u32 dbcr1; @@ -526,7 +531,7 @@ struct kvm_vcpu_arch { u8 sane; u8 cpu_type; u8 hcall_needed; - u8 epr_enabled; + u8 epr_flags; /* KVMPPC_EPR_xxx */ u8 epr_needed; u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ @@ -593,5 +598,6 @@ struct kvm_vcpu_arch { #define KVM_MMIO_REG_FQPR 0x0060 #define __KVM_HAVE_ARCH_WQP +#define __KVM_HAVE_CREATE_DEVICE #endif /* __POWERPC_KVM_HOST_H__ */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index bcc68b1..3810f9c 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -164,6 +164,8 @@ extern int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu); extern int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *); +int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); + /* * Cuts out inst bits with ordering according to spec. * That means the leftmost bit is zero. All given bits are included. @@ -245,6 +247,9 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *); void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); +struct openpic; +void kvmppc_mpic_put(struct openpic *opp); + #ifdef CONFIG_KVM_BOOK3S_64_HV static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) { @@ -270,6 +275,18 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) #endif } +#ifdef CONFIG_KVM_MPIC + +void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu); + +#else + +static inline void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu) +{ +} + +#endif /*
[PATCH 27/42] kvm/ppc/mpic: adapt to kernel style and environment
From: Scott Wood scottw...@freescale.com Remove braces that Linux style doesn't permit, remove space after '*' that Lindent added, keep error/debug strings contiguous, etc. Substitute type names, debug prints, etc. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 445 ++- 1 files changed, 208 insertions(+), 237 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index d6d70a4..1df67ae 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -42,22 +42,22 @@ #define OPENPIC_TMR_REG_SIZE 0x220 #define OPENPIC_MSI_REG_START0x1600 #define OPENPIC_MSI_REG_SIZE 0x200 -#define OPENPIC_SUMMARY_REG_START 0x3800 -#define OPENPIC_SUMMARY_REG_SIZE0x800 +#define OPENPIC_SUMMARY_REG_START0x3800 +#define OPENPIC_SUMMARY_REG_SIZE 0x800 #define OPENPIC_SRC_REG_START0x1 #define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20) #define OPENPIC_CPU_REG_START0x2 -#define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) +#define OPENPIC_CPU_REG_SIZE (0x100 + ((MAX_CPU - 1) * 0x1000)) -typedef struct FslMpicInfo { +struct fsl_mpic_info { int max_ext; -} FslMpicInfo; +}; -static FslMpicInfo fsl_mpic_20 = { +static struct fsl_mpic_info fsl_mpic_20 = { .max_ext = 12, }; -static FslMpicInfo fsl_mpic_42 = { +static struct fsl_mpic_info fsl_mpic_42 = { .max_ext = 12, }; @@ -100,44 +100,43 @@ static int get_current_cpu(void) { CPUState *cpu_single_cpu; - if (!cpu_single_env) { + if (!cpu_single_env) return -1; - } cpu_single_cpu = ENV_GET_CPU(cpu_single_env); return cpu_single_cpu-cpu_index; } -static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, int idx); -static void openpic_cpu_write_internal(void *opaque, hwaddr addr, +static uint32_t openpic_cpu_read_internal(void *opaque, gpa_t addr, int idx); +static void openpic_cpu_write_internal(void *opaque, gpa_t addr, uint32_t val, int idx); -typedef enum IRQType { +enum irq_type { IRQ_TYPE_NORMAL = 0, IRQ_TYPE_FSLINT,/* FSL internal interrupt -- level only */ IRQ_TYPE_FSLSPECIAL,/* FSL timer/IPI interrupt, edge, no polarity */ -} IRQType; +}; -typedef struct IRQQueue { +struct irq_queue { /* Round up to the nearest 64 IRQs so that the queue length * won't change when moving between 32 and 64 bit hosts. */ unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) ~63)]; int next; int priority; -} IRQQueue; +}; -typedef struct IRQSource { +struct irq_source { uint32_t ivpr; /* IRQ vector/priority register */ uint32_t idr; /* IRQ destination register */ uint32_t destmask; /* bitmap of CPU destinations */ int last_cpu; int output; /* IRQ level, e.g. OPENPIC_OUTPUT_INT */ int pending;/* TRUE if IRQ is pending */ - IRQType type; + enum irq_type type; bool level:1; /* level-triggered */ - bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ -} IRQSource; + bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ +}; #define IVPR_MASK_SHIFT 31 #define IVPR_MASK_MASK(1 IVPR_MASK_SHIFT) @@ -158,22 +157,19 @@ typedef struct IRQSource { #define IDR_EP 0x8000 /* external pin */ #define IDR_CI 0x4000 /* critical interrupt */ -typedef struct IRQDest { +struct irq_dest { int32_t ctpr; /* CPU current task priority */ - IRQQueue raised; - IRQQueue servicing; + struct irq_queue raised; + struct irq_queue servicing; qemu_irq *irqs; /* Count of IRQ sources asserting on non-INT outputs */ uint32_t outputs_active[OPENPIC_OUTPUT_NB]; -} IRQDest; - -typedef struct OpenPICState { - SysBusDevice busdev; - MemoryRegion mem; +}; +struct openpic { /* Behavior control */ - FslMpicInfo *fsl; + struct fsl_mpic_info *fsl; uint32_t model; uint32_t flags; uint32_t nb_irqs; @@ -186,9 +182,6 @@ typedef struct OpenPICState { uint32_t brr1; uint32_t mpic_mode_mask; - /* Sub-regions */ - MemoryRegion sub_io_mem[6]; - /* Global registers */ uint32_t frr; /* Feature reporting register */ uint32_t gcr; /* Global configuration register */ @@ -196,9 +189,9 @@ typedef struct OpenPICState { uint32_t spve; /* Spurious vector register */ uint32_t tfrr; /* Timer frequency reporting register */ /* Source registers */ - IRQSource src[MAX_IRQ]; + struct irq_source src[MAX_IRQ]; /* Local
[PATCH 36/42] KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls
From: Michael Ellerman mich...@ellerman.id.au For pseries machine emulation, in order to move the interrupt controller code to the kernel, we need to intercept some RTAS calls in the kernel itself. This adds an infrastructure to allow in-kernel handlers to be registered for RTAS services by name. A new ioctl, KVM_PPC_RTAS_DEFINE_TOKEN, then allows userspace to associate token values with those service names. Then, when the guest requests an RTAS service with one of those token values, it will be handled by the relevant in-kernel handler rather than being passed up to userspace as at present. Signed-off-by: Michael Ellerman mich...@ellerman.id.au Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Paul Mackerras pau...@samba.org [agraf: fix warning] Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/api.txt | 19 arch/powerpc/include/asm/hvcall.h |3 + arch/powerpc/include/asm/kvm_host.h |1 + arch/powerpc/include/asm/kvm_ppc.h |4 + arch/powerpc/include/uapi/asm/kvm.h |6 + arch/powerpc/kvm/Makefile |1 + arch/powerpc/kvm/book3s_hv.c| 18 - arch/powerpc/kvm/book3s_pr.c|1 + arch/powerpc/kvm/book3s_pr_papr.c |7 ++ arch/powerpc/kvm/book3s_rtas.c | 182 +++ arch/powerpc/kvm/powerpc.c |8 ++ include/uapi/linux/kvm.h|3 + 12 files changed, 252 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/kvm/book3s_rtas.c diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 149558b..fb308be 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2341,6 +2341,25 @@ and distributor interface, the ioctl must be called after calling KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. Calling this ioctl twice for any of the base addresses will return -EEXIST. +4.82 KVM_PPC_RTAS_DEFINE_TOKEN + +Capability: KVM_CAP_PPC_RTAS +Architectures: ppc +Type: vm ioctl +Parameters: struct kvm_rtas_token_args +Returns: 0 on success, -1 on error + +Defines a token value for a RTAS (Run Time Abstraction Services) +service in order to allow it to be handled in the kernel. The +argument struct gives the name of the service, which must be the name +of a service that has a kernel-side implementation. If the token +value is non-zero, it will be associated with that service, and +subsequent RTAS calls by the guest specifying that token will be +handled by the kernel. If the token value is 0, then any token +associated with the service will be forgotten, and subsequent RTAS +calls by the guest for that service will be passed to userspace to be +handled. + 5. The kvm_run structure diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 4bc2c3d..cf4df8e 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -270,6 +270,9 @@ #define H_SET_MODE 0x31C #define MAX_HCALL_OPCODE H_SET_MODE +/* Platform specific hcalls, used by KVM */ +#define H_RTAS 0xf000 + #ifndef __ASSEMBLY__ /** diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 13740a6..311f7e6 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -259,6 +259,7 @@ struct kvm_arch { #endif /* CONFIG_KVM_BOOK3S_64_HV */ #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; + struct list_head rtas_tokens; #endif #ifdef CONFIG_KVM_MPIC struct openpic *mpic; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index df9c80b..8a30eb7 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -166,6 +166,10 @@ extern int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *); int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); +extern int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp); +extern int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu); +extern void kvmppc_rtas_tokens_free(struct kvm *kvm); + /* * Cuts out inst bits with ordering according to spec. * That means the leftmost bit is zero. All given bits are included. diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 03c7819..eb9e25c 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -324,6 +324,12 @@ struct kvm_allocate_rma { __u64 rma_size; }; +/* for KVM_CAP_PPC_RTAS */ +struct kvm_rtas_token_args { + char name[120]; + __u64 token;/* Use a token of 0 to undefine a mapping */ +}; + struct kvm_book3e_206_tlb_entry { __u32 mas8; __u32 mas1; diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 4eada0c..3faf5c0 100644 ---
[PATCH 37/42] KVM: PPC: Book3S: Add kernel emulation for the XICS interrupt controller
From: Benjamin Herrenschmidt b...@kernel.crashing.org This adds in-kernel emulation of the XICS (eXternal Interrupt Controller Specification) interrupt controller specified by PAPR, for both HV and PR KVM guests. The XICS emulation supports up to 1048560 interrupt sources. Interrupt source numbers below 16 are reserved; 0 is used to mean no interrupt and 2 is used for IPIs. Internally these are represented in blocks of 1024, called ICS (interrupt controller source) entities, but that is not visible to userspace. Each vcpu gets one ICP (interrupt controller presentation) entity, used to store the per-vcpu state such as vcpu priority, pending interrupt state, IPI request, etc. This does not include any API or any way to connect vcpus to their ICP state; that will be added in later patches. This is based on an initial implementation by Michael Ellerman mich...@ellerman.id.au reworked by Benjamin Herrenschmidt and Paul Mackerras. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Paul Mackerras pau...@samba.org [agraf: fix typo, add dependency on !KVM_MPIC] Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/asm/kvm_book3s.h |2 + arch/powerpc/include/asm/kvm_host.h | 11 + arch/powerpc/include/asm/kvm_ppc.h| 29 + arch/powerpc/kvm/Kconfig |8 + arch/powerpc/kvm/Makefile |3 + arch/powerpc/kvm/book3s.c |2 +- arch/powerpc/kvm/book3s_hv.c |9 + arch/powerpc/kvm/book3s_pr_papr.c | 14 + arch/powerpc/kvm/book3s_rtas.c| 54 ++- arch/powerpc/kvm/book3s_xics.c| 946 + arch/powerpc/kvm/book3s_xics.h| 113 arch/powerpc/kvm/powerpc.c|3 + 12 files changed, 1192 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/kvm/book3s_xics.c create mode 100644 arch/powerpc/kvm/book3s_xics.h diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index c55f7e6..349ed85 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -142,6 +142,8 @@ extern int kvmppc_mmu_hv_init(void); extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); +extern void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu, + unsigned int vec); extern void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags); extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, u32 val); diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 311f7e6..af326cd 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -192,6 +192,10 @@ struct kvmppc_linear_info { int type; }; +/* XICS components, defined in book3s_xics.c */ +struct kvmppc_xics; +struct kvmppc_icp; + /* * The reverse mapping array has one entry for each HPTE, * which stores the guest's view of the second word of the HPTE @@ -264,6 +268,9 @@ struct kvm_arch { #ifdef CONFIG_KVM_MPIC struct openpic *mpic; #endif +#ifdef CONFIG_KVM_XICS + struct kvmppc_xics *xics; +#endif }; /* @@ -387,6 +394,7 @@ struct kvmppc_booke_debug_reg { #define KVMPPC_IRQ_DEFAULT 0 #define KVMPPC_IRQ_MPIC1 +#define KVMPPC_IRQ_XICS2 struct openpic; @@ -574,6 +582,9 @@ struct kvm_vcpu_arch { int irq_type; /* one of KVM_IRQ_* */ int irq_cpu_id; struct openpic *mpic; /* KVM_IRQ_MPIC */ +#ifdef CONFIG_KVM_XICS + struct kvmppc_icp *icp; /* XICS presentation controller */ +#endif #ifdef CONFIG_KVM_BOOK3S_64_HV struct kvm_vcpu_arch_shared shregs; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 8a30eb7..6582eed 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -130,6 +130,7 @@ extern long kvmppc_prepare_vrma(struct kvm *kvm, extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, unsigned long porder); extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu); + extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, struct kvm_create_spapr_tce *args); extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, @@ -169,6 +170,10 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); extern int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp); extern int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu); extern void kvmppc_rtas_tokens_free(struct kvm *kvm); +extern int
[PATCH 39/42] KVM: PPC: Book3S HV: Add support for real mode ICP in XICS emulation
From: Benjamin Herrenschmidt b...@kernel.crashing.org This adds an implementation of the XICS hypercalls in real mode for HV KVM, which allows us to avoid exiting the guest MMU context on all threads for a variety of operations such as fetching a pending interrupt, EOI of messages, IPIs, etc. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Paul Mackerras pau...@samba.org Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/Makefile |5 +- arch/powerpc/kvm/book3s_hv_rm_xics.c| 406 +++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 18 +- arch/powerpc/kvm/book3s_xics.c | 64 - arch/powerpc/kvm/book3s_xics.h | 16 ++ 5 files changed, 490 insertions(+), 19 deletions(-) create mode 100644 arch/powerpc/kvm/book3s_hv_rm_xics.c diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index f9b87b5..422de3f 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -72,12 +72,15 @@ kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ book3s_hv.o \ book3s_hv_interrupts.o \ book3s_64_mmu_hv.o +kvm-book3s_64-builtin-xics-objs-$(CONFIG_KVM_XICS) := \ + book3s_hv_rm_xics.o kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ book3s_hv_rmhandlers.o \ book3s_hv_rm_mmu.o \ book3s_64_vio_hv.o \ book3s_hv_ras.o \ - book3s_hv_builtin.o + book3s_hv_builtin.o \ + $(kvm-book3s_64-builtin-xics-objs-y) kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ book3s_xics.o diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c new file mode 100644 index 000..b4b0082 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c @@ -0,0 +1,406 @@ +/* + * Copyright 2012 Michael Ellerman, IBM Corporation. + * Copyright 2012 Benjamin Herrenschmidt, IBM Corporation + * + * 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. + */ + +#include linux/kernel.h +#include linux/kvm_host.h +#include linux/err.h + +#include asm/kvm_book3s.h +#include asm/kvm_ppc.h +#include asm/hvcall.h +#include asm/xics.h +#include asm/debug.h +#include asm/synch.h +#include asm/ppc-opcode.h + +#include book3s_xics.h + +#define DEBUG_PASSUP + +static inline void rm_writeb(unsigned long paddr, u8 val) +{ + __asm__ __volatile__(sync; stbcix %0,0,%1 + : : r (val), r (paddr) : memory); +} + +static void icp_rm_set_vcpu_irq(struct kvm_vcpu *vcpu, + struct kvm_vcpu *this_vcpu) +{ + struct kvmppc_icp *this_icp = this_vcpu-arch.icp; + unsigned long xics_phys; + int cpu; + + /* Mark the target VCPU as having an interrupt pending */ + vcpu-stat.queue_intr++; + set_bit(BOOK3S_IRQPRIO_EXTERNAL_LEVEL, vcpu-arch.pending_exceptions); + + /* Kick self ? Just set MER and return */ + if (vcpu == this_vcpu) { + mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_MER); + return; + } + + /* Check if the core is loaded, if not, too hard */ + cpu = vcpu-cpu; + if (cpu 0 || cpu = nr_cpu_ids) { + this_icp-rm_action |= XICS_RM_KICK_VCPU; + this_icp-rm_kick_target = vcpu; + return; + } + /* In SMT cpu will always point to thread 0, we adjust it */ + cpu += vcpu-arch.ptid; + + /* Not too hard, then poke the target */ + xics_phys = paca[cpu].kvm_hstate.xics_phys; + rm_writeb(xics_phys + XICS_MFRR, IPI_PRIORITY); +} + +static void icp_rm_clr_vcpu_irq(struct kvm_vcpu *vcpu) +{ + /* Note: Only called on self ! */ + clear_bit(BOOK3S_IRQPRIO_EXTERNAL_LEVEL, + vcpu-arch.pending_exceptions); + mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) ~LPCR_MER); +} + +static inline bool icp_rm_try_update(struct kvmppc_icp *icp, +union kvmppc_icp_state old, +union kvmppc_icp_state new) +{ + struct kvm_vcpu *this_vcpu = local_paca-kvm_hstate.kvm_vcpu; + bool success; + + /* Calculate new output value */ + new.out_ee = (new.xisr (new.pending_pri new.cppr)); + + /* Attempt atomic update */ + success = cmpxchg64(icp-state.raw, old.raw, new.raw) == old.raw; + if (!success) + goto bail; + + /* +* Check for output state update +* +* Note that this is racy since another processor could be updating +* the state already. This is why we never clear the interrupt output +* here, we only ever set it. The clear only happens prior to doing +* an update and only by the processor itself. Currently we do it +* in Accept (H_XIRR) and Up_Cppr (H_XPPR). +* +* We also do not try to figure out
[PATCH 40/42] KVM: PPC: Book3S HV: Improve real-mode handling of external interrupts
From: Paul Mackerras pau...@samba.org This streamlines our handling of external interrupts that come in while we're in the guest. First, when waking up a hardware thread that was napping, we split off the napping due to H_CEDE case earlier, and use the code that handles an external interrupt (0x500) in the guest to handle that too. Secondly, the code that handles those external interrupts now checks if any other thread is exiting to the host before bouncing an external interrupt to the guest, and also checks that there is actually an external interrupt pending for the guest before setting the LPCR MER bit (mediated external request). This also makes sure that we clear the ceded flag when we handle a wakeup from cede in real mode, and fixes a potential infinite loop in kvmppc_run_vcpu() which can occur if we ever end up with the ceded flag set but MSR[EE] off. Signed-off-by: Paul Mackerras pau...@samba.org Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/asm/reg.h |1 + arch/powerpc/kvm/book3s_hv.c|5 +- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 138 +-- 3 files changed, 80 insertions(+), 64 deletions(-) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index c9c67fc..7993224 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -290,6 +290,7 @@ #define LPCR_PECE1 0x2000 /* decrementer can cause exit */ #define LPCR_PECE2 0x1000 /* machine check etc can cause exit */ #define LPCR_MER 0x0800 /* Mediated External Exception */ +#define LPCR_MER_SH 11 #define LPCR_LPES0x000c #define LPCR_LPES0 0x0008 /* LPAR Env selector 0 */ #define LPCR_LPES1 0x0004 /* LPAR Env selector 1 */ diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 1619191..178521e 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1384,9 +1384,12 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) break; vc-runner = vcpu; n_ceded = 0; - list_for_each_entry(v, vc-runnable_threads, arch.run_list) + list_for_each_entry(v, vc-runnable_threads, arch.run_list) { if (!v-arch.pending_exceptions) n_ceded += v-arch.ceded; + else + v-arch.ceded = 0; + } if (n_ceded == vc-n_runnable) kvmppc_vcore_blocked(vc); else diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index fd3b72d..b02f91e 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -97,50 +97,51 @@ kvm_start_guest: li r0,1 stb r0,PACA_NAPSTATELOST(r13) - /* get vcpu pointer, NULL if we have no vcpu to run */ - ld r4,HSTATE_KVM_VCPU(r13) - cmpdi cr1,r4,0 + /* were we napping due to cede? */ + lbz r0,HSTATE_NAPPING(r13) + cmpwi r0,0 + bne kvm_end_cede + + /* +* We weren't napping due to cede, so this must be a secondary +* thread being woken up to run a guest, or being woken up due +* to a stray IPI. (Or due to some machine check or hypervisor +* maintenance interrupt while the core is in KVM.) +*/ /* Check the wake reason in SRR1 to see why we got here */ mfspr r3,SPRN_SRR1 rlwinm r3,r3,44-31,0x7 /* extract wake reason field */ cmpwi r3,4/* was it an external interrupt? */ - bne 27f - - /* -* External interrupt - for now assume it is an IPI, since we -* should never get any other interrupts sent to offline threads. -* Only do this for secondary threads. -*/ - beq cr1,25f - lwz r3,VCPU_PTID(r4) - cmpwi r3,0 - beq 27f -25:ld r5,HSTATE_XICS_PHYS(r13) - li r0,0xff - li r6,XICS_MFRR - li r7,XICS_XIRR + bne 27f /* if not */ + ld r5,HSTATE_XICS_PHYS(r13) + li r7,XICS_XIRR/* if it was an external interrupt, */ lwzcix r8,r5,r7/* get and ack the interrupt */ sync clrldi. r9,r8,40/* get interrupt source ID. */ - beq 27f /* none there? */ - cmpwi r9,XICS_IPI - bne 26f + beq 28f /* none there? */ + cmpwi r9,XICS_IPI /* was it an IPI? */ + bne 29f + li r0,0xff + li r6,XICS_MFRR stbcix r0,r5,r6/* clear IPI */ -26:stwcix r8,r5,r7/* EOI the interrupt
[PATCH 35/42] kvm/ppc/mpic: Eliminate mmio_mapped
From: Scott Wood scottw...@freescale.com We no longer need to keep track of this now that MPIC destruction always happens either during VM destruction (after MMIO has been destroyed) or during a failed creation (before the fd has been exposed to userspace, and thus before the MMIO region could have been registered). Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 29 + 1 files changed, 1 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 795ca0c..f3148f8 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -190,7 +190,6 @@ struct openpic { struct kvm_io_device mmio; struct list_head mmio_regions; atomic_t users; - bool mmio_mapped; gpa_t reg_base; spinlock_t lock; @@ -1428,24 +1427,13 @@ static int kvm_mpic_write(struct kvm_io_device *this, gpa_t addr, return ret; } -static void kvm_mpic_dtor(struct kvm_io_device *this) -{ - struct openpic *opp = container_of(this, struct openpic, mmio); - - opp-mmio_mapped = false; -} - static const struct kvm_io_device_ops mpic_mmio_ops = { .read = kvm_mpic_read, .write = kvm_mpic_write, - .destructor = kvm_mpic_dtor, }; static void map_mmio(struct openpic *opp) { - BUG_ON(opp-mmio_mapped); - opp-mmio_mapped = true; - kvm_iodevice_init(opp-mmio, mpic_mmio_ops); kvm_io_bus_register_dev(opp-kvm, KVM_MMIO_BUS, @@ -1455,10 +1443,7 @@ static void map_mmio(struct openpic *opp) static void unmap_mmio(struct openpic *opp) { - if (opp-mmio_mapped) { - opp-mmio_mapped = false; - kvm_io_bus_unregister_dev(opp-kvm, KVM_MMIO_BUS, opp-mmio); - } + kvm_io_bus_unregister_dev(opp-kvm, KVM_MMIO_BUS, opp-mmio); } static int set_base_addr(struct openpic *opp, struct kvm_device_attr *attr) @@ -1637,18 +1622,6 @@ static void mpic_destroy(struct kvm_device *dev) { struct openpic *opp = dev-private; - if (opp-mmio_mapped) { - /* -* Normally we get unmapped by kvm_io_bus_destroy(), -* which happens before the VCPUs release their references. -* -* Thus, we should only get here if no VCPUs took a reference -* to us in the first place. -*/ - WARN_ON(opp-nb_cpus != 0); - unmap_mmio(opp); - } - dev-kvm-arch.mpic = NULL; kfree(opp); } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 34/42] kvm: destroy emulated devices on VM exit
From: Scott Wood scottw...@freescale.com The hassle of getting refcounting right was greater than the hassle of keeping a list of devices to destroy on VM exit. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c |2 -- include/linux/kvm_host.h |3 ++- virt/kvm/kvm_main.c | 29 - 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 89fe1d6..795ca0c 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1781,7 +1781,6 @@ int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, if (opp-mpic_mode_mask == GCR_MODE_PROXY) vcpu-arch.epr_flags |= KVMPPC_EPR_KERNEL; - kvm_device_get(dev); out: spin_unlock_irq(opp-lock); return ret; @@ -1797,7 +1796,6 @@ void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu) BUG_ON(!opp-dst[vcpu-arch.irq_cpu_id].vcpu); opp-dst[vcpu-arch.irq_cpu_id].vcpu = NULL; - kvm_device_put(opp-dev); } /* diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index feffbda..36c9776 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -393,6 +393,7 @@ struct kvm { long mmu_notifier_count; #endif long tlbs_dirty; + struct list_head devices; }; #define kvm_err(fmt, ...) \ @@ -1069,8 +1070,8 @@ struct kvm_device_ops; struct kvm_device { struct kvm_device_ops *ops; struct kvm *kvm; - atomic_t users; void *private; + struct list_head vm_node; }; /* create, destroy, and name are mandatory */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f6cd14d..5da9f02 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -504,6 +504,7 @@ static struct kvm *kvm_create_vm(unsigned long type) mutex_init(kvm-irq_lock); mutex_init(kvm-slots_lock); atomic_set(kvm-users_count, 1); + INIT_LIST_HEAD(kvm-devices); r = kvm_init_mmu_notifier(kvm); if (r) @@ -581,6 +582,19 @@ void kvm_free_physmem(struct kvm *kvm) kfree(kvm-memslots); } +static void kvm_destroy_devices(struct kvm *kvm) +{ + struct list_head *node, *tmp; + + list_for_each_safe(node, tmp, kvm-devices) { + struct kvm_device *dev = + list_entry(node, struct kvm_device, vm_node); + + list_del(node); + dev-ops-destroy(dev); + } +} + static void kvm_destroy_vm(struct kvm *kvm) { int i; @@ -600,6 +614,7 @@ static void kvm_destroy_vm(struct kvm *kvm) kvm_arch_flush_shadow_all(kvm); #endif kvm_arch_destroy_vm(kvm); + kvm_destroy_devices(kvm); kvm_free_physmem(kvm); cleanup_srcu_struct(kvm-srcu); kvm_arch_free_vm(kvm); @@ -2195,23 +2210,11 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl, } } -void kvm_device_get(struct kvm_device *dev) -{ - atomic_inc(dev-users); -} - -void kvm_device_put(struct kvm_device *dev) -{ - if (atomic_dec_and_test(dev-users)) - dev-ops-destroy(dev); -} - static int kvm_device_release(struct inode *inode, struct file *filp) { struct kvm_device *dev = filp-private_data; struct kvm *kvm = dev-kvm; - kvm_device_put(dev); kvm_put_kvm(kvm); return 0; } @@ -2257,7 +2260,6 @@ static int kvm_ioctl_create_device(struct kvm *kvm, dev-ops = ops; dev-kvm = kvm; - atomic_set(dev-users, 1); ret = ops-create(dev, cd-type); if (ret 0) { @@ -2271,6 +2273,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, return ret; } + list_add(dev-vm_node, kvm-devices); kvm_get_kvm(kvm); cd-fd = ret; return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 32/42] KVM: PPC: MPIC: Restrict to e500 platforms
The code as is doesn't make any sense on non-e500 platforms. Restrict it there, so that people don't get wrong ideas on what would actually work. This patch should get reverted as soon as it's possible to either run e500 guests on non-e500 hosts or the MPIC emulation gains support for non-e500 modes. Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 4bf10b5..656e0bc 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -153,7 +153,7 @@ config KVM_E500MC config KVM_MPIC bool KVM in-kernel MPIC emulation - depends on KVM + depends on KVM E500 select HAVE_KVM_IRQCHIP select HAVE_KVM_IRQ_ROUTING select HAVE_KVM_MSI -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 33/42] KVM: IA64: Carry non-ia64 changes into ia64
We changed a few things in non-ia64 code paths. This patch blindly applies the changes to the ia64 code as well, hoping it proves useful in case anyone revives the ia64 kvm code. Signed-off-by: Alexander Graf ag...@suse.de --- arch/ia64/include/asm/kvm_host.h |1 + arch/ia64/kvm/Kconfig|1 + arch/ia64/kvm/Makefile |2 +- 3 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index cfa7498..989dd3f 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h @@ -26,6 +26,7 @@ #define KVM_USER_MEM_SLOTS 32 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 +#define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS /* define exit reasons from vmm to kvm*/ #define EXIT_REASON_VM_PANIC 0 diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 2cd225f..043183a 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig @@ -27,6 +27,7 @@ config KVM select PREEMPT_NOTIFIERS select ANON_INODES select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING select KVM_APIC_ARCHITECTURE select KVM_MMIO ---help--- diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index db3d7c5..511f64a 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile @@ -49,7 +49,7 @@ ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ - coalesced_mmio.o irq_comm.o assigned-dev.o) + coalesced_mmio.o irq_comm.o assigned-dev.o irqchip.o) ifeq ($(CONFIG_IOMMU_API),y) common-objs += $(addprefix ../../../virt/kvm/, iommu.o) -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 31/42] KVM: PPC: MPIC: Add support for KVM_IRQ_LINE
Now that all pieces are in place for reusing generic irq infrastructure, we can copy x86's implementation of KVM_IRQ_LINE irq injection and simply reuse it for PPC, as it will work there just as well. Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/uapi/asm/kvm.h |1 + arch/powerpc/kvm/powerpc.c | 13 + 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index ca87106..03c7819 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -26,6 +26,7 @@ #define __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT #define __KVM_HAVE_IRQCHIP +#define __KVM_HAVE_IRQ_LINE struct kvm_regs { __u64 pc; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 5d046bb..d8e81e6 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -33,6 +33,7 @@ #include asm/cputhreads.h #include asm/irqflags.h #include timing.h +#include irq.h #include ../mm/mmu_decl.h #define CREATE_TRACE_POINTS @@ -939,6 +940,18 @@ static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) return 0; } +int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, + bool line_status) +{ + if (!irqchip_in_kernel(kvm)) + return -ENXIO; + + irq_event-status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, + irq_event-irq, irq_event-level, + line_status); + return 0; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 29/42] kvm/ppc/mpic: add KVM_CAP_IRQ_MPIC
From: Scott Wood scottw...@freescale.com Enabling this capability connects the vcpu to the designated in-kernel MPIC. Using explicit connections between vcpus and irqchips allows for flexibility, but the main benefit at the moment is that it simplifies the code -- KVM doesn't need vm-global state to remember which MPIC object is associated with this vm, and it doesn't need to care about ordering between irqchip creation and vcpu creation. Signed-off-by: Scott Wood scottw...@freescale.com [agraf: add stub functions for kvmppc_mpic_{dis,}connect_vcpu] Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/api.txt |8 +++ arch/powerpc/include/asm/kvm_host.h |9 arch/powerpc/include/asm/kvm_ppc.h | 15 ++- arch/powerpc/kvm/booke.c|4 ++ arch/powerpc/kvm/mpic.c | 82 --- arch/powerpc/kvm/powerpc.c | 30 + include/uapi/linux/kvm.h|1 + 7 files changed, 141 insertions(+), 8 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 66b58e4..149558b 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2744,3 +2744,11 @@ to receive the topmost interrupt vector. When disabled (args[0] == 0), behavior is as if this facility is unsupported. When this capability is enabled, KVM_EXIT_EPR can occur. + +6.6 KVM_CAP_IRQ_MPIC + +Architectures: ppc +Parameters: args[0] is the MPIC device fd +args[1] is the MPIC CPU number for this vcpu + +This capability connects the vcpu to an in-kernel MPIC device. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 153c8c2..c3f8cef 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -377,6 +377,11 @@ struct kvmppc_booke_debug_reg { u64 dac[KVMPPC_BOOKE_MAX_DAC]; }; +#define KVMPPC_IRQ_DEFAULT 0 +#define KVMPPC_IRQ_MPIC1 + +struct openpic; + struct kvm_vcpu_arch { ulong host_stack; u32 host_pid; @@ -558,6 +563,10 @@ struct kvm_vcpu_arch { unsigned long magic_page_pa; /* phys addr to map the magic page to */ unsigned long magic_page_ea; /* effect. addr to map the magic page to */ + int irq_type; /* one of KVM_IRQ_* */ + int irq_cpu_id; + struct openpic *mpic; /* KVM_IRQ_MPIC */ + #ifdef CONFIG_KVM_BOOK3S_64_HV struct kvm_vcpu_arch_shared shregs; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 3810f9c..df9c80b 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -248,7 +248,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *); void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); struct openpic; -void kvmppc_mpic_put(struct openpic *opp); #ifdef CONFIG_KVM_BOOK3S_64_HV static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) @@ -278,6 +277,9 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) #ifdef CONFIG_KVM_MPIC void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu); +int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, +u32 cpu); +void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu); #else @@ -285,6 +287,17 @@ static inline void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu) { } +static inline int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, + struct kvm_vcpu *vcpu, u32 cpu) +{ + return -EINVAL; +} + +static inline void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, + struct kvm_vcpu *vcpu) +{ +} + #endif /* CONFIG_KVM_MPIC */ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 4da11ed..1020119 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -430,6 +430,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, if (update_epr == true) { if (vcpu-arch.epr_flags KVMPPC_EPR_USER) kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); + else if (vcpu-arch.epr_flags KVMPPC_EPR_KERNEL) { + BUG_ON(vcpu-arch.irq_type != KVMPPC_IRQ_MPIC); + kvmppc_mpic_set_epr(vcpu); + } } new_msr = msr_mask; diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index cb451b9..10bc08a 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -115,7 +115,7 @@ static int get_current_cpu(void) { #if defined(CONFIG_KVM) defined(CONFIG_BOOKE) struct kvm_vcpu *vcpu = current-thread.kvm_vcpu; - return vcpu ? vcpu-vcpu_id : -1; + return vcpu ? vcpu-arch.irq_cpu_id : -1; #else
[PATCH 26/42] kvm/ppc/mpic: remove some obviously unneeded code
From: Scott Wood scottw...@freescale.com Remove some parts of the code that are obviously QEMU or Raven specific before fixing style issues, to reduce the style issues that need to be fixed. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 344 --- 1 files changed, 0 insertions(+), 344 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 57655b9..d6d70a4 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -22,39 +22,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -/* - * - * Based on OpenPic implementations: - * - Intel GW80314 I/O companion chip developer's manual - * - Motorola MPC8245 MPC8540 user manuals. - * - Motorola MCP750 (aka Raven) programmer manual. - * - Motorola Harrier programmer manuel - * - * Serial interrupts, as implemented in Raven chipset are not supported yet. - * - */ -#include hw.h -#include ppc/mac.h -#include pci/pci.h -#include openpic.h -#include sysbus.h -#include pci/msi.h -#include qemu/bitops.h -#include ppc.h - -//#define DEBUG_OPENPIC - -#ifdef DEBUG_OPENPIC -static const int debug_openpic = 1; -#else -static const int debug_openpic = 0; -#endif - -#define DPRINTF(fmt, ...) do { \ -if (debug_openpic) { \ -printf(fmt , ## __VA_ARGS__); \ -} \ -} while (0) #define MAX_CPU 32 #define MAX_SRC 256 @@ -82,21 +49,6 @@ static const int debug_openpic = 0; #define OPENPIC_CPU_REG_START0x2 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) -/* Raven */ -#define RAVEN_MAX_CPU 2 -#define RAVEN_MAX_EXT 48 -#define RAVEN_MAX_IRQ 64 -#define RAVEN_MAX_TMR MAX_TMR -#define RAVEN_MAX_IPI MAX_IPI - -/* Interrupt definitions */ -#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */ -#define RAVEN_ERR_IRQ(RAVEN_MAX_EXT + 1) /* Error IRQ */ -#define RAVEN_TMR_IRQ(RAVEN_MAX_EXT + 2) /* First timer IRQ */ -#define RAVEN_IPI_IRQ(RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */ -/* First doorbell IRQ */ -#define RAVEN_DBL_IRQ(RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI)) - typedef struct FslMpicInfo { int max_ext; } FslMpicInfo; @@ -138,44 +90,6 @@ static FslMpicInfo fsl_mpic_42 = { #define ILR_INTTGT_CINT 0x01 /* critical */ #define ILR_INTTGT_MCP0x02 /* machine check */ -/* The currently supported INTTGT values happen to be the same as QEMU's - * openpic output codes, but don't depend on this. The output codes - * could change (unlikely, but...) or support could be added for - * more INTTGT values. - */ -static const int inttgt_output[][2] = { - {ILR_INTTGT_INT, OPENPIC_OUTPUT_INT}, - {ILR_INTTGT_CINT, OPENPIC_OUTPUT_CINT}, - {ILR_INTTGT_MCP, OPENPIC_OUTPUT_MCK}, -}; - -static int inttgt_to_output(int inttgt) -{ - int i; - - for (i = 0; i ARRAY_SIZE(inttgt_output); i++) { - if (inttgt_output[i][0] == inttgt) { - return inttgt_output[i][1]; - } - } - - fprintf(stderr, %s: unsupported inttgt %d\n, __func__, inttgt); - return OPENPIC_OUTPUT_INT; -} - -static int output_to_inttgt(int output) -{ - int i; - - for (i = 0; i ARRAY_SIZE(inttgt_output); i++) { - if (inttgt_output[i][1] == output) { - return inttgt_output[i][0]; - } - } - - abort(); -} - #define MSIIR_OFFSET 0x140 #define MSIIR_SRS_SHIFT29 #define MSIIR_SRS_MASK (0x7 MSIIR_SRS_SHIFT) @@ -1265,228 +1179,36 @@ static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len) return openpic_cpu_read_internal(opaque, addr, (addr 0x1f000) 12); } -static const MemoryRegionOps openpic_glb_ops_le = { - .write = openpic_gbl_write, - .read = openpic_gbl_read, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, -}; - static const MemoryRegionOps openpic_glb_ops_be = { .write = openpic_gbl_write, .read = openpic_gbl_read, - .endianness = DEVICE_BIG_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, -}; - -static const MemoryRegionOps openpic_tmr_ops_le = { - .write = openpic_tmr_write, - .read = openpic_tmr_read, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, }; static const MemoryRegionOps openpic_tmr_ops_be = { .write = openpic_tmr_write, .read = openpic_tmr_read, - .endianness = DEVICE_BIG_ENDIAN, - .impl = { -.min_access_size = 4, -
[PATCH 30/42] KVM: PPC: Support irq routing and irqfd for in-kernel MPIC
Now that all the irq routing and irqfd pieces are generic, we can expose real irqchip support to all of KVM's internal helpers. This allows us to use irqfd with the in-kernel MPIC. Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/devices/mpic.txt | 19 + arch/powerpc/include/asm/kvm_host.h|7 ++ arch/powerpc/include/uapi/asm/kvm.h|1 + arch/powerpc/kvm/Kconfig |3 + arch/powerpc/kvm/Makefile |1 + arch/powerpc/kvm/irq.h | 17 arch/powerpc/kvm/mpic.c| 111 +++- 7 files changed, 158 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/kvm/irq.h diff --git a/Documentation/virtual/kvm/devices/mpic.txt b/Documentation/virtual/kvm/devices/mpic.txt index ce98e32..ad0ac77 100644 --- a/Documentation/virtual/kvm/devices/mpic.txt +++ b/Documentation/virtual/kvm/devices/mpic.txt @@ -35,3 +35,22 @@ Groups: attr is the IRQ number. IRQ numbers for standard sources are the byte offset of the relevant IVPR from EIVPR0, divided by 32. + +IRQ Routing: + + The MPIC emulation supports IRQ routing. Only a single MPIC device can + be instantiated. Once that device has been created, it's available as + irqchip id 0. + + This irqchip 0 has 256 interrupt pins, which expose the interrupts in + the main array of interrupt sources (a.k.a. SRC interrupts). + + The numbering is the same as the MPIC device tree binding -- based on + the register offset from the beginning of the sources array, without + regard to any subdivisions in chip documentation such as internal + or external interrupts. + + Default routes are established for these pins, with the GSI being equal + to the pin number. + + Access to non-SRC interrupts is not implemented through IRQ routing mechanisms. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index c3f8cef..13740a6 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -44,6 +44,10 @@ #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #endif +/* These values are internal and can be increased later */ +#define KVM_NR_IRQCHIPS 1 +#define KVM_IRQCHIP_NUM_PINS 256 + #if !defined(CONFIG_KVM_440) #include linux/mmu_notifier.h @@ -256,6 +260,9 @@ struct kvm_arch { #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; #endif +#ifdef CONFIG_KVM_MPIC + struct openpic *mpic; +#endif }; /* diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 02ad966..ca87106 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -25,6 +25,7 @@ /* Select powerpc specific features in linux/kvm.h */ #define __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT +#define __KVM_HAVE_IRQCHIP struct kvm_regs { __u64 pc; diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index f47e95e..4bf10b5 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -154,6 +154,9 @@ config KVM_E500MC config KVM_MPIC bool KVM in-kernel MPIC emulation depends on KVM + select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING + select HAVE_KVM_MSI help Enable support for emulating MPIC devices inside the host kernel, rather than relying on userspace to emulate. diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 4a2277a..4eada0c 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -104,6 +104,7 @@ kvm-book3s_32-objs := \ kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o +kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(addprefix ../../../virt/kvm/, irqchip.o) kvm-objs := $(kvm-objs-m) $(kvm-objs-y) diff --git a/arch/powerpc/kvm/irq.h b/arch/powerpc/kvm/irq.h new file mode 100644 index 000..f1e27fd --- /dev/null +++ b/arch/powerpc/kvm/irq.h @@ -0,0 +1,17 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#include linux/kvm_host.h + +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + int ret = 0; + +#ifdef CONFIG_KVM_MPIC + ret = ret || (kvm-arch.mpic != NULL); +#endif + smp_rmb(); + return ret; +} + +#endif diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 10bc08a..89fe1d6 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1076,7 +1076,9 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr, case 0xA0: /* IACK */ /* Read-only register */ break; - case 0xB0: /* EOI */ + case 0xB0: {/* EOI */ + int notify_eoi; + pr_debug(EOI\n); s_IRQ = IRQ_get_next(opp, dst-servicing); @@ -1087,6 +1089,8 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr, }
[PATCH 25/42] kvm/ppc/mpic: import hw/openpic.c from QEMU
From: Scott Wood scottw...@freescale.com This is QEMU's hw/openpic.c from commit abd8d4a4d6dfea7ddea72f095f993e1de941614e (Update version for 1.4.0-rc0), run through Lindent with no other changes to ease merging future changes between Linux and QEMU. Remaining style issues (including those introduced by Lindent) will be fixed in a later patch. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 1686 +++ 1 files changed, 1686 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/kvm/mpic.c diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c new file mode 100644 index 000..57655b9 --- /dev/null +++ b/arch/powerpc/kvm/mpic.c @@ -0,0 +1,1686 @@ +/* + * OpenPIC emulation + * + * Copyright (c) 2004 Jocelyn Mayer + * 2011 Alexander Graf + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* + * + * Based on OpenPic implementations: + * - Intel GW80314 I/O companion chip developer's manual + * - Motorola MPC8245 MPC8540 user manuals. + * - Motorola MCP750 (aka Raven) programmer manual. + * - Motorola Harrier programmer manuel + * + * Serial interrupts, as implemented in Raven chipset are not supported yet. + * + */ +#include hw.h +#include ppc/mac.h +#include pci/pci.h +#include openpic.h +#include sysbus.h +#include pci/msi.h +#include qemu/bitops.h +#include ppc.h + +//#define DEBUG_OPENPIC + +#ifdef DEBUG_OPENPIC +static const int debug_openpic = 1; +#else +static const int debug_openpic = 0; +#endif + +#define DPRINTF(fmt, ...) do { \ +if (debug_openpic) { \ +printf(fmt , ## __VA_ARGS__); \ +} \ +} while (0) + +#define MAX_CPU 32 +#define MAX_SRC 256 +#define MAX_TMR 4 +#define MAX_IPI 4 +#define MAX_MSI 8 +#define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR) +#define VID 0x03 /* MPIC version ID */ + +/* OpenPIC capability flags */ +#define OPENPIC_FLAG_IDR_CRIT (1 0) +#define OPENPIC_FLAG_ILR (2 0) + +/* OpenPIC address map */ +#define OPENPIC_GLB_REG_START0x0 +#define OPENPIC_GLB_REG_SIZE 0x10F0 +#define OPENPIC_TMR_REG_START0x10F0 +#define OPENPIC_TMR_REG_SIZE 0x220 +#define OPENPIC_MSI_REG_START0x1600 +#define OPENPIC_MSI_REG_SIZE 0x200 +#define OPENPIC_SUMMARY_REG_START 0x3800 +#define OPENPIC_SUMMARY_REG_SIZE0x800 +#define OPENPIC_SRC_REG_START0x1 +#define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20) +#define OPENPIC_CPU_REG_START0x2 +#define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) + +/* Raven */ +#define RAVEN_MAX_CPU 2 +#define RAVEN_MAX_EXT 48 +#define RAVEN_MAX_IRQ 64 +#define RAVEN_MAX_TMR MAX_TMR +#define RAVEN_MAX_IPI MAX_IPI + +/* Interrupt definitions */ +#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */ +#define RAVEN_ERR_IRQ(RAVEN_MAX_EXT + 1) /* Error IRQ */ +#define RAVEN_TMR_IRQ(RAVEN_MAX_EXT + 2) /* First timer IRQ */ +#define RAVEN_IPI_IRQ(RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */ +/* First doorbell IRQ */ +#define RAVEN_DBL_IRQ(RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI)) + +typedef struct FslMpicInfo { + int max_ext; +} FslMpicInfo; + +static FslMpicInfo fsl_mpic_20 = { + .max_ext = 12, +}; + +static FslMpicInfo fsl_mpic_42 = { + .max_ext = 12, +}; + +#define FRR_NIRQ_SHIFT16 +#define FRR_NCPU_SHIFT 8 +#define FRR_VID_SHIFT 0 + +#define VID_REVISION_1_2 2 +#define VID_REVISION_1_3 3 + +#define VIR_GENERIC 0x/* Generic Vendor ID */ + +#define GCR_RESET0x8000 +#define GCR_MODE_PASS0x +#define GCR_MODE_MIXED 0x2000 +#define GCR_MODE_PROXY 0x6000 + +#define TBCR_CI 0x8000 /* count inhibit */ +#define TCCR_TOG 0x8000 /* toggles
[PATCH 17/42] KVM: Introduce CONFIG_HAVE_KVM_IRQ_ROUTING
Quite a bit of code in KVM has been conditionalized on availability of IOAPIC emulation. However, most of it is generically applicable to platforms that don't have an IOPIC, but a different type of irq chip. Make code that only relies on IRQ routing, not an APIC itself, on CONFIG_HAVE_KVM_IRQ_ROUTING, so that we can reuse it later. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/Kconfig |1 + include/linux/kvm_host.h |6 +++--- virt/kvm/Kconfig |3 +++ virt/kvm/eventfd.c |6 +++--- virt/kvm/kvm_main.c |2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 586f000..9d50efd 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -29,6 +29,7 @@ config KVM select MMU_NOTIFIER select ANON_INODES select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING select HAVE_KVM_EVENTFD select KVM_APIC_ARCHITECTURE select KVM_ASYNC_PF diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bf3b1dc..4215d4f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -304,7 +304,7 @@ struct kvm_kernel_irq_routing_entry { struct hlist_node link; }; -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING struct kvm_irq_routing_table { int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; @@ -432,7 +432,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); int __must_check vcpu_load(struct kvm_vcpu *vcpu); void vcpu_put(struct kvm_vcpu *vcpu); -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING int kvm_irqfd_init(void); void kvm_irqfd_exit(void); #else @@ -957,7 +957,7 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq) } #endif -#ifdef KVM_CAP_IRQ_ROUTING +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING #define KVM_MAX_IRQ_ROUTES 1024 diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index d01b24b..779262f 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -6,6 +6,9 @@ config HAVE_KVM config HAVE_KVM_IRQCHIP bool +config HAVE_KVM_IRQ_ROUTING + bool + config HAVE_KVM_EVENTFD bool select EVENTFD diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index c5d43ff..64ee720 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -35,7 +35,7 @@ #include iodev.h -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING /* * * irqfd: Allows an fd to be used to inject an interrupt to the guest @@ -433,7 +433,7 @@ fail: void kvm_eventfd_init(struct kvm *kvm) { -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING spin_lock_init(kvm-irqfds.lock); INIT_LIST_HEAD(kvm-irqfds.items); INIT_LIST_HEAD(kvm-irqfds.resampler_list); @@ -442,7 +442,7 @@ kvm_eventfd_init(struct kvm *kvm) INIT_LIST_HEAD(kvm-ioeventfds); } -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING /* * shutdown any irqfd's that match fd+gsi */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index aaac1a7..2c3b226 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2404,7 +2404,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) case KVM_CAP_SIGNAL_MSI: #endif return 1; -#ifdef KVM_CAP_IRQ_ROUTING +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING case KVM_CAP_IRQ_ROUTING: return KVM_MAX_IRQ_ROUTES; #endif -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 24/42] kvm: add device control API
From: Scott Wood scottw...@freescale.com Currently, devices that are emulated inside KVM are configured in a hardcoded manner based on an assumption that any given architecture only has one way to do it. If there's any need to access device state, it is done through inflexible one-purpose-only IOCTLs (e.g. KVM_GET/SET_LAPIC). Defining new IOCTLs for every little thing is cumbersome and depletes a limited numberspace. This API provides a mechanism to instantiate a device of a certain type, returning an ID that can be used to set/get attributes of the device. Attributes may include configuration parameters (e.g. register base address), device state, operational commands, etc. It is similar to the ONE_REG API, except that it acts on devices rather than vcpus. Both device types and individual attributes can be tested without having to create the device or get/set the attribute, without the need for separately managing enumerated capabilities. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/api.txt| 70 Documentation/virtual/kvm/devices/README |1 + include/linux/kvm_host.h | 35 include/uapi/linux/kvm.h | 27 ++ virt/kvm/kvm_main.c | 129 ++ 5 files changed, 262 insertions(+), 0 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/README diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index a1f2200..66b58e4 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2189,6 +2189,76 @@ header; first `n_valid' valid entries with contents from the data written, then `n_invalid' invalid entries, invalidating any previously valid entries found. +4.79 KVM_CREATE_DEVICE + +Capability: KVM_CAP_DEVICE_CTRL +Type: vm ioctl +Parameters: struct kvm_create_device (in/out) +Returns: 0 on success, -1 on error +Errors: + ENODEV: The device type is unknown or unsupported + EEXIST: Device already created, and this type of device may not + be instantiated multiple times + + Other error conditions may be defined by individual device types or + have their standard meanings. + +Creates an emulated device in the kernel. The file descriptor returned +in fd can be used with KVM_SET/GET/HAS_DEVICE_ATTR. + +If the KVM_CREATE_DEVICE_TEST flag is set, only test whether the +device type is supported (not necessarily whether it can be created +in the current vm). + +Individual devices should not define flags. Attributes should be used +for specifying any behavior that is not implied by the device type +number. + +struct kvm_create_device { + __u32 type; /* in: KVM_DEV_TYPE_xxx */ + __u32 fd; /* out: device handle */ + __u32 flags; /* in: KVM_CREATE_DEVICE_xxx */ +}; + +4.80 KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR + +Capability: KVM_CAP_DEVICE_CTRL +Type: device ioctl +Parameters: struct kvm_device_attr +Returns: 0 on success, -1 on error +Errors: + ENXIO: The group or attribute is unknown/unsupported for this device + EPERM: The attribute cannot (currently) be accessed this way + (e.g. read-only attribute, or attribute that only makes + sense when the device is in a different state) + + Other error conditions may be defined by individual device types. + +Gets/sets a specified piece of device configuration and/or state. The +semantics are device-specific. See individual device documentation in +the devices directory. As with ONE_REG, the size of the data +transferred is defined by the particular attribute. + +struct kvm_device_attr { + __u32 flags; /* no flags currently defined */ + __u32 group; /* device-defined */ + __u64 attr; /* group-defined */ + __u64 addr; /* userspace address of attr data */ +}; + +4.81 KVM_HAS_DEVICE_ATTR + +Capability: KVM_CAP_DEVICE_CTRL +Type: device ioctl +Parameters: struct kvm_device_attr +Returns: 0 on success, -1 on error +Errors: + ENXIO: The group or attribute is unknown/unsupported for this device + +Tests whether a device supports a particular attribute. A successful +return indicates the attribute is implemented. It does not necessarily +indicate that the attribute can be read or written in the device's +current state. addr is ignored. 4.77 KVM_ARM_VCPU_INIT diff --git a/Documentation/virtual/kvm/devices/README b/Documentation/virtual/kvm/devices/README new file mode 100644 index 000..34a6983 --- /dev/null +++ b/Documentation/virtual/kvm/devices/README @@ -0,0 +1 @@ +This directory contains specific device bindings for KVM_CAP_DEVICE_CTRL. diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index dcef724..6dab6b5 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1064,6 +1064,41 @@ static inline bool
[PATCH 22/42] KVM: Move irq routing setup to irqchip.c
Setting up IRQ routes is nothing IOAPIC specific. Extract everything that really is generic code into irqchip.c and only leave the ioapic specific bits to irq_comm.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/linux/kvm_host.h |3 ++ virt/kvm/irq_comm.c | 76 ++--- virt/kvm/irqchip.c | 85 ++ 3 files changed, 91 insertions(+), 73 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a7bfe9d..dcef724 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -961,6 +961,9 @@ int kvm_set_irq_routing(struct kvm *kvm, const struct kvm_irq_routing_entry *entries, unsigned nr, unsigned flags); +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue); void kvm_free_irq_routing(struct kvm *kvm); int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index d5008f4..e2e6b44 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -271,27 +271,14 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, rcu_read_unlock(); } -static int setup_routing_entry(struct kvm_irq_routing_table *rt, - struct kvm_kernel_irq_routing_entry *e, - const struct kvm_irq_routing_entry *ue) +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue) { int r = -EINVAL; int delta; unsigned max_pin; - struct kvm_kernel_irq_routing_entry *ei; - /* -* Do not allow GSI to be mapped to the same irqchip more than once. -* Allow only one to one mapping between GSI and MSI. -*/ - hlist_for_each_entry(ei, rt-map[ue-gsi], link) - if (ei-type == KVM_IRQ_ROUTING_MSI || - ue-type == KVM_IRQ_ROUTING_MSI || - ue-u.irqchip.irqchip == ei-irqchip.irqchip) - return r; - - e-gsi = ue-gsi; - e-type = ue-type; switch (ue-type) { case KVM_IRQ_ROUTING_IRQCHIP: delta = 0; @@ -328,68 +315,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, goto out; } - hlist_add_head(e-link, rt-map[e-gsi]); r = 0; out: return r; } -int kvm_set_irq_routing(struct kvm *kvm, - const struct kvm_irq_routing_entry *ue, - unsigned nr, - unsigned flags) -{ - struct kvm_irq_routing_table *new, *old; - u32 i, j, nr_rt_entries = 0; - int r; - - for (i = 0; i nr; ++i) { - if (ue[i].gsi = KVM_MAX_IRQ_ROUTES) - return -EINVAL; - nr_rt_entries = max(nr_rt_entries, ue[i].gsi); - } - - nr_rt_entries += 1; - - new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)) - + (nr * sizeof(struct kvm_kernel_irq_routing_entry)), - GFP_KERNEL); - - if (!new) - return -ENOMEM; - - new-rt_entries = (void *)new-map[nr_rt_entries]; - - new-nr_rt_entries = nr_rt_entries; - for (i = 0; i 3; i++) - for (j = 0; j KVM_IRQCHIP_NUM_PINS; j++) - new-chip[i][j] = -1; - - for (i = 0; i nr; ++i) { - r = -EINVAL; - if (ue-flags) - goto out; - r = setup_routing_entry(new, new-rt_entries[i], ue); - if (r) - goto out; - ++ue; - } - - mutex_lock(kvm-irq_lock); - old = kvm-irq_routing; - kvm_irq_routing_update(kvm, new); - mutex_unlock(kvm-irq_lock); - - synchronize_rcu(); - - new = old; - r = 0; - -out: - kfree(new); - return r; -} - #define IOAPIC_ROUTING_ENTRY(irq) \ { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) } diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 12f7f26..20dc9e4 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -150,3 +150,88 @@ void kvm_free_irq_routing(struct kvm *kvm) at this stage */ kfree(kvm-irq_routing); } + +static int setup_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue) +{ + int r = -EINVAL; + struct
[PATCH 23/42] KVM: Move irqfd resample cap handling to generic code
Now that we have most irqfd code completely platform agnostic, let's move irqfd's resample capability return to generic code as well. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/x86.c |1 - virt/kvm/kvm_main.c |3 +++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2a434bf..f6c3f03 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2522,7 +2522,6 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PCI_2_3: case KVM_CAP_KVMCLOCK_CTRL: case KVM_CAP_READONLY_MEM: - case KVM_CAP_IRQFD_RESAMPLE: r = 1; break; case KVM_CAP_COALESCED_MMIO: diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b6f3354..f9492f3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2433,6 +2433,9 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) #ifdef CONFIG_HAVE_KVM_MSI case KVM_CAP_SIGNAL_MSI: #endif +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING + case KVM_CAP_IRQFD_RESAMPLE: +#endif return 1; #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING case KVM_CAP_IRQ_ROUTING: -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 19/42] KVM: Remove kvm_get_intr_delivery_bitmask
The prototype has been stale for a while, I can't spot any real function define behind it. Let's just remove it. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/linux/kvm_host.h |5 - 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4215d4f..a7bfe9d 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -719,11 +719,6 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, bool mask); -#ifdef __KVM_HAVE_IOAPIC -void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, - union kvm_ioapic_redirect_entry *entry, - unsigned long *deliver_bitmask); -#endif int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, bool line_status); int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level); -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 21/42] KVM: Extract generic irqchip logic into irqchip.c
The current irq_comm.c file contains pieces of code that are generic across different irqchip implementations, as well as code that is fully IOAPIC specific. Split the generic bits out into irqchip.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/Makefile |2 +- include/trace/events/kvm.h | 12 +++- virt/kvm/irq_comm.c| 118 -- virt/kvm/irqchip.c | 152 4 files changed, 163 insertions(+), 121 deletions(-) create mode 100644 virt/kvm/irqchip.c diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 04d3040..a797b8e 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -7,7 +7,7 @@ CFLAGS_vmx.o := -I. kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ coalesced_mmio.o irq_comm.o eventfd.o \ - assigned-dev.o) + assigned-dev.o irqchip.o) kvm-$(CONFIG_IOMMU_API)+= $(addprefix ../../../virt/kvm/, iommu.o) kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 19911dd..7005d11 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -37,7 +37,7 @@ TRACE_EVENT(kvm_userspace_exit, __entry-errno 0 ? -__entry-errno : __entry-reason) ); -#if defined(__KVM_HAVE_IRQ_LINE) +#if defined(CONFIG_HAVE_KVM_IRQCHIP) TRACE_EVENT(kvm_set_irq, TP_PROTO(unsigned int gsi, int level, int irq_source_id), TP_ARGS(gsi, level, irq_source_id), @@ -122,6 +122,10 @@ TRACE_EVENT(kvm_msi_set_irq, {KVM_IRQCHIP_PIC_SLAVE, PIC slave}, \ {KVM_IRQCHIP_IOAPIC,IOAPIC} +#endif /* defined(__KVM_HAVE_IOAPIC) */ + +#if defined(CONFIG_HAVE_KVM_IRQCHIP) + TRACE_EVENT(kvm_ack_irq, TP_PROTO(unsigned int irqchip, unsigned int pin), TP_ARGS(irqchip, pin), @@ -136,14 +140,18 @@ TRACE_EVENT(kvm_ack_irq, __entry-pin= pin; ), +#ifdef kvm_irqchips TP_printk(irqchip %s pin %u, __print_symbolic(__entry-irqchip, kvm_irqchips), __entry-pin) +#else + TP_printk(irqchip %d pin %u, __entry-irqchip, __entry-pin) +#endif ); +#endif /* defined(CONFIG_HAVE_KVM_IRQCHIP) */ -#endif /* defined(__KVM_HAVE_IOAPIC) */ #define KVM_TRACE_MMIO_READ_UNSATISFIED 0 #define KVM_TRACE_MMIO_READ 1 diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 7c0071d..d5008f4 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -151,59 +151,6 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e, return -EWOULDBLOCK; } -int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) -{ - struct kvm_kernel_irq_routing_entry route; - - if (!irqchip_in_kernel(kvm) || msi-flags != 0) - return -EINVAL; - - route.msi.address_lo = msi-address_lo; - route.msi.address_hi = msi-address_hi; - route.msi.data = msi-data; - - return kvm_set_msi(route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); -} - -/* - * Return value: - * 0 Interrupt was ignored (masked or not delivered for other reasons) - * = 0 Interrupt was coalesced (previous irq is still pending) - * 0 Number of CPUs interrupt was delivered to - */ -int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, - bool line_status) -{ - struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; - int ret = -1, i = 0; - struct kvm_irq_routing_table *irq_rt; - - trace_kvm_set_irq(irq, level, irq_source_id); - - /* Not possible to detect if the guest uses the PIC or the -* IOAPIC. So set the bit in both. The guest will ignore -* writes to the unused one. -*/ - rcu_read_lock(); - irq_rt = rcu_dereference(kvm-irq_routing); - if (irq irq_rt-nr_rt_entries) - hlist_for_each_entry(e, irq_rt-map[irq], link) - irq_set[i++] = *e; - rcu_read_unlock(); - - while(i--) { - int r; - r = irq_set[i].set(irq_set[i], kvm, irq_source_id, level, - line_status); - if (r 0) - continue; - - ret = r + ((ret 0) ? 0 : ret); - } - - return ret; -} - /* * Deliver an IRQ in an atomic context if we can, or return a failure, * user can retry in a process context. @@ -241,63 +188,6 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level) return ret; } -bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) -{ - struct kvm_irq_ack_notifier *kian; - int gsi; - - rcu_read_lock(); - gsi
[PATCH 13/20] kvm/ppc/mpic: in-kernel MPIC emulation
From: Scott Wood scottw...@freescale.com Hook the MPIC code up to the KVM interfaces, add locking, etc. Signed-off-by: Scott Wood scottw...@freescale.com [agraf: add stub function for kvmppc_mpic_set_epr, non-booke, 64bit] Signed-off-by: Alexander Graf ag...@suse.de --- v2 - v3: - fix pr_debug again --- Documentation/virtual/kvm/devices/mpic.txt | 37 ++ arch/powerpc/include/asm/kvm_host.h|8 +- arch/powerpc/include/asm/kvm_ppc.h | 17 + arch/powerpc/include/uapi/asm/kvm.h|7 + arch/powerpc/kvm/Kconfig |9 + arch/powerpc/kvm/Makefile |2 + arch/powerpc/kvm/booke.c |8 +- arch/powerpc/kvm/mpic.c| 762 +--- arch/powerpc/kvm/powerpc.c | 12 +- include/linux/kvm_host.h |2 + include/uapi/linux/kvm.h |3 + virt/kvm/kvm_main.c|6 + 12 files changed, 673 insertions(+), 200 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/mpic.txt diff --git a/Documentation/virtual/kvm/devices/mpic.txt b/Documentation/virtual/kvm/devices/mpic.txt new file mode 100644 index 000..ce98e32 --- /dev/null +++ b/Documentation/virtual/kvm/devices/mpic.txt @@ -0,0 +1,37 @@ +MPIC interrupt controller += + +Device types supported: + KVM_DEV_TYPE_FSL_MPIC_20 Freescale MPIC v2.0 + KVM_DEV_TYPE_FSL_MPIC_42 Freescale MPIC v4.2 + +Only one MPIC instance, of any type, may be instantiated. The created +MPIC will act as the system interrupt controller, connecting to each +vcpu's interrupt inputs. + +Groups: + KVM_DEV_MPIC_GRP_MISC + Attributes: +KVM_DEV_MPIC_BASE_ADDR (rw, 64-bit) + Base address of the 256 KiB MPIC register space. Must be + naturally aligned. A value of zero disables the mapping. + Reset value is zero. + + KVM_DEV_MPIC_GRP_REGISTER (rw, 32-bit) +Access an MPIC register, as if the access were made from the guest. +attr is the byte offset into the MPIC register space. Accesses +must be 4-byte aligned. + +MSIs may be signaled by using this attribute group to write +to the relevant MSIIR. + + KVM_DEV_MPIC_GRP_IRQ_ACTIVE (rw, 32-bit) +IRQ input line for each standard openpic source. 0 is inactive and 1 +is active, regardless of interrupt sense. + +For edge-triggered interrupts: Writing 1 is considered an activating +edge, and writing 0 is ignored. Reading returns 1 if a previously +signaled edge has not been acknowledged, and 0 otherwise. + +attr is the IRQ number. IRQ numbers for standard sources are the +byte offset of the relevant IVPR from EIVPR0, divided by 32. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index e34f8fe..7e7aef9 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -359,6 +359,11 @@ struct kvmppc_slb { #define KVMPPC_BOOKE_MAX_IAC 4 #define KVMPPC_BOOKE_MAX_DAC 2 +/* KVMPPC_EPR_USER takes precedence over KVMPPC_EPR_KERNEL */ +#define KVMPPC_EPR_NONE0 /* EPR not supported */ +#define KVMPPC_EPR_USER1 /* exit to userspace to fill EPR */ +#define KVMPPC_EPR_KERNEL 2 /* in-kernel irqchip */ + struct kvmppc_booke_debug_reg { u32 dbcr0; u32 dbcr1; @@ -522,7 +527,7 @@ struct kvm_vcpu_arch { u8 sane; u8 cpu_type; u8 hcall_needed; - u8 epr_enabled; + u8 epr_flags; /* KVMPPC_EPR_xxx */ u8 epr_needed; u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ @@ -589,5 +594,6 @@ struct kvm_vcpu_arch { #define KVM_MMIO_REG_FQPR 0x0060 #define __KVM_HAVE_ARCH_WQP +#define __KVM_HAVE_CREATE_DEVICE #endif /* __POWERPC_KVM_HOST_H__ */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 4794de6..da43e5f 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -164,6 +164,8 @@ extern int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu); extern int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *); +int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); + /* * Cuts out inst bits with ordering according to spec. * That means the leftmost bit is zero. All given bits are included. @@ -245,6 +247,9 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *); void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); +struct openpic; +void kvmppc_mpic_put(struct openpic *opp); + #ifdef CONFIG_KVM_BOOK3S_64_HV static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) { @@ -270,6 +275,18 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) #endif } +#ifdef CONFIG_KVM_MPIC + +void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu); + +#else + +static inline void kvmppc_mpic_set_epr(struct
[PATCH 18/42] KVM: Drop __KVM_HAVE_IOAPIC condition on irq routing
We have a capability enquire system that allows user space to ask kvm whether a feature is available. The point behind this system is that we can have different kernel configurations with different capabilities and user space can adjust accordingly. Because features can always be non existent, we can drop any #ifdefs on CAP defines that could be used generically, like the irq routing bits. These can be easily reused for non-IOAPIC systems as well. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/uapi/linux/kvm.h |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 74d0ff3..c741902 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -579,9 +579,7 @@ struct kvm_ppc_smmu_info { #ifdef __KVM_HAVE_PIT #define KVM_CAP_REINJECT_CONTROL 24 #endif -#ifdef __KVM_HAVE_IOAPIC #define KVM_CAP_IRQ_ROUTING 25 -#endif #define KVM_CAP_IRQ_INJECT_STATUS 26 #ifdef __KVM_HAVE_DEVICE_ASSIGNMENT #define KVM_CAP_DEVICE_DEASSIGNMENT 27 -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 20/42] KVM: Move irq routing to generic code
The IRQ routing set ioctl lives in the hacky device assignment code inside of KVM today. This is definitely the wrong place for it. Move it to the much more natural kvm_main.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- virt/kvm/assigned-dev.c | 30 -- virt/kvm/kvm_main.c | 30 ++ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index f4c7f59..8db4370 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -983,36 +983,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, goto out; break; } -#ifdef KVM_CAP_IRQ_ROUTING - case KVM_SET_GSI_ROUTING: { - struct kvm_irq_routing routing; - struct kvm_irq_routing __user *urouting; - struct kvm_irq_routing_entry *entries; - - r = -EFAULT; - if (copy_from_user(routing, argp, sizeof(routing))) - goto out; - r = -EINVAL; - if (routing.nr = KVM_MAX_IRQ_ROUTES) - goto out; - if (routing.flags) - goto out; - r = -ENOMEM; - entries = vmalloc(routing.nr * sizeof(*entries)); - if (!entries) - goto out; - r = -EFAULT; - urouting = argp; - if (copy_from_user(entries, urouting-entries, - routing.nr * sizeof(*entries))) - goto out_free_irq_routing; - r = kvm_set_irq_routing(kvm, entries, routing.nr, - routing.flags); - out_free_irq_routing: - vfree(entries); - break; - } -#endif /* KVM_CAP_IRQ_ROUTING */ #ifdef __KVM_HAVE_MSIX case KVM_ASSIGN_SET_MSIX_NR: { struct kvm_assigned_msix_nr entry_nr; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2c3b226..b6f3354 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2274,6 +2274,36 @@ static long kvm_vm_ioctl(struct file *filp, break; } #endif +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING + case KVM_SET_GSI_ROUTING: { + struct kvm_irq_routing routing; + struct kvm_irq_routing __user *urouting; + struct kvm_irq_routing_entry *entries; + + r = -EFAULT; + if (copy_from_user(routing, argp, sizeof(routing))) + goto out; + r = -EINVAL; + if (routing.nr = KVM_MAX_IRQ_ROUTES) + goto out; + if (routing.flags) + goto out; + r = -ENOMEM; + entries = vmalloc(routing.nr * sizeof(*entries)); + if (!entries) + goto out; + r = -EFAULT; + urouting = argp; + if (copy_from_user(entries, urouting-entries, + routing.nr * sizeof(*entries))) + goto out_free_irq_routing; + r = kvm_set_irq_routing(kvm, entries, routing.nr, + routing.flags); + out_free_irq_routing: + vfree(entries); + break; + } +#endif /* CONFIG_HAVE_KVM_IRQ_ROUTING */ default: r = kvm_arch_vm_ioctl(filp, ioctl, arg); if (r == -ENOTTY) -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/42] KVM: PPC: e500: Add e6500 core to Kconfig description
From: Mihai Caraman mihai.cara...@freescale.com Add e6500 core to Kconfig description. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/Kconfig |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 63c67ec..4489520 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -136,15 +136,15 @@ config KVM_E500V2 If unsure, say N. config KVM_E500MC - bool KVM support for PowerPC E500MC/E5500 processors + bool KVM support for PowerPC E500MC/E5500/E6500 processors depends on PPC_E500MC select KVM select KVM_MMIO select KVM_BOOKE_HV select MMU_NOTIFIER ---help--- - Support running unmodified E500MC/E5500 (32-bit) guest kernels in - virtual machines on E500MC/E5500 host processors. + Support running unmodified E500MC/E5500/E6500 guest kernels in + virtual machines on E500MC/E5500/E6500 host processors. This module provides access to the hardware capabilities through a character device node named /dev/kvm. -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/42] KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions
From: Mihai Caraman mihai.cara...@freescale.com Vcpu's MMU default configuration and geometry update logic was buried in a chunk of code. Move them to dedicated functions to add more clarity. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/e500_mmu.c | 60 +++--- 1 files changed, 38 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index 44f7762..08a5b0d 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -690,6 +690,20 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, return r; } +static int vcpu_mmu_geometry_update(struct kvm_vcpu *vcpu, + struct kvm_book3e_206_tlb_params *params) +{ + vcpu-arch.tlbcfg[0] = ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); + if (params-tlb_sizes[0] = 2048) + vcpu-arch.tlbcfg[0] |= params-tlb_sizes[0]; + vcpu-arch.tlbcfg[0] |= params-tlb_ways[0] TLBnCFG_ASSOC_SHIFT; + + vcpu-arch.tlbcfg[1] = ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); + vcpu-arch.tlbcfg[1] |= params-tlb_sizes[1]; + vcpu-arch.tlbcfg[1] |= params-tlb_ways[1] TLBnCFG_ASSOC_SHIFT; + return 0; +} + int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, struct kvm_config_tlb *cfg) { @@ -786,16 +800,8 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, vcpu_e500-gtlb_offset[0] = 0; vcpu_e500-gtlb_offset[1] = params.tlb_sizes[0]; - vcpu-arch.mmucfg = mfspr(SPRN_MMUCFG) ~MMUCFG_LPIDSIZE; - - vcpu-arch.tlbcfg[0] = ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); - if (params.tlb_sizes[0] = 2048) - vcpu-arch.tlbcfg[0] |= params.tlb_sizes[0]; - vcpu-arch.tlbcfg[0] |= params.tlb_ways[0] TLBnCFG_ASSOC_SHIFT; - - vcpu-arch.tlbcfg[1] = ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); - vcpu-arch.tlbcfg[1] |= params.tlb_sizes[1]; - vcpu-arch.tlbcfg[1] |= params.tlb_ways[1] TLBnCFG_ASSOC_SHIFT; + /* Update vcpu's MMU geometry based on SW_TLB input */ + vcpu_mmu_geometry_update(vcpu, params); vcpu_e500-shared_tlb_pages = pages; vcpu_e500-num_shared_tlb_pages = num_pages; @@ -831,6 +837,27 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu, return 0; } +/* Vcpu's MMU default configuration */ +static int vcpu_mmu_init(struct kvm_vcpu *vcpu, + struct kvmppc_e500_tlb_params *params) +{ + /* Initialize RASIZE, PIDSIZE, NTLBS and MAVN fields with host values*/ + vcpu-arch.mmucfg = mfspr(SPRN_MMUCFG) ~MMUCFG_LPIDSIZE; + + /* Initialize TLBnCFG fields with host values and SW_TLB geometry*/ + vcpu-arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) +~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); + vcpu-arch.tlbcfg[0] |= params[0].entries; + vcpu-arch.tlbcfg[0] |= params[0].ways TLBnCFG_ASSOC_SHIFT; + + vcpu-arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) +~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); + vcpu-arch.tlbcfg[1] |= params[1].entries; + vcpu-arch.tlbcfg[1] |= params[1].ways TLBnCFG_ASSOC_SHIFT; + + return 0; +} + int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500) { struct kvm_vcpu *vcpu = vcpu_e500-vcpu; @@ -875,18 +902,7 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500) if (!vcpu_e500-g2h_tlb1_map) goto err; - /* Init TLB configuration register */ - vcpu-arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) -~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); - vcpu-arch.tlbcfg[0] |= vcpu_e500-gtlb_params[0].entries; - vcpu-arch.tlbcfg[0] |= - vcpu_e500-gtlb_params[0].ways TLBnCFG_ASSOC_SHIFT; - - vcpu-arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) -~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); - vcpu-arch.tlbcfg[1] |= vcpu_e500-gtlb_params[1].entries; - vcpu-arch.tlbcfg[1] |= - vcpu_e500-gtlb_params[1].ways TLBnCFG_ASSOC_SHIFT; + vcpu_mmu_init(vcpu, vcpu_e500-gtlb_params); kvmppc_recalc_tlb1map_range(vcpu_e500); return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/42] KVM: PPC: e500: Add support for EPTCFG register
From: Mihai Caraman mihai.cara...@freescale.com EPTCFG register defined by E.PT is accessed unconditionally by Linux guests in the presence of MAV 2.0. Emulate it now. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/api.txt |1 + arch/powerpc/include/asm/kvm_host.h |1 + arch/powerpc/include/uapi/asm/kvm.h |1 + arch/powerpc/kvm/e500_emulate.c |9 + arch/powerpc/kvm/e500_mmu.c | 12 5 files changed, 24 insertions(+), 0 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index f045377..a1f2200 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1807,6 +1807,7 @@ registers, find a list below: PPC | KVM_REG_PPC_TLB1PS | 32 PPC | KVM_REG_PPC_TLB2PS | 32 PPC | KVM_REG_PPC_TLB3PS | 32 + PPC | KVM_REG_PPC_EPTCFG | 32 ARM registers are mapped using the lower 32 bits. The upper 16 of that is the register group type, or coprocessor number: diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 3b6cee3..8a48e68 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -504,6 +504,7 @@ struct kvm_vcpu_arch { u32 tlbcfg[4]; u32 tlbps[4]; u32 mmucfg; + u32 eptcfg; u32 epr; u32 crit_save; struct kvmppc_booke_debug_reg dbg_reg; diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 4dd36c3..41d59d8 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -469,5 +469,6 @@ struct kvm_get_htab_header { #define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98) #define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99) #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) +#define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b) #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 12b8de2..b10a012 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) case SPRN_MMUCFG: *spr_val = vcpu-arch.mmucfg; break; + case SPRN_EPTCFG: + if (!has_feature(vcpu, VCPU_FTR_MMU_V2)) + return EMULATE_FAIL; + /* +* Legacy Linux guests access EPTCFG register even if the E.PT +* category is disabled in the VM. Give them a chance to live. +*/ + *spr_val = vcpu-arch.eptcfg; + break; /* extra exceptions */ case SPRN_IVOR32: diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index a863dc1..1c1c5cb 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -624,6 +624,9 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, case KVM_REG_PPC_MMUCFG: *val = get_reg_val(id, vcpu-arch.mmucfg); break; + case KVM_REG_PPC_EPTCFG: + *val = get_reg_val(id, vcpu-arch.eptcfg); + break; case KVM_REG_PPC_TLB0CFG: case KVM_REG_PPC_TLB1CFG: case KVM_REG_PPC_TLB2CFG: @@ -678,6 +681,12 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, r = -EINVAL; break; } + case KVM_REG_PPC_EPTCFG: { + u32 reg = set_reg_val(id, *val); + if (reg != vcpu-arch.eptcfg) + r = -EINVAL; + break; + } case KVM_REG_PPC_TLB0CFG: case KVM_REG_PPC_TLB1CFG: case KVM_REG_PPC_TLB2CFG: @@ -875,6 +884,9 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu, if (has_feature(vcpu, VCPU_FTR_MMU_V2)) { vcpu-arch.tlbps[0] = mfspr(SPRN_TLB0PS); vcpu-arch.tlbps[1] = mfspr(SPRN_TLB1PS); + + /* Guest mmu emulation currently doesn't handle E.PT */ + vcpu-arch.eptcfg = 0; } return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/42] KVM: PPC: Book3S HV: Make HPT reading code notice R/C bit changes
From: Paul Mackerras pau...@samba.org At present, the code that determines whether a HPT entry has changed, and thus needs to be sent to userspace when it is copying the HPT, doesn't consider a hardware update to the reference and change bits (R and C) in the HPT entries to constitute a change that needs to be sent to userspace. This adds code to check for changes in R and C when we are scanning the HPT to find changed entries, and adds code to set the changed flag for the HPTE when we update the R and C bits in the guest view of the HPTE. Since we now need to set the HPTE changed flag in book3s_64_mmu_hv.c as well as book3s_hv_rm_mmu.c, we move the note_hpte_modification() function into kvm_book3s_64.h. Current Linux guest kernels don't use the hardware updates of R and C in the HPT, so this change won't affect them. Linux (or other) kernels might in future want to use the R and C bits and have them correctly transferred across when a guest is migrated, so it is better to correct this deficiency. Signed-off-by: Paul Mackerras pau...@samba.org Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/asm/kvm_book3s_64.h | 13 +++ arch/powerpc/kvm/book3s_64_mmu_hv.c | 59 +- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 11 -- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index 38bec1d..9c1ff33 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -268,4 +268,17 @@ static inline int is_vrma_hpte(unsigned long hpte_v) (HPTE_V_1TB_SEG | (VRMA_VSID (40 - 16))); } +#ifdef CONFIG_KVM_BOOK3S_64_HV +/* + * Note modification of an HPTE; set the HPTE modified bit + * if anyone is interested. + */ +static inline void note_hpte_modification(struct kvm *kvm, + struct revmap_entry *rev) +{ + if (atomic_read(kvm-arch.hpte_mod_interest)) + rev-guest_rpte |= HPTE_GR_MODIFIED; +} +#endif /* CONFIG_KVM_BOOK3S_64_HV */ + #endif /* __ASM_KVM_BOOK3S_64_H__ */ diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 8cc18ab..d641a66 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -893,7 +893,10 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, /* Harvest R and C */ rcbits = hptep[1] (HPTE_R_R | HPTE_R_C); *rmapp |= rcbits KVMPPC_RMAP_RC_SHIFT; - rev[i].guest_rpte = ptel | rcbits; + if (rcbits ~rev[i].guest_rpte) { + rev[i].guest_rpte = ptel | rcbits; + note_hpte_modification(kvm, rev[i]); + } } unlock_rmap(rmapp); hptep[0] = ~HPTE_V_HVLOCK; @@ -976,7 +979,10 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, /* Now check and modify the HPTE */ if ((hptep[0] HPTE_V_VALID) (hptep[1] HPTE_R_R)) { kvmppc_clear_ref_hpte(kvm, hptep, i); - rev[i].guest_rpte |= HPTE_R_R; + if (!(rev[i].guest_rpte HPTE_R_R)) { + rev[i].guest_rpte |= HPTE_R_R; + note_hpte_modification(kvm, rev[i]); + } ret = 1; } hptep[0] = ~HPTE_V_HVLOCK; @@ -1080,7 +1086,10 @@ static int kvm_test_clear_dirty(struct kvm *kvm, unsigned long *rmapp) hptep[1] = ~HPTE_R_C; eieio(); hptep[0] = (hptep[0] ~HPTE_V_ABSENT) | HPTE_V_VALID; - rev[i].guest_rpte |= HPTE_R_C; + if (!(rev[i].guest_rpte HPTE_R_C)) { + rev[i].guest_rpte |= HPTE_R_C; + note_hpte_modification(kvm, rev[i]); + } ret = 1; } hptep[0] = ~HPTE_V_HVLOCK; @@ -1193,16 +1202,36 @@ struct kvm_htab_ctx { #define HPTE_SIZE (2 * sizeof(unsigned long)) +/* + * Returns 1 if this HPT entry has been modified or has pending + * R/C bit changes. + */ +static int hpte_dirty(struct revmap_entry *revp, unsigned long *hptp) +{ + unsigned long rcbits_unset; + + if (revp-guest_rpte HPTE_GR_MODIFIED) + return 1; + + /* Also need to consider changes in reference and changed bits */ + rcbits_unset = ~revp-guest_rpte (HPTE_R_R | HPTE_R_C); + if ((hptp[0] HPTE_V_VALID) (hptp[1] rcbits_unset)) + return 1; + + return 0; +} + static long record_hpte(unsigned long flags, unsigned long *hptp,
[PATCH 16/42] KVM: Add KVM_IRQCHIP_NUM_PINS in addition to KVM_IOAPIC_NUM_PINS
The concept of routing interrupt lines to an irqchip is nothing that is IOAPIC specific. Every irqchip has a maximum number of pins that can be linked to irq lines. So let's add a new define that allows us to reuse generic code for non-IOAPIC platforms. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/include/asm/kvm_host.h |2 ++ include/linux/kvm_host.h|2 +- virt/kvm/irq_comm.c |2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 18635ae..14337fa 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -43,6 +43,8 @@ #define KVM_PIO_PAGE_OFFSET 1 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2 +#define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS + #define CR0_RESERVED_BITS \ (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \ | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 93a5005..bf3b1dc 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -307,7 +307,7 @@ struct kvm_kernel_irq_routing_entry { #ifdef __KVM_HAVE_IOAPIC struct kvm_irq_routing_table { - int chip[KVM_NR_IRQCHIPS][KVM_IOAPIC_NUM_PINS]; + int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; struct kvm_kernel_irq_routing_entry *rt_entries; u32 nr_rt_entries; /* diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 25ab480..7c0071d 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -480,7 +480,7 @@ int kvm_set_irq_routing(struct kvm *kvm, new-nr_rt_entries = nr_rt_entries; for (i = 0; i 3; i++) - for (j = 0; j KVM_IOAPIC_NUM_PINS; j++) + for (j = 0; j KVM_IRQCHIP_NUM_PINS; j++) new-chip[i][j] = -1; for (i = 0; i nr; ++i) { -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/42] KVM: PPC: Book3S HV: Report VPA and DTL modifications in dirty map
From: Paul Mackerras pau...@samba.org At present, the KVM_GET_DIRTY_LOG ioctl doesn't report modifications done by the host to the virtual processor areas (VPAs) and dispatch trace logs (DTLs) registered by the guest. This is because those modifications are done either in real mode or in the host kernel context, and in neither case does the access go through the guest's HPT, and thus no change (C) bit gets set in the guest's HPT. However, the changes done by the host do need to be tracked so that the modified pages get transferred when doing live migration. In order to track these modifications, this adds a dirty flag to the struct representing the VPA/DTL areas, and arranges to set the flag when the VPA/DTL gets modified by the host. Then, when we are collecting the dirty log, we also check the dirty flags for the VPA and DTL for each vcpu and set the relevant bit in the dirty log if necessary. Doing this also means we now need to keep track of the guest physical address of the VPA/DTL areas. So as not to lose track of modifications to a VPA/DTL area when it gets unregistered, or when a new area gets registered in its place, we need to transfer the dirty state to the rmap chain. This adds code to kvmppc_unpin_guest_page() to do that if the area was dirty. To simplify that code, we now require that all VPA, DTL and SLB shadow buffer areas fit within a single host page. Guests already comply with this requirement because pHyp requires that these areas not cross a 4k boundary. Signed-off-by: Paul Mackerras pau...@samba.org Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/asm/kvm_book3s.h |3 +- arch/powerpc/include/asm/kvm_host.h |2 + arch/powerpc/kernel/asm-offsets.c |1 + arch/powerpc/kvm/book3s_64_mmu_hv.c | 61 ++- arch/powerpc/kvm/book3s_hv.c| 30 ++-- arch/powerpc/kvm/book3s_hv_rmhandlers.S |4 ++ 6 files changed, 80 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index bc81842..c55f7e6 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -156,7 +156,8 @@ void kvmppc_clear_ref_hpte(struct kvm *kvm, unsigned long *hptep, unsigned long pte_index); extern void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long addr, unsigned long *nb_ret); -extern void kvmppc_unpin_guest_page(struct kvm *kvm, void *addr); +extern void kvmppc_unpin_guest_page(struct kvm *kvm, void *addr, + unsigned long gpa, bool dirty); extern long kvmppc_virtmode_h_enter(struct kvm_vcpu *vcpu, unsigned long flags, long pte_index, unsigned long pteh, unsigned long ptel); extern long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 8a48e68..1443768 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -301,11 +301,13 @@ struct kvmppc_vcore { * that a guest can register. */ struct kvmppc_vpa { + unsigned long gpa; /* Current guest phys addr */ void *pinned_addr; /* Address in kernel linear mapping */ void *pinned_end; /* End of region */ unsigned long next_gpa; /* Guest phys addr for update */ unsigned long len; /* Number of bytes required */ u8 update_pending; /* 1 = update pinned_addr from next_gpa */ + bool dirty; /* true = area has been modified by kernel */ }; struct kvmppc_pte { diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index d87c908..dbfd549 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -477,6 +477,7 @@ int main(void) DEFINE(VCPU_DSISR, offsetof(struct kvm_vcpu, arch.shregs.dsisr)); DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr)); + DEFINE(VCPU_VPA_DIRTY, offsetof(struct kvm_vcpu, arch.vpa.dirty)); #endif #ifdef CONFIG_PPC_BOOK3S DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id)); diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index d641a66..69efe0d 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -1099,11 +1099,30 @@ static int kvm_test_clear_dirty(struct kvm *kvm, unsigned long *rmapp) return ret; } +static void harvest_vpa_dirty(struct kvmppc_vpa *vpa, + struct kvm_memory_slot *memslot, + unsigned long *map) +{ + unsigned long gfn; + + if (!vpa-dirty || !vpa-pinned_addr) + return; + gfn = vpa-gpa PAGE_SHIFT; + if (gfn memslot-base_gfn || + gfn =
[PATCH 12/42] KVM: PPC: e500mc: Enable e6500 cores
From: Mihai Caraman mihai.cara...@freescale.com Extend processor compatibility names to e6500 cores. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Reviewed-by: Alexander Graf ag...@suse.de Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/e500mc.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index ab073a8..c3bdc0a 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -172,6 +172,8 @@ int kvmppc_core_check_processor_compat(void) r = 0; else if (strcmp(cur_cpu_spec-cpu_name, e5500) == 0) r = 0; + else if (strcmp(cur_cpu_spec-cpu_name, e6500) == 0) + r = 0; else r = -ENOTSUPP; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/42] KVM: PPC: e500: Add support for TLBnPS registers
From: Mihai Caraman mihai.cara...@freescale.com Add support for TLBnPS registers available in MMU Architecture Version (MAV) 2.0. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/api.txt |4 arch/powerpc/include/asm/kvm_host.h |1 + arch/powerpc/include/uapi/asm/kvm.h |4 arch/powerpc/kvm/e500.h | 18 ++ arch/powerpc/kvm/e500_emulate.c | 10 ++ arch/powerpc/kvm/e500_mmu.c | 22 ++ 6 files changed, 59 insertions(+), 0 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 1a76663..f045377 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1803,6 +1803,10 @@ registers, find a list below: PPC | KVM_REG_PPC_TLB1CFG | 32 PPC | KVM_REG_PPC_TLB2CFG | 32 PPC | KVM_REG_PPC_TLB3CFG | 32 + PPC | KVM_REG_PPC_TLB0PS | 32 + PPC | KVM_REG_PPC_TLB1PS | 32 + PPC | KVM_REG_PPC_TLB2PS | 32 + PPC | KVM_REG_PPC_TLB3PS | 32 ARM registers are mapped using the lower 32 bits. The upper 16 of that is the register group type, or coprocessor number: diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index e34f8fe..3b6cee3 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -502,6 +502,7 @@ struct kvm_vcpu_arch { spinlock_t wdt_lock; struct timer_list wdt_timer; u32 tlbcfg[4]; + u32 tlbps[4]; u32 mmucfg; u32 epr; u32 crit_save; diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 0c5cffb..4dd36c3 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -465,5 +465,9 @@ struct kvm_get_htab_header { #define KVM_REG_PPC_TLB1CFG(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94) #define KVM_REG_PPC_TLB2CFG(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95) #define KVM_REG_PPC_TLB3CFG(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96) +#define KVM_REG_PPC_TLB0PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97) +#define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98) +#define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99) +#define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index b73ca7a..c2e5e98 100644 --- a/arch/powerpc/kvm/e500.h +++ b/arch/powerpc/kvm/e500.h @@ -23,6 +23,10 @@ #include asm/mmu-book3e.h #include asm/tlb.h +enum vcpu_ftr { + VCPU_FTR_MMU_V2 +}; + #define E500_PID_NUM 3 #define E500_TLB_NUM 2 @@ -299,4 +303,18 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu) #define get_tlb_sts(gtlbe) (MAS1_TS) #endif /* !BOOKE_HV */ +static inline bool has_feature(const struct kvm_vcpu *vcpu, + enum vcpu_ftr ftr) +{ + bool has_ftr; + switch (ftr) { + case VCPU_FTR_MMU_V2: + has_ftr = ((vcpu-arch.mmucfg MMUCFG_MAVN) == MMUCFG_MAVN_V2); + break; + default: + return false; + } + return has_ftr; +} + #endif /* KVM_E500_H */ diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index e78f353..12b8de2 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -284,6 +284,16 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) case SPRN_TLB1CFG: *spr_val = vcpu-arch.tlbcfg[1]; break; + case SPRN_TLB0PS: + if (!has_feature(vcpu, VCPU_FTR_MMU_V2)) + return EMULATE_FAIL; + *spr_val = vcpu-arch.tlbps[0]; + break; + case SPRN_TLB1PS: + if (!has_feature(vcpu, VCPU_FTR_MMU_V2)) + return EMULATE_FAIL; + *spr_val = vcpu-arch.tlbps[1]; + break; case SPRN_L1CSR0: *spr_val = vcpu_e500-l1csr0; break; diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index 08a5b0d..a863dc1 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -631,6 +631,13 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, i = id - KVM_REG_PPC_TLB0CFG; *val = get_reg_val(id, vcpu-arch.tlbcfg[i]); break; + case KVM_REG_PPC_TLB0PS: + case KVM_REG_PPC_TLB1PS: + case KVM_REG_PPC_TLB2PS: + case KVM_REG_PPC_TLB3PS: + i = id - KVM_REG_PPC_TLB0PS; + *val = get_reg_val(id, vcpu-arch.tlbps[i]); + break; default: r = -EINVAL; break; @@ -682,6 +689,16 @@ int kvmppc_set_one_reg_e500_tlb(struct
[PATCH 11/42] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
From: Mihai Caraman mihai.cara...@freescale.com Embedded.Page Table (E.PT) category is not supported yet in e6500 kernel. Configure TLBnCFG to remove E.PT and E.HV.LRAT categories from VCPUs. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/e500_mmu.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index 1c1c5cb..c41a5a9 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -885,8 +885,12 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu, vcpu-arch.tlbps[0] = mfspr(SPRN_TLB0PS); vcpu-arch.tlbps[1] = mfspr(SPRN_TLB1PS); + vcpu-arch.mmucfg = ~MMUCFG_LRAT; + /* Guest mmu emulation currently doesn't handle E.PT */ vcpu-arch.eptcfg = 0; + vcpu-arch.tlbcfg[0] = ~TLBnCFG_PT; + vcpu-arch.tlbcfg[1] = ~TLBnCFG_IND; } return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/42] KVM: PPC: e500: Expose MMU registers via ONE_REG
From: Mihai Caraman mihai.cara...@freescale.com MMU registers were exposed to user-space using sregs interface. Add them to ONE_REG interface using kvmppc_get_one_reg/kvmppc_set_one_reg delegation mechanism. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/api.txt | 11 arch/powerpc/include/uapi/asm/kvm.h | 17 ++ arch/powerpc/kvm/e500.c |6 ++- arch/powerpc/kvm/e500.h |4 ++ arch/powerpc/kvm/e500_mmu.c | 94 +++ arch/powerpc/kvm/e500mc.c |6 ++- 6 files changed, 134 insertions(+), 4 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 976eb65..1a76663 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1792,6 +1792,17 @@ registers, find a list below: PPC | KVM_REG_PPC_TSR | 32 PPC | KVM_REG_PPC_OR_TSR | 32 PPC | KVM_REG_PPC_CLEAR_TSR| 32 + PPC | KVM_REG_PPC_MAS0 | 32 + PPC | KVM_REG_PPC_MAS1 | 32 + PPC | KVM_REG_PPC_MAS2 | 64 + PPC | KVM_REG_PPC_MAS7_3 | 64 + PPC | KVM_REG_PPC_MAS4 | 32 + PPC | KVM_REG_PPC_MAS6 | 32 + PPC | KVM_REG_PPC_MMUCFG | 32 + PPC | KVM_REG_PPC_TLB0CFG | 32 + PPC | KVM_REG_PPC_TLB1CFG | 32 + PPC | KVM_REG_PPC_TLB2CFG | 32 + PPC | KVM_REG_PPC_TLB3CFG | 32 ARM registers are mapped using the lower 32 bits. The upper 16 of that is the register group type, or coprocessor number: diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index c0c38ed..0c5cffb 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -449,4 +449,21 @@ struct kvm_get_htab_header { /* Debugging: Special instruction for software breakpoint */ #define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b) +/* MMU registers */ +#define KVM_REG_PPC_MAS0 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c) +#define KVM_REG_PPC_MAS1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8d) +#define KVM_REG_PPC_MAS2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e) +#define KVM_REG_PPC_MAS7_3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8f) +#define KVM_REG_PPC_MAS4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90) +#define KVM_REG_PPC_MAS6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91) +#define KVM_REG_PPC_MMUCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92) +/* + * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using + * KVM_CAP_SW_TLB ioctl + */ +#define KVM_REG_PPC_TLB0CFG(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93) +#define KVM_REG_PPC_TLB1CFG(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94) +#define KVM_REG_PPC_TLB2CFG(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95) +#define KVM_REG_PPC_TLB3CFG(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96) + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 576010f..ce6b73c 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -428,13 +428,15 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) { - return -EINVAL; + int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); + return r; } int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) { - return -EINVAL; + int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); + return r; } struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index 33db48a..b73ca7a 100644 --- a/arch/powerpc/kvm/e500.h +++ b/arch/powerpc/kvm/e500.h @@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500); void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val); +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val); #ifdef CONFIG_KVM_E500V2 unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500, diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index 5c44759..44f7762 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -596,6 +596,100 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) return 0; } +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) +{ + int r = 0; + long int i; + + switch (id) { + case KVM_REG_PPC_MAS0: + *val =
[PATCH 02/42] KVM: PPC: debug stub interface parameter defined
From: Bharat Bhushan r65...@freescale.com This patch defines the interface parameter for KVM_SET_GUEST_DEBUG ioctl support. Follow up patches will use this for setting up hardware breakpoints, watchpoints and software breakpoints. Also kvm_arch_vcpu_ioctl_set_guest_debug() is brought one level below. This is because I am not sure what is required for book3s. So this ioctl behaviour will not change for book3s. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/uapi/asm/kvm.h | 23 +++ arch/powerpc/kvm/book3s.c |6 ++ arch/powerpc/kvm/booke.c|6 ++ arch/powerpc/kvm/powerpc.c |6 -- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index c2ff99c..c0c38ed 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -272,8 +272,31 @@ struct kvm_debug_exit_arch { /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { + struct { + /* H/W breakpoint/watchpoint address */ + __u64 addr; + /* +* Type denotes h/w breakpoint, read watchpoint, write +* watchpoint or watchpoint (both read and write). +*/ +#define KVMPPC_DEBUG_NONE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT(1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE (1UL 2) +#define KVMPPC_DEBUG_WATCH_READ(1UL 3) + __u32 type; + __u32 reserved; + } bp[16]; }; +/* Debug related defines */ +/* + * kvm_guest_debug-control is a 32 bit field. The lower 16 bits are generic + * and upper 16 bits are architecture specific. Architecture specific defines + * that ioctl is for setting hardware breakpoint or software breakpoint. + */ +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + /* definition of registers in kvm_run */ struct kvm_sync_regs { }; diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 2d32ae4..128ed3a 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -612,6 +612,12 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, return 0; } +int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, + struct kvm_guest_debug *dbg) +{ + return -EINVAL; +} + void kvmppc_decrementer_func(unsigned long data) { struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index a49a68a..a3e2db0 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -1526,6 +1526,12 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) return r; } +int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, +struct kvm_guest_debug *dbg) +{ + return -EINVAL; +} + int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { return -ENOTSUPP; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index a822659..6b81086 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -531,12 +531,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) #endif } -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, -struct kvm_guest_debug *dbg) -{ - return -EINVAL; -} - static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, struct kvm_run *run) { -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/42] KVM: PPC: Book3E: Refactor ONE_REG ioctl implementation
From: Mihai Caraman mihai.cara...@freescale.com Refactor Book3E ONE_REG ioctl implementation to use kvmppc_get_one_reg/ kvmppc_set_one_reg delegation interface introduced by Book3S. This is necessary for MMU SPRs which are platform specifics. Get rid of useless case braces in the process. Signed-off-by: Mihai Caraman mihai.cara...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/44x.c| 12 + arch/powerpc/kvm/booke.c | 102 - arch/powerpc/kvm/e500.c | 12 + arch/powerpc/kvm/e500mc.c | 12 + 4 files changed, 91 insertions(+), 47 deletions(-) diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index 3d7fd21..2f5c6b6 100644 --- a/arch/powerpc/kvm/44x.c +++ b/arch/powerpc/kvm/44x.c @@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) return kvmppc_set_sregs_ivor(vcpu, sregs); } +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) +{ + return -EINVAL; +} + +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) +{ + return -EINVAL; +} + struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) { struct kvmppc_vcpu_44x *vcpu_44x; diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 97ae158..0275653 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -1415,117 +1415,125 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) { - int r = -EINVAL; + int r = 0; + union kvmppc_one_reg val; + int size; + long int i; + + size = one_reg_size(reg-id); + if (size sizeof(val)) + return -EINVAL; switch (reg-id) { case KVM_REG_PPC_IAC1: case KVM_REG_PPC_IAC2: case KVM_REG_PPC_IAC3: - case KVM_REG_PPC_IAC4: { - int iac = reg-id - KVM_REG_PPC_IAC1; - r = copy_to_user((u64 __user *)(long)reg-addr, -vcpu-arch.dbg_reg.iac[iac], sizeof(u64)); + case KVM_REG_PPC_IAC4: + i = reg-id - KVM_REG_PPC_IAC1; + val = get_reg_val(reg-id, vcpu-arch.dbg_reg.iac[i]); break; - } case KVM_REG_PPC_DAC1: - case KVM_REG_PPC_DAC2: { - int dac = reg-id - KVM_REG_PPC_DAC1; - r = copy_to_user((u64 __user *)(long)reg-addr, -vcpu-arch.dbg_reg.dac[dac], sizeof(u64)); + case KVM_REG_PPC_DAC2: + i = reg-id - KVM_REG_PPC_DAC1; + val = get_reg_val(reg-id, vcpu-arch.dbg_reg.dac[i]); break; - } case KVM_REG_PPC_EPR: { u32 epr = get_guest_epr(vcpu); - r = put_user(epr, (u32 __user *)(long)reg-addr); + val = get_reg_val(reg-id, epr); break; } #if defined(CONFIG_64BIT) case KVM_REG_PPC_EPCR: - r = put_user(vcpu-arch.epcr, (u32 __user *)(long)reg-addr); + val = get_reg_val(reg-id, vcpu-arch.epcr); break; #endif case KVM_REG_PPC_TCR: - r = put_user(vcpu-arch.tcr, (u32 __user *)(long)reg-addr); + val = get_reg_val(reg-id, vcpu-arch.tcr); break; case KVM_REG_PPC_TSR: - r = put_user(vcpu-arch.tsr, (u32 __user *)(long)reg-addr); + val = get_reg_val(reg-id, vcpu-arch.tsr); break; - case KVM_REG_PPC_DEBUG_INST: { - u32 opcode = KVMPPC_INST_EHPRIV; - r = copy_to_user((u32 __user *)(long)reg-addr, -opcode, sizeof(u32)); + case KVM_REG_PPC_DEBUG_INST: + val = get_reg_val(reg-id, KVMPPC_INST_EHPRIV); break; - } default: + r = kvmppc_get_one_reg(vcpu, reg-id, val); break; } + + if (r) + return r; + + if (copy_to_user((char __user *)(unsigned long)reg-addr, val, size)) + r = -EFAULT; + return r; } int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) { - int r = -EINVAL; + int r = 0; + union kvmppc_one_reg val; + int size; + long int i; + + size = one_reg_size(reg-id); + if (size sizeof(val)) + return -EINVAL; + + if (copy_from_user(val, (char __user *)(unsigned long)reg-addr, size)) + return -EFAULT; switch (reg-id) { case KVM_REG_PPC_IAC1: case KVM_REG_PPC_IAC2: case KVM_REG_PPC_IAC3: - case KVM_REG_PPC_IAC4: { - int iac = reg-id - KVM_REG_PPC_IAC1; - r = copy_from_user(vcpu-arch.dbg_reg.iac[iac], -
[PATCH 19/20] kvm: destroy emulated devices on VM exit
From: Scott Wood scottw...@freescale.com The hassle of getting refcounting right was greater than the hassle of keeping a list of devices to destroy on VM exit. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c |2 -- include/linux/kvm_host.h |3 ++- virt/kvm/kvm_main.c | 29 - 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 89fe1d6..795ca0c 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1781,7 +1781,6 @@ int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, if (opp-mpic_mode_mask == GCR_MODE_PROXY) vcpu-arch.epr_flags |= KVMPPC_EPR_KERNEL; - kvm_device_get(dev); out: spin_unlock_irq(opp-lock); return ret; @@ -1797,7 +1796,6 @@ void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu) BUG_ON(!opp-dst[vcpu-arch.irq_cpu_id].vcpu); opp-dst[vcpu-arch.irq_cpu_id].vcpu = NULL; - kvm_device_put(opp-dev); } /* diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index feffbda..36c9776 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -393,6 +393,7 @@ struct kvm { long mmu_notifier_count; #endif long tlbs_dirty; + struct list_head devices; }; #define kvm_err(fmt, ...) \ @@ -1069,8 +1070,8 @@ struct kvm_device_ops; struct kvm_device { struct kvm_device_ops *ops; struct kvm *kvm; - atomic_t users; void *private; + struct list_head vm_node; }; /* create, destroy, and name are mandatory */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f6cd14d..5da9f02 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -504,6 +504,7 @@ static struct kvm *kvm_create_vm(unsigned long type) mutex_init(kvm-irq_lock); mutex_init(kvm-slots_lock); atomic_set(kvm-users_count, 1); + INIT_LIST_HEAD(kvm-devices); r = kvm_init_mmu_notifier(kvm); if (r) @@ -581,6 +582,19 @@ void kvm_free_physmem(struct kvm *kvm) kfree(kvm-memslots); } +static void kvm_destroy_devices(struct kvm *kvm) +{ + struct list_head *node, *tmp; + + list_for_each_safe(node, tmp, kvm-devices) { + struct kvm_device *dev = + list_entry(node, struct kvm_device, vm_node); + + list_del(node); + dev-ops-destroy(dev); + } +} + static void kvm_destroy_vm(struct kvm *kvm) { int i; @@ -600,6 +614,7 @@ static void kvm_destroy_vm(struct kvm *kvm) kvm_arch_flush_shadow_all(kvm); #endif kvm_arch_destroy_vm(kvm); + kvm_destroy_devices(kvm); kvm_free_physmem(kvm); cleanup_srcu_struct(kvm-srcu); kvm_arch_free_vm(kvm); @@ -2195,23 +2210,11 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl, } } -void kvm_device_get(struct kvm_device *dev) -{ - atomic_inc(dev-users); -} - -void kvm_device_put(struct kvm_device *dev) -{ - if (atomic_dec_and_test(dev-users)) - dev-ops-destroy(dev); -} - static int kvm_device_release(struct inode *inode, struct file *filp) { struct kvm_device *dev = filp-private_data; struct kvm *kvm = dev-kvm; - kvm_device_put(dev); kvm_put_kvm(kvm); return 0; } @@ -2257,7 +2260,6 @@ static int kvm_ioctl_create_device(struct kvm *kvm, dev-ops = ops; dev-kvm = kvm; - atomic_set(dev-users, 1); ret = ops-create(dev, cd-type); if (ret 0) { @@ -2271,6 +2273,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, return ret; } + list_add(dev-vm_node, kvm-devices); kvm_get_kvm(kvm); cd-fd = ret; return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/42] KVM: extend EMULATE_EXIT_USER to support different exit reasons
From: Bharat Bhushan bharat.bhus...@freescale.com Currently the instruction emulator code returns EMULATE_EXIT_USER and common code initializes the run-exit_reason = .. and vcpu-arch.hcall_needed = .. with one fixed reason. But there can be different reasons when emulator need to exit to user space. To support that the run-exit_reason = .. and vcpu-arch.hcall_needed = .. initialization is moved a level up to emulator. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/book3s_emulate.c |2 ++ arch/powerpc/kvm/book3s_pr.c |2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index cdd19d6..1f6344c 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -194,6 +194,8 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, run-papr_hcall.args[i] = gpr; } + run-exit_reason = KVM_EXIT_PAPR_HCALL; + vcpu-arch.hcall_needed = 1; emulated = EMULATE_EXIT_USER; break; } diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index b960faf..c1cffa8 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -763,8 +763,6 @@ program_interrupt: r = RESUME_HOST_NV; break; case EMULATE_EXIT_USER: - run-exit_reason = KVM_EXIT_PAPR_HCALL; - vcpu-arch.hcall_needed = 1; r = RESUME_HOST_NV; break; default: -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/42] Rename EMULATE_DO_PAPR to EMULATE_EXIT_USER
From: Bharat Bhushan r65...@freescale.com Instruction emulation return EMULATE_DO_PAPR when it requires exit to userspace on book3s. Similar return is required for booke. EMULATE_DO_PAPR reads out to be confusing so it is renamed to EMULATE_EXIT_USER. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/asm/kvm_ppc.h |2 +- arch/powerpc/kvm/book3s_emulate.c |2 +- arch/powerpc/kvm/book3s_pr.c |2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 4794de6..bcc68b1 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -44,7 +44,7 @@ enum emulation_result { EMULATE_DO_DCR, /* kvm_run filled with DCR request */ EMULATE_FAIL, /* can't emulate this instruction */ EMULATE_AGAIN,/* something went wrong. go again */ - EMULATE_DO_PAPR, /* kvm_run filled with PAPR request */ + EMULATE_EXIT_USER,/* emulation requires exit to user-space */ }; extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 836c569..cdd19d6 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -194,7 +194,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, run-papr_hcall.args[i] = gpr; } - emulated = EMULATE_DO_PAPR; + emulated = EMULATE_EXIT_USER; break; } #endif diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 286e23e..b960faf 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -762,7 +762,7 @@ program_interrupt: run-exit_reason = KVM_EXIT_MMIO; r = RESUME_HOST_NV; break; - case EMULATE_DO_PAPR: + case EMULATE_EXIT_USER: run-exit_reason = KVM_EXIT_PAPR_HCALL; vcpu-arch.hcall_needed = 1; r = RESUME_HOST_NV; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 18/20] KVM: IA64: Carry non-ia64 changes into ia64
We changed a few things in non-ia64 code paths. This patch blindly applies the changes to the ia64 code as well, hoping it proves useful in case anyone revives the ia64 kvm code. Signed-off-by: Alexander Graf ag...@suse.de --- arch/ia64/include/asm/kvm_host.h |1 + arch/ia64/kvm/Kconfig|1 + arch/ia64/kvm/Makefile |2 +- 3 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index cfa7498..989dd3f 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h @@ -26,6 +26,7 @@ #define KVM_USER_MEM_SLOTS 32 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 +#define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS /* define exit reasons from vmm to kvm*/ #define EXIT_REASON_VM_PANIC 0 diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 2cd225f..043183a 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig @@ -27,6 +27,7 @@ config KVM select PREEMPT_NOTIFIERS select ANON_INODES select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING select KVM_APIC_ARCHITECTURE select KVM_MMIO ---help--- diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index db3d7c5..511f64a 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile @@ -49,7 +49,7 @@ ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ - coalesced_mmio.o irq_comm.o assigned-dev.o) + coalesced_mmio.o irq_comm.o assigned-dev.o irqchip.o) ifeq ($(CONFIG_IOMMU_API),y) common-objs += $(addprefix ../../../virt/kvm/, iommu.o) -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/20] KVM: PPC: Support irq routing and irqfd for in-kernel MPIC
Now that all the irq routing and irqfd pieces are generic, we can expose real irqchip support to all of KVM's internal helpers. This allows us to use irqfd with the in-kernel MPIC. Signed-off-by: Alexander Graf ag...@suse.de --- v2 - v3: - make mpic pointer type safe - add wmb before setting global mpic variable - make eoi notification happen unlockedly - add IRQ routing documentation - announce mpic availability after its creation v3 - v4: - update documentation - fix spin locks - remove default routing map - move eoi notify code into eoi register handler --- Documentation/virtual/kvm/devices/mpic.txt | 19 + arch/powerpc/include/asm/kvm_host.h|7 ++ arch/powerpc/include/uapi/asm/kvm.h|1 + arch/powerpc/kvm/Kconfig |3 + arch/powerpc/kvm/Makefile |1 + arch/powerpc/kvm/irq.h | 17 arch/powerpc/kvm/mpic.c| 111 +++- 7 files changed, 158 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/kvm/irq.h diff --git a/Documentation/virtual/kvm/devices/mpic.txt b/Documentation/virtual/kvm/devices/mpic.txt index ce98e32..ad0ac77 100644 --- a/Documentation/virtual/kvm/devices/mpic.txt +++ b/Documentation/virtual/kvm/devices/mpic.txt @@ -35,3 +35,22 @@ Groups: attr is the IRQ number. IRQ numbers for standard sources are the byte offset of the relevant IVPR from EIVPR0, divided by 32. + +IRQ Routing: + + The MPIC emulation supports IRQ routing. Only a single MPIC device can + be instantiated. Once that device has been created, it's available as + irqchip id 0. + + This irqchip 0 has 256 interrupt pins, which expose the interrupts in + the main array of interrupt sources (a.k.a. SRC interrupts). + + The numbering is the same as the MPIC device tree binding -- based on + the register offset from the beginning of the sources array, without + regard to any subdivisions in chip documentation such as internal + or external interrupts. + + Default routes are established for these pins, with the GSI being equal + to the pin number. + + Access to non-SRC interrupts is not implemented through IRQ routing mechanisms. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 36368c9..80f2004 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -44,6 +44,10 @@ #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #endif +/* These values are internal and can be increased later */ +#define KVM_NR_IRQCHIPS 1 +#define KVM_IRQCHIP_NUM_PINS 256 + #if !defined(CONFIG_KVM_440) #include linux/mmu_notifier.h @@ -256,6 +260,9 @@ struct kvm_arch { #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; #endif +#ifdef CONFIG_KVM_MPIC + struct openpic *mpic; +#endif }; /* diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 36be2fe..3537bf3 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -25,6 +25,7 @@ /* Select powerpc specific features in linux/kvm.h */ #define __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT +#define __KVM_HAVE_IRQCHIP struct kvm_regs { __u64 pc; diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 938a729..a608570 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -154,6 +154,9 @@ config KVM_E500MC config KVM_MPIC bool KVM in-kernel MPIC emulation depends on KVM + select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING + select HAVE_KVM_MSI help Enable support for emulating MPIC devices inside the host kernel, rather than relying on userspace to emulate. diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 4a2277a..4eada0c 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -104,6 +104,7 @@ kvm-book3s_32-objs := \ kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o +kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(addprefix ../../../virt/kvm/, irqchip.o) kvm-objs := $(kvm-objs-m) $(kvm-objs-y) diff --git a/arch/powerpc/kvm/irq.h b/arch/powerpc/kvm/irq.h new file mode 100644 index 000..f1e27fd --- /dev/null +++ b/arch/powerpc/kvm/irq.h @@ -0,0 +1,17 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#include linux/kvm_host.h + +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + int ret = 0; + +#ifdef CONFIG_KVM_MPIC + ret = ret || (kvm-arch.mpic != NULL); +#endif + smp_rmb(); + return ret; +} + +#endif diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 10bc08a..89fe1d6 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1076,7 +1076,9 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr, case 0xA0: /* IACK */ /*
[PATCH 11/20] kvm/ppc/mpic: remove some obviously unneeded code
From: Scott Wood scottw...@freescale.com Remove some parts of the code that are obviously QEMU or Raven specific before fixing style issues, to reduce the style issues that need to be fixed. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 344 --- 1 files changed, 0 insertions(+), 344 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 57655b9..d6d70a4 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -22,39 +22,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -/* - * - * Based on OpenPic implementations: - * - Intel GW80314 I/O companion chip developer's manual - * - Motorola MPC8245 MPC8540 user manuals. - * - Motorola MCP750 (aka Raven) programmer manual. - * - Motorola Harrier programmer manuel - * - * Serial interrupts, as implemented in Raven chipset are not supported yet. - * - */ -#include hw.h -#include ppc/mac.h -#include pci/pci.h -#include openpic.h -#include sysbus.h -#include pci/msi.h -#include qemu/bitops.h -#include ppc.h - -//#define DEBUG_OPENPIC - -#ifdef DEBUG_OPENPIC -static const int debug_openpic = 1; -#else -static const int debug_openpic = 0; -#endif - -#define DPRINTF(fmt, ...) do { \ -if (debug_openpic) { \ -printf(fmt , ## __VA_ARGS__); \ -} \ -} while (0) #define MAX_CPU 32 #define MAX_SRC 256 @@ -82,21 +49,6 @@ static const int debug_openpic = 0; #define OPENPIC_CPU_REG_START0x2 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) -/* Raven */ -#define RAVEN_MAX_CPU 2 -#define RAVEN_MAX_EXT 48 -#define RAVEN_MAX_IRQ 64 -#define RAVEN_MAX_TMR MAX_TMR -#define RAVEN_MAX_IPI MAX_IPI - -/* Interrupt definitions */ -#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */ -#define RAVEN_ERR_IRQ(RAVEN_MAX_EXT + 1) /* Error IRQ */ -#define RAVEN_TMR_IRQ(RAVEN_MAX_EXT + 2) /* First timer IRQ */ -#define RAVEN_IPI_IRQ(RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */ -/* First doorbell IRQ */ -#define RAVEN_DBL_IRQ(RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI)) - typedef struct FslMpicInfo { int max_ext; } FslMpicInfo; @@ -138,44 +90,6 @@ static FslMpicInfo fsl_mpic_42 = { #define ILR_INTTGT_CINT 0x01 /* critical */ #define ILR_INTTGT_MCP0x02 /* machine check */ -/* The currently supported INTTGT values happen to be the same as QEMU's - * openpic output codes, but don't depend on this. The output codes - * could change (unlikely, but...) or support could be added for - * more INTTGT values. - */ -static const int inttgt_output[][2] = { - {ILR_INTTGT_INT, OPENPIC_OUTPUT_INT}, - {ILR_INTTGT_CINT, OPENPIC_OUTPUT_CINT}, - {ILR_INTTGT_MCP, OPENPIC_OUTPUT_MCK}, -}; - -static int inttgt_to_output(int inttgt) -{ - int i; - - for (i = 0; i ARRAY_SIZE(inttgt_output); i++) { - if (inttgt_output[i][0] == inttgt) { - return inttgt_output[i][1]; - } - } - - fprintf(stderr, %s: unsupported inttgt %d\n, __func__, inttgt); - return OPENPIC_OUTPUT_INT; -} - -static int output_to_inttgt(int output) -{ - int i; - - for (i = 0; i ARRAY_SIZE(inttgt_output); i++) { - if (inttgt_output[i][1] == output) { - return inttgt_output[i][0]; - } - } - - abort(); -} - #define MSIIR_OFFSET 0x140 #define MSIIR_SRS_SHIFT29 #define MSIIR_SRS_MASK (0x7 MSIIR_SRS_SHIFT) @@ -1265,228 +1179,36 @@ static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len) return openpic_cpu_read_internal(opaque, addr, (addr 0x1f000) 12); } -static const MemoryRegionOps openpic_glb_ops_le = { - .write = openpic_gbl_write, - .read = openpic_gbl_read, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, -}; - static const MemoryRegionOps openpic_glb_ops_be = { .write = openpic_gbl_write, .read = openpic_gbl_read, - .endianness = DEVICE_BIG_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, -}; - -static const MemoryRegionOps openpic_tmr_ops_le = { - .write = openpic_tmr_write, - .read = openpic_tmr_read, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { -.min_access_size = 4, -.max_access_size = 4, -}, }; static const MemoryRegionOps openpic_tmr_ops_be = { .write = openpic_tmr_write, .read = openpic_tmr_read, - .endianness = DEVICE_BIG_ENDIAN, - .impl = { -.min_access_size = 4, -
[PATCH 14/20] kvm/ppc/mpic: add KVM_CAP_IRQ_MPIC
From: Scott Wood scottw...@freescale.com Enabling this capability connects the vcpu to the designated in-kernel MPIC. Using explicit connections between vcpus and irqchips allows for flexibility, but the main benefit at the moment is that it simplifies the code -- KVM doesn't need vm-global state to remember which MPIC object is associated with this vm, and it doesn't need to care about ordering between irqchip creation and vcpu creation. Signed-off-by: Scott Wood scottw...@freescale.com [agraf: add stub functions for kvmppc_mpic_{dis,}connect_vcpu] Signed-off-by: Alexander Graf ag...@suse.de --- Documentation/virtual/kvm/api.txt |8 +++ arch/powerpc/include/asm/kvm_host.h |9 arch/powerpc/include/asm/kvm_ppc.h | 15 ++- arch/powerpc/kvm/booke.c|4 ++ arch/powerpc/kvm/mpic.c | 82 --- arch/powerpc/kvm/powerpc.c | 30 + include/uapi/linux/kvm.h|1 + 7 files changed, 141 insertions(+), 8 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index d52f3f9..4c326ae 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2728,3 +2728,11 @@ to receive the topmost interrupt vector. When disabled (args[0] == 0), behavior is as if this facility is unsupported. When this capability is enabled, KVM_EXIT_EPR can occur. + +6.6 KVM_CAP_IRQ_MPIC + +Architectures: ppc +Parameters: args[0] is the MPIC device fd +args[1] is the MPIC CPU number for this vcpu + +This capability connects the vcpu to an in-kernel MPIC device. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 7e7aef9..36368c9 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -375,6 +375,11 @@ struct kvmppc_booke_debug_reg { u64 dac[KVMPPC_BOOKE_MAX_DAC]; }; +#define KVMPPC_IRQ_DEFAULT 0 +#define KVMPPC_IRQ_MPIC1 + +struct openpic; + struct kvm_vcpu_arch { ulong host_stack; u32 host_pid; @@ -554,6 +559,10 @@ struct kvm_vcpu_arch { unsigned long magic_page_pa; /* phys addr to map the magic page to */ unsigned long magic_page_ea; /* effect. addr to map the magic page to */ + int irq_type; /* one of KVM_IRQ_* */ + int irq_cpu_id; + struct openpic *mpic; /* KVM_IRQ_MPIC */ + #ifdef CONFIG_KVM_BOOK3S_64_HV struct kvm_vcpu_arch_shared shregs; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index da43e5f..fa85d56 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -248,7 +248,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *); void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); struct openpic; -void kvmppc_mpic_put(struct openpic *opp); #ifdef CONFIG_KVM_BOOK3S_64_HV static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) @@ -278,6 +277,9 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) #ifdef CONFIG_KVM_MPIC void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu); +int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, +u32 cpu); +void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu); #else @@ -285,6 +287,17 @@ static inline void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu) { } +static inline int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, + struct kvm_vcpu *vcpu, u32 cpu) +{ + return -EINVAL; +} + +static inline void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, + struct kvm_vcpu *vcpu) +{ +} + #endif /* CONFIG_KVM_MPIC */ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index cff53d4..0097912 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -430,6 +430,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, if (update_epr == true) { if (vcpu-arch.epr_flags KVMPPC_EPR_USER) kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); + else if (vcpu-arch.epr_flags KVMPPC_EPR_KERNEL) { + BUG_ON(vcpu-arch.irq_type != KVMPPC_IRQ_MPIC); + kvmppc_mpic_set_epr(vcpu); + } } new_msr = msr_mask; diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index cb451b9..10bc08a 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -115,7 +115,7 @@ static int get_current_cpu(void) { #if defined(CONFIG_KVM) defined(CONFIG_BOOKE) struct kvm_vcpu *vcpu = current-thread.kvm_vcpu; - return vcpu ? vcpu-vcpu_id : -1; + return vcpu ? vcpu-arch.irq_cpu_id : -1; #else
[PATCH 16/20] KVM: PPC: MPIC: Add support for KVM_IRQ_LINE
Now that all pieces are in place for reusing generic irq infrastructure, we can copy x86's implementation of KVM_IRQ_LINE irq injection and simply reuse it for PPC, as it will work there just as well. Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/include/uapi/asm/kvm.h |1 + arch/powerpc/kvm/powerpc.c | 13 + 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 3537bf3..dbb2ac2 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -26,6 +26,7 @@ #define __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT #define __KVM_HAVE_IRQCHIP +#define __KVM_HAVE_IRQ_LINE struct kvm_regs { __u64 pc; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index c431fea..874c106 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -33,6 +33,7 @@ #include asm/cputhreads.h #include asm/irqflags.h #include timing.h +#include irq.h #include ../mm/mmu_decl.h #define CREATE_TRACE_POINTS @@ -945,6 +946,18 @@ static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) return 0; } +int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, + bool line_status) +{ + if (!irqchip_in_kernel(kvm)) + return -ENXIO; + + irq_event-status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, + irq_event-irq, irq_event-level, + line_status); + return 0; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/20] kvm/ppc/mpic: import hw/openpic.c from QEMU
From: Scott Wood scottw...@freescale.com This is QEMU's hw/openpic.c from commit abd8d4a4d6dfea7ddea72f095f993e1de941614e (Update version for 1.4.0-rc0), run through Lindent with no other changes to ease merging future changes between Linux and QEMU. Remaining style issues (including those introduced by Lindent) will be fixed in a later patch. Signed-off-by: Scott Wood scottw...@freescale.com Signed-off-by: Alexander Graf ag...@suse.de --- arch/powerpc/kvm/mpic.c | 1686 +++ 1 files changed, 1686 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/kvm/mpic.c diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c new file mode 100644 index 000..57655b9 --- /dev/null +++ b/arch/powerpc/kvm/mpic.c @@ -0,0 +1,1686 @@ +/* + * OpenPIC emulation + * + * Copyright (c) 2004 Jocelyn Mayer + * 2011 Alexander Graf + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* + * + * Based on OpenPic implementations: + * - Intel GW80314 I/O companion chip developer's manual + * - Motorola MPC8245 MPC8540 user manuals. + * - Motorola MCP750 (aka Raven) programmer manual. + * - Motorola Harrier programmer manuel + * + * Serial interrupts, as implemented in Raven chipset are not supported yet. + * + */ +#include hw.h +#include ppc/mac.h +#include pci/pci.h +#include openpic.h +#include sysbus.h +#include pci/msi.h +#include qemu/bitops.h +#include ppc.h + +//#define DEBUG_OPENPIC + +#ifdef DEBUG_OPENPIC +static const int debug_openpic = 1; +#else +static const int debug_openpic = 0; +#endif + +#define DPRINTF(fmt, ...) do { \ +if (debug_openpic) { \ +printf(fmt , ## __VA_ARGS__); \ +} \ +} while (0) + +#define MAX_CPU 32 +#define MAX_SRC 256 +#define MAX_TMR 4 +#define MAX_IPI 4 +#define MAX_MSI 8 +#define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR) +#define VID 0x03 /* MPIC version ID */ + +/* OpenPIC capability flags */ +#define OPENPIC_FLAG_IDR_CRIT (1 0) +#define OPENPIC_FLAG_ILR (2 0) + +/* OpenPIC address map */ +#define OPENPIC_GLB_REG_START0x0 +#define OPENPIC_GLB_REG_SIZE 0x10F0 +#define OPENPIC_TMR_REG_START0x10F0 +#define OPENPIC_TMR_REG_SIZE 0x220 +#define OPENPIC_MSI_REG_START0x1600 +#define OPENPIC_MSI_REG_SIZE 0x200 +#define OPENPIC_SUMMARY_REG_START 0x3800 +#define OPENPIC_SUMMARY_REG_SIZE0x800 +#define OPENPIC_SRC_REG_START0x1 +#define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20) +#define OPENPIC_CPU_REG_START0x2 +#define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) + +/* Raven */ +#define RAVEN_MAX_CPU 2 +#define RAVEN_MAX_EXT 48 +#define RAVEN_MAX_IRQ 64 +#define RAVEN_MAX_TMR MAX_TMR +#define RAVEN_MAX_IPI MAX_IPI + +/* Interrupt definitions */ +#define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */ +#define RAVEN_ERR_IRQ(RAVEN_MAX_EXT + 1) /* Error IRQ */ +#define RAVEN_TMR_IRQ(RAVEN_MAX_EXT + 2) /* First timer IRQ */ +#define RAVEN_IPI_IRQ(RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */ +/* First doorbell IRQ */ +#define RAVEN_DBL_IRQ(RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI)) + +typedef struct FslMpicInfo { + int max_ext; +} FslMpicInfo; + +static FslMpicInfo fsl_mpic_20 = { + .max_ext = 12, +}; + +static FslMpicInfo fsl_mpic_42 = { + .max_ext = 12, +}; + +#define FRR_NIRQ_SHIFT16 +#define FRR_NCPU_SHIFT 8 +#define FRR_VID_SHIFT 0 + +#define VID_REVISION_1_2 2 +#define VID_REVISION_1_3 3 + +#define VIR_GENERIC 0x/* Generic Vendor ID */ + +#define GCR_RESET0x8000 +#define GCR_MODE_PASS0x +#define GCR_MODE_MIXED 0x2000 +#define GCR_MODE_PROXY 0x6000 + +#define TBCR_CI 0x8000 /* count inhibit */ +#define TCCR_TOG 0x8000 /* toggles
[PATCH 07/20] KVM: Move irq routing setup to irqchip.c
Setting up IRQ routes is nothing IOAPIC specific. Extract everything that really is generic code into irqchip.c and only leave the ioapic specific bits to irq_comm.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- include/linux/kvm_host.h |3 ++ virt/kvm/irq_comm.c | 76 ++--- virt/kvm/irqchip.c | 85 ++ 3 files changed, 91 insertions(+), 73 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a7bfe9d..dcef724 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -961,6 +961,9 @@ int kvm_set_irq_routing(struct kvm *kvm, const struct kvm_irq_routing_entry *entries, unsigned nr, unsigned flags); +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue); void kvm_free_irq_routing(struct kvm *kvm); int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index d5008f4..e2e6b44 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -271,27 +271,14 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, rcu_read_unlock(); } -static int setup_routing_entry(struct kvm_irq_routing_table *rt, - struct kvm_kernel_irq_routing_entry *e, - const struct kvm_irq_routing_entry *ue) +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue) { int r = -EINVAL; int delta; unsigned max_pin; - struct kvm_kernel_irq_routing_entry *ei; - /* -* Do not allow GSI to be mapped to the same irqchip more than once. -* Allow only one to one mapping between GSI and MSI. -*/ - hlist_for_each_entry(ei, rt-map[ue-gsi], link) - if (ei-type == KVM_IRQ_ROUTING_MSI || - ue-type == KVM_IRQ_ROUTING_MSI || - ue-u.irqchip.irqchip == ei-irqchip.irqchip) - return r; - - e-gsi = ue-gsi; - e-type = ue-type; switch (ue-type) { case KVM_IRQ_ROUTING_IRQCHIP: delta = 0; @@ -328,68 +315,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, goto out; } - hlist_add_head(e-link, rt-map[e-gsi]); r = 0; out: return r; } -int kvm_set_irq_routing(struct kvm *kvm, - const struct kvm_irq_routing_entry *ue, - unsigned nr, - unsigned flags) -{ - struct kvm_irq_routing_table *new, *old; - u32 i, j, nr_rt_entries = 0; - int r; - - for (i = 0; i nr; ++i) { - if (ue[i].gsi = KVM_MAX_IRQ_ROUTES) - return -EINVAL; - nr_rt_entries = max(nr_rt_entries, ue[i].gsi); - } - - nr_rt_entries += 1; - - new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)) - + (nr * sizeof(struct kvm_kernel_irq_routing_entry)), - GFP_KERNEL); - - if (!new) - return -ENOMEM; - - new-rt_entries = (void *)new-map[nr_rt_entries]; - - new-nr_rt_entries = nr_rt_entries; - for (i = 0; i 3; i++) - for (j = 0; j KVM_IRQCHIP_NUM_PINS; j++) - new-chip[i][j] = -1; - - for (i = 0; i nr; ++i) { - r = -EINVAL; - if (ue-flags) - goto out; - r = setup_routing_entry(new, new-rt_entries[i], ue); - if (r) - goto out; - ++ue; - } - - mutex_lock(kvm-irq_lock); - old = kvm-irq_routing; - kvm_irq_routing_update(kvm, new); - mutex_unlock(kvm-irq_lock); - - synchronize_rcu(); - - new = old; - r = 0; - -out: - kfree(new); - return r; -} - #define IOAPIC_ROUTING_ENTRY(irq) \ { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) } diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 12f7f26..20dc9e4 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -150,3 +150,88 @@ void kvm_free_irq_routing(struct kvm *kvm) at this stage */ kfree(kvm-irq_routing); } + +static int setup_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue) +{ + int r = -EINVAL; + struct
[PATCH 02/20] KVM: Introduce CONFIG_HAVE_KVM_IRQ_ROUTING
Quite a bit of code in KVM has been conditionalized on availability of IOAPIC emulation. However, most of it is generically applicable to platforms that don't have an IOPIC, but a different type of irq chip. Make code that only relies on IRQ routing, not an APIC itself, on CONFIG_HAVE_KVM_IRQ_ROUTING, so that we can reuse it later. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/Kconfig |1 + include/linux/kvm_host.h |6 +++--- virt/kvm/Kconfig |3 +++ virt/kvm/eventfd.c |6 +++--- virt/kvm/kvm_main.c |2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 586f000..9d50efd 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -29,6 +29,7 @@ config KVM select MMU_NOTIFIER select ANON_INODES select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQ_ROUTING select HAVE_KVM_EVENTFD select KVM_APIC_ARCHITECTURE select KVM_ASYNC_PF diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bf3b1dc..4215d4f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -304,7 +304,7 @@ struct kvm_kernel_irq_routing_entry { struct hlist_node link; }; -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING struct kvm_irq_routing_table { int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; @@ -432,7 +432,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); int __must_check vcpu_load(struct kvm_vcpu *vcpu); void vcpu_put(struct kvm_vcpu *vcpu); -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING int kvm_irqfd_init(void); void kvm_irqfd_exit(void); #else @@ -957,7 +957,7 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq) } #endif -#ifdef KVM_CAP_IRQ_ROUTING +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING #define KVM_MAX_IRQ_ROUTES 1024 diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index d01b24b..779262f 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -6,6 +6,9 @@ config HAVE_KVM config HAVE_KVM_IRQCHIP bool +config HAVE_KVM_IRQ_ROUTING + bool + config HAVE_KVM_EVENTFD bool select EVENTFD diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index c5d43ff..64ee720 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -35,7 +35,7 @@ #include iodev.h -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING /* * * irqfd: Allows an fd to be used to inject an interrupt to the guest @@ -433,7 +433,7 @@ fail: void kvm_eventfd_init(struct kvm *kvm) { -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING spin_lock_init(kvm-irqfds.lock); INIT_LIST_HEAD(kvm-irqfds.items); INIT_LIST_HEAD(kvm-irqfds.resampler_list); @@ -442,7 +442,7 @@ kvm_eventfd_init(struct kvm *kvm) INIT_LIST_HEAD(kvm-ioeventfds); } -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING /* * shutdown any irqfd's that match fd+gsi */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index aaac1a7..2c3b226 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2404,7 +2404,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) case KVM_CAP_SIGNAL_MSI: #endif return 1; -#ifdef KVM_CAP_IRQ_ROUTING +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING case KVM_CAP_IRQ_ROUTING: return KVM_MAX_IRQ_ROUTES; #endif -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/20] KVM: Extract generic irqchip logic into irqchip.c
The current irq_comm.c file contains pieces of code that are generic across different irqchip implementations, as well as code that is fully IOAPIC specific. Split the generic bits out into irqchip.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/Makefile |2 +- include/trace/events/kvm.h | 12 +++- virt/kvm/irq_comm.c| 118 -- virt/kvm/irqchip.c | 152 4 files changed, 163 insertions(+), 121 deletions(-) create mode 100644 virt/kvm/irqchip.c diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 04d3040..a797b8e 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -7,7 +7,7 @@ CFLAGS_vmx.o := -I. kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ coalesced_mmio.o irq_comm.o eventfd.o \ - assigned-dev.o) + assigned-dev.o irqchip.o) kvm-$(CONFIG_IOMMU_API)+= $(addprefix ../../../virt/kvm/, iommu.o) kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 19911dd..7005d11 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -37,7 +37,7 @@ TRACE_EVENT(kvm_userspace_exit, __entry-errno 0 ? -__entry-errno : __entry-reason) ); -#if defined(__KVM_HAVE_IRQ_LINE) +#if defined(CONFIG_HAVE_KVM_IRQCHIP) TRACE_EVENT(kvm_set_irq, TP_PROTO(unsigned int gsi, int level, int irq_source_id), TP_ARGS(gsi, level, irq_source_id), @@ -122,6 +122,10 @@ TRACE_EVENT(kvm_msi_set_irq, {KVM_IRQCHIP_PIC_SLAVE, PIC slave}, \ {KVM_IRQCHIP_IOAPIC,IOAPIC} +#endif /* defined(__KVM_HAVE_IOAPIC) */ + +#if defined(CONFIG_HAVE_KVM_IRQCHIP) + TRACE_EVENT(kvm_ack_irq, TP_PROTO(unsigned int irqchip, unsigned int pin), TP_ARGS(irqchip, pin), @@ -136,14 +140,18 @@ TRACE_EVENT(kvm_ack_irq, __entry-pin= pin; ), +#ifdef kvm_irqchips TP_printk(irqchip %s pin %u, __print_symbolic(__entry-irqchip, kvm_irqchips), __entry-pin) +#else + TP_printk(irqchip %d pin %u, __entry-irqchip, __entry-pin) +#endif ); +#endif /* defined(CONFIG_HAVE_KVM_IRQCHIP) */ -#endif /* defined(__KVM_HAVE_IOAPIC) */ #define KVM_TRACE_MMIO_READ_UNSATISFIED 0 #define KVM_TRACE_MMIO_READ 1 diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 7c0071d..d5008f4 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -151,59 +151,6 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e, return -EWOULDBLOCK; } -int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) -{ - struct kvm_kernel_irq_routing_entry route; - - if (!irqchip_in_kernel(kvm) || msi-flags != 0) - return -EINVAL; - - route.msi.address_lo = msi-address_lo; - route.msi.address_hi = msi-address_hi; - route.msi.data = msi-data; - - return kvm_set_msi(route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); -} - -/* - * Return value: - * 0 Interrupt was ignored (masked or not delivered for other reasons) - * = 0 Interrupt was coalesced (previous irq is still pending) - * 0 Number of CPUs interrupt was delivered to - */ -int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, - bool line_status) -{ - struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; - int ret = -1, i = 0; - struct kvm_irq_routing_table *irq_rt; - - trace_kvm_set_irq(irq, level, irq_source_id); - - /* Not possible to detect if the guest uses the PIC or the -* IOAPIC. So set the bit in both. The guest will ignore -* writes to the unused one. -*/ - rcu_read_lock(); - irq_rt = rcu_dereference(kvm-irq_routing); - if (irq irq_rt-nr_rt_entries) - hlist_for_each_entry(e, irq_rt-map[irq], link) - irq_set[i++] = *e; - rcu_read_unlock(); - - while(i--) { - int r; - r = irq_set[i].set(irq_set[i], kvm, irq_source_id, level, - line_status); - if (r 0) - continue; - - ret = r + ((ret 0) ? 0 : ret); - } - - return ret; -} - /* * Deliver an IRQ in an atomic context if we can, or return a failure, * user can retry in a process context. @@ -241,63 +188,6 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level) return ret; } -bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) -{ - struct kvm_irq_ack_notifier *kian; - int gsi; - - rcu_read_lock(); - gsi
[PATCH 08/20] KVM: Move irqfd resample cap handling to generic code
Now that we have most irqfd code completely platform agnostic, let's move irqfd's resample capability return to generic code as well. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- arch/x86/kvm/x86.c |1 - virt/kvm/kvm_main.c |3 +++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 50e2e10..888d892 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2513,7 +2513,6 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PCI_2_3: case KVM_CAP_KVMCLOCK_CTRL: case KVM_CAP_READONLY_MEM: - case KVM_CAP_IRQFD_RESAMPLE: r = 1; break; case KVM_CAP_COALESCED_MMIO: diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b6f3354..f9492f3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2433,6 +2433,9 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) #ifdef CONFIG_HAVE_KVM_MSI case KVM_CAP_SIGNAL_MSI: #endif +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING + case KVM_CAP_IRQFD_RESAMPLE: +#endif return 1; #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING case KVM_CAP_IRQ_ROUTING: -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/20] KVM: Move irq routing to generic code
The IRQ routing set ioctl lives in the hacky device assignment code inside of KVM today. This is definitely the wrong place for it. Move it to the much more natural kvm_main.c. Signed-off-by: Alexander Graf ag...@suse.de Acked-by: Michael S. Tsirkin m...@redhat.com --- virt/kvm/assigned-dev.c | 30 -- virt/kvm/kvm_main.c | 30 ++ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index f4c7f59..8db4370 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -983,36 +983,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, goto out; break; } -#ifdef KVM_CAP_IRQ_ROUTING - case KVM_SET_GSI_ROUTING: { - struct kvm_irq_routing routing; - struct kvm_irq_routing __user *urouting; - struct kvm_irq_routing_entry *entries; - - r = -EFAULT; - if (copy_from_user(routing, argp, sizeof(routing))) - goto out; - r = -EINVAL; - if (routing.nr = KVM_MAX_IRQ_ROUTES) - goto out; - if (routing.flags) - goto out; - r = -ENOMEM; - entries = vmalloc(routing.nr * sizeof(*entries)); - if (!entries) - goto out; - r = -EFAULT; - urouting = argp; - if (copy_from_user(entries, urouting-entries, - routing.nr * sizeof(*entries))) - goto out_free_irq_routing; - r = kvm_set_irq_routing(kvm, entries, routing.nr, - routing.flags); - out_free_irq_routing: - vfree(entries); - break; - } -#endif /* KVM_CAP_IRQ_ROUTING */ #ifdef __KVM_HAVE_MSIX case KVM_ASSIGN_SET_MSIX_NR: { struct kvm_assigned_msix_nr entry_nr; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2c3b226..b6f3354 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2274,6 +2274,36 @@ static long kvm_vm_ioctl(struct file *filp, break; } #endif +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING + case KVM_SET_GSI_ROUTING: { + struct kvm_irq_routing routing; + struct kvm_irq_routing __user *urouting; + struct kvm_irq_routing_entry *entries; + + r = -EFAULT; + if (copy_from_user(routing, argp, sizeof(routing))) + goto out; + r = -EINVAL; + if (routing.nr = KVM_MAX_IRQ_ROUTES) + goto out; + if (routing.flags) + goto out; + r = -ENOMEM; + entries = vmalloc(routing.nr * sizeof(*entries)); + if (!entries) + goto out; + r = -EFAULT; + urouting = argp; + if (copy_from_user(entries, urouting-entries, + routing.nr * sizeof(*entries))) + goto out_free_irq_routing; + r = kvm_set_irq_routing(kvm, entries, routing.nr, + routing.flags); + out_free_irq_routing: + vfree(entries); + break; + } +#endif /* CONFIG_HAVE_KVM_IRQ_ROUTING */ default: r = kvm_arch_vm_ioctl(filp, ioctl, arg); if (r == -ENOTTY) -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 0/8] In-kernel XICS interrupt controller emulation
On 04/26/2013 06:52:47 PM, Paul Mackerras wrote: On Fri, Apr 26, 2013 at 12:13:33PM -0500, Scott Wood wrote: Also please note that we no longer hold kvm-lock during device creation, so your EEXIST check looks racy. Huh? Patch 2/8 adds this code: + mutex_lock(kvm-lock); + if (kvm-arch.xics) + ret = -EEXIST; + else + kvm-arch.xics = xics; + mutex_unlock(kvm-lock); How is that racy? Sorry, it's not -- I must have been looking at the previous version of the patchset by mistake. :-( -Scott -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] kvm/ppc/booke: Hold srcu lock when calling gfn functions
KVM core expects arch code to acquire the srcu lock when calling gfn_to_memslot and similar functions. Signed-off-by: Scott Wood scottw...@freescale.com --- arch/powerpc/kvm/44x_tlb.c |5 + arch/powerpc/kvm/booke.c| 19 +++ arch/powerpc/kvm/e500_mmu.c |5 + 3 files changed, 29 insertions(+) diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 5dd3ab4..ed03854 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c @@ -441,6 +441,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); struct kvmppc_44x_tlbe *tlbe; unsigned int gtlb_index; + int idx; gtlb_index = kvmppc_get_gpr(vcpu, ra); if (gtlb_index = KVM44x_GUEST_TLB_SIZE) { @@ -473,6 +474,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) return EMULATE_FAIL; } + idx = srcu_read_lock(vcpu-kvm-srcu); + if (tlbe_is_host_safe(vcpu, tlbe)) { gva_t eaddr; gpa_t gpaddr; @@ -489,6 +492,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); } + srcu_read_unlock(vcpu-kvm-srcu, idx); + trace_kvm_gtlb_write(gtlb_index, tlbe-tid, tlbe-word0, tlbe-word1, tlbe-word2); diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 1020119..506c87d 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -832,6 +832,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, { int r = RESUME_HOST; int s; + int idx = 0; /* silence bogus uninitialized warning */ + bool need_srcu = false; /* update before a new last_exit_type is rewritten */ kvmppc_update_timing_stats(vcpu); @@ -847,6 +849,20 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, run-exit_reason = KVM_EXIT_UNKNOWN; run-ready_for_interrupt_injection = 1; + /* +* Don't get the srcu lock unconditionally, because kvm_ppc_pv() +* can call kvm_vcpu_block(), and kvm_ppc_pv() is shared with +* book3s, so dropping the srcu lock there would be awkward. +*/ + switch (exit_nr) { + case BOOKE_INTERRUPT_ITLB_MISS: + case BOOKE_INTERRUPT_DTLB_MISS: + need_srcu = true; + } + + if (need_srcu) + idx = srcu_read_lock(vcpu-kvm-srcu); + switch (exit_nr) { case BOOKE_INTERRUPT_MACHINE_CHECK: printk(MACHINE CHECK: %lx\n, mfspr(SPRN_MCSR)); @@ -1138,6 +1154,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, BUG(); } + if (need_srcu) + srcu_read_unlock(vcpu-kvm-srcu, idx); + /* * To avoid clobbering exit_reason, only check for signals if we * aren't already exiting to userspace for some other reason. diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index c41a5a9..6d6f153 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -396,6 +396,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) struct kvm_book3e_206_tlb_entry *gtlbe; int tlbsel, esel; int recal = 0; + int idx; tlbsel = get_tlb_tlbsel(vcpu); esel = get_tlb_esel(vcpu, tlbsel); @@ -430,6 +431,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) kvmppc_set_tlb1map_range(vcpu, gtlbe); } + idx = srcu_read_lock(vcpu-kvm-srcu); + /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ if (tlbe_is_host_safe(vcpu, gtlbe)) { u64 eaddr = get_tlb_eaddr(gtlbe); @@ -444,6 +447,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) kvmppc_mmu_map(vcpu, eaddr, raddr, index_of(tlbsel, esel)); } + srcu_read_unlock(vcpu-kvm-srcu, idx); + kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); return EMULATE_DONE; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] kvm/ppc: Hold srcu lock when calling kvm_io_bus_read/write
These functions do an srcu_dereference without acquiring the srcu lock themselves. Signed-off-by: Scott Wood scottw...@freescale.com --- arch/powerpc/kvm/powerpc.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 31084c6..270773f 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -622,6 +622,8 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int rt, unsigned int bytes, int is_bigendian) { + int idx, ret; + if (bytes sizeof(run-mmio.data)) { printk(KERN_ERR %s: bad MMIO length: %d\n, __func__, run-mmio.len); @@ -637,8 +639,14 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu-mmio_is_write = 0; vcpu-arch.mmio_sign_extend = 0; - if (!kvm_io_bus_read(vcpu-kvm, KVM_MMIO_BUS, run-mmio.phys_addr, -bytes, run-mmio.data)) { + idx = srcu_read_lock(vcpu-kvm-srcu); + + ret = kvm_io_bus_read(vcpu-kvm, KVM_MMIO_BUS, run-mmio.phys_addr, + bytes, run-mmio.data); + + srcu_read_unlock(vcpu-kvm-srcu, idx); + + if (!ret) { kvmppc_complete_mmio_load(vcpu, run); vcpu-mmio_needed = 0; return EMULATE_DONE; @@ -663,6 +671,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, u64 val, unsigned int bytes, int is_bigendian) { void *data = run-mmio.data; + int idx, ret; if (bytes sizeof(run-mmio.data)) { printk(KERN_ERR %s: bad MMIO length: %d\n, __func__, @@ -692,8 +701,14 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, } } - if (!kvm_io_bus_write(vcpu-kvm, KVM_MMIO_BUS, run-mmio.phys_addr, - bytes, run-mmio.data)) { + idx = srcu_read_lock(vcpu-kvm-srcu); + + ret = kvm_io_bus_write(vcpu-kvm, KVM_MMIO_BUS, run-mmio.phys_addr, + bytes, run-mmio.data); + + srcu_read_unlock(vcpu-kvm-srcu, idx); + + if (!ret) { vcpu-mmio_needed = 0; return EMULATE_DONE; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html