Re: [PATCH 15/17] ARM: KVM: KVM_GET_MSR_INDEX_LIST/KVM_GET_MSRS/KVM_SET_MSRS for cp15 regs.

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

 



On Sun, Aug 5, 2012 at 11:12 PM, Rusty Russell <rusty.russell@xxxxxxxxxx> wrote:
> On Fri, 3 Aug 2012 13:57:00 +0200, Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>> On Thu, Jul 12, 2012 at 7:54 AM, Rusty Russell <rusty.russell@xxxxxxxxxx> wrote:
>> > Now we have a table for all the cp15 registers, we can drive a generic
>> > API.  x86 already has one for sparse-numbered registers, so we simply
>> > reproduce that.  The only difference is that our KVM_GET_MSR_INDEX_LIST
>> > is a per-vcpu ioctl; we can't know the MSRs until we know the cpu type.
>> >
>> > The numbering for the indices for coprocesors is simple, if userspace
>> > cares (it might not for simple save and restore): the upper 16 bits
>> > are the coprocessor number.  If it's > 15, it's something else, for
>> > future expansion.
>> >
>> > Bit 15 indicates a 64-bit register.  For 64 bit registers the bottom 4
>> > bits are CRm, the next 4 are opc1 (just like the MCRR/MRCC instruction
>> > encoding).  For 32 bit registers, the bottom 4 bits are CRm, the next
>> > 3 are opc2, the next 4 CRn, and the next 3 opc1 (the same order as the
>> > MRC/MCR instruction encoding, but not the same bit positions).
>> >
>> > 64-bit coprocessor register:
>> >        ...|19 18 17 16|15|14 13 12 11 10  9  8| 7  6  5  4 |3  2  1  0|
>> >   ...0  0 |  cp num   | 1| 0  0  0  0  0  0  0|   opc1     |   CRm    |
>> >
>> > 32-bit coprocessor register:
>> >        ...|19 18 17 16|15|14|13 12 11|10  9  8  7 |6  5  4 |3  2  1  0|
>> >   ...0  0 |  cp num   | 0| 0|  opc1  |    CRn     | opc2   |   CRm    |
>> >
>> > Non-coprocessor register:
>> >
>> >    | 32 31 30 29 28 27 26 25 24 23 22 21 20|19 18 17 16 15 ...
>> >    |     < some non-zero value >           | ...
>> >
>> > Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
>> > ---
>> >  arch/arm/include/asm/kvm.h        |   31 +++++
>> >  arch/arm/include/asm/kvm_coproc.h |    7 ++
>> >  arch/arm/kvm/arm.c                |   29 +++++
>> >  arch/arm/kvm/coproc.c             |  237 +++++++++++++++++++++++++++++++++++++
>> >  4 files changed, 304 insertions(+)
>> >
>> > diff --git a/arch/arm/include/asm/kvm.h b/arch/arm/include/asm/kvm.h
>> > index 09b5be3..d6531e8 100644
>> > --- a/arch/arm/include/asm/kvm.h
>> > +++ b/arch/arm/include/asm/kvm.h
>> > @@ -92,4 +92,35 @@ struct kvm_sync_regs {
>> >  struct kvm_arch_memory_slot {
>> >  };
>> >
>> > +/* Exactly like x86. */
>> > +struct kvm_msr_entry {
>> > +       __u32 index;
>> > +       __u32 reserved;
>> > +       __u64 data;
>> > +};
>>
>> makes sense to move this to include/linux/kvm.h ?
>
> x86 didn't, and you can get away with it because it's only used in a
> #define.
>

ok, fine with me.

>> > +static int get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *val)
>> > +{
>> > +       const struct coproc_reg *r;
>> > +       u32 coproc = get_bits(index, KVM_ARM_MSR_COPROC_MASK);
>> > +
>> > +       /* We only do cp15 for now. */
>> > +       if (coproc != 15)
>> > +               return -EINVAL;
>> > +
>> > +       r = index_to_cp15(vcpu, index);
>> > +       if (!r)
>> > +               return -EINVAL;
>> > +
>> > +       *val = vcpu->arch.cp15[r->reg];
>> > +       if (r->is_64)
>> > +               *val |= ((u64)vcpu->arch.cp15[r->reg+1]) << 32;
>> > +       return 0;
>> > +}
>> > +
>> > +static int set_msr(struct kvm_vcpu *vcpu, u32 index, u64 val)
>> > +{
>> > +       const struct coproc_reg *r;
>> > +       u32 coproc = get_bits(index, KVM_ARM_MSR_COPROC_MASK);
>> > +
>> > +       /* We only do cp15 for now. */
>> > +       if (coproc != 15)
>> > +               return -EINVAL;
>> > +
>> > +       r = index_to_cp15(vcpu, index);
>> > +       if (!r)
>> > +               return -EINVAL;
>> > +
>> > +       vcpu->arch.cp15[r->reg] = val;
>> > +       if (r->is_64)
>> > +               vcpu->arch.cp15[r->reg+1] = (val >> 32);
>> > +       return 0;
>> > +}
>>
>> worth combining get_msr and set_msr with a 'bool write' parameter?
>
> Almost, but not quite, IMHO.  I renamed index_to_cp15 to
> index_to_coproc_reg and put the coproc check in there, so it shares even
> more code though.
>

sounds good

>> > +       u32 i, index;
>> > +       u64 val;
>> > +       u64 __user *uval;
>> > +       int ret;
>> > +
>> > +       for (i = 0; i < num; i++) {
>> > +               uval = get_umsr(&entries[i], &index);
>> > +               if (!uval)
>> > +                       return -EFAULT;
>> > +               if (copy_from_user(&val, uval, sizeof(val)) != 0)
>> > +                       return -EFAULT;
>>
>> get_user ?
>
> Didn't compile with a u64 IIRC.
>
>> > +       /* FIXME: Assumes no duplicates! */
>>
>> If this is a FIXME, shouldn't we just fix it (allocate a table of the
>> registers, zero it out, set a bit and only count once)? I prefer not
>> merging new FIXMEs if possible.
>
> OK, that makes it a bit more complex.  We actually do want
> target-specific entries to be able to override generic ones, I think,
> though it's not necessary today.
>
> This is the only code which doesn't respect that, so I wrote a function
> to walk both and do the Right Thing with duplicates.
>
>> > +/* Puts in the position indicated by mask (assumes val fits in mask) */
>> > +static inline u32 set_bits(u32 val, u32 mask)
>> > +{
>> > +       return val << (ffs(mask)-1);
>>
>> spaces around the - operator iirc.
>
> Fixed (though I prefer it without spaces, as it's clearer).
>

Actually, I thought checkpatch would complain, but it turns out it doesn't.

>> > +/**
>> > + * kvm_arm_msridx - what's the index value for the nth register.
>>
>> this is not the name of the function
>>
>> > + *
>> > + * This is for special registers, particularly cp15.
>> > + */
>> > +int kvm_copy_msrindices(struct kvm_vcpu *vcpu, u32 __user *uindices)
>>
>> shouldn't this be kvm_arm_copy_msrindicies for consistency?
>
> Yep, fixed.
>
>> ok, this is pretty damn nice. Good argument for driving the cp15
>> register reset from here ;)
>
> Yes, I wrote this patch series backwards, starting here.
>

-Christoffer
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[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