[Android-virt] [PATCH 03/15] ARM: KVM: Initial VGIC MMIO support code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 20/06/12 00:08, Christoffer Dall wrote:
> On Mon, May 14, 2012 at 9:05 AM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>> Wire the initial in-kernel MMIO support code for the VGIC, used
>> for the distributor emulation.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>

[...]

>> diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c
>> new file mode 100644
>> index 0000000..f7856a9
>> --- /dev/null
>> +++ b/arch/arm/kvm/vgic.c
>> +
>> +static void mmio_do_copy(struct kvm_run *run, u32 *reg, u32 offset, int mode)
> 
> Ah, reg is mmio-mapped gic_reg. That's confusing.
> 
> I think a comment here may be helpful. Also, I'm not sure about the
> name. Isn't this in fact vgic_ctrl_access(...) or something like that?

Well, nothing in this function is GIC specific, really. It's just a
helper for accessing a register with a particular mode. How about
mmio_access()?

> 
>> +{
>> +       int u32off = offset & 3;
> 
> I fail to see why it's named u32off, is it because it's a word offset?

Yes. I'll rename it to word_offset to make things clearer.

> 
>> +       int shift = u32off * 8;
>> +       u32 mask;
>> +       u32 regval;
>> +
>> +       /*
>> +        * We do silly things on cross-register accesses, so pretend
>> +        * they do not exist. Will have to be handled though...
>> +        */
> 
> By 'We' do you mean this function or the ARM/GIC architecture? Is this
> actually allowed? Why does it need to be handled and is it too
> complicated to handle right away?

'We' as the function. Cross-register (actually, any unaligned) access on
device memory should give an Alignment fault. Not something we handle yet.

> 
>> +       if (WARN_ON((u32off + run->mmio.len) > 4))
>> +               run->mmio.len = 4 - u32off;
> 
> does this fix make sense? Does it actually happen or should we just
> bail out? Seems like the WARN_ON could generate a lot of host
> interference and flood the host log if the guest can keep provoking
> it. Unsure how this is called so far though, will look in following
> patches.

Bailing out is probably the best, together with the injection of an
Alignment fault in the guest. I'll remove this and add a comment.

>> +
>> +       mask = ((u32)-1) >> (u32off * 8);
> 
> consider (~0U) to avoid the cast?

Yup.

>> +       if (reg)
>> +               regval = *reg;
>> +       else {
>> +               BUG_ON(mode != (ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED));
>> +               regval = 0;
>> +       }
>> +
>> +       if (run->mmio.is_write) {
>> +               u32 data = (*((u32 *)run->mmio.data) & mask) << shift;
>> +               switch (ACCESS_WRITE_MASK(mode)) {
>> +               case ACCESS_WRITE_IGNORED:
>> +                       return;
>> +
> 
> I don't think these spaces before the next 'case' line is commonplace
> in the kernel...

It is not uncommon, but I don't mind removing them.

>> +               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 *)run->mmio.data) = (regval >> shift) & mask;
>> +               }
>> +       }
>> +}
>> +
>> +/* All this should really be generic code... FIXME!!! */
> 
> generic code as in arch-generic? are there similar constructs in
> x86/powerpc/...? The FIXME!!! is quite strong, should we fix it now or
> is it ok for this code to live in KVM for somer time after a merge?

Generic as in KVM common code. This should really be handled by the
kvm_io_bus_*() stuff. Unfortunately, it is not suitable yet (it only
passes the kvm struct around, while we actually need the vcpu struct). I
think we can get away with merging this, and the screaming FIXME should
be an incentive to keep it in mind.

> 
>> +struct mmio_range {
>> +       unsigned long base;
>> +       unsigned long len;
>> +       void (*handle_mmio)(struct kvm_vcpu *vcpu, struct kvm_run *run,
>> +                           u32 offset);
>> +};
>> +
>> +static const struct mmio_range vgic_ranges[] = {
>> +       {}
>> +};
>> +
>> +static const
>> +struct mmio_range *find_matching_range(const struct mmio_range *ranges,
>> +                                      struct kvm_run *run)
>> +{
>> +       const struct mmio_range *r = ranges;
> 
> consider newline

OK.

>> +       while (r->len) {
>> +               if (run->mmio.phys_addr >= r->base &&
>> +                   (run->mmio.phys_addr + run->mmio.len) <= (r->base + r->len))
>> +                       return r;
>> +               r++;
>> +       }
>> +
>> +       return NULL;
>> +}
>> +
>> +int vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run)
> 
> document the exported function please.

OK.

>> +{
>> +       const struct mmio_range *range;
>> +
>> +       if (!irqchip_in_kernel(vcpu->kvm))
>> +               return KVM_EXIT_MMIO;
>> +
>> +       range = find_matching_range(vgic_ranges, run);
>> +       if (!range || !range->handle_mmio)
>> +               return KVM_EXIT_MMIO;
>> +
>> +       pr_debug("emulating %d %08llx %d\n", run->mmio.is_write,
>> +                run->mmio.phys_addr, run->mmio.len);
> 
> kvm_debug?

OK.

>> +       range->handle_mmio(vcpu, run, run->mmio.phys_addr - range->base);
>> +       kvm_handle_mmio_return(vcpu, run);
>> +
>> +       return KVM_EXIT_UNKNOWN;
>> +}
>> --
>> 1.7.7.1
>>
>>
>>
>> _______________________________________________
>> Android-virt mailing list
>> Android-virt at lists.cs.columbia.edu
>> https://lists.cs.columbia.edu/cucslists/listinfo/android-virt
> 


-- 
Jazz is not dead. It just smells funny...




[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux