Hello Marc,
By chance I noticed some minor issues when compiling the kernel with KVM,
but your VGIC support disabled.
On Thu, Jul 5, 2012 at 5:28 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> Plug the interrupt injection code. Interrupts can now be generated
> from user space.
>
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
> arch/arm/include/asm/kvm_vgic.h | 1 +
> arch/arm/kvm/arm.c | 43 ++++++++++++++++++++++++++++--
> arch/arm/kvm/vgic.c | 56
> +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 98 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_vgic.h
> b/arch/arm/include/asm/kvm_vgic.h
> index 481f4a9..48c27da 100644
> --- a/arch/arm/include/asm/kvm_vgic.h
> +++ b/arch/arm/include/asm/kvm_vgic.h
> @@ -220,6 +220,7 @@ 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, const struct
> kvm_irq_level *irq);
> int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
> int vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
> struct kvm_exit_mmio *mmio);
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index bdf0f86..7b27a4e 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -654,6 +654,12 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct
> kvm_irq_level *irq_level)
> bool set;
> int bit_nr;
>
> + if (irqchip_in_kernel(kvm)) {
> + if (irq_level->irq < 32)
> + return -EINVAL;
> + return kvm_vgic_inject_irq(kvm, 0, irq_level);
> + }
> +
>
This will cause the compilation to fail. Should be "#ifdef"ed like
everything else.
> vcpu_idx = irq_level->irq >> 1;
> if (vcpu_idx >= KVM_MAX_VCPUS)
> return -EINVAL;
> @@ -696,7 +702,28 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct
> kvm_irq_level *irq_level)
> long kvm_arch_vcpu_ioctl(struct file *filp,
> unsigned int ioctl, unsigned long arg)
> {
> - return -EINVAL;
> + struct kvm_vcpu *vcpu = filp->private_data;
> + void __user *argp = (void __user *)arg;
> +
> + switch (ioctl) {
> +#ifdef CONFIG_KVM_ARM_VGIC
> + case KVM_IRQ_LINE: {
> + struct kvm_irq_level irq_event;
> +
> + if (copy_from_user(&irq_event, argp, sizeof irq_event))
> + return -EFAULT;
> +
> + if (!irqchip_in_kernel(vcpu->kvm))
> + return -EINVAL;
> +
> + if (irq_event.irq < 16 || irq_event.irq >= 32)
> + return -EINVAL;
> + return kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
> &irq_event);
> + }
> +#endif
> + default:
> + return -EINVAL;
> + }
> }
>
>
Will cause warnings for unused variables vcpu and argp.
> int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
> @@ -707,7 +734,19 @@ 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;
> + struct kvm *kvm = filp->private_data;
> +
> + switch (ioctl) {
> +#ifdef CONFIG_KVM_ARM_VGIC
> + case KVM_CREATE_IRQCHIP:
> + if (vgic_present)
> + return kvm_vgic_init(kvm);
> + else
> + return -EINVAL;
> +#endif
> + default:
> + return -EINVAL;
> + }
> }
>
>
Ditto for variable kvm.
> static void cpu_set_vector(void *vector)
> diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c
> index 8722efc..4d5d23a 100644
> --- a/arch/arm/kvm/vgic.c
> +++ b/arch/arm/kvm/vgic.c
> @@ -69,6 +69,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)
> @@ -500,6 +501,8 @@ int vgic_handle_mmio(struct kvm_vcpu *vcpu, struct
> kvm_run *run, struct kvm_exit
> kvm_handle_mmio_return(vcpu, run);
> spin_unlock(&vcpu->kvm->arch.vgic.lock);
>
> + vgic_kick_vcpus(vcpu->kvm);
> +
> return KVM_EXIT_UNKNOWN;
> }
>
> @@ -795,3 +798,56 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
>
> return test_bit(1 << 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)) {
> + vcpu->arch.wait_for_interrupts = 0;
> + kvm_vcpu_kick(vcpu);
> + }
> + }
> +}
> +
> +int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, const struct
> kvm_irq_level *irq)
> +{
> + struct vgic_dist *dist = &kvm->arch.vgic;
> + int nrcpus = atomic_read(&kvm->online_vcpus);
> + int is_edge, state;
> +
> + if (cpuid >= nrcpus)
> + return -EINVAL;
> +
> + /* Only PPIs or SPIs */
> + if (irq->irq >= VGIC_NR_IRQS || irq->irq < 16)
> + return -EINVAL;
> +
> + kvm_debug("Inject IRQ%d\n", irq->irq);
> + spin_lock(&dist->lock);
> + is_edge = vgic_irq_is_edge(dist, irq->irq);
> + state = vgic_bitmap_get_irq_val(&dist->irq_state, cpuid, irq->irq);
> +
> + /*
> + * Inject an interrupt if:
> + * - level triggered and we change level
> + * - edge triggered and we have a rising edge
> + */
> + if ((!is_edge && (state ^ !!irq->level)) ||
> + (is_edge && !state && irq->level)) {
> + vgic_bitmap_set_irq_val(&dist->irq_state, cpuid,
> + irq->irq, !!irq->level);
> + vgic_update_state(kvm);
> + }
> + spin_unlock(&dist->lock);
> +
> + vgic_kick_vcpus(kvm);
> +
> + return 0;
> +}
> --
> 1.7.10.3
>
>
>
> _______________________________________________
> Android-virt mailing list
> Android-virt at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/android-virt
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.cs.columbia.edu/pipermail/kvmarm/attachments/20120730/6a9c0302/attachment-0001.html
[Spice Development]
[Libvirt]
[Libvirt Users]
[Linux USB Devel]
[Video for Linux]
[Linux Audio Users]
[Photo]
[Yosemite News]
[Yosemite Photos]
[POF Sucks]
[Linux Kernel]
[Linux SCSI]
[XFree86]