RE: Audio starts working several hours after starting Windows Vista guest
Dirk, sometimes when windows detects new hardware on a write-protected image, it needs to reinstall it on boot. For USB controllers this is usually on a 10-15 minute cycle. It may use a similar service startup cycle for audio hardware. Is your Vista image in 'snapshot=off' mode? Simon From: dirk.heinri...@altum.de To: kvm@vger.kernel.org Subject: Audio starts working several hours after starting Windows Vista guest Date: Sun, 30 Sep 2012 09:34:06 +0200 Hello, since a week or two, I have a very strange problem with audio output on a Windows Vista guest. Right after booting the guest, audio does not work. If I leave the guest running for some hours (don't know how many, I usually try again next day), audio output works fine. I'm using es1370 emulation, but I get the same results with the other alternatives, too. Guest: Windows Vista SP1 32bit Host: Ubuntu 12.10 64bit % dpkg --list|grep -e kvm -e qemu ii kvm-ipxe 1.0.0+git-3.55f6c88-0ubuntu5 all PXE ROM's for KVM ii qemu-common 1.2.0+noroms-0ubuntu2 all qemu common functionality (bios, documentation, etc) ii qemu-kvm 1.2.0+noroms-0ubuntu2 amd64 Full virtualization on supported hardware ii qemu-kvm-spice 1.2.0-2012.09-0ubuntu1 amd64 Full virtualization on amd64 hardware ii qemu-utils 1.2.0+noroms-0ubuntu2 amd64 qemu utilities Is this a known problem? What could I do to resolve it? Thanks... Dirk -- Dirk Heinrichs dirk.heinri...@altum.de Tel: +49 (0)2471 209385 | Mobil: +49 (0)176 34473913 GPG Public Key C2E467BB | Jabber: dirk.heinri...@altum.de -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Audio starts working several hours after starting Windows Vista guest
Am Montag 01 Oktober 2012, 06:54:04 schrieb Veruca Salt: sometimes when windows detects new hardware on a write-protected image, it needs to reinstall it on boot. For USB controllers this is usually on a 10-15 minute cycle. It may use a similar service startup cycle for audio hardware. Is your Vista image in 'snapshot=off' mode? I don't think so, but I don't really know. How can I tell? Bye... Dirk -- Dirk Heinrichs dirk.heinri...@altum.de Tel: +49 (0)2471 209385 | Mobil: +49 (0)176 34473913 GPG Public Key C2E467BB | Jabber: dirk.heinri...@altum.de signature.asc Description: This is a digitally signed message part.
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On 2012-09-30 21:11, Marcelo Tosatti wrote: Option is deprecated and warning has been in place for one year. Do we really care about such cosmetics? What is the big plan for qemu-kvm now? For 1.3 and then beyond? Jan Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/blockdev.c b/blockdev.c index 4a5266e..7c83baa 100644 --- a/blockdev.c +++ b/blockdev.c @@ -432,12 +432,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) return NULL; } -if (qemu_opt_get(opts, boot) != NULL) { -fprintf(stderr, qemu-kvm: boot=on|off is deprecated and will be -ignored. Future versions will reject this parameter. Please -update your scripts.\n); -} - on_write_error = BLOCK_ERR_STOP_ENOSPC; if ((buf = qemu_opt_get(opts, werror)) != NULL) { if (type != IF_IDE type != IF_SCSI type != IF_VIRTIO type != IF_NONE) { diff --git a/qemu-config.c b/qemu-config.c index 3eaee48..eba977e 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -114,10 +114,6 @@ static QemuOptsList qemu_drive_opts = { .name = copy-on-read, .type = QEMU_OPT_BOOL, .help = copy read data from backing file into image file, -},{ -.name = boot, -.type = QEMU_OPT_BOOL, -.help = (deprecated, ignored), }, { /* end of list */ } }, -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: Audio starts working several hours after starting Windows Vista guest
From: dirk.heinri...@altum.de To: kvm@vger.kernel.org Subject: Re: Audio starts working several hours after starting Windows Vista guest Date: Mon, 1 Oct 2012 09:06:57 +0200 Am Montag 01 Oktober 2012, 06:54:04 schrieb Veruca Salt: sometimes when windows detects new hardware on a write-protected image, it needs to reinstall it on boot. For USB controllers this is usually on a 10-15 minute cycle. It may use a similar service startup cycle for audio hardware. Is your Vista image in 'snapshot=off' mode? I don't think so, but I don't really know. How can I tell? Bye... Dirk -- Dirk Heinrichs dirk.heinri...@altum.de Tel: +49 (0)2471 209385 | Mobil: +49 (0)176 34473913 GPG Public Key C2E467BB | Jabber: dirk.heinri...@altum.de If you are using VirtManager, I don't know, as I'm a command line user, but I guess you could google 'make qemu guest writeable' and that might give you some information about checking. Sorry I can't help more. Simon -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 00/10] KVM/ARM Implementation
The following series implements KVM support for ARM processors, specifically on the Cortex A-15 platform. We feel this is ready to be merged. Work is done in collaboration between Columbia University, Virtual Open Systems and ARM/Linaro. The patch series applies to Linux 3.6 with a number of merges: 1. git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git branch: hyp-mode-boot-next (e5a04cb0b4a) 2. git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git branch: timers-next (437814c44c) 3. git://git.kernel.org/pub/scm/virt/kvm/kvm.git branch: next (1e08ec4a) This is Version 12 of the patch series, the first 10 versions were reviewed on the KVM/ARM and KVM mailing lists. Changes can also be pulled from: git://github.com/virtualopensystems/linux-kvm-arm.git branch: kvm-arm-v12 branch: kvm-arm-v12-vgic branch: kvm-arm-v12-vgic-timers A non-flattened edition of the patch series, which can always be merged, can be found at: git://github.com/virtualopensystems/linux-kvm-arm.git kvm-arm-master This patch series requires QEMU compatibility. Use the branch git://github.com/virtualopensystems/qemu.git kvm-arm Following this patch series, which implements core KVM support are two other patch series implementing Virtual Generic Interrupt Controller (VGIC) support and Architected Generic Timers. All three patch series should be applied for full QEMU compatibility. The implementation is broken up into a logical set of patches, the first are preparatory patches: 1. ARM: Add page table defines for KVM 3. ARM: Section based HYP idmaps 3. ARM: Factor out cpuid implementor and part_number fields The main implementation is broken up into separate patches, the first containing a skeleton of files, makefile changes, the basic user space interface and KVM architecture specific stubs. Subsequent patches implement parts of the system as listed: 4. Skeleton and reset hooks 5. Hypervisor initialization 6. Memory virtualization setup (hyp mode mappings and 2nd stage) 7. Inject IRQs and FIQs from userspace 8. World-switch implementation and Hyp exception vectors 9. Emulation framework and coproc emulation 10. Coproc user space API 11. Demux multiplexed coproc registers 12. User spac API to get/set VFP registers 13. Handle guest user memory aborts 14. Handle guest MMIO aborts Testing: Tested on FAST Models and Versatile Express test-chip2. Tested by running three simultaenous VMs, all running SMP, on an SMP host, each VM running hackbench and cyclictest and with extreme memory pressure applied to the host with swapping enabled to provoke page eviction. Also tested KSM merging and GCC inside VMs. Fully boots both Ubuntu (user space Thumb-2) and Debian (user space ARM) guests. For a guide on how to set up a testing environment and try out these patches, see: http://www.virtualopensystems.com/media/pdf/kvm-arm-guide.pdf Changes since v11: - Memory setup and page table defines reworked - We do not export unused perf bitfields anymore - No module support anymore and following cleanup - Hide vcpu register accessors - Fix unmap range mmu notifier race condition - Factored out A15 coprocs in separate file - Factored out world-switch assembly macros to separate file - Add dmux of multiplexed coprocs to user space - Add VFP get/set interface to user space - Addressed various cleanup comments from reviewers Changes since v10: - Boot in Hyp mode and user HVC to initialize HVBAR - Support VGIC - Support Arch timers - Support Thumb-2 mmio instruction decoding - Transition to GET_ONE/SET_ONE register API - Added KVM_VCPU_GET_REG_LIST - New interrupt injection API - Don't pin guest pages anymore - Fix race condition in page fault handler - Cleanup guest instruction copying. - Fix race when copying SMP guest instructions - Inject data/prefetch aborts when guest does something strange Changes since v9: - Addressed reviewer comments (see mailing list archive) - Limit the user of .arch_extensiion sec/virt for compilers that need them - VFP/Neon Support (Antonios Motakis) - Run exit handling under preemption and still handle guest cache ops - Add support for IO mapping at Hyp level (VGIC prep) - Add support for IO mapping at Guest level (VGIC prep) - Remove backdoor call to irq_svc - Complete rework of CP15 handling and register reset (Rusty Russell) - Don't use HSTR for anything else than CR 15 - New ioctl to set emulation target core (only A15 supported for now) - Support KVM_GET_MSRS / KVM_SET_MSRS - Add page accounting and page table eviction - Change pgd lock to spinlock and fix sleeping in atomic bugs - Check kvm_condition_valid for HVC traps of undefs - Added a naive implementation of kvm_unmap_hva_range Changes since v8: - Support cache maintenance on SMP through set/way - Hyp mode idmaps are now section based and happen at kernel init - Handle aborts in Hyp mode - Inject
[PATCH v2 01/10] ARM: KVM: Keep track of currently running vcpus
From: Marc Zyngier marc.zyng...@arm.com When an interrupt occurs for the guest, it is sometimes necessary to find out which vcpu was running at that point. Keep track of which vcpu is being tun in kvm_arch_vcpu_ioctl_run(), and allow the data to be retrived using either: - kvm_arm_get_running_vcpu(): returns the vcpu running at this point on the current CPU. Can only be used in a non-preemptable context. - kvm_arm_get_running_vcpus(): returns the per-CPU variable holding the the running vcpus, useable for per-CPU interrupts. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_host.h |9 + arch/arm/kvm/arm.c | 30 ++ 2 files changed, 39 insertions(+) diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index e4b5352..69a8680 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -151,4 +151,13 @@ static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) { return 0; } + +struct kvm_vcpu *kvm_arm_get_running_vcpu(void); +struct kvm_vcpu __percpu **kvm_get_running_vcpus(void); + +int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); +unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu); +struct kvm_one_reg; +int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); +int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); #endif /* __ARM_KVM_HOST_H__ */ diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 50e9585..8764dd0 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -53,11 +53,38 @@ static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); static struct vfp_hard_struct __percpu *kvm_host_vfp_state; static unsigned long hyp_default_vectors; +/* Per-CPU variable containing the currently running vcpu. */ +static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu); + /* The VMID used in the VTTBR */ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); static u8 kvm_next_vmid; static DEFINE_SPINLOCK(kvm_vmid_lock); +static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) +{ + BUG_ON(preemptible()); + __get_cpu_var(kvm_arm_running_vcpu) = vcpu; +} + +/** + * kvm_arm_get_running_vcpu - get the vcpu running on the current CPU. + * Must be called from non-preemptible context + */ +struct kvm_vcpu *kvm_arm_get_running_vcpu(void) +{ + BUG_ON(preemptible()); + return __get_cpu_var(kvm_arm_running_vcpu); +} + +/** + * kvm_arm_get_running_vcpus - get the per-CPU array on currently running vcpus. + */ +struct kvm_vcpu __percpu **kvm_get_running_vcpus(void) +{ + return kvm_arm_running_vcpu; +} + int kvm_arch_hardware_enable(void *garbage) { return 0; @@ -296,10 +323,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) cpumask_clear_cpu(cpu, vcpu-arch.require_dcache_flush); flush_cache_all(); /* We'd really want v7_flush_dcache_all() */ } + + kvm_arm_set_running_vcpu(vcpu); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { + kvm_arm_set_running_vcpu(NULL); } int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 02/10] ARM: KVM: Initial VGIC infrastructure support
From: Marc Zyngier marc.zyng...@arm.com Wire the basic framework code for VGIC support. Nothing to enable yet. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_host.h |7 arch/arm/include/asm/kvm_vgic.h | 65 +++ arch/arm/kvm/arm.c | 21 - arch/arm/kvm/interrupts.S |4 ++ arch/arm/kvm/mmu.c |3 ++ virt/kvm/kvm_main.c |5 ++- 6 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 arch/arm/include/asm/kvm_vgic.h diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 69a8680..d65faea 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -22,6 +22,7 @@ #include asm/kvm.h #include asm/kvm_asm.h #include asm/fpstate.h +#include asm/kvm_vgic.h #define KVM_MAX_VCPUS NR_CPUS #define KVM_MEMORY_SLOTS 32 @@ -52,6 +53,9 @@ struct kvm_arch { /* VTTBR value associated with above pgd and vmid */ u64vttbr; + + /* Interrupt controller */ + struct vgic_distvgic; }; #define KVM_NR_MEM_OBJS 40 @@ -87,6 +91,9 @@ struct kvm_vcpu_arch { struct vfp_hard_struct vfp_guest; struct vfp_hard_struct *vfp_host; + /* VGIC state */ + struct vgic_cpu vgic_cpu; + /* * Anything that is not used directly from assembly code goes * here. diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h new file mode 100644 index 000..e1fd530 --- /dev/null +++ b/arch/arm/include/asm/kvm_vgic.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier marc.zyng...@arm.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_KVM_VGIC_H +#define __ASM_ARM_KVM_VGIC_H + +struct vgic_dist { +}; + +struct vgic_cpu { +}; + +struct kvm; +struct kvm_vcpu; +struct kvm_run; +struct kvm_exit_mmio; + +#ifndef CONFIG_KVM_ARM_VGIC +static inline int kvm_vgic_hyp_init(void) +{ + return 0; +} + +static inline int kvm_vgic_init(struct kvm *kvm) +{ + return 0; +} + +static inline void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) {} +static inline void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu) {} +static inline void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu) {} + +static inline int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) +{ + return 0; +} + +static inline bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_exit_mmio *mmio) +{ + return false; +} + +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + return 0; +} +#endif + +#endif diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 8764dd0..cf13340 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -183,6 +183,9 @@ int kvm_dev_ioctl_check_extension(long ext) { int r; switch (ext) { +#ifdef CONFIG_KVM_ARM_VGIC + case KVM_CAP_IRQCHIP: +#endif case KVM_CAP_USER_MEMORY: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: case KVM_CAP_ONE_REG: @@ -301,6 +304,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) { /* Force users to call KVM_ARM_VCPU_INIT */ vcpu-arch.target = -1; + + /* Set up VGIC */ + kvm_vgic_vcpu_init(vcpu); + return 0; } @@ -360,7 +367,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, */ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) { - return !!v-arch.irq_lines; + return !!v-arch.irq_lines || kvm_vgic_vcpu_pending_irq(v); } int kvm_arch_vcpu_in_guest_mode(struct kvm_vcpu *v) @@ -629,6 +636,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) update_vttbr(vcpu-kvm); + kvm_vgic_sync_to_cpu(vcpu); + local_irq_disable(); /* @@ -641,6 +650,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) if (ret = 0 || need_new_vmid_gen(vcpu-kvm)) { local_irq_enable(); + kvm_vgic_sync_from_cpu(vcpu); continue; } @@ -679,6 +689,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
[PATCH v2 03/10] ARM: KVM: Initial VGIC MMIO support code
From: Marc Zyngier marc.zyng...@arm.com Wire the initial in-kernel MMIO support code for the VGIC, used for the distributor emulation. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h |6 +- arch/arm/kvm/Makefile |1 arch/arm/kvm/vgic.c | 138 +++ 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 arch/arm/kvm/vgic.c diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index e1fd530..a87ec6c 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -30,7 +30,11 @@ struct kvm_vcpu; struct kvm_run; struct kvm_exit_mmio; -#ifndef CONFIG_KVM_ARM_VGIC +#ifdef CONFIG_KVM_ARM_VGIC +bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_exit_mmio *mmio); + +#else static inline int kvm_vgic_hyp_init(void) { return 0; diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index ea5b282..89608c0 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += $(addprefix ../../../virt/kvm/, kvm_main.o coalesc obj-$(CONFIG_KVM_ARM_HOST) += arm.o guest.o mmu.o emulate.o reset.o obj-$(CONFIG_KVM_ARM_HOST) += coproc.o coproc_a15.o +obj-$(CONFIG_KVM_ARM_VGIC) += vgic.o diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c new file mode 100644 index 000..26ada3b --- /dev/null +++ b/arch/arm/kvm/vgic.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier marc.zyng...@arm.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include linux/kvm.h +#include linux/kvm_host.h +#include linux/interrupt.h +#include linux/io.h +#include asm/kvm_emulate.h + +#define ACCESS_READ_VALUE (1 0) +#define ACCESS_READ_RAZ(0 0) +#define ACCESS_READ_MASK(x)((x) (1 0)) +#define ACCESS_WRITE_IGNORED (0 1) +#define ACCESS_WRITE_SETBIT(1 1) +#define ACCESS_WRITE_CLEARBIT (2 1) +#define ACCESS_WRITE_VALUE (3 1) +#define ACCESS_WRITE_MASK(x) ((x) (3 1)) + +/** + * vgic_reg_access - access vgic register + * @mmio: pointer to the data describing the mmio access + * @reg:pointer to the virtual backing of the vgic distributor struct + * @offset: least significant 2 bits used for word offset + * @mode: ACCESS_ mode (see defines above) + * + * Helper to make vgic register access easier using one of the access + * modes defined for vgic register access + * (read,raz,write-ignored,setbit,clearbit,write) + */ +static void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg, + u32 offset, int mode) +{ + int word_offset = offset 3; + int shift = word_offset * 8; + u32 mask; + u32 regval; + + /* +* Any alignment fault should have been delivered to the guest +* directly (ARM ARM B3.12.7 Prioritization of aborts). +*/ + + mask = (~0U) (word_offset * 8); + if (reg) + regval = *reg; + else { + BUG_ON(mode != (ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED)); + regval = 0; + } + + if (mmio-is_write) { + u32 data = (*((u32 *)mmio-data) mask) shift; + switch (ACCESS_WRITE_MASK(mode)) { + case ACCESS_WRITE_IGNORED: + return; + + case ACCESS_WRITE_SETBIT: + regval |= data; + break; + + case ACCESS_WRITE_CLEARBIT: + regval = ~data; + break; + + case ACCESS_WRITE_VALUE: + regval = (regval ~(mask shift)) | data; + break; + } + *reg = regval; + } else { + switch (ACCESS_READ_MASK(mode)) { + case ACCESS_READ_RAZ: + regval = 0; + /* fall through */ + + case ACCESS_READ_VALUE: + *((u32 *)mmio-data) = (regval shift) mask; + } + } +} + +/* All this should be handled by kvm_bus_io_*()... FIXME!!! */ +struct mmio_range { + unsigned long base; + unsigned long len; + bool
[PATCH v2 04/10] ARM: KVM: VGIC distributor handling
From: Marc Zyngier marc.zyng...@arm.com Add the GIC distributor emulation code. A number of the GIC features are simply ignored as they are not required to boot a Linux guest. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h | 170 ++ arch/arm/kvm/vgic.c | 475 +++ 2 files changed, 644 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index a87ec6c..a82699f 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -19,7 +19,177 @@ #ifndef __ASM_ARM_KVM_VGIC_H #define __ASM_ARM_KVM_VGIC_H +#include linux/kernel.h +#include linux/kvm.h +#include linux/kvm_host.h +#include linux/irqreturn.h +#include linux/spinlock.h +#include linux/types.h + +#define VGIC_NR_IRQS 128 +#define VGIC_NR_SHARED_IRQS(VGIC_NR_IRQS - 32) +#define VGIC_MAX_CPUS NR_CPUS + +/* Sanity checks... */ +#if (VGIC_MAX_CPUS 8) +#error Invalid number of CPU interfaces +#endif + +#if (VGIC_NR_IRQS 31) +#error VGIC_NR_IRQS must be a multiple of 32 +#endif + +#if (VGIC_NR_IRQS 1024) +#error VGIC_NR_IRQS must be = 1024 +#endif + +/* + * The GIC distributor registers describing interrupts have two parts: + * - 32 per-CPU interrupts (SGI + PPI) + * - a bunch of shared interrups (SPI) + */ +struct vgic_bitmap { + union { + u32 reg[1]; + unsigned long reg_ul[0]; + } percpu[VGIC_MAX_CPUS]; + union { + u32 reg[VGIC_NR_SHARED_IRQS / 32]; + unsigned long reg_ul[0]; + } shared; +}; + +static inline u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, + int cpuid, u32 offset) +{ + offset = 2; + BUG_ON(offset (VGIC_NR_IRQS / 32)); + if (!offset) + return x-percpu[cpuid].reg; + else + return x-shared.reg + offset - 1; +} + +static inline int vgic_bitmap_get_irq_val(struct vgic_bitmap *x, +int cpuid, int irq) +{ + if (irq 32) + return test_bit(irq, x-percpu[cpuid].reg_ul); + + return test_bit(irq - 32, x-shared.reg_ul); +} + +static inline void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, + int cpuid, int irq, int val) +{ + unsigned long *reg; + + if (irq 32) + reg = x-percpu[cpuid].reg_ul; + else { + reg = x-shared.reg_ul; + irq -= 32; + } + + if (val) + set_bit(irq, reg); + else + clear_bit(irq, reg); +} + +static inline unsigned long *vgic_bitmap_get_cpu_map(struct vgic_bitmap *x, +int cpuid) +{ + if (unlikely(cpuid = VGIC_MAX_CPUS)) + return NULL; + return x-percpu[cpuid].reg_ul; +} + +static inline unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x) +{ + return x-shared.reg_ul; +} + +struct vgic_bytemap { + union { + u32 reg[8]; + unsigned long reg_ul[0]; + } percpu[VGIC_MAX_CPUS]; + union { + u32 reg[VGIC_NR_SHARED_IRQS / 4]; + unsigned long reg_ul[0]; + } shared; +}; + +static inline u32 *vgic_bytemap_get_reg(struct vgic_bytemap *x, + int cpuid, u32 offset) +{ + offset = 2; + BUG_ON(offset (VGIC_NR_IRQS / 4)); + if (offset 4) + return x-percpu[cpuid].reg + offset; + else + return x-shared.reg + offset - 8; +} + +static inline int vgic_bytemap_get_irq_val(struct vgic_bytemap *x, + int cpuid, int irq) +{ + u32 *reg, shift; + shift = (irq 3) * 8; + reg = vgic_bytemap_get_reg(x, cpuid, irq); + return (*reg shift) 0xff; +} + +static inline void vgic_bytemap_set_irq_val(struct vgic_bytemap *x, + int cpuid, int irq, int val) +{ + u32 *reg, shift; + shift = (irq 3) * 8; + reg = vgic_bytemap_get_reg(x, cpuid, irq); + *reg = ~(0xff shift); + *reg |= (val 0xff) shift; +} + struct vgic_dist { +#ifdef CONFIG_KVM_ARM_VGIC + spinlock_t lock; + + /* Virtual control interface mapping */ + void __iomem*vctrl_base; + + /* Distributor mapping in the guest */ + unsigned long vgic_dist_base; + unsigned long vgic_dist_size; + + /* Distributor enabled */ + u32 enabled; + + /* Interrupt enabled (one bit per IRQ) */ + struct vgic_bitmap irq_enabled; + + /* Interrupt 'pin' level */ + struct vgic_bitmap irq_state; + + /* Level-triggered interrupt in progress */ +
[PATCH v2 05/10] ARM: KVM: VGIC virtual CPU interface management
From: Marc Zyngier marc.zyng...@arm.com Add VGIC virtual CPU interface code, picking pending interrupts from the distributor and stashing them in the VGIC control interface list registers. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h | 41 +++ arch/arm/kvm/vgic.c | 224 +++ 2 files changed, 264 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index a82699f..bb67076 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -193,17 +193,58 @@ struct vgic_dist { }; struct vgic_cpu { +#ifdef CONFIG_KVM_ARM_VGIC + /* per IRQ to LR mapping */ + u8 vgic_irq_lr_map[VGIC_NR_IRQS]; + + /* Pending interrupts on this VCPU */ + DECLARE_BITMAP( pending, VGIC_NR_IRQS); + + /* Bitmap of used/free list registers */ + DECLARE_BITMAP( lr_used, 64); + + /* Number of list registers on this CPU */ + int nr_lr; + + /* CPU vif control registers for world switch */ + u32 vgic_hcr; + u32 vgic_vmcr; + u32 vgic_misr; /* Saved only */ + u32 vgic_eisr[2]; /* Saved only */ + u32 vgic_elrsr[2]; /* Saved only */ + u32 vgic_apr; + u32 vgic_lr[64];/* A15 has only 4... */ +#endif }; +#define VGIC_HCR_EN(1 0) +#define VGIC_HCR_UIE (1 1) + +#define VGIC_LR_VIRTUALID (0x3ff 0) +#define VGIC_LR_PHYSID_CPUID (7 10) +#define VGIC_LR_STATE (3 28) +#define VGIC_LR_PENDING_BIT(1 28) +#define VGIC_LR_ACTIVE_BIT (1 29) +#define VGIC_LR_EOI(1 19) + +#define VGIC_MISR_EOI (1 0) +#define VGIC_MISR_U(1 1) + +#define LR_EMPTY 0xff + struct kvm; struct kvm_vcpu; struct kvm_run; struct kvm_exit_mmio; #ifdef CONFIG_KVM_ARM_VGIC +void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu); +void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu); +int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, struct kvm_exit_mmio *mmio); +#define irqchip_in_kernel(k) (!!((k)-arch.vgic.vctrl_base)) #else static inline int kvm_vgic_hyp_init(void) { diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index a870596..2b90785 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -584,7 +584,25 @@ static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg) static int compute_pending_for_cpu(struct kvm_vcpu *vcpu) { - return 0; + struct vgic_dist *dist = vcpu-kvm-arch.vgic; + unsigned long *pending, *enabled, *pend; + int vcpu_id; + + vcpu_id = vcpu-vcpu_id; + pend = vcpu-arch.vgic_cpu.pending; + + pending = vgic_bitmap_get_cpu_map(dist-irq_state, vcpu_id); + enabled = vgic_bitmap_get_cpu_map(dist-irq_enabled, vcpu_id); + bitmap_and(pend, pending, enabled, 32); + + pending = vgic_bitmap_get_shared_map(dist-irq_state); + enabled = vgic_bitmap_get_shared_map(dist-irq_enabled); + bitmap_and(pend + 1, pending, enabled, VGIC_NR_SHARED_IRQS); + bitmap_and(pend + 1, pend + 1, + vgic_bitmap_get_shared_map(dist-irq_spi_target[vcpu_id]), + VGIC_NR_SHARED_IRQS); + + return (find_first_bit(pend, VGIC_NR_IRQS) VGIC_NR_IRQS); } /* @@ -609,3 +627,207 @@ static void vgic_update_state(struct kvm *kvm) } } } + +#define LR_PHYSID(lr) (((lr) VGIC_LR_PHYSID_CPUID) 10) +#define MK_LR_PEND(src, irq) (VGIC_LR_PENDING_BIT | ((src) 10) | (irq)) +/* + * Queue an interrupt to a CPU virtual interface. Return true on success, + * or false if it wasn't possible to queue it. + */ +static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) +{ + struct vgic_cpu *vgic_cpu = vcpu-arch.vgic_cpu; + struct vgic_dist *dist = vcpu-kvm-arch.vgic; + int lr, is_level; + + /* Sanitize the input... */ + BUG_ON(sgi_source_id ~7); + BUG_ON(sgi_source_id irq 15); + BUG_ON(irq = VGIC_NR_IRQS); + + kvm_debug(Queue IRQ%d\n, irq); + + lr = vgic_cpu-vgic_irq_lr_map[irq]; + is_level = !vgic_irq_is_edge(dist, irq); + + /* Do we have an active interrupt for the same CPUID? */ + if (lr != LR_EMPTY + (LR_PHYSID(vgic_cpu-vgic_lr[lr]) == sgi_source_id)) { + kvm_debug(LR%d piggyback for IRQ%d %x\n, lr, irq, vgic_cpu-vgic_lr[lr]); + BUG_ON(!test_bit(lr, vgic_cpu-lr_used)); + vgic_cpu-vgic_lr[lr] |= VGIC_LR_PENDING_BIT; + if (is_level) + vgic_cpu-vgic_lr[lr] |= VGIC_LR_EOI; + return true; + } + + /* Try to use
Re: [PATCH v2 00/10] KVM/ARM Implementation
On Mon, Oct 1, 2012 at 5:07 AM, Christoffer Dall c.d...@virtualopensystems.com wrote: The following series implements KVM support for ARM processors, specifically on the Cortex A-15 platform. We feel this is ready to be merged. Work is done in collaboration between Columbia University, Virtual Open Systems and ARM/Linaro. The patch series applies to Linux 3.6 with a number of merges: 1. git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git branch: hyp-mode-boot-next (e5a04cb0b4a) 2. git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git branch: timers-next (437814c44c) 3. git://git.kernel.org/pub/scm/virt/kvm/kvm.git branch: next (1e08ec4a) This is Version 12 of the patch series, the first 10 versions were reviewed on the KVM/ARM and KVM mailing lists. Changes can also be pulled from: git://github.com/virtualopensystems/linux-kvm-arm.git branch: kvm-arm-v12 branch: kvm-arm-v12-vgic branch: kvm-arm-v12-vgic-timers A non-flattened edition of the patch series, which can always be merged, can be found at: git://github.com/virtualopensystems/linux-kvm-arm.git kvm-arm-master This patch series requires QEMU compatibility. Use the branch git://github.com/virtualopensystems/qemu.git kvm-arm Following this patch series, which implements core KVM support are two other patch series implementing Virtual Generic Interrupt Controller (VGIC) support and Architected Generic Timers. All three patch series should be applied for full QEMU compatibility. The implementation is broken up into a logical set of patches, the first are preparatory patches: 1. ARM: Add page table defines for KVM 3. ARM: Section based HYP idmaps 3. ARM: Factor out cpuid implementor and part_number fields The main implementation is broken up into separate patches, the first containing a skeleton of files, makefile changes, the basic user space interface and KVM architecture specific stubs. Subsequent patches implement parts of the system as listed: 4. Skeleton and reset hooks 5. Hypervisor initialization 6. Memory virtualization setup (hyp mode mappings and 2nd stage) 7. Inject IRQs and FIQs from userspace 8. World-switch implementation and Hyp exception vectors 9. Emulation framework and coproc emulation 10. Coproc user space API 11. Demux multiplexed coproc registers 12. User spac API to get/set VFP registers 13. Handle guest user memory aborts 14. Handle guest MMIO aborts Testing: Tested on FAST Models and Versatile Express test-chip2. Tested by running three simultaenous VMs, all running SMP, on an SMP host, each VM running hackbench and cyclictest and with extreme memory pressure applied to the host with swapping enabled to provoke page eviction. Also tested KSM merging and GCC inside VMs. Fully boots both Ubuntu (user space Thumb-2) and Debian (user space ARM) guests. For a guide on how to set up a testing environment and try out these patches, see: http://www.virtualopensystems.com/media/pdf/kvm-arm-guide.pdf Changes since v11: - Memory setup and page table defines reworked - We do not export unused perf bitfields anymore - No module support anymore and following cleanup - Hide vcpu register accessors - Fix unmap range mmu notifier race condition - Factored out A15 coprocs in separate file - Factored out world-switch assembly macros to separate file - Add dmux of multiplexed coprocs to user space - Add VFP get/set interface to user space - Addressed various cleanup comments from reviewers Changes since v10: - Boot in Hyp mode and user HVC to initialize HVBAR - Support VGIC - Support Arch timers - Support Thumb-2 mmio instruction decoding - Transition to GET_ONE/SET_ONE register API - Added KVM_VCPU_GET_REG_LIST - New interrupt injection API - Don't pin guest pages anymore - Fix race condition in page fault handler - Cleanup guest instruction copying. - Fix race when copying SMP guest instructions - Inject data/prefetch aborts when guest does something strange Changes since v9: - Addressed reviewer comments (see mailing list archive) - Limit the user of .arch_extensiion sec/virt for compilers that need them - VFP/Neon Support (Antonios Motakis) - Run exit handling under preemption and still handle guest cache ops - Add support for IO mapping at Hyp level (VGIC prep) - Add support for IO mapping at Guest level (VGIC prep) - Remove backdoor call to irq_svc - Complete rework of CP15 handling and register reset (Rusty Russell) - Don't use HSTR for anything else than CR 15 - New ioctl to set emulation target core (only A15 supported for now) - Support KVM_GET_MSRS / KVM_SET_MSRS - Add page accounting and page table eviction - Change pgd lock to spinlock and fix sleeping in atomic bugs - Check kvm_condition_valid for HVC traps of undefs - Added a naive implementation of
[PATCH v2 00/14] KVM/ARM Implementation
The following series implements KVM support for ARM processors, specifically on the Cortex A-15 platform. We feel this is ready to be merged. Work is done in collaboration between Columbia University, Virtual Open Systems and ARM/Linaro. The patch series applies to Linux 3.6 with a number of merges: 1. git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git branch: hyp-mode-boot-next (e5a04cb0b4a) 2. git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git branch: timers-next (437814c44c) 3. git://git.kernel.org/pub/scm/virt/kvm/kvm.git branch: next (1e08ec4a) This is Version 12 of the patch series, the first 10 versions were reviewed on the KVM/ARM and KVM mailing lists. Changes can also be pulled from: git://github.com/virtualopensystems/linux-kvm-arm.git branch: kvm-arm-v12 branch: kvm-arm-v12-vgic branch: kvm-arm-v12-vgic-timers A non-flattened edition of the patch series, which can always be merged, can be found at: git://github.com/virtualopensystems/linux-kvm-arm.git kvm-arm-master This patch series requires QEMU compatibility. Use the branch git://github.com/virtualopensystems/qemu.git kvm-arm Following this patch series, which implements core KVM support are two other patch series implementing Virtual Generic Interrupt Controller (VGIC) support and Architected Generic Timers. All three patch series should be applied for full QEMU compatibility. The implementation is broken up into a logical set of patches, the first are preparatory patches: 1. ARM: Add page table defines for KVM 3. ARM: Section based HYP idmaps 3. ARM: Factor out cpuid implementor and part_number fields The main implementation is broken up into separate patches, the first containing a skeleton of files, makefile changes, the basic user space interface and KVM architecture specific stubs. Subsequent patches implement parts of the system as listed: 4. Skeleton and reset hooks 5. Hypervisor initialization 6. Memory virtualization setup (hyp mode mappings and 2nd stage) 7. Inject IRQs and FIQs from userspace 8. World-switch implementation and Hyp exception vectors 9. Emulation framework and coproc emulation 10. Coproc user space API 11. Demux multiplexed coproc registers 12. User spac API to get/set VFP registers 13. Handle guest user memory aborts 14. Handle guest MMIO aborts Testing: Tested on FAST Models and Versatile Express test-chip2. Tested by running three simultaenous VMs, all running SMP, on an SMP host, each VM running hackbench and cyclictest and with extreme memory pressure applied to the host with swapping enabled to provoke page eviction. Also tested KSM merging and GCC inside VMs. Fully boots both Ubuntu (user space Thumb-2) and Debian (user space ARM) guests. For a guide on how to set up a testing environment and try out these patches, see: http://www.virtualopensystems.com/media/pdf/kvm-arm-guide.pdf Changes since v11: - Memory setup and page table defines reworked - We do not export unused perf bitfields anymore - No module support anymore and following cleanup - Hide vcpu register accessors - Fix unmap range mmu notifier race condition - Factored out A15 coprocs in separate file - Factored out world-switch assembly macros to separate file - Add dmux of multiplexed coprocs to user space - Add VFP get/set interface to user space - Addressed various cleanup comments from reviewers Changes since v10: - Boot in Hyp mode and user HVC to initialize HVBAR - Support VGIC - Support Arch timers - Support Thumb-2 mmio instruction decoding - Transition to GET_ONE/SET_ONE register API - Added KVM_VCPU_GET_REG_LIST - New interrupt injection API - Don't pin guest pages anymore - Fix race condition in page fault handler - Cleanup guest instruction copying. - Fix race when copying SMP guest instructions - Inject data/prefetch aborts when guest does something strange Changes since v9: - Addressed reviewer comments (see mailing list archive) - Limit the user of .arch_extensiion sec/virt for compilers that need them - VFP/Neon Support (Antonios Motakis) - Run exit handling under preemption and still handle guest cache ops - Add support for IO mapping at Hyp level (VGIC prep) - Add support for IO mapping at Guest level (VGIC prep) - Remove backdoor call to irq_svc - Complete rework of CP15 handling and register reset (Rusty Russell) - Don't use HSTR for anything else than CR 15 - New ioctl to set emulation target core (only A15 supported for now) - Support KVM_GET_MSRS / KVM_SET_MSRS - Add page accounting and page table eviction - Change pgd lock to spinlock and fix sleeping in atomic bugs - Check kvm_condition_valid for HVC traps of undefs - Added a naive implementation of kvm_unmap_hva_range Changes since v8: - Support cache maintenance on SMP through set/way - Hyp mode idmaps are now section based and happen at kernel init - Handle aborts in Hyp mode - Inject
[PATCH v2 01/14] ARM: Add page table and page defines needed by KVM
KVM uses the stage-2 page tables and the Hyp page table format, so we define the fields and page protection flags needed by KVM. The nomenclature is this: - page_hyp:PL2 code/data mappings - page_hyp_device: PL2 device mappings (vgic access) - page_s2: Stage-2 code/data page mappings - page_s2_device: Stage-2 device mappings (vgic access) Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/pgtable-3level.h | 18 ++ arch/arm/include/asm/pgtable.h|7 +++ arch/arm/mm/mmu.c | 25 + 3 files changed, 50 insertions(+) diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index b249035..eaba5a4 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h @@ -102,11 +102,29 @@ */ #define L_PGD_SWAPPER (_AT(pgdval_t, 1) 55)/* swapper_pg_dir entry */ +/* + * 2nd stage PTE definitions for LPAE. + */ +#define L_PTE_S2_MT_UNCACHED(_AT(pteval_t, 0x5) 2) /* MemAttr[3:0] */ +#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) 2) /* MemAttr[3:0] */ +#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) 2) /* MemAttr[3:0] */ +#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) 6) /* HAP[1] */ +#define L_PTE_S2_RDWR (_AT(pteval_t, 2) 6) /* HAP[2:1] */ + +/* + * Hyp-mode PL2 PTE definitions for LPAE. + */ +#define L_PTE_HYP L_PTE_USER + #ifndef __ASSEMBLY__ #define pud_none(pud) (!pud_val(pud)) #define pud_bad(pud) (!(pud_val(pud) 2)) #define pud_present(pud) (pud_val(pud)) +#define pmd_table(pmd) ((pmd_val(pmd) PMD_TYPE_MASK) == \ +PMD_TYPE_TABLE) +#define pmd_sect(pmd) ((pmd_val(pmd) PMD_TYPE_MASK) == \ +PMD_TYPE_SECT) #define pud_clear(pudp)\ do {\ diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 41dc31f..cb8a72c 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -70,6 +70,9 @@ extern void __pgd_error(const char *file, int line, pgd_t); extern pgprot_tpgprot_user; extern pgprot_tpgprot_kernel; +extern pgprot_tpgprot_hyp_device; +extern pgprot_tpgprot_s2; +extern pgprot_tpgprot_s2_device; #define _MOD_PROT(p, b)__pgprot(pgprot_val(p) | (b)) @@ -82,6 +85,10 @@ extern pgprot_t pgprot_kernel; #define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY) #define PAGE_KERNEL_MOD_PROT(pgprot_kernel, L_PTE_XN) #define PAGE_KERNEL_EXEC pgprot_kernel +#define PAGE_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP) +#define PAGE_HYP_DEVICE_MOD_PROT(pgprot_hyp_device, L_PTE_HYP) +#define PAGE_S2_MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY) +#define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_USER | L_PTE_S2_RDONLY) #define __PAGE_NONE__pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN) #define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index c2fa21d..40d4dc1 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -56,43 +56,61 @@ static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; static unsigned int ecc_mask __initdata = 0; pgprot_t pgprot_user; pgprot_t pgprot_kernel; +pgprot_t pgprot_hyp_device; +pgprot_t pgprot_s2; +pgprot_t pgprot_s2_device; EXPORT_SYMBOL(pgprot_user); EXPORT_SYMBOL(pgprot_kernel); +EXPORT_SYMBOL(pgprot_hyp_device); +EXPORT_SYMBOL(pgprot_s2); +EXPORT_SYMBOL(pgprot_s2_device); struct cachepolicy { const char policy[16]; unsigned intcr_mask; pmdval_tpmd; pteval_tpte; + pteval_tpte_s2; }; +#ifdef CONFIG_ARM_LPAE +#define s2_policy(policy) policy +#else +#define s2_policy(policy) 0 +#endif + static struct cachepolicy cache_policies[] __initdata = { { .policy = uncached, .cr_mask= CR_W|CR_C, .pmd= PMD_SECT_UNCACHED, .pte= L_PTE_MT_UNCACHED, + .pte_s2 = s2_policy(L_PTE_S2_MT_UNCACHED), }, { .policy = buffered, .cr_mask= CR_C, .pmd= PMD_SECT_BUFFERED, .pte= L_PTE_MT_BUFFERABLE, + .pte_s2 = s2_policy(L_PTE_S2_MT_UNCACHED), }, { .policy = writethrough, .cr_mask= 0, .pmd= PMD_SECT_WT, .pte= L_PTE_MT_WRITETHROUGH, +
[PATCH v2 02/14] ARM: Section based HYP idmap
Add a method (hyp_idmap_setup) to populate a hyp pgd with an identity mapping of the code contained in the .hyp.idmap.text section. Offer a method to drop the this identity mapping through hyp_idmap_teardown. Make all the above depend on CONFIG_ARM_VIRT_EXT and CONFIG_ARM_LPAE. Cc: Will Deacon will.dea...@arm.com Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/idmap.h|5 ++ arch/arm/include/asm/pgtable-3level-hwdef.h |1 arch/arm/kernel/vmlinux.lds.S |6 ++ arch/arm/mm/idmap.c | 74 +++ 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h index bf863ed..36708ba 100644 --- a/arch/arm/include/asm/idmap.h +++ b/arch/arm/include/asm/idmap.h @@ -11,4 +11,9 @@ extern pgd_t *idmap_pgd; void setup_mm_for_reboot(void); +#ifdef CONFIG_ARM_VIRT_EXT +void hyp_idmap_teardown(pgd_t *hyp_pgd); +void hyp_idmap_setup(pgd_t *hyp_pgd); +#endif + #endif /* __ASM_IDMAP_H */ diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h index d795282..a2d404e 100644 --- a/arch/arm/include/asm/pgtable-3level-hwdef.h +++ b/arch/arm/include/asm/pgtable-3level-hwdef.h @@ -44,6 +44,7 @@ #define PMD_SECT_XN(_AT(pmdval_t, 1) 54) #define PMD_SECT_AP_WRITE (_AT(pmdval_t, 0)) #define PMD_SECT_AP_READ (_AT(pmdval_t, 0)) +#define PMD_SECT_AP1 (_AT(pmdval_t, 1) 6) #define PMD_SECT_TEX(x)(_AT(pmdval_t, 0)) /* diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 36ff15b..12fd2eb 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -19,7 +19,11 @@ ALIGN_FUNCTION(); \ VMLINUX_SYMBOL(__idmap_text_start) = .; \ *(.idmap.text) \ - VMLINUX_SYMBOL(__idmap_text_end) = .; + VMLINUX_SYMBOL(__idmap_text_end) = .; \ + ALIGN_FUNCTION(); \ + VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ + *(.hyp.idmap.text) \ + VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; #ifdef CONFIG_HOTPLUG_CPU #define ARM_CPU_DISCARD(x) diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index ab88ed4..ea7430e 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -1,4 +1,6 @@ +#include linux/module.h #include linux/kernel.h +#include linux/slab.h #include asm/cputype.h #include asm/idmap.h @@ -6,6 +8,7 @@ #include asm/pgtable.h #include asm/sections.h #include asm/system_info.h +#include asm/virt.h pgd_t *idmap_pgd; @@ -59,11 +62,20 @@ static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end, } while (pud++, addr = next, addr != end); } -static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) +static void identity_mapping_add(pgd_t *pgd, const char *text_start, +const char *text_end, unsigned long prot) { - unsigned long prot, next; + unsigned long addr, end; + unsigned long next; + + addr = virt_to_phys(text_start); + end = virt_to_phys(text_end); + + pr_info(Setting up static %sidentity map for 0x%llx - 0x%llx\n, + prot ? HYP : , + (long long)addr, (long long)end); + prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; - prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; if (cpu_architecture() = CPU_ARCH_ARMv5TEJ !cpu_is_xscale()) prot |= PMD_BIT4; @@ -78,24 +90,62 @@ extern char __idmap_text_start[], __idmap_text_end[]; static int __init init_static_idmap(void) { - phys_addr_t idmap_start, idmap_end; - idmap_pgd = pgd_alloc(init_mm); if (!idmap_pgd) return -ENOMEM; - /* Add an identity mapping for the physical address of the section. */ - idmap_start = virt_to_phys((void *)__idmap_text_start); - idmap_end = virt_to_phys((void *)__idmap_text_end); - - pr_info(Setting up static identity map for 0x%llx - 0x%llx\n, - (long long)idmap_start, (long long)idmap_end); - identity_mapping_add(idmap_pgd, idmap_start, idmap_end); + identity_mapping_add(idmap_pgd, __idmap_text_start, +__idmap_text_end, 0); return 0; } early_initcall(init_static_idmap); +#if defined(CONFIG_ARM_VIRT_EXT) defined(CONFIG_ARM_LPAE) +static void hyp_idmap_del_pmd(pgd_t *pgd, unsigned long addr) +{ + pud_t *pud; + pmd_t *pmd; + + pud = pud_offset(pgd, addr); + pmd = pmd_offset(pud, addr); +
[PATCH v2 03/14] ARM: Factor out cpuid implementor and part number
Decoding the implementor and part number of the CPU id in the CPU ID register is needed by KVM, so we factor it out to share the code. Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/cputype.h | 26 ++ arch/arm/kernel/perf_event.c | 30 +++--- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index cb47d28..306fb2c 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -51,6 +51,22 @@ extern unsigned int processor_id; #define read_cpuid_ext(reg) 0 #endif +#define IMPLEMENTOR_ARM0x41 +#define IMPLEMENTOR_INTEL 0x69 + +#define PART_NUMBER_ARM11360xB360 +#define PART_NUMBER_ARM11560xB560 +#define PART_NUMBER_ARM11760xB760 +#define PART_NUMBER_ARM11MPCORE0xB020 +#define PART_NUMBER_CORTEX_A8 0xC080 +#define PART_NUMBER_CORTEX_A9 0xC090 +#define PART_NUMBER_CORTEX_A5 0xC050 +#define PART_NUMBER_CORTEX_A15 0xC0F0 +#define PART_NUMBER_CORTEX_A7 0xC070 + +#define PART_NUMBER_XSCALE10x1 +#define PART_NUMBER_XSCALE20x2 + /* * The CPU ID never changes at run time, so we might as well tell the * compiler that it's constant. Use this function to read the CPU ID @@ -61,6 +77,16 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void) return read_cpuid(CPUID_ID); } +static inline unsigned int __attribute_const__ read_cpuid_implementor(void) +{ + return (read_cpuid_id() 0xFF00) 24; +} + +static inline unsigned int __attribute_const__ read_cpuid_part_number(void) +{ + return (read_cpuid_id() 0xFFF0); +} + static inline unsigned int __attribute_const__ read_cpuid_cachetype(void) { return read_cpuid(CPUID_CACHETYPE); diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index ab243b8..c8243c6 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -709,44 +709,44 @@ static int __init init_hw_perf_events(void) { unsigned long cpuid = read_cpuid_id(); - unsigned long implementor = (cpuid 0xFF00) 24; - unsigned long part_number = (cpuid 0xFFF0); + unsigned long implementor = read_cpuid_implementor(); + unsigned long part_number = read_cpuid_part_number(); /* ARM Ltd CPUs. */ - if (0x41 == implementor) { + if (implementor == IMPLEMENTOR_ARM) { switch (part_number) { - case 0xB360:/* ARM1136 */ - case 0xB560:/* ARM1156 */ - case 0xB760:/* ARM1176 */ + case PART_NUMBER_ARM1136: + case PART_NUMBER_ARM1156: + case PART_NUMBER_ARM1176: cpu_pmu = armv6pmu_init(); break; - case 0xB020:/* ARM11mpcore */ + case PART_NUMBER_ARM11MPCORE: cpu_pmu = armv6mpcore_pmu_init(); break; - case 0xC080:/* Cortex-A8 */ + case PART_NUMBER_CORTEX_A8: cpu_pmu = armv7_a8_pmu_init(); break; - case 0xC090:/* Cortex-A9 */ + case PART_NUMBER_CORTEX_A9: cpu_pmu = armv7_a9_pmu_init(); break; - case 0xC050:/* Cortex-A5 */ + case PART_NUMBER_CORTEX_A5: cpu_pmu = armv7_a5_pmu_init(); break; - case 0xC0F0:/* Cortex-A15 */ + case PART_NUMBER_CORTEX_A15: cpu_pmu = armv7_a15_pmu_init(); break; - case 0xC070:/* Cortex-A7 */ + case PART_NUMBER_CORTEX_A7: cpu_pmu = armv7_a7_pmu_init(); break; } /* Intel CPUs [xscale]. */ - } else if (0x69 == implementor) { + } else if (implementor == IMPLEMENTOR_INTEL) { part_number = (cpuid 13) 0x7; switch (part_number) { - case 1: + case PART_NUMBER_XSCALE1: cpu_pmu = xscale1pmu_init(); break; - case 2: + case PART_NUMBER_XSCALE2: cpu_pmu = xscale2pmu_init(); break; } -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 04/14] KVM: ARM: Initial skeleton to compile KVM support
Targets KVM support for Cortex A-15 processors. Contains all the framework components, make files, header files, some tracing functionality, and basic user space API. Only supported core is Cortex-A15 for now. Most functionality is in arch/arm/kvm/* or arch/arm/include/asm/kvm_*.h. Signed-off-by: Rusty Russell rusty.russ...@linaro.org Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- Documentation/virtual/kvm/api.txt | 54 +- arch/arm/Kconfig |2 arch/arm/Makefile |1 arch/arm/include/asm/kvm.h | 89 + arch/arm/include/asm/kvm_arm.h | 24 +++ arch/arm/include/asm/kvm_asm.h | 58 ++ arch/arm/include/asm/kvm_coproc.h | 24 +++ arch/arm/include/asm/kvm_emulate.h | 62 +++ arch/arm/include/asm/kvm_host.h| 116 arch/arm/kvm/Kconfig | 44 + arch/arm/kvm/Makefile | 21 ++ arch/arm/kvm/arm.c | 343 arch/arm/kvm/coproc.c | 22 ++ arch/arm/kvm/emulate.c | 185 +++ arch/arm/kvm/guest.c | 221 +++ arch/arm/kvm/init.S| 19 ++ arch/arm/kvm/interrupts.S | 19 ++ arch/arm/kvm/mmu.c | 17 ++ arch/arm/kvm/reset.c | 74 arch/arm/kvm/trace.h | 52 + include/linux/kvm.h|2 21 files changed, 1445 insertions(+), 4 deletions(-) create mode 100644 arch/arm/include/asm/kvm.h create mode 100644 arch/arm/include/asm/kvm_arm.h create mode 100644 arch/arm/include/asm/kvm_asm.h create mode 100644 arch/arm/include/asm/kvm_coproc.h create mode 100644 arch/arm/include/asm/kvm_emulate.h create mode 100644 arch/arm/include/asm/kvm_host.h create mode 100644 arch/arm/kvm/Kconfig create mode 100644 arch/arm/kvm/Makefile create mode 100644 arch/arm/kvm/arm.c create mode 100644 arch/arm/kvm/coproc.c create mode 100644 arch/arm/kvm/emulate.c create mode 100644 arch/arm/kvm/guest.c create mode 100644 arch/arm/kvm/init.S create mode 100644 arch/arm/kvm/interrupts.S create mode 100644 arch/arm/kvm/mmu.c create mode 100644 arch/arm/kvm/reset.c create mode 100644 arch/arm/kvm/trace.h diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 36befa7..599b1e7 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -293,7 +293,7 @@ kvm_run' (see below). 4.11 KVM_GET_REGS Capability: basic -Architectures: all +Architectures: all except ARM Type: vcpu ioctl Parameters: struct kvm_regs (out) Returns: 0 on success, -1 on error @@ -314,7 +314,7 @@ struct kvm_regs { 4.12 KVM_SET_REGS Capability: basic -Architectures: all +Architectures: all except ARM Type: vcpu ioctl Parameters: struct kvm_regs (in) Returns: 0 on success, -1 on error @@ -600,7 +600,7 @@ struct kvm_fpu { 4.24 KVM_CREATE_IRQCHIP Capability: KVM_CAP_IRQCHIP -Architectures: x86, ia64 +Architectures: x86, ia64, ARM Type: vm ioctl Parameters: none Returns: 0 on success, -1 on error @@ -608,7 +608,8 @@ Returns: 0 on success, -1 on error Creates an interrupt controller model in the kernel. On x86, creates a virtual ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 -only go to the IOAPIC. On ia64, a IOSAPIC is created. +only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM, a GIC is +created. 4.25 KVM_IRQ_LINE @@ -1732,6 +1733,11 @@ registers, find a list below: | | PPC | KVM_REG_PPC_HIOR | 64 +ARM registers are mapped using the lower 32 bits. The upper 16 of that +is the register group type, or coprocessor number: + +ARM core registers have the following id bit patterns: + 0x4002 0010 index into the kvm_regs struct:16 4.69 KVM_GET_ONE_REG @@ -1985,6 +1991,46 @@ the virtualized real-mode area (VRMA) facility, the kernel will re-create the VMRA HPTEs on the next KVM_RUN of any vcpu.) +4.77 KVM_ARM_VCPU_INIT + +Capability: basic +Architectures: arm +Type: vcpu ioctl +Parameters: struct struct kvm_vcpu_init (in) +Returns: 0 on success; -1 on error +Errors: + EINVAL: the target is unknown, or the combination of features is invalid. + ENOENT: a features bit specified is unknown. + +This tells KVM what type of CPU to present to the guest, and what +optional features it should have. This will cause a reset of the cpu +registers to their initial values. If this is not called, KVM_RUN will +return ENOEXEC for that vcpu. + +Note that because some registers reflect machine topology, all vcpus +should be created before this ioctl is invoked. + + +4.78 KVM_GET_REG_LIST + +Capability: basic +Architectures: arm +Type: vcpu ioctl +Parameters: struct kvm_reg_list
[PATCH v2 05/14] KVM: ARM: Hypervisor inititalization
Sets up KVM code to handle all exceptions taken to Hyp mode. When the kernel is booted in Hyp mode, calling hvc #0xff with r0 pointing to the new vectors, the HVBAR is changed to the the vector pointers. This allows subsystems (like KVM here) to execute code in Hyp-mode with the MMU disabled. We initialize other Hyp-mode registers and enables the MMU for Hyp-mode from the id-mapped hyp initialization code. Afterwards, the HVBAR is changed to point to KVM Hyp vectors used to catch guest faults and to switch to Hyp mode to perform a world-switch into a KVM guest. If the KVM module is unloaded we call hvc #0xff once more to disable the MMU in Hyp mode again and install a vector handler to change the HVBAR for a subsequent reload of KVM or another hypervisor. Also provides memory mapping code to map required code pages, data structures, and I/O regions accessed in Hyp mode at the same virtual address as the host kernel virtual addresses, but which conforms to the architectural requirements for translations in Hyp mode. This interface is added in arch/arm/kvm/arm_mmu.c and comprises: - create_hyp_mappings(from, to); - create_hyp_io_mappings(from, to, phys_addr); - free_hyp_pmds(); Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arm.h | 107 ++ arch/arm/include/asm/kvm_asm.h | 20 +++ arch/arm/include/asm/kvm_mmu.h | 39 + arch/arm/include/asm/pgtable-3level-hwdef.h |4 + arch/arm/kvm/arm.c | 172 ++ arch/arm/kvm/init.S | 107 ++ arch/arm/kvm/interrupts.S | 48 ++ arch/arm/kvm/mmu.c | 210 +++ mm/memory.c |2 9 files changed, 709 insertions(+) create mode 100644 arch/arm/include/asm/kvm_mmu.h diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index c196a22..f6e8f6f 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -21,4 +21,111 @@ #include asm/types.h +/* Hyp Configuration Register (HCR) bits */ +#define HCR_TGE(1 27) +#define HCR_TVM(1 26) +#define HCR_TTLB (1 25) +#define HCR_TPU(1 24) +#define HCR_TPC(1 23) +#define HCR_TSW(1 22) +#define HCR_TAC(1 21) +#define HCR_TIDCP (1 20) +#define HCR_TSC(1 19) +#define HCR_TID3 (1 18) +#define HCR_TID2 (1 17) +#define HCR_TID1 (1 16) +#define HCR_TID0 (1 15) +#define HCR_TWE(1 14) +#define HCR_TWI(1 13) +#define HCR_DC (1 12) +#define HCR_BSU(3 10) +#define HCR_BSU_IS (1 10) +#define HCR_FB (1 9) +#define HCR_VA (1 8) +#define HCR_VI (1 7) +#define HCR_VF (1 6) +#define HCR_AMO(1 5) +#define HCR_IMO(1 4) +#define HCR_FMO(1 3) +#define HCR_PTW(1 2) +#define HCR_SWIO (1 1) +#define HCR_VM 1 + +/* + * The bits we set in HCR: + * TAC:Trap ACTLR + * TSC:Trap SMC + * TSW:Trap cache operations by set/way + * TWI:Trap WFI + * TIDCP: Trap L2CTLR/L2ECTLR + * BSU_IS: Upgrade barriers to the inner shareable domain + * FB: Force broadcast of all maintainance operations + * AMO:Override CPSR.A and enable signaling with VA + * IMO:Override CPSR.I and enable signaling with VI + * FMO:Override CPSR.F and enable signaling with VF + * SWIO: Turn set/way invalidates into set/way clean+invalidate + */ +#define HCR_GUEST_MASK (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \ + HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \ + HCR_SWIO | HCR_TIDCP) + +/* Hyp System Control Register (HSCTLR) bits */ +#define HSCTLR_TE (1 30) +#define HSCTLR_EE (1 25) +#define HSCTLR_FI (1 21) +#define HSCTLR_WXN (1 19) +#define HSCTLR_I (1 12) +#define HSCTLR_C (1 2) +#define HSCTLR_A (1 1) +#define HSCTLR_M 1 +#define HSCTLR_MASK(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I | \ +HSCTLR_WXN | HSCTLR_FI | HSCTLR_EE | HSCTLR_TE) + +/* TTBCR and HTCR Registers bits */ +#define TTBCR_EAE (1 31) +#define TTBCR_IMP (1 30) +#define TTBCR_SH1 (3 28) +#define TTBCR_ORGN1(3 26) +#define TTBCR_IRGN1(3 24) +#define TTBCR_EPD1 (1 23) +#define TTBCR_A1 (1 22) +#define TTBCR_T1SZ (3 16) +#define TTBCR_SH0 (3 12) +#define TTBCR_ORGN0(3 10) +#define TTBCR_IRGN0(3 8) +#define TTBCR_EPD0 (1 7) +#define TTBCR_T0SZ 3 +#define HTCR_MASK
[PATCH v2 06/14] KVM: ARM: Memory virtualization setup
This commit introduces the framework for guest memory management through the use of 2nd stage translation. Each VM has a pointer to a level-1 table (the pgd field in struct kvm_arch) which is used for the 2nd stage translations. Entries are added when handling guest faults (later patch) and the table itself can be allocated and freed through the following functions implemented in arch/arm/kvm/arm_mmu.c: - kvm_alloc_stage2_pgd(struct kvm *kvm); - kvm_free_stage2_pgd(struct kvm *kvm); Each entry in TLBs and caches are tagged with a VMID identifier in addition to ASIDs. The VMIDs are assigned consecutively to VMs in the order that VMs are executed, and caches and tlbs are invalidated when the VMID space has been used to allow for more than 255 simultaenously running guests. The 2nd stage pgd is allocated in kvm_arch_init_vm(). The table is freed in kvm_arch_destroy_vm(). Both functions are called from the main KVM code. We pre-allocate page table memory to be able to synchronize using a spinlock and be called under rcu_read_lock from the MMU notifiers. We steal the mmu_memory_cache implementation from x86 and adapt for our specific usage. We support MMU notifiers (thanks to Marc Zyngier) through kvm_unmap_hva and kvm_set_spte_hva. Finally, define kvm_phys_addr_ioremap() to map a device at a guest IPA, which is used by VGIC support to map the virtual CPU interface registers to the guest. This support is added by Marc Zyngier. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_asm.h |2 arch/arm/include/asm/kvm_host.h | 18 ++ arch/arm/include/asm/kvm_mmu.h |9 + arch/arm/kvm/Kconfig|1 arch/arm/kvm/arm.c | 37 arch/arm/kvm/interrupts.S |8 + arch/arm/kvm/mmu.c | 381 +++ arch/arm/kvm/trace.h| 46 + 8 files changed, 501 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 954bf7c..47a0e57 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -57,6 +57,7 @@ #define ARM_EXCEPTION_HVC7 #ifndef __ASSEMBLY__ +struct kvm; struct kvm_vcpu; extern char __kvm_hyp_init[]; @@ -71,6 +72,7 @@ extern char __kvm_hyp_code_start[]; extern char __kvm_hyp_code_end[]; extern void __kvm_flush_vm_context(void); +extern void __kvm_tlb_flush_vmid(struct kvm *kvm); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); #endif diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 1849803..f1c7725 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -113,4 +113,22 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); struct kvm_one_reg; int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); + +#define KVM_ARCH_WANT_MMU_NOTIFIER +struct kvm; +int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); +int kvm_unmap_hva_range(struct kvm *kvm, + unsigned long start, unsigned long end); +void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); + +/* We do not have shadow page tables, hence the empty hooks */ +static inline int kvm_age_hva(struct kvm *kvm, unsigned long hva) +{ + return 0; +} + +static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) +{ + return 0; +} #endif /* __ARM_KVM_HOST_H__ */ diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 741ab8f..9bd0508 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -33,6 +33,15 @@ int create_hyp_mappings(void *from, void *to); int create_hyp_io_mappings(void *from, void *to, phys_addr_t); void free_hyp_pmds(void); +int kvm_alloc_stage2_pgd(struct kvm *kvm); +void kvm_free_stage2_pgd(struct kvm *kvm); +int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, + phys_addr_t pa, unsigned long size); + +int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); + +void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu); + unsigned long kvm_mmu_get_httbr(void); int kvm_mmu_init(void); void kvm_mmu_exit(void); diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index a07ddcc..47c5500 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig @@ -36,6 +36,7 @@ config KVM_ARM_HOST depends on KVM depends on MMU depends on CPU_V7 ARM_VIRT_EXT + select MMU_NOTIFIER ---help--- Provides host support for ARM processors. diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 8e1ea2b..5ac3132 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -81,12 +81,33 @@ void kvm_arch_sync_events(struct kvm *kvm) { } +/** + * kvm_arch_init_vm - initializes a
[PATCH v2 07/14] KVM: ARM: Inject IRQs and FIQs from userspace
From: Christoffer Dall cd...@cs.columbia.edu All interrupt injection is now based on the VM ioctl KVM_IRQ_LINE. This works semantically well for the GIC as we in fact raise/lower a line on a machine component (the gic). The IOCTL uses the follwing struct. struct kvm_irq_level { union { __u32 irq; /* GSI */ __s32 status; /* not used for KVM_IRQ_LEVEL */ }; __u32 level; /* 0 or 1 */ }; ARM can signal an interrupt either at the CPU level, or at the in-kernel irqchip (GIC), and for in-kernel irqchip can tell the GIC to use PPIs designated for specific cpus. The irq field is interpreted like this: bits: | 31 ... 24 | 23 ... 16 | 15...0 | field: | irq_type | vcpu_index | irq_number | The irq_type field has the following values: - irq_type[0]: out-of-kernel GIC: irq_number 0 is IRQ, irq_number 1 is FIQ - irq_type[1]: in-kernel GIC: SPI, irq_number between 32 and 1019 (incl.) (the vcpu_index field is ignored) - irq_type[2]: in-kernel GIC: PPI, irq_number between 16 and 31 (incl.) The irq_number thus corresponds to the irq ID in as in the GICv2 specs. This is documented in Documentation/kvm/api.txt. Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- Documentation/virtual/kvm/api.txt | 25 +++-- arch/arm/include/asm/kvm.h| 21 +++ arch/arm/include/asm/kvm_arm.h|1 + arch/arm/kvm/arm.c| 70 + arch/arm/kvm/trace.h | 25 + include/linux/kvm.h |1 + 6 files changed, 139 insertions(+), 4 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 599b1e7..fd1c1bc 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -615,15 +615,32 @@ created. 4.25 KVM_IRQ_LINE Capability: KVM_CAP_IRQCHIP -Architectures: x86, ia64 +Architectures: x86, ia64, arm Type: vm ioctl Parameters: struct kvm_irq_level Returns: 0 on success, -1 on error Sets the level of a GSI input to the interrupt controller model in the kernel. -Requires that an interrupt controller model has been previously created with -KVM_CREATE_IRQCHIP. Note that edge-triggered interrupts require the level -to be set to 1 and then back to 0. +On some architectures it is required that an interrupt controller model has +been previously created with KVM_CREATE_IRQCHIP. Note that edge-triggered +interrupts require the level to be set to 1 and then back to 0. + +ARM can signal an interrupt either at the CPU level, or at the in-kernel irqchip +(GIC), and for in-kernel irqchip can tell the GIC to use PPIs designated for +specific cpus. The irq field is interpreted like this: + + bits: | 31 ... 24 | 23 ... 16 | 15...0 | + field: | irq_type | vcpu_index | irq_id | + +The irq_type field has the following values: +- irq_type[0]: out-of-kernel GIC: irq_id 0 is IRQ, irq_id 1 is FIQ +- irq_type[1]: in-kernel GIC: SPI, irq_id between 32 and 1019 (incl.) + (the vcpu_index field is ignored) +- irq_type[2]: in-kernel GIC: PPI, irq_id between 16 and 31 (incl.) + +(The irq_id field thus corresponds nicely to the IRQ ID in the ARM GIC specs) + +In both cases, level is used to raise/lower the line. struct kvm_irq_level { union { diff --git a/arch/arm/include/asm/kvm.h b/arch/arm/include/asm/kvm.h index 5918afe..eb5f528 100644 --- a/arch/arm/include/asm/kvm.h +++ b/arch/arm/include/asm/kvm.h @@ -22,6 +22,7 @@ #include asm/types.h #define __KVM_HAVE_GUEST_DEBUG +#define __KVM_HAVE_IRQ_LINE #define KVM_REG_SIZE(id) \ (1U (((id) KVM_REG_SIZE_MASK) KVM_REG_SIZE_SHIFT)) @@ -86,4 +87,24 @@ struct kvm_reg_list { #define KVM_REG_ARM_CORE (0x0010 KVM_REG_ARM_COPROC_SHIFT) #define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4) +/* KVM_IRQ_LINE irq field index values */ +#define KVM_ARM_IRQ_TYPE_SHIFT 24 +#define KVM_ARM_IRQ_TYPE_MASK 0xff +#define KVM_ARM_IRQ_VCPU_SHIFT 16 +#define KVM_ARM_IRQ_VCPU_MASK 0xff +#define KVM_ARM_IRQ_NUM_SHIFT 0 +#define KVM_ARM_IRQ_NUM_MASK 0x + +/* irq_type field */ +#define KVM_ARM_IRQ_TYPE_CPU 0 +#define KVM_ARM_IRQ_TYPE_SPI 1 +#define KVM_ARM_IRQ_TYPE_PPI 2 + +/* out-of-kernel GIC cpu interrupt injection irq_number field */ +#define KVM_ARM_IRQ_CPU_IRQ0 +#define KVM_ARM_IRQ_CPU_FIQ1 + +/* Highest supported SPI, from VGIC_NR_IRQS */ +#define KVM_ARM_IRQ_GIC_MAX127 + #endif /* __ARM_KVM_H__ */ diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index f6e8f6f..4f54cda 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -68,6 +68,7 @@ #define HCR_GUEST_MASK (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM
[PATCH v2 08/14] KVM: ARM: World-switch implementation
Provides complete world-switch implementation to switch to other guests running in non-secure modes. Includes Hyp exception handlers that capture necessary exception information and stores the information on the VCPU and KVM structures. The following Hyp-ABI is also documented in the code: Hyp-ABI: Switching from host kernel to Hyp-mode: Switching to Hyp mode is done through a simple HVC #0 instruction. The exception vector code will check that the HVC comes from VMID==0 and if so will store the necessary state on the Hyp stack, which will look like this (growing downwards, see the hyp_hvc handler): ... stack_page + 4: spsr (Host-SVC cpsr) stack_page: lr_usr --: stack bottom Hyp-ABI: Switching from Hyp-mode to host kernel SVC mode: When returning from Hyp mode to SVC mode, another HVC instruction is executed from Hyp mode, which is taken in the hyp_svc handler. The bottom of the Hyp is derived from the Hyp stack pointer (only a single page aligned stack is used per CPU) and the initial SVC registers are used to restore the host state. Hyp-ABI: Change the HVBAR: When removing the KVM module we want to reset our hold on Hyp mode. This is accomplished by calling HVC #0xff from the host kernel (VMID==0) with the desired new HVBAR in r0. Otherwise, the world-switch is pretty straight-forward. All state that can be modified by the guest is first backed up on the Hyp stack and the VCPU values is loaded onto the hardware. State, which is not loaded, but theoretically modifiable by the guest is protected through the virtualiation features to generate a trap and cause software emulation. Upon guest returns, all state is restored from hardware onto the VCPU struct and the original state is restored from the Hyp-stack onto the hardware. SMP support using the VMPIDR calculated on the basis of the host MPIDR and overriding the low bits with KVM vcpu_id contributed by Marc Zyngier. Reuse of VMIDs has been implemented by Antonios Motakis and adapated from a separate patch into the appropriate patches introducing the functionality. Note that the VMIDs are stored per VM as required by the ARM architecture reference manual. To support VFP/NEON we trap those instructions using the HPCTR. When we trap, we switch the FPU. After a guest exit, the VFP state is returned to the host. When disabling access to floating point instructions, we also mask FPEXC_EN in order to avoid the guest receiving Undefined instruction exceptions before we have a chance to switch back the floating point state. We are reusing vfp_hard_struct, so we depend on VFPv3 being enabled in the host kernel, if not, we still trap cp10 and cp11 in order to inject an undefined instruction exception whenever the guest tries to use VFP/NEON. VFP/NEON developed by Antionios Motakis and Rusty Russell. Signed-off-by: Rusty Russell rusty.russ...@linaro.org Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arm.h | 38 +++ arch/arm/include/asm/kvm_host.h |9 + arch/arm/kernel/asm-offsets.c | 24 ++ arch/arm/kvm/arm.c | 163 +++ arch/arm/kvm/interrupts.S | 431 +++ arch/arm/kvm/interrupts_head.S | 293 +++ 6 files changed, 952 insertions(+), 6 deletions(-) create mode 100644 arch/arm/kvm/interrupts_head.S diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 4f54cda..aecd05f 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -98,6 +98,18 @@ #define TTBCR_T0SZ 3 #define HTCR_MASK (TTBCR_T0SZ | TTBCR_IRGN0 | TTBCR_ORGN0 | TTBCR_SH0) +/* Hyp System Trap Register */ +#define HSTR_T(x) (1 x) +#define HSTR_TTEE (1 16) +#define HSTR_TJDBX (1 17) + +/* Hyp Coprocessor Trap Register */ +#define HCPTR_TCP(x) (1 x) +#define HCPTR_TCP_MASK (0x3fff) +#define HCPTR_TASE (1 15) +#define HCPTR_TTA (1 20) +#define HCPTR_TCPAC(1 31) + /* Hyp Debug Configuration Register bits */ #define HDCR_TDRA (1 11) #define HDCR_TDOSA (1 10) @@ -128,5 +140,31 @@ #define VTTBR_X(5 - VTCR_GUEST_T0SZ) #endif +/* Hyp Syndrome Register (HSR) bits */ +#define HSR_EC_SHIFT (26) +#define HSR_EC (0x3fU HSR_EC_SHIFT) +#define HSR_IL (1U 25) +#define HSR_ISS(HSR_IL - 1) +#define HSR_ISV_SHIFT (24) +#define HSR_ISV(1U HSR_ISV_SHIFT) + +#define HSR_EC_UNKNOWN (0x00) +#define HSR_EC_WFI (0x01) +#define HSR_EC_CP15_32 (0x03) +#define HSR_EC_CP15_64 (0x04) +#define HSR_EC_CP14_MR (0x05) +#define HSR_EC_CP14_LS (0x06) +#define HSR_EC_CP_0_13 (0x07) +#define HSR_EC_CP10_ID (0x08) +#define HSR_EC_JAZELLE (0x09) +#define HSR_EC_BXJ (0x0A) +#define HSR_EC_CP14_64 (0x0C) +#define
[PATCH v2 09/14] KVM: ARM: Emulation framework and CP15 emulation
Adds a new important function in the main KVM/ARM code called handle_exit() which is called from kvm_arch_vcpu_ioctl_run() on returns from guest execution. This function examines the Hyp-Syndrome-Register (HSR), which contains information telling KVM what caused the exit from the guest. Some of the reasons for an exit are CP15 accesses, which are not allowed from the guest and this commit handles these exits by emulating the intended operation in software and skipping the guest instruction. Minor notes about the coproc register reset: 1) We reserve a value of 0 as an invalid cp15 offset, to catch bugs in our table, at cost of 4 bytes per vcpu. 2) Added comments on the table indicating how we handle each register, for simplicity of understanding. Signed-off-by: Rusty Russell rusty.russ...@linaro.org Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arm.h |9 + arch/arm/include/asm/kvm_coproc.h | 14 + arch/arm/include/asm/kvm_emulate.h |6 + arch/arm/include/asm/kvm_host.h|4 arch/arm/kvm/Makefile |3 arch/arm/kvm/arm.c | 179 +- arch/arm/kvm/coproc.c | 363 arch/arm/kvm/coproc.h | 153 +++ arch/arm/kvm/coproc_a15.c | 164 arch/arm/kvm/emulate.c | 218 ++ arch/arm/kvm/trace.h | 45 11 files changed, 1152 insertions(+), 6 deletions(-) create mode 100644 arch/arm/kvm/coproc.h create mode 100644 arch/arm/kvm/coproc_a15.c diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index aecd05f..6b8bb51 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -70,6 +70,11 @@ HCR_SWIO | HCR_TIDCP) #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) +/* System Control Register (SCTLR) bits */ +#define SCTLR_TE (1 30) +#define SCTLR_EE (1 25) +#define SCTLR_V(1 13) + /* Hyp System Control Register (HSCTLR) bits */ #define HSCTLR_TE (1 30) #define HSCTLR_EE (1 25) @@ -147,6 +152,10 @@ #define HSR_ISS(HSR_IL - 1) #define HSR_ISV_SHIFT (24) #define HSR_ISV(1U HSR_ISV_SHIFT) +#define HSR_CV_SHIFT (24) +#define HSR_CV (1U HSR_CV_SHIFT) +#define HSR_COND_SHIFT (20) +#define HSR_COND (0xfU HSR_COND_SHIFT) #define HSR_EC_UNKNOWN (0x00) #define HSR_EC_WFI (0x01) diff --git a/arch/arm/include/asm/kvm_coproc.h b/arch/arm/include/asm/kvm_coproc.h index b6d023d..bd1ace0 100644 --- a/arch/arm/include/asm/kvm_coproc.h +++ b/arch/arm/include/asm/kvm_coproc.h @@ -21,4 +21,18 @@ void kvm_reset_coprocs(struct kvm_vcpu *vcpu); +struct kvm_coproc_target_table { + unsigned target; + const struct coproc_reg *table; + size_t num; +}; +void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table); + +int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); +void kvm_coproc_table_init(void); #endif /* __ARM_KVM_COPROC_H__ */ diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index f6f9578..10e6bea 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -25,6 +25,12 @@ u32 *vcpu_reg_mode(struct kvm_vcpu *vcpu, u8 reg_num, u32 cpsr); u32 *vcpu_spsr_mode(struct kvm_vcpu *vcpu, u32 cpsr); +int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run); +void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr); +void kvm_inject_undefined(struct kvm_vcpu *vcpu); +void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); +void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); + /* Get vcpu register for current mode */ static inline u32 *vcpu_reg(struct kvm_vcpu *vcpu, unsigned long reg_num) { diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 2d98fee..5ad798b 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -90,6 +90,10 @@ struct kvm_vcpu_arch { * Anything that is not used directly from assembly code goes * here. */ + /* dcache set/way operation pending */ + int last_pcpu; + cpumask_t require_dcache_flush; + /* IO related fields */ struct { bool sign_extend; /* for byte/halfword loads */ diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 7acf3ea..ea5b282 100644 --- a/arch/arm/kvm/Makefile +++
[PATCH v2 10/14] KVM: ARM: User space API for getting/setting co-proc registers
The following three ioctls are implemented: - KVM_GET_REG_LIST - KVM_GET_ONE_REG - KVM_SET_ONE_REG Now we have a table for all the cp15 registers, we can drive a generic API. The register IDs carry the following encoding: ARM registers are mapped using the lower 32 bits. The upper 16 of that is the register group type, or coprocessor number: ARM 32-bit CP15 registers have the following id bit patterns: 0x4002 000F zero:1 crn:4 crm:4 opc1:4 opc2:3 ARM 64-bit CP15 registers have the following id bit patterns: 0x4003 000F zero:1 zero:4 crm:4 opc1:4 zero:3 For futureproofing, we need to tell QEMU about the CP15 registers the host lets the guest access. It will need this information to restore a current guest on a future CPU or perhaps a future KVM which allow some of these to be changed. We use a separate table for these, as they're only for the userspace API. Signed-off-by: Rusty Russell rusty.russ...@linaro.org Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- Documentation/virtual/kvm/api.txt | 46 + arch/arm/include/asm/kvm_coproc.h |9 + arch/arm/include/asm/kvm_host.h |4 arch/arm/kvm/coproc.c | 327 + arch/arm/kvm/guest.c |9 + 5 files changed, 391 insertions(+), 4 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index fd1c1bc..c7eb72b 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1756,6 +1756,13 @@ is the register group type, or coprocessor number: ARM core registers have the following id bit patterns: 0x4002 0010 index into the kvm_regs struct:16 +ARM 32-bit CP15 registers have the following id bit patterns: + 0x4002 000F zero:1 crn:4 crm:4 opc1:4 opc2:3 + +ARM 64-bit CP15 registers have the following id bit patterns: + 0x4003 000F zero:1 zero:4 crm:4 opc1:4 zero:3 + + 4.69 KVM_GET_ONE_REG Capability: KVM_CAP_ONE_REG @@ -2048,6 +2055,45 @@ This ioctl returns the guest registers that are supported for the KVM_GET_ONE_REG/KVM_SET_ONE_REG calls. +4.77 KVM_ARM_VCPU_INIT + +Capability: basic +Architectures: arm +Type: vcpu ioctl +Parameters: struct struct kvm_vcpu_init (in) +Returns: 0 on success; -1 on error +Errors: + EINVAL: the target is unknown, or the combination of features is invalid. + ENOENT: a features bit specified is unknown. + +This tells KVM what type of CPU to present to the guest, and what +optional features it should have. This will cause a reset of the cpu +registers to their initial values. If this is not called, KVM_RUN will +return ENOEXEC for that vcpu. + +Note that because some registers reflect machine topology, all vcpus +should be created before this ioctl is invoked. + +4.78 KVM_GET_REG_LIST + +Capability: basic +Architectures: arm +Type: vcpu ioctl +Parameters: struct kvm_reg_list (in/out) +Returns: 0 on success; -1 on error +Errors: + E2BIG: the reg index list is too big to fit in the array specified by + the user (the number required will be written into n). + +struct kvm_reg_list { + __u64 n; /* number of registers in reg[] */ + __u64 reg[0]; +}; + +This ioctl returns the guest registers that are supported for the +KVM_GET_ONE_REG/KVM_SET_ONE_REG calls. + + 5. The kvm_run structure diff --git a/arch/arm/include/asm/kvm_coproc.h b/arch/arm/include/asm/kvm_coproc.h index bd1ace0..4917c2f 100644 --- a/arch/arm/include/asm/kvm_coproc.h +++ b/arch/arm/include/asm/kvm_coproc.h @@ -34,5 +34,14 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); + +unsigned long kvm_arm_num_guest_msrs(struct kvm_vcpu *vcpu); +int kvm_arm_copy_msrindices(struct kvm_vcpu *vcpu, u64 __user *uindices); void kvm_coproc_table_init(void); + +struct kvm_one_reg; +int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); +int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); +int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); +unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu); #endif /* __ARM_KVM_COPROC_H__ */ diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 5ad798b..914f7eb 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -27,6 +27,7 @@ #define KVM_MEMORY_SLOTS 32 #define KVM_PRIVATE_MEM_SLOTS 4 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 +#define KVM_HAVE_ONE_REG #define KVM_VCPU_MAX_FEATURES 0 @@ -134,6 +135,9 @@ int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end); void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
[PATCH v2 11/14] KVM: ARM: Demux CCSIDR in the userspace API
The Cache Size Selection Register (CSSELR) selects the current Cache Size ID Register (CCSIDR). You write which cache you are interested in to CSSELR, and read the information out of CCSIDR. Which cache numbers are valid is known by reading the Cache Level ID Register (CLIDR). To export this state to userspace, we add a KVM_REG_ARM_DEMUX numberspace (17), which uses 8 bits to represent which register is being demultiplexed (0 for CCSIDR), and the lower 8 bits to represent this demultiplexing (in our case, the CSSELR value, which is 4 bits). Signed-off-by: Rusty Russell rusty.russ...@linaro.org --- Documentation/virtual/kvm/api.txt |2 arch/arm/include/asm/kvm.h|9 ++ arch/arm/kvm/coproc.c | 163 - 3 files changed, 171 insertions(+), 3 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index c7eb72b..74223f3 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1762,6 +1762,8 @@ ARM 32-bit CP15 registers have the following id bit patterns: ARM 64-bit CP15 registers have the following id bit patterns: 0x4003 000F zero:1 zero:4 crm:4 opc1:4 zero:3 +ARM CCSIDR registers are demultiplexed by CSSELR value: + 0x4002 0011 00 csselr:8 4.69 KVM_GET_ONE_REG diff --git a/arch/arm/include/asm/kvm.h b/arch/arm/include/asm/kvm.h index eb5f528..0ab12fd 100644 --- a/arch/arm/include/asm/kvm.h +++ b/arch/arm/include/asm/kvm.h @@ -87,6 +87,15 @@ struct kvm_reg_list { #define KVM_REG_ARM_CORE (0x0010 KVM_REG_ARM_COPROC_SHIFT) #define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4) +/* Some registers need more space to represent values. */ +#define KVM_REG_ARM_DEMUX (0x0011 KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_DEMUX_ID_MASK 0xFF00 +#define KVM_REG_ARM_DEMUX_ID_SHIFT 8 +#define KVM_REG_ARM_DEMUX_ID_CCSIDR(0x00 KVM_REG_ARM_DEMUX_ID_SHIFT) +#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00FF +#define KVM_REG_ARM_DEMUX_VAL_SHIFT0 + + /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 #define KVM_ARM_IRQ_TYPE_MASK 0xff diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index 3998f46..7addf62 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c @@ -35,6 +35,12 @@ * Co-processor emulation */ +/* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */ +static u32 cache_levels; + +/* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ +#define CSSELR_MAX 12 + int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run) { kvm_inject_undefined(vcpu); @@ -548,11 +554,112 @@ static int set_invariant_cp15(u64 id, void __user *uaddr) return 0; } +static bool is_valid_cache(u32 val) +{ + u32 level, ctype; + + if (val = CSSELR_MAX) + return -ENOENT; + + /* Bottom bit is Instruction or Data bit. Next 3 bits are level. */ +level = (val 1); +ctype = (cache_levels (level * 3)) 7; + + switch (ctype) { + case 0: /* No cache */ + return false; + case 1: /* Instruction cache only */ + return (val 1); + case 2: /* Data cache only */ + case 4: /* Unified cache */ + return !(val 1); + case 3: /* Separate instruction and data caches */ + return true; + default: /* Reserved: we can't know instruction or data. */ + return false; + } +} + +/* Which cache CCSIDR represents depends on CSSELR value. */ +static u32 get_ccsidr(u32 csselr) +{ + u32 ccsidr; + + /* Make sure noone else changes CSSELR during this! */ + local_irq_disable(); + /* Put value into CSSELR */ + asm volatile(mcr p15, 2, %0, c0, c0, 0 : : r (csselr)); + /* Read result out of CCSIDR */ + asm volatile(mrc p15, 1, %0, c0, c0, 0 : =r (ccsidr)); + local_irq_enable(); + + return ccsidr; +} + +static int demux_c15_get(u64 id, void __user *uaddr) +{ + u32 val; + u32 __user *uval = uaddr; + + /* Fail if we have unknown bits set. */ + if (id ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK + | ((1 KVM_REG_ARM_COPROC_SHIFT)-1))) + return -ENOENT; + + switch (id KVM_REG_ARM_DEMUX_ID_MASK) { + case KVM_REG_ARM_DEMUX_ID_CCSIDR: + if (KVM_REG_SIZE(id) != 4) + return -ENOENT; + val = (id KVM_REG_ARM_DEMUX_VAL_MASK) +KVM_REG_ARM_DEMUX_VAL_SHIFT; + if (!is_valid_cache(val)) + return -ENOENT; + + return put_user(get_ccsidr(val), uval); + default: + return -ENOENT; + } +} + +static int
[PATCH v2 12/14] KVM: ARM: VFP userspace interface
From: Rusty Russell rusty.russ...@linaro.org We use space #18 for floating point regs. Signed-off-by: Rusty Russell ru...@rustcorp.com.au Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- Documentation/virtual/kvm/api.txt |6 + arch/arm/include/asm/kvm.h| 12 ++ arch/arm/kvm/coproc.c | 178 + 3 files changed, 196 insertions(+) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 74223f3..7695425 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1765,6 +1765,12 @@ ARM 64-bit CP15 registers have the following id bit patterns: ARM CCSIDR registers are demultiplexed by CSSELR value: 0x4002 0011 00 csselr:8 +ARM 32-bit VFP control registers have the following id bit patterns: + 0x4002 0012 1 selector:3 + +ARM 64-bit FP registers have the following id bit patterns: + 0x4002 0012 0 selector:3 + 4.69 KVM_GET_ONE_REG Capability: KVM_CAP_ONE_REG diff --git a/arch/arm/include/asm/kvm.h b/arch/arm/include/asm/kvm.h index 0ab12fd..b6eaf0c 100644 --- a/arch/arm/include/asm/kvm.h +++ b/arch/arm/include/asm/kvm.h @@ -95,6 +95,18 @@ struct kvm_reg_list { #define KVM_REG_ARM_DEMUX_VAL_MASK 0x00FF #define KVM_REG_ARM_DEMUX_VAL_SHIFT0 +/* VFP registers: we could overload CP10 like ARM does, but that's ugly. */ +#define KVM_REG_ARM_VFP(0x0012 KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_VFP_MASK 0x +#define KVM_REG_ARM_VFP_BASE_REG 0x0 +#define KVM_REG_ARM_VFP_FPSID 0x1000 +#define KVM_REG_ARM_VFP_FPSCR 0x1001 +#define KVM_REG_ARM_VFP_MVFR1 0x1006 +#define KVM_REG_ARM_VFP_MVFR0 0x1007 +#define KVM_REG_ARM_VFP_FPEXC 0x1008 +#define KVM_REG_ARM_VFP_FPINST 0x1009 +#define KVM_REG_ARM_VFP_FPINST20x100A + /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index 7addf62..b8bddd7 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c @@ -26,6 +26,8 @@ #include asm/cacheflush.h #include asm/cputype.h #include trace/events/kvm.h +#include asm/vfp.h +#include ../vfp/vfpinstr.h #include trace.h #include coproc.h @@ -652,6 +654,170 @@ static int demux_c15_set(u64 id, void __user *uaddr) } } +#ifdef CONFIG_VFPv3 +static const int vfp_sysregs[] = { KVM_REG_ARM_VFP_FPEXC, + KVM_REG_ARM_VFP_FPSCR, + KVM_REG_ARM_VFP_FPINST, + KVM_REG_ARM_VFP_FPINST2, + KVM_REG_ARM_VFP_MVFR0, + KVM_REG_ARM_VFP_MVFR1, + KVM_REG_ARM_VFP_FPSID }; + +static unsigned int num_fp_regs(void) +{ + if (((fmrx(MVFR0) MVFR0_A_SIMD_MASK) MVFR0_A_SIMD_BIT) == 2) + return 32; + else + return 16; +} + +static unsigned int num_vfp_regs(void) +{ + /* Normal FP regs + control regs. */ + return num_fp_regs() + ARRAY_SIZE(vfp_sysregs); +} + +static int copy_vfp_regids(u64 __user *uindices) +{ + unsigned int i; + const u64 u32reg = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP; + const u64 u64reg = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP; + + for (i = 0; i num_fp_regs(); i++) { + if (put_user((u64reg | KVM_REG_ARM_VFP_BASE_REG) + i, +uindices)) + return -EFAULT; + uindices++; + } + + for (i = 0; i ARRAY_SIZE(vfp_sysregs); i++) { + if (put_user(u32reg | vfp_sysregs[i], uindices)) + return -EFAULT; + uindices++; + } + + return num_vfp_regs(); +} + +static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr) +{ + u32 vfpid = (id KVM_REG_ARM_VFP_MASK); + u32 val; + + /* Fail if we have unknown bits set. */ + if (id ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK + | ((1 KVM_REG_ARM_COPROC_SHIFT)-1))) + return -ENOENT; + + if (vfpid num_fp_regs()) { + if (KVM_REG_SIZE(id) != 8) + return -ENOENT; + return reg_to_user(uaddr, vcpu-arch.vfp_guest.fpregs[vfpid], + id); + } + + /* FP control registers are all 32 bit. */ + if (KVM_REG_SIZE(id) != 4) + return -ENOENT; + + switch (vfpid) { + case KVM_REG_ARM_VFP_FPEXC: + return reg_to_user(uaddr, vcpu-arch.vfp_guest.fpexc, id); + case KVM_REG_ARM_VFP_FPSCR: + return reg_to_user(uaddr, vcpu-arch.vfp_guest.fpscr, id); + case KVM_REG_ARM_VFP_FPINST: + return reg_to_user(uaddr,
[PATCH v2 13/14] KVM: ARM: Handle guest faults in KVM
Handles the guest faults in KVM by mapping in corresponding user pages in the 2nd stage page tables. We invalidate the instruction cache by MVA whenever we map a page to the guest (no, we cannot only do it when we have an iabt because the guest may happily read/write a page before hitting the icache) if the hardware uses VIPT or PIPT. In the latter case, we can invalidate only that physical page. In the first case, all bets are off and we simply must invalidate the whole affair. Not that VIVT icaches are tagged with vmids, and we are out of the woods on that one. Alexander Graf was nice enough to remind us of this massive pain. There is also a subtle bug hidden somewhere, which we currently hide by marking all pages dirty even when the pages are only mapped read-only. The current hypothesis is that marking pages dirty may exercise the IO system and data cache more and therefore we don't see stale data in the guest, but it's purely guesswork. The bug is manifested by seemingly random kernel crashes in guests when the host is under extreme memory pressure and swapping is enabled. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arm.h |9 ++ arch/arm/include/asm/kvm_asm.h |2 + arch/arm/kvm/mmu.c | 145 arch/arm/kvm/trace.h | 28 4 files changed, 183 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 6b8bb51..61d8a26 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -152,11 +152,20 @@ #define HSR_ISS(HSR_IL - 1) #define HSR_ISV_SHIFT (24) #define HSR_ISV(1U HSR_ISV_SHIFT) +#define HSR_FSC(0x3f) +#define HSR_FSC_TYPE (0x3c) +#define HSR_WNR(1 6) #define HSR_CV_SHIFT (24) #define HSR_CV (1U HSR_CV_SHIFT) #define HSR_COND_SHIFT (20) #define HSR_COND (0xfU HSR_COND_SHIFT) +#define FSC_FAULT (0x04) +#define FSC_PERM (0x0c) + +/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ +#define HPFAR_MASK (~0xf) + #define HSR_EC_UNKNOWN (0x00) #define HSR_EC_WFI (0x01) #define HSR_EC_CP15_32 (0x03) diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 47a0e57..6fccdb3 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -71,6 +71,8 @@ extern char __kvm_hyp_vector[]; extern char __kvm_hyp_code_start[]; extern char __kvm_hyp_code_end[]; +extern void __kvm_tlb_flush_vmid(struct kvm *kvm); + extern void __kvm_flush_vm_context(void); extern void __kvm_tlb_flush_vmid(struct kvm *kvm); diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 3f835a2..15ca732 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -21,9 +21,11 @@ #include linux/io.h #include asm/idmap.h #include asm/pgalloc.h +#include asm/cacheflush.h #include asm/kvm_arm.h #include asm/kvm_mmu.h #include asm/kvm_asm.h +#include asm/kvm_emulate.h #include asm/mach/map.h #include trace/events/kvm.h @@ -491,9 +493,150 @@ out: return ret; } +static void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) +{ + /* +* If we are going to insert an instruction page and the icache is +* either VIPT or PIPT, there is a potential problem where the host +* (or another VM) may have used this page at the same virtual address +* as this guest, and we read incorrect data from the icache. If +* we're using a PIPT cache, we can invalidate just that page, but if +* we are using a VIPT cache we need to invalidate the entire icache - +* damn shame - as written in the ARM ARM (DDI 0406C - Page B3-1384) +*/ + if (icache_is_pipt()) { + unsigned long hva = gfn_to_hva(kvm, gfn); + __cpuc_coherent_user_range(hva, hva + PAGE_SIZE); + } else if (!icache_is_vivt_asid_tagged()) { + /* any kind of VIPT cache */ + __flush_icache_all(); + } +} + +static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, + gfn_t gfn, struct kvm_memory_slot *memslot, + bool is_iabt, unsigned long fault_status) +{ + pte_t new_pte; + pfn_t pfn; + int ret; + bool write_fault, writable; + unsigned long mmu_seq; + struct kvm_mmu_memory_cache *memcache = vcpu-arch.mmu_page_cache; + + if (is_iabt) + write_fault = false; + else if ((vcpu-arch.hsr HSR_ISV) !(vcpu-arch.hsr HSR_WNR)) + write_fault = false; + else + write_fault = true; + + if (fault_status == FSC_PERM !write_fault) { + kvm_err(Unexpected L2 read permission error\n); + return -EFAULT; + } + + /* We need minimum
[PATCH v2 14/14] KVM: ARM: Handle I/O aborts
When the guest accesses I/O memory this will create data abort exceptions and they are handled by decoding the HSR information (physical address, read/write, length, register) and forwarding reads and writes to QEMU which performs the device emulation. Certain classes of load/store operations do not support the syndrome information provided in the HSR and we therefore must be able to fetch the offending instruction from guest memory and decode it manually. We only support instruction decoding for valid reasonable MMIO operations where trapping them do not provide sufficient information in the HSR (no 16-bit Thumb instructions provide register writeback that we care about). The following instruciton types are NOT supported for MMIO operations despite the HSR not containing decode info: - any Load/Store multiple - any load/store exclusive - any load/store dual - anything with the PC as the dest register This requires changing the general flow somewhat since new calls to run the VCPU must check if there's a pending MMIO load and perform the write after userspace has made the data available. Rusty Russell fixed a horrible race pointed out by Ben Herrenschmidt: (1) Guest complicated mmio instruction traps. (2) The hardware doesn't tell us enough, so we need to read the actual instruction which was being exectuted. (3) KVM maps the instruction virtual address to a physical address. (4) The guest (SMP) swaps out that page, and fills it with something else. (5) We read the physical address, but now that's the wrong thing. Signed-off-by: Rusty Russell rusty.russ...@linaro.org Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arm.h |3 arch/arm/include/asm/kvm_asm.h |2 arch/arm/include/asm/kvm_emulate.h | 22 ++ arch/arm/include/asm/kvm_host.h|3 arch/arm/include/asm/kvm_mmu.h |1 arch/arm/kvm/arm.c | 14 + arch/arm/kvm/emulate.c | 444 arch/arm/kvm/interrupts.S | 41 +++ arch/arm/kvm/mmu.c | 266 +- arch/arm/kvm/trace.h | 21 ++ 10 files changed, 814 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 61d8a26..4f1bb01 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -152,8 +152,11 @@ #define HSR_ISS(HSR_IL - 1) #define HSR_ISV_SHIFT (24) #define HSR_ISV(1U HSR_ISV_SHIFT) +#define HSR_SRT_SHIFT (16) +#define HSR_SRT_MASK (0xf HSR_SRT_SHIFT) #define HSR_FSC(0x3f) #define HSR_FSC_TYPE (0x3c) +#define HSR_SSE(1 21) #define HSR_WNR(1 6) #define HSR_CV_SHIFT (24) #define HSR_CV (1U HSR_CV_SHIFT) diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 6fccdb3..99c0faf 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -77,6 +77,8 @@ extern void __kvm_flush_vm_context(void); extern void __kvm_tlb_flush_vmid(struct kvm *kvm); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); + +extern u64 __kvm_va_to_pa(struct kvm_vcpu *vcpu, u32 va, bool priv); #endif #endif /* __ARM_KVM_ASM_H__ */ diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index 10e6bea..c954ff7 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -24,8 +24,30 @@ u32 *vcpu_reg_mode(struct kvm_vcpu *vcpu, u8 reg_num, u32 cpsr); u32 *vcpu_spsr_mode(struct kvm_vcpu *vcpu, u32 cpsr); +/* + * The in-kernel MMIO emulation code wants to use a copy of run-mmio, + * which is an anonymous type. Use our own type instead. + */ +struct kvm_exit_mmio { + phys_addr_t phys_addr; + u8 data[8]; + u32 len; + boolis_write; +}; + +static inline void kvm_prepare_mmio(struct kvm_run *run, + struct kvm_exit_mmio *mmio) +{ + run-mmio.phys_addr = mmio-phys_addr; + run-mmio.len = mmio-len; + run-mmio.is_write = mmio-is_write; + memcpy(run-mmio.data, mmio-data, mmio-len); + run-exit_reason= KVM_EXIT_MMIO; +} int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_emulate_mmio_ls(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, + unsigned long instr, struct kvm_exit_mmio *mmio); void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr); void kvm_inject_undefined(struct kvm_vcpu *vcpu); void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 914f7eb..e4b5352 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -95,6 +95,9 @@ struct kvm_vcpu_arch { int last_pcpu; cpumask_t
[PATCH v2 00/10] KVM/ARM vGIC support
The following series implements support for the virtual generic interrupt controller architecture for KVM/ARM. This is an unmodified repost of the previously submitted series. This patch series can also be pulled from: git://github.com/virtualopensystems/linux-kvm-arm.git branch: kvm-arm-v12-vgic --- Marc Zyngier (10): ARM: KVM: Keep track of currently running vcpus ARM: KVM: Initial VGIC infrastructure support ARM: KVM: Initial VGIC MMIO support code ARM: KVM: VGIC distributor handling ARM: KVM: VGIC virtual CPU interface management ARM: KVM: VGIC interrupt injection ARM: KVM: VGIC control interface world switch ARM: KVM: VGIC initialisation code ARM: KVM: vgic: reduce the number of vcpu kick ARM: KVM: Add VGIC configuration option arch/arm/include/asm/kvm_arm.h | 12 arch/arm/include/asm/kvm_host.h | 16 + arch/arm/include/asm/kvm_vgic.h | 301 +++ arch/arm/kernel/asm-offsets.c | 12 arch/arm/kvm/Kconfig|7 arch/arm/kvm/Makefile |1 arch/arm/kvm/arm.c | 101 +++- arch/arm/kvm/interrupts.S |4 arch/arm/kvm/interrupts_head.S | 68 ++ arch/arm/kvm/mmu.c |3 arch/arm/kvm/vgic.c | 1115 +++ virt/kvm/kvm_main.c |5 12 files changed, 1640 insertions(+), 5 deletions(-) create mode 100644 arch/arm/include/asm/kvm_vgic.h create mode 100644 arch/arm/kvm/vgic.c -- -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 01/10] ARM: KVM: Keep track of currently running vcpus
From: Marc Zyngier marc.zyng...@arm.com When an interrupt occurs for the guest, it is sometimes necessary to find out which vcpu was running at that point. Keep track of which vcpu is being tun in kvm_arch_vcpu_ioctl_run(), and allow the data to be retrived using either: - kvm_arm_get_running_vcpu(): returns the vcpu running at this point on the current CPU. Can only be used in a non-preemptable context. - kvm_arm_get_running_vcpus(): returns the per-CPU variable holding the the running vcpus, useable for per-CPU interrupts. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_host.h |9 + arch/arm/kvm/arm.c | 30 ++ 2 files changed, 39 insertions(+) diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index e4b5352..69a8680 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -151,4 +151,13 @@ static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) { return 0; } + +struct kvm_vcpu *kvm_arm_get_running_vcpu(void); +struct kvm_vcpu __percpu **kvm_get_running_vcpus(void); + +int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); +unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu); +struct kvm_one_reg; +int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); +int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); #endif /* __ARM_KVM_HOST_H__ */ diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 50e9585..8764dd0 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -53,11 +53,38 @@ static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); static struct vfp_hard_struct __percpu *kvm_host_vfp_state; static unsigned long hyp_default_vectors; +/* Per-CPU variable containing the currently running vcpu. */ +static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu); + /* The VMID used in the VTTBR */ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); static u8 kvm_next_vmid; static DEFINE_SPINLOCK(kvm_vmid_lock); +static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) +{ + BUG_ON(preemptible()); + __get_cpu_var(kvm_arm_running_vcpu) = vcpu; +} + +/** + * kvm_arm_get_running_vcpu - get the vcpu running on the current CPU. + * Must be called from non-preemptible context + */ +struct kvm_vcpu *kvm_arm_get_running_vcpu(void) +{ + BUG_ON(preemptible()); + return __get_cpu_var(kvm_arm_running_vcpu); +} + +/** + * kvm_arm_get_running_vcpus - get the per-CPU array on currently running vcpus. + */ +struct kvm_vcpu __percpu **kvm_get_running_vcpus(void) +{ + return kvm_arm_running_vcpu; +} + int kvm_arch_hardware_enable(void *garbage) { return 0; @@ -296,10 +323,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) cpumask_clear_cpu(cpu, vcpu-arch.require_dcache_flush); flush_cache_all(); /* We'd really want v7_flush_dcache_all() */ } + + kvm_arm_set_running_vcpu(vcpu); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { + kvm_arm_set_running_vcpu(NULL); } int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 02/10] ARM: KVM: Initial VGIC infrastructure support
From: Marc Zyngier marc.zyng...@arm.com Wire the basic framework code for VGIC support. Nothing to enable yet. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_host.h |7 arch/arm/include/asm/kvm_vgic.h | 65 +++ arch/arm/kvm/arm.c | 21 - arch/arm/kvm/interrupts.S |4 ++ arch/arm/kvm/mmu.c |3 ++ virt/kvm/kvm_main.c |5 ++- 6 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 arch/arm/include/asm/kvm_vgic.h diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 69a8680..d65faea 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -22,6 +22,7 @@ #include asm/kvm.h #include asm/kvm_asm.h #include asm/fpstate.h +#include asm/kvm_vgic.h #define KVM_MAX_VCPUS NR_CPUS #define KVM_MEMORY_SLOTS 32 @@ -52,6 +53,9 @@ struct kvm_arch { /* VTTBR value associated with above pgd and vmid */ u64vttbr; + + /* Interrupt controller */ + struct vgic_distvgic; }; #define KVM_NR_MEM_OBJS 40 @@ -87,6 +91,9 @@ struct kvm_vcpu_arch { struct vfp_hard_struct vfp_guest; struct vfp_hard_struct *vfp_host; + /* VGIC state */ + struct vgic_cpu vgic_cpu; + /* * Anything that is not used directly from assembly code goes * here. diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h new file mode 100644 index 000..e1fd530 --- /dev/null +++ b/arch/arm/include/asm/kvm_vgic.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier marc.zyng...@arm.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_KVM_VGIC_H +#define __ASM_ARM_KVM_VGIC_H + +struct vgic_dist { +}; + +struct vgic_cpu { +}; + +struct kvm; +struct kvm_vcpu; +struct kvm_run; +struct kvm_exit_mmio; + +#ifndef CONFIG_KVM_ARM_VGIC +static inline int kvm_vgic_hyp_init(void) +{ + return 0; +} + +static inline int kvm_vgic_init(struct kvm *kvm) +{ + return 0; +} + +static inline void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) {} +static inline void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu) {} +static inline void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu) {} + +static inline int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) +{ + return 0; +} + +static inline bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_exit_mmio *mmio) +{ + return false; +} + +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + return 0; +} +#endif + +#endif diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 8764dd0..cf13340 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -183,6 +183,9 @@ int kvm_dev_ioctl_check_extension(long ext) { int r; switch (ext) { +#ifdef CONFIG_KVM_ARM_VGIC + case KVM_CAP_IRQCHIP: +#endif case KVM_CAP_USER_MEMORY: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: case KVM_CAP_ONE_REG: @@ -301,6 +304,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) { /* Force users to call KVM_ARM_VCPU_INIT */ vcpu-arch.target = -1; + + /* Set up VGIC */ + kvm_vgic_vcpu_init(vcpu); + return 0; } @@ -360,7 +367,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, */ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) { - return !!v-arch.irq_lines; + return !!v-arch.irq_lines || kvm_vgic_vcpu_pending_irq(v); } int kvm_arch_vcpu_in_guest_mode(struct kvm_vcpu *v) @@ -629,6 +636,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) update_vttbr(vcpu-kvm); + kvm_vgic_sync_to_cpu(vcpu); + local_irq_disable(); /* @@ -641,6 +650,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) if (ret = 0 || need_new_vmid_gen(vcpu-kvm)) { local_irq_enable(); + kvm_vgic_sync_from_cpu(vcpu); continue; } @@ -679,6 +689,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
[PATCH v2 03/10] ARM: KVM: Initial VGIC MMIO support code
From: Marc Zyngier marc.zyng...@arm.com Wire the initial in-kernel MMIO support code for the VGIC, used for the distributor emulation. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h |6 +- arch/arm/kvm/Makefile |1 arch/arm/kvm/vgic.c | 138 +++ 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 arch/arm/kvm/vgic.c diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index e1fd530..a87ec6c 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -30,7 +30,11 @@ struct kvm_vcpu; struct kvm_run; struct kvm_exit_mmio; -#ifndef CONFIG_KVM_ARM_VGIC +#ifdef CONFIG_KVM_ARM_VGIC +bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_exit_mmio *mmio); + +#else static inline int kvm_vgic_hyp_init(void) { return 0; diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index ea5b282..89608c0 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += $(addprefix ../../../virt/kvm/, kvm_main.o coalesc obj-$(CONFIG_KVM_ARM_HOST) += arm.o guest.o mmu.o emulate.o reset.o obj-$(CONFIG_KVM_ARM_HOST) += coproc.o coproc_a15.o +obj-$(CONFIG_KVM_ARM_VGIC) += vgic.o diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c new file mode 100644 index 000..26ada3b --- /dev/null +++ b/arch/arm/kvm/vgic.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier marc.zyng...@arm.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include linux/kvm.h +#include linux/kvm_host.h +#include linux/interrupt.h +#include linux/io.h +#include asm/kvm_emulate.h + +#define ACCESS_READ_VALUE (1 0) +#define ACCESS_READ_RAZ(0 0) +#define ACCESS_READ_MASK(x)((x) (1 0)) +#define ACCESS_WRITE_IGNORED (0 1) +#define ACCESS_WRITE_SETBIT(1 1) +#define ACCESS_WRITE_CLEARBIT (2 1) +#define ACCESS_WRITE_VALUE (3 1) +#define ACCESS_WRITE_MASK(x) ((x) (3 1)) + +/** + * vgic_reg_access - access vgic register + * @mmio: pointer to the data describing the mmio access + * @reg:pointer to the virtual backing of the vgic distributor struct + * @offset: least significant 2 bits used for word offset + * @mode: ACCESS_ mode (see defines above) + * + * Helper to make vgic register access easier using one of the access + * modes defined for vgic register access + * (read,raz,write-ignored,setbit,clearbit,write) + */ +static void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg, + u32 offset, int mode) +{ + int word_offset = offset 3; + int shift = word_offset * 8; + u32 mask; + u32 regval; + + /* +* Any alignment fault should have been delivered to the guest +* directly (ARM ARM B3.12.7 Prioritization of aborts). +*/ + + mask = (~0U) (word_offset * 8); + if (reg) + regval = *reg; + else { + BUG_ON(mode != (ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED)); + regval = 0; + } + + if (mmio-is_write) { + u32 data = (*((u32 *)mmio-data) mask) shift; + switch (ACCESS_WRITE_MASK(mode)) { + case ACCESS_WRITE_IGNORED: + return; + + case ACCESS_WRITE_SETBIT: + regval |= data; + break; + + case ACCESS_WRITE_CLEARBIT: + regval = ~data; + break; + + case ACCESS_WRITE_VALUE: + regval = (regval ~(mask shift)) | data; + break; + } + *reg = regval; + } else { + switch (ACCESS_READ_MASK(mode)) { + case ACCESS_READ_RAZ: + regval = 0; + /* fall through */ + + case ACCESS_READ_VALUE: + *((u32 *)mmio-data) = (regval shift) mask; + } + } +} + +/* All this should be handled by kvm_bus_io_*()... FIXME!!! */ +struct mmio_range { + unsigned long base; + unsigned long len; + bool
[PATCH v2 04/10] ARM: KVM: VGIC distributor handling
From: Marc Zyngier marc.zyng...@arm.com Add the GIC distributor emulation code. A number of the GIC features are simply ignored as they are not required to boot a Linux guest. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h | 170 ++ arch/arm/kvm/vgic.c | 475 +++ 2 files changed, 644 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index a87ec6c..a82699f 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -19,7 +19,177 @@ #ifndef __ASM_ARM_KVM_VGIC_H #define __ASM_ARM_KVM_VGIC_H +#include linux/kernel.h +#include linux/kvm.h +#include linux/kvm_host.h +#include linux/irqreturn.h +#include linux/spinlock.h +#include linux/types.h + +#define VGIC_NR_IRQS 128 +#define VGIC_NR_SHARED_IRQS(VGIC_NR_IRQS - 32) +#define VGIC_MAX_CPUS NR_CPUS + +/* Sanity checks... */ +#if (VGIC_MAX_CPUS 8) +#error Invalid number of CPU interfaces +#endif + +#if (VGIC_NR_IRQS 31) +#error VGIC_NR_IRQS must be a multiple of 32 +#endif + +#if (VGIC_NR_IRQS 1024) +#error VGIC_NR_IRQS must be = 1024 +#endif + +/* + * The GIC distributor registers describing interrupts have two parts: + * - 32 per-CPU interrupts (SGI + PPI) + * - a bunch of shared interrups (SPI) + */ +struct vgic_bitmap { + union { + u32 reg[1]; + unsigned long reg_ul[0]; + } percpu[VGIC_MAX_CPUS]; + union { + u32 reg[VGIC_NR_SHARED_IRQS / 32]; + unsigned long reg_ul[0]; + } shared; +}; + +static inline u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, + int cpuid, u32 offset) +{ + offset = 2; + BUG_ON(offset (VGIC_NR_IRQS / 32)); + if (!offset) + return x-percpu[cpuid].reg; + else + return x-shared.reg + offset - 1; +} + +static inline int vgic_bitmap_get_irq_val(struct vgic_bitmap *x, +int cpuid, int irq) +{ + if (irq 32) + return test_bit(irq, x-percpu[cpuid].reg_ul); + + return test_bit(irq - 32, x-shared.reg_ul); +} + +static inline void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, + int cpuid, int irq, int val) +{ + unsigned long *reg; + + if (irq 32) + reg = x-percpu[cpuid].reg_ul; + else { + reg = x-shared.reg_ul; + irq -= 32; + } + + if (val) + set_bit(irq, reg); + else + clear_bit(irq, reg); +} + +static inline unsigned long *vgic_bitmap_get_cpu_map(struct vgic_bitmap *x, +int cpuid) +{ + if (unlikely(cpuid = VGIC_MAX_CPUS)) + return NULL; + return x-percpu[cpuid].reg_ul; +} + +static inline unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x) +{ + return x-shared.reg_ul; +} + +struct vgic_bytemap { + union { + u32 reg[8]; + unsigned long reg_ul[0]; + } percpu[VGIC_MAX_CPUS]; + union { + u32 reg[VGIC_NR_SHARED_IRQS / 4]; + unsigned long reg_ul[0]; + } shared; +}; + +static inline u32 *vgic_bytemap_get_reg(struct vgic_bytemap *x, + int cpuid, u32 offset) +{ + offset = 2; + BUG_ON(offset (VGIC_NR_IRQS / 4)); + if (offset 4) + return x-percpu[cpuid].reg + offset; + else + return x-shared.reg + offset - 8; +} + +static inline int vgic_bytemap_get_irq_val(struct vgic_bytemap *x, + int cpuid, int irq) +{ + u32 *reg, shift; + shift = (irq 3) * 8; + reg = vgic_bytemap_get_reg(x, cpuid, irq); + return (*reg shift) 0xff; +} + +static inline void vgic_bytemap_set_irq_val(struct vgic_bytemap *x, + int cpuid, int irq, int val) +{ + u32 *reg, shift; + shift = (irq 3) * 8; + reg = vgic_bytemap_get_reg(x, cpuid, irq); + *reg = ~(0xff shift); + *reg |= (val 0xff) shift; +} + struct vgic_dist { +#ifdef CONFIG_KVM_ARM_VGIC + spinlock_t lock; + + /* Virtual control interface mapping */ + void __iomem*vctrl_base; + + /* Distributor mapping in the guest */ + unsigned long vgic_dist_base; + unsigned long vgic_dist_size; + + /* Distributor enabled */ + u32 enabled; + + /* Interrupt enabled (one bit per IRQ) */ + struct vgic_bitmap irq_enabled; + + /* Interrupt 'pin' level */ + struct vgic_bitmap irq_state; + + /* Level-triggered interrupt in progress */ +
[PATCH v2 05/10] ARM: KVM: VGIC virtual CPU interface management
From: Marc Zyngier marc.zyng...@arm.com Add VGIC virtual CPU interface code, picking pending interrupts from the distributor and stashing them in the VGIC control interface list registers. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h | 41 +++ arch/arm/kvm/vgic.c | 224 +++ 2 files changed, 264 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index a82699f..bb67076 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -193,17 +193,58 @@ struct vgic_dist { }; struct vgic_cpu { +#ifdef CONFIG_KVM_ARM_VGIC + /* per IRQ to LR mapping */ + u8 vgic_irq_lr_map[VGIC_NR_IRQS]; + + /* Pending interrupts on this VCPU */ + DECLARE_BITMAP( pending, VGIC_NR_IRQS); + + /* Bitmap of used/free list registers */ + DECLARE_BITMAP( lr_used, 64); + + /* Number of list registers on this CPU */ + int nr_lr; + + /* CPU vif control registers for world switch */ + u32 vgic_hcr; + u32 vgic_vmcr; + u32 vgic_misr; /* Saved only */ + u32 vgic_eisr[2]; /* Saved only */ + u32 vgic_elrsr[2]; /* Saved only */ + u32 vgic_apr; + u32 vgic_lr[64];/* A15 has only 4... */ +#endif }; +#define VGIC_HCR_EN(1 0) +#define VGIC_HCR_UIE (1 1) + +#define VGIC_LR_VIRTUALID (0x3ff 0) +#define VGIC_LR_PHYSID_CPUID (7 10) +#define VGIC_LR_STATE (3 28) +#define VGIC_LR_PENDING_BIT(1 28) +#define VGIC_LR_ACTIVE_BIT (1 29) +#define VGIC_LR_EOI(1 19) + +#define VGIC_MISR_EOI (1 0) +#define VGIC_MISR_U(1 1) + +#define LR_EMPTY 0xff + struct kvm; struct kvm_vcpu; struct kvm_run; struct kvm_exit_mmio; #ifdef CONFIG_KVM_ARM_VGIC +void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu); +void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu); +int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, struct kvm_exit_mmio *mmio); +#define irqchip_in_kernel(k) (!!((k)-arch.vgic.vctrl_base)) #else static inline int kvm_vgic_hyp_init(void) { diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index a870596..2b90785 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -584,7 +584,25 @@ static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg) static int compute_pending_for_cpu(struct kvm_vcpu *vcpu) { - return 0; + struct vgic_dist *dist = vcpu-kvm-arch.vgic; + unsigned long *pending, *enabled, *pend; + int vcpu_id; + + vcpu_id = vcpu-vcpu_id; + pend = vcpu-arch.vgic_cpu.pending; + + pending = vgic_bitmap_get_cpu_map(dist-irq_state, vcpu_id); + enabled = vgic_bitmap_get_cpu_map(dist-irq_enabled, vcpu_id); + bitmap_and(pend, pending, enabled, 32); + + pending = vgic_bitmap_get_shared_map(dist-irq_state); + enabled = vgic_bitmap_get_shared_map(dist-irq_enabled); + bitmap_and(pend + 1, pending, enabled, VGIC_NR_SHARED_IRQS); + bitmap_and(pend + 1, pend + 1, + vgic_bitmap_get_shared_map(dist-irq_spi_target[vcpu_id]), + VGIC_NR_SHARED_IRQS); + + return (find_first_bit(pend, VGIC_NR_IRQS) VGIC_NR_IRQS); } /* @@ -609,3 +627,207 @@ static void vgic_update_state(struct kvm *kvm) } } } + +#define LR_PHYSID(lr) (((lr) VGIC_LR_PHYSID_CPUID) 10) +#define MK_LR_PEND(src, irq) (VGIC_LR_PENDING_BIT | ((src) 10) | (irq)) +/* + * Queue an interrupt to a CPU virtual interface. Return true on success, + * or false if it wasn't possible to queue it. + */ +static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) +{ + struct vgic_cpu *vgic_cpu = vcpu-arch.vgic_cpu; + struct vgic_dist *dist = vcpu-kvm-arch.vgic; + int lr, is_level; + + /* Sanitize the input... */ + BUG_ON(sgi_source_id ~7); + BUG_ON(sgi_source_id irq 15); + BUG_ON(irq = VGIC_NR_IRQS); + + kvm_debug(Queue IRQ%d\n, irq); + + lr = vgic_cpu-vgic_irq_lr_map[irq]; + is_level = !vgic_irq_is_edge(dist, irq); + + /* Do we have an active interrupt for the same CPUID? */ + if (lr != LR_EMPTY + (LR_PHYSID(vgic_cpu-vgic_lr[lr]) == sgi_source_id)) { + kvm_debug(LR%d piggyback for IRQ%d %x\n, lr, irq, vgic_cpu-vgic_lr[lr]); + BUG_ON(!test_bit(lr, vgic_cpu-lr_used)); + vgic_cpu-vgic_lr[lr] |= VGIC_LR_PENDING_BIT; + if (is_level) + vgic_cpu-vgic_lr[lr] |= VGIC_LR_EOI; + return true; + } + + /* Try to use
[PATCH v2 06/10] ARM: KVM: VGIC interrupt injection
From: Marc Zyngier marc.zyng...@arm.com Plug the interrupt injection code. Interrupts can now be generated from user space. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h |8 arch/arm/kvm/arm.c | 36 ++ arch/arm/kvm/vgic.c | 77 +++ 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index bb67076..9740f1f 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -240,6 +240,8 @@ struct kvm_exit_mmio; #ifdef CONFIG_KVM_ARM_VGIC void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu); void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu); +int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, + bool level); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, struct kvm_exit_mmio *mmio); @@ -260,6 +262,12 @@ static inline void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) {} static inline void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu) {} static inline void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu) {} +static inline int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, + const struct kvm_irq_level *irq) +{ + return 0; +} + static inline int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) { return 0; diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index cf13340..be593220 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -758,10 +758,31 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level) switch (irq_type) { case KVM_ARM_IRQ_TYPE_CPU: + if (irqchip_in_kernel(kvm)) + return -ENXIO; + if (irq_num KVM_ARM_IRQ_CPU_FIQ) return -EINVAL; return vcpu_interrupt_line(vcpu, irq_num, level); +#ifdef CONFIG_KVM_ARM_VGIC + case KVM_ARM_IRQ_TYPE_PPI: + if (!irqchip_in_kernel(kvm)) + return -ENXIO; + + if (irq_num 16 || irq_num 31) + return -EINVAL; + + return kvm_vgic_inject_irq(kvm, vcpu-vcpu_id, irq_num, level); + case KVM_ARM_IRQ_TYPE_SPI: + if (!irqchip_in_kernel(kvm)) + return -ENXIO; + + if (irq_num 32 || irq_num KVM_ARM_IRQ_GIC_MAX) + return -EINVAL; + + return kvm_vgic_inject_irq(kvm, 0, irq_num, level); +#endif } return -EINVAL; @@ -821,7 +842,20 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { - return -EINVAL; + + switch (ioctl) { +#ifdef CONFIG_KVM_ARM_VGIC + case KVM_CREATE_IRQCHIP: { + struct kvm *kvm = filp-private_data; + if (vgic_present) + return kvm_vgic_init(kvm); + else + return -EINVAL; + } +#endif + default: + return -EINVAL; + } } static void cpu_init_hyp_mode(void *vector) diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index 2b90785..b52d4c2 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -72,6 +72,7 @@ #define ACCESS_WRITE_MASK(x) ((x) (3 1)) static void vgic_update_state(struct kvm *kvm); +static void vgic_kick_vcpus(struct kvm *kvm); static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); static inline int vgic_irq_is_edge(struct vgic_dist *dist, int irq) @@ -539,6 +540,9 @@ bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, struct kvm_exi kvm_prepare_mmio(run, mmio); kvm_handle_mmio_return(vcpu, run); + if (updated_state) + vgic_kick_vcpus(vcpu-kvm); + return true; } @@ -831,3 +835,76 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) return test_bit(vcpu-vcpu_id, dist-irq_pending_on_cpu); } + +static void vgic_kick_vcpus(struct kvm *kvm) +{ + struct kvm_vcpu *vcpu; + int c; + + /* +* We've injected an interrupt, time to find out who deserves +* a good kick... +*/ + kvm_for_each_vcpu(c, vcpu, kvm) { + if (kvm_vgic_vcpu_pending_irq(vcpu)) + kvm_vcpu_kick(vcpu); + } +} + +static bool vgic_update_irq_state(struct kvm *kvm, int cpuid, + unsigned int irq_num, bool level) +{ + struct vgic_dist *dist = kvm-arch.vgic; + struct kvm_vcpu *vcpu; + int is_edge, is_level, state; + int pend, enabled; + + spin_lock(dist-lock); + +
[PATCH v2 07/10] ARM: KVM: VGIC control interface world switch
From: Marc Zyngier marc.zyng...@arm.com Enable the VGIC control interface to be save-restored on world switch. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arm.h | 12 +++ arch/arm/kernel/asm-offsets.c | 12 +++ arch/arm/kvm/interrupts_head.S | 68 3 files changed, 92 insertions(+) diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 4f1bb01..e1e39d6 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -188,4 +188,16 @@ #define HSR_EC_DABT(0x24) #define HSR_EC_DABT_HYP(0x25) +/* GICH offsets */ +#define GICH_HCR 0x0 +#define GICH_VTR 0x4 +#define GICH_VMCR 0x8 +#define GICH_MISR 0x10 +#define GICH_EISR0 0x20 +#define GICH_EISR1 0x24 +#define GICH_ELRSR00x30 +#define GICH_ELRSR10x34 +#define GICH_APR 0xf0 +#define GICH_LR0 0x100 + #endif /* __ARM_KVM_ARM_H__ */ diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index d020e6aa..1f4a894 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -166,6 +166,18 @@ int main(void) DEFINE(VCPU_HIFAR, offsetof(struct kvm_vcpu, arch.hifar)); DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.hpfar)); DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.hyp_pc)); +#ifdef CONFIG_KVM_ARM_VGIC + DEFINE(VCPU_VGIC_CPU,offsetof(struct kvm_vcpu, arch.vgic_cpu)); + DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); + DEFINE(VGIC_CPU_VMCR,offsetof(struct vgic_cpu, vgic_vmcr)); + DEFINE(VGIC_CPU_MISR,offsetof(struct vgic_cpu, vgic_misr)); + DEFINE(VGIC_CPU_EISR,offsetof(struct vgic_cpu, vgic_eisr)); + DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr)); + DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); + DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); + DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); + DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); +#endif DEFINE(KVM_VTTBR,offsetof(struct kvm, arch.vttbr)); #endif return 0; diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index b29bd62..e44aea6 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -225,6 +225,45 @@ * @vcpup: Register pointing to VCPU struct */ .macro save_vgic_state vcpup +#ifdef CONFIG_KVM_ARM_VGIC + /* Get VGIC VCTRL base into r2 */ + ldr r2, [\vcpup, #VCPU_KVM] + ldr r2, [r2, #KVM_VGIC_VCTRL] + cmp r2, #0 + beq 2f + + /* Compute the address of struct vgic_cpu */ + add r11, \vcpup, #VCPU_VGIC_CPU + + /* Save all interesting registers */ + ldr r3, [r2, #GICH_HCR] + ldr r4, [r2, #GICH_VMCR] + ldr r5, [r2, #GICH_MISR] + ldr r6, [r2, #GICH_EISR0] + ldr r7, [r2, #GICH_EISR1] + ldr r8, [r2, #GICH_ELRSR0] + ldr r9, [r2, #GICH_ELRSR1] + ldr r10, [r2, #GICH_APR] + + str r3, [r11, #VGIC_CPU_HCR] + str r4, [r11, #VGIC_CPU_VMCR] + str r5, [r11, #VGIC_CPU_MISR] + str r6, [r11, #VGIC_CPU_EISR] + str r7, [r11, #(VGIC_CPU_EISR + 4)] + str r8, [r11, #VGIC_CPU_ELRSR] + str r9, [r11, #(VGIC_CPU_ELRSR + 4)] + str r10, [r11, #VGIC_CPU_APR] + + /* Save list registers */ + add r2, r2, #GICH_LR0 + add r3, r11, #VGIC_CPU_LR + ldr r4, [r11, #VGIC_CPU_NR_LR] +1: ldr r6, [r2], #4 + str r6, [r3], #4 + subsr4, r4, #1 + bne 1b +2: +#endif .endm /* @@ -232,6 +271,35 @@ * @vcpup: Register pointing to VCPU struct */ .macro restore_vgic_state vcpup +#ifdef CONFIG_KVM_ARM_VGIC + /* Get VGIC VCTRL base into r2 */ + ldr r2, [\vcpup, #VCPU_KVM] + ldr r2, [r2, #KVM_VGIC_VCTRL] + cmp r2, #0 + beq 2f + + /* Compute the address of struct vgic_cpu */ + add r11, \vcpup, #VCPU_VGIC_CPU + + /* We only restore a minimal set of registers */ + ldr r3, [r11, #VGIC_CPU_HCR] + ldr r4, [r11, #VGIC_CPU_VMCR] + ldr r8, [r11, #VGIC_CPU_APR] + + str r3, [r2, #GICH_HCR] + str r4, [r2, #GICH_VMCR] + str r8, [r2, #GICH_APR] + + /* Restore list registers */ + add r2, r2, #GICH_LR0 + add r3, r11, #VGIC_CPU_LR + ldr r4, [r11, #VGIC_CPU_NR_LR] +1: ldr r6, [r3], #4 + str r6, [r2], #4 + subsr4, r4, #1 + bne 1b +2: +#endif .endm /* Configures the HSTR (Hyp System Trap Register) on entry/return -- To unsubscribe from this list: send the
[PATCH v2 08/10] ARM: KVM: VGIC initialisation code
From: Marc Zyngier marc.zyng...@arm.com Add the init code for the hypervisor, the virtual machine, and the virtual CPUs. An interrupt handler is also wired to allow the VGIC maintenance interrupts, used to deal with level triggered interrupts and LR underflows. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_vgic.h |3 + arch/arm/kvm/arm.c |8 +- arch/arm/kvm/vgic.c | 199 +++ 3 files changed, 208 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h index 9740f1f..c8327f3 100644 --- a/arch/arm/include/asm/kvm_vgic.h +++ b/arch/arm/include/asm/kvm_vgic.h @@ -238,6 +238,9 @@ struct kvm_run; struct kvm_exit_mmio; #ifdef CONFIG_KVM_ARM_VGIC +int kvm_vgic_hyp_init(void); +int kvm_vgic_init(struct kvm *kvm); +void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu); void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index be593220..f88fd18 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -61,6 +61,8 @@ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); static u8 kvm_next_vmid; static DEFINE_SPINLOCK(kvm_vmid_lock); +static bool vgic_present; + static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) { BUG_ON(preemptible()); @@ -185,6 +187,8 @@ int kvm_dev_ioctl_check_extension(long ext) switch (ext) { #ifdef CONFIG_KVM_ARM_VGIC case KVM_CAP_IRQCHIP: + r = vgic_present; + break; #endif case KVM_CAP_USER_MEMORY: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: @@ -992,8 +996,8 @@ static int init_hyp_mode(void) * Init HYP view of VGIC */ err = kvm_vgic_hyp_init(); - if (err) - goto out_free_mappings; + if (!err) + vgic_present = true; return 0; out_free_vfp: diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index b52d4c2..fc2a138 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -20,7 +20,14 @@ #include linux/kvm_host.h #include linux/interrupt.h #include linux/io.h +#include linux/of.h +#include linux/of_address.h +#include linux/of_irq.h + #include asm/kvm_emulate.h +#include asm/hardware/gic.h +#include asm/kvm_arm.h +#include asm/kvm_mmu.h /* * How the whole thing works (courtesy of Christoffer Dall): @@ -61,6 +68,13 @@ /* Temporary hacks, need to be provided by userspace emulation */ #define VGIC_DIST_BASE 0x2c001000 #define VGIC_DIST_SIZE 0x1000 +#define VGIC_CPU_BASE 0x2c002000 +#define VGIC_CPU_SIZE 0x2000 + +/* Virtual control interface base address */ +static void __iomem *vgic_vctrl_base; + +static struct device_node *vgic_node; #define ACCESS_READ_VALUE (1 0) #define ACCESS_READ_RAZ(0 0) @@ -908,3 +922,188 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, return 0; } + +static irqreturn_t vgic_maintenance_handler(int irq, void *data) +{ + struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)data; + struct vgic_dist *dist; + struct vgic_cpu *vgic_cpu; + + if (WARN(!vcpu, +VGIC interrupt on CPU %d with no vcpu\n, smp_processor_id())) + return IRQ_HANDLED; + + vgic_cpu = vcpu-arch.vgic_cpu; + dist = vcpu-kvm-arch.vgic; + kvm_debug(MISR = %08x\n, vgic_cpu-vgic_misr); + + /* +* We do not need to take the distributor lock here, since the only +* action we perform is clearing the irq_active_bit for an EOIed +* level interrupt. There is a potential race with +* the queuing of an interrupt in __kvm_sync_to_cpu(), where we check +* if the interrupt is already active. Two possibilities: +* +* - The queuing is occuring on the same vcpu: cannot happen, as we're +* already in the context of this vcpu, and executing the handler +* - The interrupt has been migrated to another vcpu, and we ignore +* this interrupt for this run. Big deal. It is still pending though, +* and will get considered when this vcpu exits. +*/ + if (vgic_cpu-vgic_misr VGIC_MISR_EOI) { + /* +* Some level interrupts have been EOIed. Clear their +* active bit. +*/ + int lr, irq; + + for_each_set_bit(lr, (unsigned long *)vgic_cpu-vgic_eisr, +vgic_cpu-nr_lr) { + irq = vgic_cpu-vgic_lr[lr] VGIC_LR_VIRTUALID; + + vgic_bitmap_set_irq_val(dist-irq_active, + vcpu-vcpu_id, irq, 0); +
[PATCH v2 10/10] ARM: KVM: Add VGIC configuration option
From: Marc Zyngier marc.zyng...@arm.com It is now possible to select the VGIC configuration option. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/kvm/Kconfig |7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 47c5500..867551e 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig @@ -40,6 +40,13 @@ config KVM_ARM_HOST ---help--- Provides host support for ARM processors. +config KVM_ARM_VGIC +bool KVM support for Virtual GIC + depends on KVM_ARM_HOST OF + select HAVE_KVM_IRQCHIP + ---help--- + Adds support for a hardware assisted, in-kernel GIC emulation. + source drivers/virtio/Kconfig endif # VIRTUALIZATION -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/5] KVM/ARM Architected Timers support
The following series implements support for the architected generic timers for KVM/ARM. This is an unmodified repost of the previously submitted series. This patch series can also be pulled from: git://github.com/virtualopensystems/linux-kvm-arm.git branch: kvm-arm-v12-vgic-timers --- Marc Zyngier (5): ARM: arch_timers: switch to physical timers if HYP mode is available ARM: KVM: arch_timers: Add minimal infrastructure ARM: KVM: arch_timers: Add guest timer core support ARM: KVM: arch_timers: Add timer world switch ARM: KVM: arch_timers: Wire the init code and config option arch/arm/include/asm/kvm_arch_timer.h | 95 +++ arch/arm/include/asm/kvm_host.h |5 + arch/arm/kernel/arch_timer.c |7 + arch/arm/kernel/asm-offsets.c |8 + arch/arm/kvm/Kconfig |7 + arch/arm/kvm/Makefile |1 arch/arm/kvm/arm.c| 14 ++ arch/arm/kvm/interrupts.S |2 arch/arm/kvm/interrupts_head.S| 60 ++ arch/arm/kvm/reset.c |9 + arch/arm/kvm/timer.c | 204 + arch/arm/kvm/vgic.c |4 + 12 files changed, 415 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/kvm_arch_timer.h create mode 100644 arch/arm/kvm/timer.c -- -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/5] ARM: arch_timers: switch to physical timers if HYP mode is available
From: Marc Zyngier marc.zyng...@arm.com If we're booted in HYP mode, it is possible that we'll run some kind of virtualized environment. In this case, it is a better to switch to the physical timers, and leave the virtual timers to guests. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/kernel/arch_timer.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index c04c2a6..8a30186 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -25,6 +25,7 @@ #include asm/arch_timer.h #include asm/system_info.h #include asm/sched_clock.h +#include asm/virt.h static unsigned long arch_timer_rate; @@ -490,10 +491,14 @@ int __init arch_timer_of_register(void) arch_timer_ppi[i] = irq_of_parse_and_map(np, i); /* +* If HYP mode is available, we know that the physical timer +* has been configured to be accessible from PL1. Use it, so +* that a guest can use the virtual timer instead. +* * If no interrupt provided for virtual timer, we'll have to * stick to the physical timer. It'd better be accessible... */ - if (!arch_timer_ppi[VIRT_PPI]) { + if (is_hyp_mode_available() || !arch_timer_ppi[VIRT_PPI]) { arch_timer_use_virtual = false; if (!arch_timer_ppi[PHYS_SECURE_PPI] || -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/5] ARM: KVM: arch_timers: Add minimal infrastructure
From: Marc Zyngier marc.zyng...@arm.com Add some very minimal architected timer related infrastructure. For the moment, we just provide empty structures, and enable/disable access to the physical timer across world switch. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arch_timer.h | 45 + arch/arm/include/asm/kvm_host.h |5 arch/arm/kvm/interrupts.S |2 + arch/arm/kvm/interrupts_head.S| 19 ++ 4 files changed, 71 insertions(+) create mode 100644 arch/arm/include/asm/kvm_arch_timer.h diff --git a/arch/arm/include/asm/kvm_arch_timer.h b/arch/arm/include/asm/kvm_arch_timer.h new file mode 100644 index 000..513b852 --- /dev/null +++ b/arch/arm/include/asm/kvm_arch_timer.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier marc.zyng...@arm.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_KVM_ARCH_TIMER_H +#define __ASM_ARM_KVM_ARCH_TIMER_H + +struct arch_timer_kvm { +}; + +struct arch_timer_cpu { +}; + +#ifndef CONFIG_KVM_ARM_TIMER +static inline int kvm_timer_hyp_init(void) +{ + return 0; +}; + +static inline int kvm_timer_init(struct kvm *kvm) +{ + return 0; +} + +static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_sync_to_cpu(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_sync_from_cpu(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {} +#endif + +#endif diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index d65faea..96cae84 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -23,6 +23,7 @@ #include asm/kvm_asm.h #include asm/fpstate.h #include asm/kvm_vgic.h +#include asm/kvm_arch_timer.h #define KVM_MAX_VCPUS NR_CPUS #define KVM_MEMORY_SLOTS 32 @@ -56,6 +57,9 @@ struct kvm_arch { /* Interrupt controller */ struct vgic_distvgic; + + /* Timer */ + struct arch_timer_kvm timer; }; #define KVM_NR_MEM_OBJS 40 @@ -93,6 +97,7 @@ struct kvm_vcpu_arch { /* VGIC state */ struct vgic_cpu vgic_cpu; + struct arch_timer_cpu timer_cpu; /* * Anything that is not used directly from assembly code goes diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 914c7f2..0e7afd6 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S @@ -105,6 +105,7 @@ ENTRY(__kvm_vcpu_run) store_mode_state sp, fiq restore_vgic_state r0 + restore_timer_state r0 @ Store hardware CP15 state and load guest state read_cp15_state @@ -223,6 +224,7 @@ after_vfp_restore: read_cp15_state 1, r1 write_cp15_state + save_timer_state r1 save_vgic_state r1 load_mode_state sp, fiq diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index e44aea6..4703035 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -302,6 +302,25 @@ #endif .endm +#define CNTHCTL_PL1PCTEN (1 0) +#define CNTHCTL_PL1PCEN(1 1) + +.macro save_timer_statevcpup + @ Allow physical timer/counter access for the host + mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL + orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN) + mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL +.endm + +.macro restore_timer_state vcpup + @ Disallow physical timer access for the guest + @ Physical counter access is allowed + mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL + orr r2, r2, #CNTHCTL_PL1PCTEN + bic r2, r2, #CNTHCTL_PL1PCEN + mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL +.endm + /* Configures the HSTR (Hyp System Trap Register) on entry/return * (hardware reset value is 0) */ .macro set_hstr entry -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/5] ARM: KVM: arch_timers: Add guest timer core support
From: Marc Zyngier marc.zyng...@arm.com We can inject a timer interrupt into the guest as a result of three possible events: - The virtual timer interrupt has fired while we were still executing the guest - The timer interrupt hasn't fired, but it expired while we were doing the world switch - A hrtimer we programmed earlier has fired Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/include/asm/kvm_arch_timer.h | 52 arch/arm/kvm/reset.c |9 + arch/arm/kvm/timer.c | 204 + 3 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 arch/arm/kvm/timer.c diff --git a/arch/arm/include/asm/kvm_arch_timer.h b/arch/arm/include/asm/kvm_arch_timer.h index 513b852..512ee39 100644 --- a/arch/arm/include/asm/kvm_arch_timer.h +++ b/arch/arm/include/asm/kvm_arch_timer.h @@ -19,13 +19,63 @@ #ifndef __ASM_ARM_KVM_ARCH_TIMER_H #define __ASM_ARM_KVM_ARCH_TIMER_H +#include linux/clocksource.h +#include linux/hrtimer.h +#include linux/workqueue.h + struct arch_timer_kvm { +#ifdef CONFIG_KVM_ARM_TIMER + /* Is the timer enabled */ + boolenabled; + + /* +* Virtual offset (kernel access it through cntvoff, HYP code +* access it as two 32bit values). +*/ + union { + cycle_t cntvoff; + struct { + u32 low;/* Restored only */ + u32 high; /* Restored only */ + } cntvoff32; + }; +#endif }; struct arch_timer_cpu { +#ifdef CONFIG_KVM_ARM_TIMER + /* Background timer used when the guest is not running */ + struct hrtimer timer; + + /* Work queued with the above timer expires */ + struct work_struct expired; + + /* Background timer active */ + boolarmed; + + /* Timer IRQ */ + const struct kvm_irq_level *irq; + + /* Registers: control register, timer value */ + u32 cntv_ctl; /* Saved/restored */ + union { + cycle_t cntv_cval; + struct { + u32 low;/* Saved/restored */ + u32 high; /* Saved/restored */ + } cntv_cval32; + }; +#endif }; -#ifndef CONFIG_KVM_ARM_TIMER +#ifdef CONFIG_KVM_ARM_TIMER +int kvm_timer_hyp_init(void); +int kvm_timer_init(struct kvm *kvm); +void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); +void kvm_timer_sync_to_cpu(struct kvm_vcpu *vcpu); +void kvm_timer_sync_from_cpu(struct kvm_vcpu *vcpu); +void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); +#else static inline int kvm_timer_hyp_init(void) { return 0; diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c index 290a13d..bb17def 100644 --- a/arch/arm/kvm/reset.c +++ b/arch/arm/kvm/reset.c @@ -37,6 +37,12 @@ static struct kvm_regs a15_regs_reset = { .cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, }; +#ifdef CONFIG_KVM_ARM_TIMER +static const struct kvm_irq_level a15_virt_timer_ppi = { + .irq= 27, /* A7/A15 specific */ + .level = 1, +}; +#endif /*** * Exported reset function @@ -59,6 +65,9 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) return -EINVAL; cpu_reset = a15_regs_reset; vcpu-arch.midr = read_cpuid_id(); +#ifdef CONFIG_KVM_ARM_TIMER + vcpu-arch.timer_cpu.irq = a15_virt_timer_ppi; +#endif break; default: return -ENODEV; diff --git a/arch/arm/kvm/timer.c b/arch/arm/kvm/timer.c new file mode 100644 index 000..a241298 --- /dev/null +++ b/arch/arm/kvm/timer.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier marc.zyng...@arm.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include linux/of_irq.h +#include linux/kvm.h +#include linux/kvm_host.h +#include linux/interrupt.h + +#include asm/arch_timer.h + +#include asm/kvm_vgic.h +#include asm/kvm_arch_timer.h + +static struct timecounter *timecounter; +static struct
[PATCH v2 4/5] ARM: KVM: arch_timers: Add timer world switch
From: Marc Zyngier marc.zyng...@arm.com Do the necessary save/restore dance for the timers in the world switch code. In the process, allow the guest to read the physical counter, which is useful for its own clock_event_device. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/kernel/asm-offsets.c |8 arch/arm/kvm/arm.c |3 +++ arch/arm/kvm/interrupts_head.S | 41 3 files changed, 52 insertions(+) diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 1f4a894..1c4181e 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -176,6 +176,14 @@ int main(void) DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); +#ifdef CONFIG_KVM_ARM_TIMER + DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); + DEFINE(VCPU_TIMER_CNTV_CVALH,offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval32.high)); + DEFINE(VCPU_TIMER_CNTV_CVALL,offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval32.low)); + DEFINE(KVM_TIMER_CNTVOFF_H, offsetof(struct kvm, arch.timer.cntvoff32.high)); + DEFINE(KVM_TIMER_CNTVOFF_L, offsetof(struct kvm, arch.timer.cntvoff32.low)); + DEFINE(KVM_TIMER_ENABLED,offsetof(struct kvm, arch.timer.enabled)); +#endif DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); #endif DEFINE(KVM_VTTBR,offsetof(struct kvm, arch.vttbr)); diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index b03e604..c62bf28 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -649,6 +649,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) update_vttbr(vcpu-kvm); kvm_vgic_sync_to_cpu(vcpu); + kvm_timer_sync_to_cpu(vcpu); local_irq_disable(); @@ -662,6 +663,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) if (ret = 0 || need_new_vmid_gen(vcpu-kvm)) { local_irq_enable(); + kvm_timer_sync_from_cpu(vcpu); kvm_vgic_sync_from_cpu(vcpu); continue; } @@ -701,6 +703,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) * Back from guest */ + kvm_timer_sync_from_cpu(vcpu); kvm_vgic_sync_from_cpu(vcpu); ret = handle_exit(vcpu, run, ret); diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 4703035..514a75a 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -306,6 +306,25 @@ #define CNTHCTL_PL1PCEN(1 1) .macro save_timer_statevcpup +#ifdef CONFIG_KVM_ARM_TIMER + ldr r4, [\vcpup, #VCPU_KVM] + ldr r2, [r4, #KVM_TIMER_ENABLED] + cmp r2, #0 + beq 1f + + mrc p15, 0, r2, c14, c3, 1 @ CNTV_CTL + and r2, #3 + str r2, [\vcpup, #VCPU_TIMER_CNTV_CTL] + bic r2, #1 @ Clear ENABLE + mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL + isb + + mrrcp15, 3, r2, r3, c14 @ CNTV_CVAL + str r3, [\vcpup, #VCPU_TIMER_CNTV_CVALH] + str r2, [\vcpup, #VCPU_TIMER_CNTV_CVALL] + +1: +#endif @ Allow physical timer/counter access for the host mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN) @@ -319,6 +338,28 @@ orr r2, r2, #CNTHCTL_PL1PCTEN bic r2, r2, #CNTHCTL_PL1PCEN mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL + +#ifdef CONFIG_KVM_ARM_TIMER + ldr r4, [\vcpup, #VCPU_KVM] + ldr r2, [r4, #KVM_TIMER_ENABLED] + cmp r2, #0 + beq 1f + + ldr r3, [r4, #KVM_TIMER_CNTVOFF_H] + ldr r2, [r4, #KVM_TIMER_CNTVOFF_L] + mcrrp15, 4, r2, r3, c14 @ CNTVOFF + isb + + ldr r3, [\vcpup, #VCPU_TIMER_CNTV_CVALH] + ldr r2, [\vcpup, #VCPU_TIMER_CNTV_CVALL] + mcrrp15, 3, r2, r3, c14 @ CNTV_CVAL + + ldr r2, [\vcpup, #VCPU_TIMER_CNTV_CTL] + and r2, #3 + mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL + isb +1: +#endif .endm /* Configures the HSTR (Hyp System Trap Register) on entry/return -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/5] ARM: KVM: arch_timers: Wire the init code and config option
From: Marc Zyngier marc.zyng...@arm.com It is now possible to select CONFIG_KVM_ARM_TIMER to enable the KVM architected timer support. Signed-off-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com --- arch/arm/kvm/Kconfig |7 +++ arch/arm/kvm/Makefile |1 + arch/arm/kvm/arm.c| 11 +++ arch/arm/kvm/vgic.c |4 4 files changed, 23 insertions(+) diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 867551e..ade2673 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig @@ -47,6 +47,13 @@ config KVM_ARM_VGIC ---help--- Adds support for a hardware assisted, in-kernel GIC emulation. +config KVM_ARM_TIMER +bool KVM support for Architected Timers + depends on KVM_ARM_VGIC ARM_ARCH_TIMER + select HAVE_KVM_IRQCHIP + ---help--- + Adds support for the Architected Timers in virtual machines + source drivers/virtio/Kconfig endif # VIRTUALIZATION diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 89608c0..8f4aa02 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += $(addprefix ../../../virt/kvm/, kvm_main.o coalesc obj-$(CONFIG_KVM_ARM_HOST) += arm.o guest.o mmu.o emulate.o reset.o obj-$(CONFIG_KVM_ARM_HOST) += coproc.o coproc_a15.o obj-$(CONFIG_KVM_ARM_VGIC) += vgic.o +obj-$(CONFIG_KVM_ARM_TIMER) += timer.o diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index c62bf28..f8c377b 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -283,6 +283,7 @@ out: void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) { kvm_mmu_free_memory_caches(vcpu); + kvm_timer_vcpu_terminate(vcpu); kmem_cache_free(kvm_vcpu_cache, vcpu); } @@ -320,6 +321,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) /* Set up VGIC */ kvm_vgic_vcpu_init(vcpu); + /* Set up the timer */ + kvm_timer_vcpu_init(vcpu); + return 0; } @@ -1010,6 +1014,13 @@ static int init_hyp_mode(void) if (!err) vgic_present = true; + /* +* Init HYP architected timer support +*/ + err = kvm_timer_hyp_init(); + if (err) + goto out_free_mappings; + return 0; out_free_vfp: free_percpu(kvm_host_vfp_state); diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index 63fe0dd..494d94d 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -,5 +,9 @@ int kvm_vgic_init(struct kvm *kvm) out: mutex_unlock(kvm-lock); + + if (!ret) + kvm_timer_init(kvm); + return ret; } -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On Mon, Oct 01, 2012 at 10:05:21AM +0200, Jan Kiszka wrote: On 2012-09-30 21:11, Marcelo Tosatti wrote: Option is deprecated and warning has been in place for one year. Do we really care about such cosmetics? We care about removing qemu-kvm to null. What is the big plan for qemu-kvm now? For 1.3 and then beyond? I suggested this: provide a configuration file (and proper guide on how to use it on announce email) to be shipped with qemu 1.3.0. That is: For compatibility with qemu-kvm 1.2.0, use qemu-system-x86_64 -config /usr/share/qemu/qemu-kvm-1.2-compat.opt This would work for rtl8139-as-default, vga-ram-size differences. And drop all command line option compatibility (which can be easily fixed by an administrator/end user). Comments? -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On 2012-10-01 11:31, Marcelo Tosatti wrote: On Mon, Oct 01, 2012 at 10:05:21AM +0200, Jan Kiszka wrote: On 2012-09-30 21:11, Marcelo Tosatti wrote: Option is deprecated and warning has been in place for one year. Do we really care about such cosmetics? We care about removing qemu-kvm to null. What is the big plan for qemu-kvm now? For 1.3 and then beyond? I suggested this: provide a configuration file (and proper guide on how to use it on announce email) to be shipped with qemu 1.3.0. That is: For compatibility with qemu-kvm 1.2.0, use qemu-system-x86_64 -config /usr/share/qemu/qemu-kvm-1.2-compat.opt This would work for rtl8139-as-default, vga-ram-size differences. And drop all command line option compatibility (which can be easily fixed by an administrator/end user). Comments? It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. But I would really stop worrying about the qemu-kvm code base. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm 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: PPC: e500: fix allocation size error on g2h_tlb1_map
On 30.09.2012, at 13:29, Avi Kivity wrote: On 09/27/2012 09:59 PM, Alexander Graf wrote: Do you have the auto-autotest setup ready? I guess we can do it manually until it is. I do have a local autotest setup. Or what exactly are you referring to? Getting autotest to run automatically and produce readable reports, and auto-bisection. I'm not quite there yet :). Do you have any precooked things I could reuse? Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
KVM: x86: retain pvclock guest stopped bit in guest memory
Otherwise its possible for an unrelated KVM_REQ_UPDATE_CLOCK (such as due to CPU migration) to clear the bit. Noticed by Paolo Bonzini. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 19047ea..7d47fb6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1134,6 +1134,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) unsigned long this_tsc_khz; s64 kernel_ns, max_kernel_ns; u64 tsc_timestamp; + struct pvclock_vcpu_time_info *guest_hv_clock; u8 pvclock_flags; /* Keep irq disabled to prevent changes to the clock */ @@ -1217,13 +1218,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) vcpu-last_kernel_ns = kernel_ns; vcpu-last_guest_tsc = tsc_timestamp; - pvclock_flags = 0; - if (vcpu-pvclock_set_guest_stopped_request) { - pvclock_flags |= PVCLOCK_GUEST_STOPPED; - vcpu-pvclock_set_guest_stopped_request = false; - } - - vcpu-hv_clock.flags = pvclock_flags; /* * The interface expects us to write an even number signaling that the @@ -1234,6 +1228,18 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) shared_kaddr = kmap_atomic(vcpu-time_page); + guest_hv_clock = shared_kaddr + vcpu-time_offset; + + /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */ + pvclock_flags = (guest_hv_clock-flags PVCLOCK_GUEST_STOPPED); + + if (vcpu-pvclock_set_guest_stopped_request) { + pvclock_flags |= PVCLOCK_GUEST_STOPPED; + vcpu-pvclock_set_guest_stopped_request = false; + } + + vcpu-hv_clock.flags = pvclock_flags; + memcpy(shared_kaddr + vcpu-time_offset, vcpu-hv_clock, sizeof(vcpu-hv_clock)); -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 14/15] KVM: ARM: Handle I/O aborts
On Sun, Sep 30, 2012 at 05:49:21PM -0400, Christoffer Dall wrote: On Thu, Sep 27, 2012 at 11:11 AM, Will Deacon will.dea...@arm.com wrote: On Sat, Sep 15, 2012 at 04:35:59PM +0100, Christoffer Dall wrote: When the guest accesses I/O memory this will create data abort exceptions and they are handled by decoding the HSR information (physical address, read/write, length, register) and forwarding reads and writes to QEMU which performs the device emulation. Certain classes of load/store operations do not support the syndrome information provided in the HSR and we therefore must be able to fetch the offending instruction from guest memory and decode it manually. We only support instruction decoding for valid reasonable MMIO operations where trapping them do not provide sufficient information in the HSR (no 16-bit Thumb instructions provide register writeback that we care about). The following instruciton types are NOT supported for MMIO operations despite the HSR not containing decode info: - any Load/Store multiple - any load/store exclusive - any load/store dual - anything with the PC as the dest register [...] + +/** + * Load-Store instruction emulation + */ + +/* + * Must be ordered with LOADS first and WRITES afterwards + * for easy distinction when doing MMIO. + */ +#define NUM_LD_INSTR 9 +enum INSTR_LS_INDEXES { + INSTR_LS_LDRBT, INSTR_LS_LDRT, INSTR_LS_LDR, INSTR_LS_LDRB, + INSTR_LS_LDRD, INSTR_LS_LDREX, INSTR_LS_LDRH, INSTR_LS_LDRSB, + INSTR_LS_LDRSH, + INSTR_LS_STRBT, INSTR_LS_STRT, INSTR_LS_STR, INSTR_LS_STRB, + INSTR_LS_STRD, INSTR_LS_STREX, INSTR_LS_STRH, + NUM_LS_INSTR +}; + +static u32 ls_instr[NUM_LS_INSTR][2] = { + {0x0470, 0x0d70}, /* LDRBT */ + {0x0430, 0x0d70}, /* LDRT */ + {0x0410, 0x0c50}, /* LDR */ + {0x0450, 0x0c50}, /* LDRB */ + {0x00d0, 0x0e1000f0}, /* LDRD */ + {0x01900090, 0x0ff000f0}, /* LDREX */ + {0x001000b0, 0x0e1000f0}, /* LDRH */ + {0x001000d0, 0x0e1000f0}, /* LDRSB */ + {0x001000f0, 0x0e1000f0}, /* LDRSH */ + {0x0460, 0x0d70}, /* STRBT */ + {0x0420, 0x0d70}, /* STRT */ + {0x0400, 0x0c50}, /* STR */ + {0x0440, 0x0c50}, /* STRB */ + {0x00f0, 0x0e1000f0}, /* STRD */ + {0x01800090, 0x0ff000f0}, /* STREX */ + {0x00b0, 0x0e1000f0} /* STRH */ +}; + +static inline int get_arm_ls_instr_index(u32 instr) +{ + return kvm_instr_index(instr, ls_instr, NUM_LS_INSTR); +} + +/* + * Load-Store instruction decoding + */ +#define INSTR_LS_TYPE_BIT 26 +#define INSTR_LS_RD_MASK 0xf000 +#define INSTR_LS_RD_SHIFT 12 +#define INSTR_LS_RN_MASK 0x000f +#define INSTR_LS_RN_SHIFT 16 +#define INSTR_LS_RM_MASK 0x000f +#define INSTR_LS_OFFSET12_MASK 0x0fff I'm afraid you're not going to thank me much for this, but it's high time we unified the various instruction decoding functions we have under arch/arm/ and this seems like a good opportunity for that. For example, look at the following snippets (there is much more in the files I list) in addition to what you have: I think it would be great if we had a set of unified decoding functions! However, I think it's a shame if we can't merge KVM because we want to clean up this code. There would be nothing in the way of breaking API or anything like that preventing us from cleaning this up after the code has been merged. Please consider reviewing the code for correctness and consider if the code could be merged as is. On the other hand, if you or Dave or anyone else wants to create a set of patches that cleans this up in a timely manner, I will be happy to merge them for my code as well ;) The time I would have available to put into this is rather limited, but I have some initial ideas, as outlined below. Tixy (who did the kprobes implementation, which is probably the most sophisticated opcode handling we have in the kernel right now) may have ideas too. I would hope that any common framework could reuse a fair chunk of his implementation and test coverage. I think that a common framework would have to start out a lot more generic that the special-purpose code in current subsystems, at least initially. We should try to move all the knowledge about how instructions are encoded out of subsystems and into the common framework, so far as possible. We might end up with an interface like this: Instruction data in memory - __arm_mem_to_opcode*() and friends - canonical form canonical form -
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On Mon, Oct 01, 2012 at 12:21:18PM +0200, Jan Kiszka wrote: On 2012-10-01 11:31, Marcelo Tosatti wrote: On Mon, Oct 01, 2012 at 10:05:21AM +0200, Jan Kiszka wrote: On 2012-09-30 21:11, Marcelo Tosatti wrote: Option is deprecated and warning has been in place for one year. Do we really care about such cosmetics? We care about removing qemu-kvm to null. What is the big plan for qemu-kvm now? For 1.3 and then beyond? I suggested this: provide a configuration file (and proper guide on how to use it on announce email) to be shipped with qemu 1.3.0. That is: For compatibility with qemu-kvm 1.2.0, use qemu-system-x86_64 -config /usr/share/qemu/qemu-kvm-1.2-compat.opt This would work for rtl8139-as-default, vga-ram-size differences. And drop all command line option compatibility (which can be easily fixed by an administrator/end user). Comments? It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). Right, VGA RAM size differences are part of migration compatibility. The other two are ACPI and i8254 (will be looking into details soon, thanks). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. Do you have an objection against just pushing the responsability to administrators? It can be seen as configuration file format change. Most users should not be using direct command line anyway. But I would really stop worrying about the qemu-kvm code base. Jan Right, thats what we're trying to do here. -- To unsubscribe from this list: send the line unsubscribe kvm 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] virtio-scsi fixes for 3.6
Il 26/07/2012 15:28, Paolo Bonzini ha scritto: James, patch 1 fixes scanning of LUNs whose number is greater than 255. QEMU passes a max_lun of 16383 (because it uses SAM numbering) but in Linux it must become 32768 (because LUNs above 255 are relocated to 16640). Patch 2 is a resubmission of the patch for online resizing of virtio-scsi LUNs, which needs to be rebased. LUNs above 255 now work for all of scanning, hotplug, hotunplug and resize. Thanks, Paolo Paolo Bonzini (2): virtio-scsi: fix LUNs greater than 255 virtio-scsi: support online resizing of disks drivers/scsi/virtio_scsi.c | 37 +++-- include/linux/virtio_scsi.h |2 ++ 2 files changed, 37 insertions(+), 2 deletions(-) Ping, are these patches going into 3.7? Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On 2012-10-01 15:03, Marcelo Tosatti wrote: On Mon, Oct 01, 2012 at 12:21:18PM +0200, Jan Kiszka wrote: On 2012-10-01 11:31, Marcelo Tosatti wrote: On Mon, Oct 01, 2012 at 10:05:21AM +0200, Jan Kiszka wrote: On 2012-09-30 21:11, Marcelo Tosatti wrote: Option is deprecated and warning has been in place for one year. Do we really care about such cosmetics? We care about removing qemu-kvm to null. What is the big plan for qemu-kvm now? For 1.3 and then beyond? I suggested this: provide a configuration file (and proper guide on how to use it on announce email) to be shipped with qemu 1.3.0. That is: For compatibility with qemu-kvm 1.2.0, use qemu-system-x86_64 -config /usr/share/qemu/qemu-kvm-1.2-compat.opt This would work for rtl8139-as-default, vga-ram-size differences. And drop all command line option compatibility (which can be easily fixed by an administrator/end user). Comments? It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). Right, VGA RAM size differences are part of migration compatibility. The other two are ACPI and i8254 (will be looking into details soon, thanks). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. Do you have an objection against just pushing the responsability to administrators? It can be seen as configuration file format change. This is about helping him in the most appropriate way. Most users should not be using direct command line anyway. If you are using the command line, you shouldn't care about qemu-kvm's legacy. But there might be home-grown management stacks or scripts around that have to be adjusted. So some wrapper may help in this process, either as reference or as intermediate adapter. But I would really stop worrying about the qemu-kvm code base. Jan Right, thats what we're trying to do here. Just that I'm missing how this patch correlates with the goal to get QEMU ready for qemu-kvm users. :) Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
Jan Kiszka jan.kis...@siemens.com writes: On 2012-10-01 11:31, Marcelo Tosatti wrote: It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. qemu-kvm has: -no-kvm -no-kvm-irqchip -no-kvm-pit -no-kvm-pit-reinjection -tdf - does nothing There are replacements for all of the above. If we need to add them to qemu.git, it's not big deal to add them. -drive ...,boot= - this is ignored cpu_set command for CPU hotplug which is known broken in qemu-kvm. testdev which is nice but only used for development Default nic is rtl8139 vs. e1000. Some logic to move change the default VGA ram size to 16mb for pc-1.2 (QEMU uses 16mb by default now too). I think at this point, none of this matters but I added the various distro maintainers to the thread. I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? Regards, Anthony Liguori But I would really stop worrying about the qemu-kvm code base. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm 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 in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [kvmarm] [PATCH 06/15] KVM: ARM: Initial skeleton to compile KVM support
On Sun, 30 Sep 2012 15:21:54 -0400, Christoffer Dall c.d...@virtualopensystems.com wrote: On Thu, Sep 27, 2012 at 10:13 AM, Will Deacon will.dea...@arm.com wrote: I think Marc (CC'd) had a go at this with some success. great, if this improves the code, then I suggest someone rebases an appropriate patch and sends it to the kvmarm mailing list so we can have a look at it, but there are users out there looking to try kvm/arm and we should try to give it to them. Incoming. M. -- Who you jivin' with that Cosmik Debris? -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kvm forum schedule?
Christoph Hellwig h...@infradead.org writes: Does anyone know when the kvm forum schedule for this year will be published? It should be published soon. I'm especially curious if Friday will be a full conference day or if it makes sense to fly back in the afternoon. Friday afternoon will be a hackathon starting after lunch. Regards, Anthony Liguori -- To unsubscribe from this list: send the line unsubscribe kvm 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 in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On 2012-10-01 15:19, Anthony Liguori wrote: Jan Kiszka jan.kis...@siemens.com writes: On 2012-10-01 11:31, Marcelo Tosatti wrote: It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. qemu-kvm has: -no-kvm -no-kvm-irqchip -no-kvm-pit -no-kvm-pit-reinjection -tdf - does nothing There are replacements for all of the above. If we need to add them to qemu.git, it's not big deal to add them. But I don't think we should add them to the source code. This can perfectly be handled my a (disposable) script layer on top of qemu-system-x86_64 - the namespace (qemu-kvm in most cases) is also free. -drive ...,boot= - this is ignored cpu_set command for CPU hotplug which is known broken in qemu-kvm. Right, so nothing is lost when migrating to QEMU. testdev which is nice but only used for development Default nic is rtl8139 vs. e1000. Some logic to move change the default VGA ram size to 16mb for pc-1.2 (QEMU uses 16mb by default now too). Also nicely manageable in a wrapper. I think at this point, none of this matters but I added the various distro maintainers to the thread. I think it's time for the distros to drop qemu-kvm and just ship qemu.git. +1 Jan Is there anything else that needs to happen to make that switch? Regards, Anthony Liguori -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On Mon, Oct 01, 2012 at 08:19:29AM -0500, Anthony Liguori wrote: Jan Kiszka jan.kis...@siemens.com writes: On 2012-10-01 11:31, Marcelo Tosatti wrote: It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. qemu-kvm has: -no-kvm -no-kvm-irqchip -no-kvm-pit -no-kvm-pit-reinjection -tdf - does nothing There are replacements for all of the above. If we need to add them to qemu.git, it's not big deal to add them. At the moment the only purpose of this command line options is for compability with scripts. My view is that scripts are easily fixed, so we can just drop them. No need to carry this to QEMU. -drive ...,boot= - this is ignored cpu_set command for CPU hotplug which is known broken in qemu-kvm. testdev which is nice but only used for development Default nic is rtl8139 vs. e1000. Config file (as suggested earlier on this thread). Some logic to move change the default VGA ram size to 16mb for pc-1.2 (QEMU uses 16mb by default now too). Config file. I think at this point, none of this matters but I added the various distro maintainers to the thread. I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? Regards, Anthony Liguori But I would really stop worrying about the qemu-kvm code base. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm 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 in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On 2012-10-01 15:31, Marcelo Tosatti wrote: On Mon, Oct 01, 2012 at 08:19:29AM -0500, Anthony Liguori wrote: Jan Kiszka jan.kis...@siemens.com writes: On 2012-10-01 11:31, Marcelo Tosatti wrote: It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. qemu-kvm has: -no-kvm -no-kvm-irqchip -no-kvm-pit -no-kvm-pit-reinjection -tdf - does nothing There are replacements for all of the above. If we need to add them to qemu.git, it's not big deal to add them. At the moment the only purpose of this command line options is for compability with scripts. My view is that scripts are easily fixed, so we can just drop them. No need to carry this to QEMU. -drive ...,boot= - this is ignored cpu_set command for CPU hotplug which is known broken in qemu-kvm. testdev which is nice but only used for development Default nic is rtl8139 vs. e1000. Config file (as suggested earlier on this thread). If you need to append -config bla, you can also specify the desired NIC explicitly - I see no value in the former. If we decide to mangle a qemu-kvm command line before calling QEMU binaries, we can adjust this variation there. Otherwise it's the same as with all those -kvm*: Scripts/management tools will need adjustment. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
Il 01/10/2012 15:19, Anthony Liguori ha scritto: I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? Perhaps change the default to -machine accel=kvm:tcg? Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
01.10.2012 17:36, Jan Kiszka wrote: On 2012-10-01 15:31, Marcelo Tosatti wrote: Default nic is rtl8139 vs. e1000. Config file (as suggested earlier on this thread). If you need to append -config bla, you can also specify the desired NIC explicitly - I see no value in the former. If we decide to mangle a qemu-kvm command line before calling QEMU binaries, we can adjust this variation there. Otherwise it's the same as with all those -kvm*: Scripts/management tools will need adjustment. I don't think there's a need to manage this rtl8139 at all at this level. Let's declare that qemu-kvm 1.3+ will switch from rtl8139 to e1000 by default as a more suitable in modern world, -- the same way as qemu did the switch earlier, and be done with that. I think. Note that this is JUST for -net nic users, which should be the minority (proper usage is -device rtl8139 or -device e1000, with explicit model). Thanks, /mjt -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On 2012-10-01 15:38, Paolo Bonzini wrote: Il 01/10/2012 15:19, Anthony Liguori ha scritto: I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? Perhaps change the default to -machine accel=kvm:tcg? That's the old discussion again: This way we generate that silent failure (unless you monitor the console output), where users will complain that QEMU is so slow because something is blocking KVM. Maybe the risk for the latter is lower these days as modules are auto-loaded now, don't know. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
On 2012-10-01 15:44, Michael Tokarev wrote: 01.10.2012 17:36, Jan Kiszka wrote: On 2012-10-01 15:31, Marcelo Tosatti wrote: Default nic is rtl8139 vs. e1000. Config file (as suggested earlier on this thread). If you need to append -config bla, you can also specify the desired NIC explicitly - I see no value in the former. If we decide to mangle a qemu-kvm command line before calling QEMU binaries, we can adjust this variation there. Otherwise it's the same as with all those -kvm*: Scripts/management tools will need adjustment. I don't think there's a need to manage this rtl8139 at all at this level. Let's declare that qemu-kvm 1.3+ will switch from rtl8139 to e1000 by default as a more suitable in modern world, -- the same way as qemu did the switch earlier, and be done with that. I think. Note that this is JUST for -net nic users, which should be the minority (proper usage is -device rtl8139 or -device e1000, with explicit model). Well, the alternative to config files or wrapper scripts is just a detailed checklist how to migrate from qemu-kvm to QEMU. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
Paolo Bonzini pbonz...@redhat.com writes: Il 01/10/2012 15:19, Anthony Liguori ha scritto: I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? Perhaps change the default to -machine accel=kvm:tcg? Paolo I would be in favor of: #if defined(CONFIG_KVM) accel=kvm #else accel=tcg #endif If KVM is available for your target, you almost certainly want to use it. I'd be very happy with that change for 1.3. Regards, Anthony Liguori -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] qemu-kvm: remove boot=on|off drive parameter compatibility
On 01.10.2012, at 15:19, Anthony Liguori wrote: Jan Kiszka jan.kis...@siemens.com writes: On 2012-10-01 11:31, Marcelo Tosatti wrote: It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. qemu-kvm has: -no-kvm Should be easy to have around as backwards compat hack. All it needs to do is set accel=tcg. -no-kvm-irqchip -no-kvm-pit -no-kvm-pit-reinjection Those are quite important, as we need cmdline backwards compatibility. -tdf - does nothing There are replacements for all of the above. If we need to add them to qemu.git, it's not big deal to add them. -drive ...,boot= - this is ignored It's ignored, but useful for certain things. I don't know how many of our users use boot= today, but it's certainly still in the code, and supported. I honestly wouldn't mind to carry a SUSE specific patch that implements boot= for now until we can deem it deprecated enough that we can drop it. cpu_set command for CPU hotplug which is known broken in qemu-kvm. testdev which is nice but only used for development Default nic is rtl8139 vs. e1000. Couldn't we have a machine option that tells us that -M pc-1.2 is really -M pc-kvm-1.2? That way we could implement the device difference, right? Alex Some logic to move change the default VGA ram size to 16mb for pc-1.2 (QEMU uses 16mb by default now too). I think at this point, none of this matters but I added the various distro maintainers to the thread. I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? Regards, Anthony Liguori But I would really stop worrying about the qemu-kvm code base. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm 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 in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility (fwd)
We (Ubuntu) plan to switch to qemu in the next release which opens in November. I suppose there's likely to be a hiccough or two, but I can't think of any offhand. -serge Quoting Scott Moser (smo...@ubuntu.com): you should have been added here. -- Forwarded message -- Date: Mon, 1 Oct 2012 09:19:29 From: Anthony Liguori anth...@codemonkey.ws To: Jan Kiszka jan.kis...@siemens.com, Marcelo Tosatti mtosa...@redhat.com Cc: kvm kvm@vger.kernel.org, qemu-devel qemu-de...@nongnu.org, Cole Robinson crobi...@redhat.com, Scott Moser smo...@ubuntu.com, Andreas Färber afaer...@suse.de, Michael Tokarev m...@tls.msk.ru Subject: Re: qemu-kvm: remove boot=on|off drive parameter compatibility Jan Kiszka jan.kis...@siemens.com writes: On 2012-10-01 11:31, Marcelo Tosatti wrote: It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. qemu-kvm has: -no-kvm -no-kvm-irqchip -no-kvm-pit -no-kvm-pit-reinjection -tdf - does nothing There are replacements for all of the above. If we need to add them to qemu.git, it's not big deal to add them. -drive ...,boot= - this is ignored cpu_set command for CPU hotplug which is known broken in qemu-kvm. testdev which is nice but only used for development Default nic is rtl8139 vs. e1000. Some logic to move change the default VGA ram size to 16mb for pc-1.2 (QEMU uses 16mb by default now too). I think at this point, none of this matters but I added the various distro maintainers to the thread. I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? Regards, Anthony Liguori But I would really stop worrying about the qemu-kvm code base. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm 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 in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: remove boot=on|off drive parameter compatibility
Il 01/10/2012 16:07, Alexander Graf ha scritto: -drive ...,boot= - this is ignored It's ignored, but useful for certain things. I don't know how many of our users use boot= today, but it's certainly still in the code, and supported. I honestly wouldn't mind to carry a SUSE specific patch that implements boot= for now until we can deem it deprecated enough that we can drop it. Extboot is not going to be backported to QEMU, but SeaBIOS can now boot from all emulated device models except MegaSAS. So we may at most have just the option, for example making it an alias for bootindex=1 on the corresponding device. Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Audio starts working several hours after starting Windows Vista guest
Il 30/09/2012 09:34, Dirk Heinrichs ha scritto: Hello, since a week or two, I have a very strange problem with audio output on a Windows Vista guest. Right after booting the guest, audio does not work. If I leave the guest running for some hours (don't know how many, I usually try again next day), audio output works fine. I'm using es1370 emulation, but I get the same results with the other alternatives, too. Guest: Windows Vista SP1 32bit Host: Ubuntu 12.10 64bit % dpkg --list|grep -e kvm -e qemu ii kvm-ipxe 1.0.0+git-3.55f6c88-0ubuntu5 all PXE ROM's for KVM ii qemu-common 1.2.0+noroms-0ubuntu2 all qemu common functionality (bios, documentation, etc) ii qemu-kvm 1.2.0+noroms-0ubuntu2 amd64Full virtualization on supported hardware ii qemu-kvm-spice1.2.0-2012.09-0ubuntu1 amd64Full virtualization on amd64 hardware ii qemu-utils1.2.0+noroms-0ubuntu2 amd64qemu utilities Is this a known problem? What could I do to resolve it? Thanks... Dirk Please open a bug on Launchpad. It will be examined by the Ubuntu maintainers and possibly forwarded to the QEMU project. Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] qemu-kvm: remove boot=on|off drive parameter compatibility (fwd)
On 1 October 2012 15:15, Serge Hallyn serge.hal...@canonical.com wrote: We (Ubuntu) plan to switch to qemu in the next release which opens in November. I suppose there's likely to be a hiccough or two, but I can't think of any offhand. Are you planning to do that for all CPU target architectures, or to maintain the current split between x86 and everything-else ? -- PMM -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] kvm: Set default accelerator to kvm if the host supports it
If we built a target for a host that supports KVM in principle, set the default accelerator to KVM as well. This also means the start of QEMU will fail to start if KVM support turns out to be unavailable at runtime. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c |1 + kvm-stub.c |1 + kvm.h |1 + vl.c |4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 92a7137..4d5f86c 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -103,6 +103,7 @@ struct KVMState #endif }; +bool kvm_configured = true; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm-stub.c b/kvm-stub.c index 3c52eb5..86a6451 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -17,6 +17,7 @@ #include gdbstub.h #include kvm.h +bool kvm_configured; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm.h b/kvm.h index dea2998..9936e5f 100644 --- a/kvm.h +++ b/kvm.h @@ -22,6 +22,7 @@ #include linux/kvm.h #endif +extern bool kvm_configured; extern int kvm_allowed; extern bool kvm_kernel_irqchip; extern bool kvm_async_interrupts_allowed; diff --git a/vl.c b/vl.c index 8d305ca..f557bd1 100644 --- a/vl.c +++ b/vl.c @@ -2215,8 +2215,8 @@ static int configure_accelerator(void) } if (p == NULL) { -/* Use the default accelerator, tcg */ -p = tcg; +/* The default accelerator depends on the availability of KVM. */ +p = kvm_configured ? kvm : tcg; } while (!accel_initialised *p != '\0') { -- 1.7.3.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] qemu-kvm: remove boot=on|off drive parameter compatibility
On 10/1/2012 at 07:19 AM, Anthony Liguori anth...@codemonkey.ws wrote: Jan Kiszka jan.kis...@siemens.com writes: On 2012-10-01 11:31, Marcelo Tosatti wrote: It's not just about default configs. We need to validate if the migration formats are truly compatible (qemu-kvm - QEMU, the other way around definitely not). For the command line switches, we could provide a wrapper script that translates them into upstream format or simply ignores them. That should be harmless to carry upstream. qemu-kvm has: -no-kvm -no-kvm-irqchip -no-kvm-pit -no-kvm-pit-reinjection -tdf - does nothing There are replacements for all of the above. If we need to add them to qemu.git, it's not big deal to add them. -drive ...,boot= - this is ignored cpu_set command for CPU hotplug which is known broken in qemu-kvm. testdev which is nice but only used for development Default nic is rtl8139 vs. e1000. Some logic to move change the default VGA ram size to 16mb for pc-1.2 (QEMU uses 16mb by default now too). I think at this point, none of this matters but I added the various distro maintainers to the thread. I think it's time for the distros to drop qemu-kvm and just ship qemu.git. Is there anything else that needs to happen to make that switch? We are seriously considering moving to qemu.git for our SP3 release of SUSE SLES 11. There are just a handful of patches that provide the backwards compatibility we need to maintain (default to kvm, default nic model, vga ram size), so assuming there is a 100% commitment to fully supporting kvm in qemu going forward (which I don't doubt) I think this is a good time for us to make that switch. Bruce -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 14/15] KVM: ARM: Handle I/O aborts
On Mon, Oct 01, 2012 at 04:12:09PM +0100, Jon Medhurst (Tixy) wrote: On Mon, 2012-10-01 at 13:53 +0100, Dave Martin wrote: On Sun, Sep 30, 2012 at 05:49:21PM -0400, Christoffer Dall wrote: On Thu, Sep 27, 2012 at 11:11 AM, Will Deacon will.dea...@arm.com wrote: On Sat, Sep 15, 2012 at 04:35:59PM +0100, Christoffer Dall wrote: I'm afraid you're not going to thank me much for this, but it's high time we unified the various instruction decoding functions we have under arch/arm/ and this seems like a good opportunity for that. For example, look at the following snippets (there is much more in the files I list) in addition to what you have: I think it would be great if we had a set of unified decoding functions! However, I think it's a shame if we can't merge KVM because we want to clean up this code. There would be nothing in the way of breaking API or anything like that preventing us from cleaning this up after the code has been merged. Please consider reviewing the code for correctness and consider if the code could be merged as is. On the other hand, if you or Dave or anyone else wants to create a set of patches that cleans this up in a timely manner, I will be happy to merge them for my code as well ;) The time I would have available to put into this is rather limited, but I have some initial ideas, as outlined below. Tixy (who did the kprobes implementation, which is probably the most sophisticated opcode handling we have in the kernel right now) may have ideas too. I would hope that any common framework could reuse a fair chunk of his implementation and test coverage. To my thinking, the kprobes code is very tailored to the job it needs to do and that turning it into something generic is just going to make everything bigger and more complex - because a generic framework would be bigger (as it's trying to be generic) and then things like kprobes will probably end up having an additional framework layered over the top to bend it to it's purposes. Perhaps I'm being too pessimistic. Perhaps kprobes is a bit of a double-edged example. It's an example of an implementation with some good features, but because it is larger the amount of adaptation required to convert to a common framework would necessarily be larger also. Yet, kprobes isn't trying to solve radically different problems from other subsystems in the kernel. It doesn't just want to descode and manipulate the properties of instructions, it is actually interested in many of the same properties (for example, whether an instruction is a load or store, whether it modifies the PC etc.) as some other subsystems. I worry that by default every implementation of this ends up rather deeply tailored to its correcponding subsystem -- so we gradually accumulate more incompatible partially-overlapping duplicates of this functionality over time. This doesn't feel like a good thing. It would also requiring an inordinate amount of time to thrash out requirements, design, prototype, and to implement. (I don't think I'm being overly pessimistic about that ;-) So, unless some-one has serious quantities of spare time lying around... Well, I don't suggest that we should expect to get there in one go: such an effort won't ever the off the ground for sure. If we can consolidate a few simpler subsystems' opcode handling then that would still be a step in the right direction, even if integrating kprobes could not happen until much later. If we do nothing, the situation will just gradually get worse. Cheers ---Dave -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 0/4] VFIO-based PCI device assignment
Alex Williamson alex.william...@redhat.com writes: v6: Update patch 4/4 so Makefile just uses CONFIG_LINUX and avoids all the noise in configure. Also available in git here: git://github.com/awilliam/qemu-vfio.git branch: vfio-for-qemu tag: vfio-pci-for-qemu-v6 Applied. Thanks. Regards, Anthony Liguori --- Alex Williamson (4): vfio: Enable vfio-pci and mark supported vfio: vfio-pci device assignment driver Update Linux kernel headers Update kernel header script to include vfio MAINTAINERS |5 hw/Makefile.objs|3 hw/vfio_pci.c | 1864 +++ hw/vfio_pci_int.h | 114 ++ linux-headers/linux/vfio.h | 368 scripts/update-linux-headers.sh |2 6 files changed, 2354 insertions(+), 2 deletions(-) create mode 100644 hw/vfio_pci.c create mode 100644 hw/vfio_pci_int.h create mode 100644 linux-headers/linux/vfio.h -- To unsubscribe from this list: send the line unsubscribe kvm 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 in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 14/15] KVM: ARM: Handle I/O aborts
On Mon, 2012-10-01 at 13:53 +0100, Dave Martin wrote: On Sun, Sep 30, 2012 at 05:49:21PM -0400, Christoffer Dall wrote: On Thu, Sep 27, 2012 at 11:11 AM, Will Deacon will.dea...@arm.com wrote: On Sat, Sep 15, 2012 at 04:35:59PM +0100, Christoffer Dall wrote: I'm afraid you're not going to thank me much for this, but it's high time we unified the various instruction decoding functions we have under arch/arm/ and this seems like a good opportunity for that. For example, look at the following snippets (there is much more in the files I list) in addition to what you have: I think it would be great if we had a set of unified decoding functions! However, I think it's a shame if we can't merge KVM because we want to clean up this code. There would be nothing in the way of breaking API or anything like that preventing us from cleaning this up after the code has been merged. Please consider reviewing the code for correctness and consider if the code could be merged as is. On the other hand, if you or Dave or anyone else wants to create a set of patches that cleans this up in a timely manner, I will be happy to merge them for my code as well ;) The time I would have available to put into this is rather limited, but I have some initial ideas, as outlined below. Tixy (who did the kprobes implementation, which is probably the most sophisticated opcode handling we have in the kernel right now) may have ideas too. I would hope that any common framework could reuse a fair chunk of his implementation and test coverage. To my thinking, the kprobes code is very tailored to the job it needs to do and that turning it into something generic is just going to make everything bigger and more complex - because a generic framework would be bigger (as it's trying to be generic) and then things like kprobes will probably end up having an additional framework layered over the top to bend it to it's purposes. Perhaps I'm being too pessimistic. It would also requiring an inordinate amount of time to thrash out requirements, design, prototype, and to implement. (I don't think I'm being overly pessimistic about that ;-) So, unless some-one has serious quantities of spare time lying around... -- Tixy -- To unsubscribe from this list: send the line unsubscribe kvm 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: Set default accelerator to kvm if the host supports it
Jan Kiszka jan.kis...@siemens.com writes: If we built a target for a host that supports KVM in principle, set the default accelerator to KVM as well. This also means the start of QEMU will fail to start if KVM support turns out to be unavailable at runtime. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c |1 + kvm-stub.c |1 + kvm.h |1 + vl.c |4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 92a7137..4d5f86c 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -103,6 +103,7 @@ struct KVMState #endif }; +bool kvm_configured = true; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm-stub.c b/kvm-stub.c index 3c52eb5..86a6451 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -17,6 +17,7 @@ #include gdbstub.h #include kvm.h +bool kvm_configured; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm.h b/kvm.h index dea2998..9936e5f 100644 --- a/kvm.h +++ b/kvm.h @@ -22,6 +22,7 @@ #include linux/kvm.h #endif +extern bool kvm_configured; extern int kvm_allowed; extern bool kvm_kernel_irqchip; extern bool kvm_async_interrupts_allowed; diff --git a/vl.c b/vl.c index 8d305ca..f557bd1 100644 --- a/vl.c +++ b/vl.c @@ -2215,8 +2215,8 @@ static int configure_accelerator(void) } if (p == NULL) { -/* Use the default accelerator, tcg */ -p = tcg; +/* The default accelerator depends on the availability of KVM. */ +p = kvm_configured ? kvm : tcg; } How about making this an arch_init() function call and then using a #if defined(KVM_CONFIG) in arch_init.c? I hate to introduce another global variable if we can avoid it... Otherwise: Acked-by: Anthony Liguori aligu...@us.ibm.com Blue/Aurelien, any objections? Regards, Anthony Liguori while (!accel_initialised *p != '\0') { -- 1.7.3.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH] kvm: Set default accelerator to kvm if the host supports it
Hello Jan, Am 01.10.2012 16:34, schrieb Jan Kiszka: If we built a target for a host that supports KVM in principle, set the default accelerator to KVM as well. This also means the start of QEMU will fail to start if KVM support turns out to be unavailable at runtime. From a distro point of view this of course means that we will build against KVM and that the new KVM default will start to fail for users on very old hardware. Can't we do a runtime check to select the default? Would be nice to at least amend the commit message with how they are expected to remedy that via command line. -machine accel=tcg? Regards, Andreas Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c |1 + kvm-stub.c |1 + kvm.h |1 + vl.c |4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 92a7137..4d5f86c 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -103,6 +103,7 @@ struct KVMState #endif }; +bool kvm_configured = true; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm-stub.c b/kvm-stub.c index 3c52eb5..86a6451 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -17,6 +17,7 @@ #include gdbstub.h #include kvm.h +bool kvm_configured; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm.h b/kvm.h index dea2998..9936e5f 100644 --- a/kvm.h +++ b/kvm.h @@ -22,6 +22,7 @@ #include linux/kvm.h #endif +extern bool kvm_configured; extern int kvm_allowed; extern bool kvm_kernel_irqchip; extern bool kvm_async_interrupts_allowed; diff --git a/vl.c b/vl.c index 8d305ca..f557bd1 100644 --- a/vl.c +++ b/vl.c @@ -2215,8 +2215,8 @@ static int configure_accelerator(void) } if (p == NULL) { -/* Use the default accelerator, tcg */ -p = tcg; +/* The default accelerator depends on the availability of KVM. */ +p = kvm_configured ? kvm : tcg; } while (!accel_initialised *p != '\0') { -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH] kvm: Set default accelerator to kvm if the host supports it
On Mon, Oct 01, 2012 at 06:43:00PM +0200, Andreas Färber wrote: Hello Jan, Am 01.10.2012 16:34, schrieb Jan Kiszka: If we built a target for a host that supports KVM in principle, set the default accelerator to KVM as well. This also means the start of QEMU will fail to start if KVM support turns out to be unavailable at runtime. From a distro point of view this of course means that we will build against KVM and that the new KVM default will start to fail for users on very old hardware. Can't we do a runtime check to select the default? NB, this is *not* only about old hardware. There are plenty of users who use QEMU inside VMs. One very common usage I know of is image building tools which are run inside Amazon VMs, using libguestfs QEMU. IMHO, default to KVM, fallback to TCG is the most friendly default behaviour. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] qemu-kvm: remove boot=on|off drive parameter compatibility (fwd)
Quoting Peter Maydell (peter.mayd...@linaro.org): On 1 October 2012 15:15, Serge Hallyn serge.hal...@canonical.com wrote: We (Ubuntu) plan to switch to qemu in the next release which opens in November. I suppose there's likely to be a hiccough or two, but I can't think of any offhand. Are you planning to do that for all CPU target architectures, or to maintain the current split between x86 and everything-else ? -- PMM I'll have to talk to qemu-linaro folks about that. I don't mind carrying patchsets (that are headed upstream) to enable some chipsets if that's what's needed to consolidate the source trees. The bigger question relates to main vs universe. For instance qemu-system is built against vde2, and qemu-kvm-spice against spice, both of which are in universe. I understand the distinction may change or disappear soon, so this may not be an issue. I intend to schedule a session on this at UDS. -serge -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH v6 3/4] vfio: vfio-pci device assignment driver
This: struct vfio_iommu_type1_dma_map map = { .argsz = sizeof(map), .flags = VFIO_DMA_MAP_FLAG_READ, .vaddr = (__u64)vaddr, .iova = iova, .size = size, }; (around line 771) breaks in my environment. I am in a crosschain environment on a i386 buildin PPC (32bit) binaries. I am using emdebian utilities, and have been cross building qemu for months now. The configure: PKG_CONFIG_PATH=/usr/powerpc-linux-gnu/lib/pkgconfig ./configure --prefix=/mnt/DATA/DARCO/alien --enable-debug-tcg --enable-debug --enable-trace-backend=simple --disable-strip --disable-kvm --enable-profiler --target-list=i386-softmmu --static --disable-curl --cross-prefix=powerpc-linux-gnu- --with-coroutine=sigaltstack The build: make clean make -j make install The error: /mnt/DATA/DARCO/qemu-git/hw/vfio_pci.c: In function 'vfio_dma_map': /mnt/DATA/DARCO/qemu-git/hw/vfio_pci.c:771: error: cast from pointer to integer of different size -- To unsubscribe from this list: send the line unsubscribe kvm 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: Set default accelerator to kvm if the host supports it
On Mon, Oct 01, 2012 at 11:20:41AM -0500, Anthony Liguori wrote: Jan Kiszka jan.kis...@siemens.com writes: If we built a target for a host that supports KVM in principle, set the default accelerator to KVM as well. This also means the start of QEMU will fail to start if KVM support turns out to be unavailable at runtime. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c |1 + kvm-stub.c |1 + kvm.h |1 + vl.c |4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 92a7137..4d5f86c 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -103,6 +103,7 @@ struct KVMState #endif }; +bool kvm_configured = true; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm-stub.c b/kvm-stub.c index 3c52eb5..86a6451 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -17,6 +17,7 @@ #include gdbstub.h #include kvm.h +bool kvm_configured; KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; diff --git a/kvm.h b/kvm.h index dea2998..9936e5f 100644 --- a/kvm.h +++ b/kvm.h @@ -22,6 +22,7 @@ #include linux/kvm.h #endif +extern bool kvm_configured; extern int kvm_allowed; extern bool kvm_kernel_irqchip; extern bool kvm_async_interrupts_allowed; diff --git a/vl.c b/vl.c index 8d305ca..f557bd1 100644 --- a/vl.c +++ b/vl.c @@ -2215,8 +2215,8 @@ static int configure_accelerator(void) } if (p == NULL) { -/* Use the default accelerator, tcg */ -p = tcg; +/* The default accelerator depends on the availability of KVM. */ +p = kvm_configured ? kvm : tcg; } How about making this an arch_init() function call and then using a #if defined(KVM_CONFIG) in arch_init.c? I hate to introduce another global variable if we can avoid it... Otherwise: Acked-by: Anthony Liguori aligu...@us.ibm.com Blue/Aurelien, any objections? I am not sure this way of doing is really distribution friendly, where the QEMU package is built for a large variety of hosts, some of them maybe without KVM support. I am all for enabling KVM by default, but I think it should fall back to TCG if it is not enabled (probably with a warning so that the user is aware of that). On the other hand, if the user explicitly enables KVM support with -enable-kvm or with accel=kvm, it should fail to start. In other words, a bit like the configure script options, by default we use auto-detection, but if an option is explicitly enabled, it fails if it can't be enabled. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH v10] kvm: notify host when the guest is panicked
On Wed, 29 Aug 2012 13:18:54 +0800 Wen Congyang we...@cn.fujitsu.com wrote: We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. What's the status of this series? It got lost in my queue and I ended up not reviewing it, but it seems to be stuck. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- Documentation/virtual/kvm/pv_event.txt | 32 arch/ia64/include/asm/kvm_para.h | 14 ++ arch/powerpc/include/asm/kvm_para.h| 14 ++ arch/s390/include/asm/kvm_para.h | 14 ++ arch/x86/include/asm/kvm_para.h| 27 +++ arch/x86/kernel/kvm.c | 25 + include/linux/kvm_para.h | 23 +++ 7 files changed, 149 insertions(+), 0 deletions(-) create mode 100644 Documentation/virtual/kvm/pv_event.txt diff --git a/Documentation/virtual/kvm/pv_event.txt b/Documentation/virtual/kvm/pv_event.txt new file mode 100644 index 000..bb04de0 --- /dev/null +++ b/Documentation/virtual/kvm/pv_event.txt @@ -0,0 +1,32 @@ +The KVM paravirtual event interface += + +Initializing the paravirtual event interface +== +kvm_pv_event_init() +Argiments: + None + +Return Value: + 0: The guest kernel can use paravirtual event interface. + 1: The guest kernel can't use paravirtual event interface. + +Querying whether the event can be ejected +== +kvm_pv_has_feature() +Arguments: + feature: The bit value of this paravirtual event to query + +Return Value: + 0 : The guest kernel can't eject this paravirtual event. + -1: The guest kernel can eject this paravirtual event. + + +Ejecting paravirtual event +== +kvm_pv_eject_event() +Arguments: + event: The event to be ejected. + +Return Value: + None diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h index 2019cb9..b5ec658 100644 --- a/arch/ia64/include/asm/kvm_para.h +++ b/arch/ia64/include/asm/kvm_para.h @@ -31,6 +31,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index c18916b..01b98c7 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -211,6 +211,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index da44867..00ce058 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,6 +154,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif #endif /* __S390_KVM_PARA_H */ diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 2f7712e..7d297f0 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -96,8 +96,11 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT(0x505UL) + #ifdef __KERNEL__ #include asm/processor.h +#include linux/ioport.h extern void kvmclock_init(void); extern int kvm_register_clock(char *txt); @@ -228,6 +231,30 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline int kvm_arch_pv_event_init(void) +{ +
Re: [Qemu-devel] [PATCH] kvm: Set default accelerator to kvm if the host supports it
Daniel P. Berrange berra...@redhat.com writes: On Mon, Oct 01, 2012 at 06:43:00PM +0200, Andreas Färber wrote: Hello Jan, Am 01.10.2012 16:34, schrieb Jan Kiszka: If we built a target for a host that supports KVM in principle, set the default accelerator to KVM as well. This also means the start of QEMU will fail to start if KVM support turns out to be unavailable at runtime. From a distro point of view this of course means that we will build against KVM and that the new KVM default will start to fail for users on very old hardware. Can't we do a runtime check to select the default? NB, this is *not* only about old hardware. There are plenty of users who use QEMU inside VMs. One very common usage I know of is image building tools which are run inside Amazon VMs, using libguestfs QEMU. But libguest can set it's accelerator option to whatever it wants. If your running QEMU under a VM, it's pretty reasonable to have to use a special option IMHO. IMHO, default to KVM, fallback to TCG is the most friendly default behaviour. Except if a user expects good network performance and can't understand why they're getting 100kb/s. Regards, Anthony Liguori Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH] kvm: Set default accelerator to kvm if the host supports it
But libguest can set it's accelerator option to whatever it wants. If your running QEMU under a VM, it's pretty reasonable to have to use a special option IMHO. It's also reasonable to have consecutive releases change defaults in a more friendly way (i.e. from tcg to kvm:tcg), especially since we'll get users that formerly used qemu-kvm and never had to specify neither -machine accel nor --enable-kvm. IMHO, default to KVM, fallback to TCG is the most friendly default behaviour. Except if a user expects good network performance and can't understand why they're getting 100kb/s. libguestfs doesn't need network at all (though I wonder if they could use lxc instead...). Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH v10] kvm: notify host when the guest is panicked
On Mon, Oct 01, 2012 at 03:57:40PM -0300, Luiz Capitulino wrote: On Wed, 29 Aug 2012 13:18:54 +0800 Wen Congyang we...@cn.fujitsu.com wrote: We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. What's the status of this series? It got lost in my queue and I ended up not reviewing it, but it seems to be stuck. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Have you tried to move it early enough to minimize the number of calls to panic()? Say, how many panics can occur between first Linux instruction and initialization of netconsole? Because this interface (all the way to QEMU) is going to be reimplemented with different code later, in case other architectures want similar interface, which makes maintenance more difficult. Using PCI would basically replacing I/O port write with PCI write (or virtio write). Avi? Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- Documentation/virtual/kvm/pv_event.txt | 32 arch/ia64/include/asm/kvm_para.h | 14 ++ arch/powerpc/include/asm/kvm_para.h| 14 ++ arch/s390/include/asm/kvm_para.h | 14 ++ arch/x86/include/asm/kvm_para.h| 27 +++ arch/x86/kernel/kvm.c | 25 + include/linux/kvm_para.h | 23 +++ 7 files changed, 149 insertions(+), 0 deletions(-) create mode 100644 Documentation/virtual/kvm/pv_event.txt diff --git a/Documentation/virtual/kvm/pv_event.txt b/Documentation/virtual/kvm/pv_event.txt new file mode 100644 index 000..bb04de0 --- /dev/null +++ b/Documentation/virtual/kvm/pv_event.txt @@ -0,0 +1,32 @@ +The KVM paravirtual event interface += + +Initializing the paravirtual event interface +== +kvm_pv_event_init() +Argiments: + None + +Return Value: + 0: The guest kernel can use paravirtual event interface. + 1: The guest kernel can't use paravirtual event interface. + +Querying whether the event can be ejected +== +kvm_pv_has_feature() +Arguments: + feature: The bit value of this paravirtual event to query + +Return Value: + 0 : The guest kernel can't eject this paravirtual event. + -1: The guest kernel can eject this paravirtual event. + + +Ejecting paravirtual event +== +kvm_pv_eject_event() +Arguments: + event: The event to be ejected. + +Return Value: + None diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h index 2019cb9..b5ec658 100644 --- a/arch/ia64/include/asm/kvm_para.h +++ b/arch/ia64/include/asm/kvm_para.h @@ -31,6 +31,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index c18916b..01b98c7 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -211,6 +211,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index da44867..00ce058 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,6 +154,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif #endif /* __S390_KVM_PARA_H */
KVM call agenda for 2012-10-01
hi Please send in any agenda topics you are interested in. Later, Juan. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH] kvm: Set default accelerator to kvm if the host supports it
Paolo Bonzini pbonz...@redhat.com writes: But libguest can set it's accelerator option to whatever it wants. If your running QEMU under a VM, it's pretty reasonable to have to use a special option IMHO. It's also reasonable to have consecutive releases change defaults in a more friendly way (i.e. from tcg to kvm:tcg), especially since we'll get users that formerly used qemu-kvm and never had to specify neither -machine accel nor --enable-kvm. I agree with you except for the 'kvm:tcg' part. IMHO, default to KVM, fallback to TCG is the most friendly default behaviour. Except if a user expects good network performance and can't understand why they're getting 100kb/s. libguestfs doesn't need network at all (though I wonder if they could use lxc instead...). FWIW, libguestfs already uses -machine accel=kvm:tcg so we can completely the libguestfs use-case for this discussion. Regards, Anthony Liguori Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] KVM call agenda for 2012-10-01
Juan Quintela quint...@redhat.com writes: hi Please send in any agenda topics you are interested in. 1) TODO to finish off qemu-kvm.git/master... Regards, Anthony Liguori Later, Juan. -- To unsubscribe from this list: send the line unsubscribe kvm 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: PPC: e500: fix allocation size error on g2h_tlb1_map
On 30.09.2012, at 13:29, Avi Kivity wrote: On 09/27/2012 09:59 PM, Alexander Graf wrote: Do you have the auto-autotest setup ready? I guess we can do it manually until it is. I do have a local autotest setup. Or what exactly are you referring to? Getting autotest to run automatically and produce readable reports, and auto-bisection. I'm not quite there yet :). Do you have any precooked things I could reuse? 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