[added back cc]

Paul Turner wrote:
> On 7/13/07, Avi Kivity <[EMAIL PROTECTED]> wrote:
>> Paul Turner wrote:
>> > From: Paul Turner <[EMAIL PROTECTED]>
>> >
>> > - vcpus now allocated on demand
>> > - vmx/svm fields separated into arch specific structures on vcpus
>> > - vmx/svm fields now only allocated on corresponding architectures
>> >
>> > - Paul
>> >
>> > diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
>> > index 0f7a4d9..c631192 100644
>> > --- a/drivers/kvm/kvm.h
>> > +++ b/drivers/kvm/kvm.h
>> > @@ -16,6 +16,7 @@ #include <linux/mm.h>
>> >  #include <asm/signal.h>
>> >
>> >  #include "vmx.h"
>> > +#include "kvm_svm.h"
>>
>> This can probably be avoided, see below.
>>
>> >  #include <linux/kvm.h>
>> >  #include <linux/kvm_para.h>
>> >
>> > @@ -326,16 +327,64 @@ struct kvm_io_device *kvm_io_bus_find_de
>> >  void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
>> >                   struct kvm_io_device *dev);
>> >
>> > +struct kvm_vmx_data {
>> > +    int msr_offset_efer;
>> > +
>> > +        #ifdef CONFIG_X86_64
>> > +    int msr_offset_kernel_gs_base;
>> > +        #endif
>> > +
>> > +        struct vmx_host_state {
>> > +        int loaded;
>> > +        u16 fs_sel, gs_sel, ldt_sel;
>> > +        int fs_gs_ldt_reload_needed;
>> > +    } host_state;
>> > +
>> > +    struct vmx_msr_entry *guest_msrs;
>> > +    struct vmx_msr_entry *host_msrs;
>> > +
>> > +    struct {
>> > +        int active;
>> > +        u8 save_iopl;
>> > +        struct kvm_save_segment {
>> > +            u16 selector;
>> > +            unsigned long base;
>> > +            u32 limit;
>> > +            u32 ar;
>> > +        } tr, es, ds, fs, gs;
>> > +    } rmode;
>> > +    int halt_request; /* real mode */
>> > + +    struct vmcs *vmcs;
>> > +};
>> > +
>>
>> If this is moved to vmx.c, we can avoid including vmx.h and have no arch
>> dependent code here (given that we don't even need the size).
>>
>
> I originally did this however gcc refuses to compile with the
> incomplete types, although after further investigation it turns out
> it's a bug in gcc with an incomplete implementation of zero sized
> arrays under a union, so I can fix this now.  See notes below..
>

Looks like you forgot the notes below :)

Anyway the only fix I can see is to have a long[0] member at the end,
and have vmx.c define a function vmx(vcpu) which returns the vmx
specific data.  Accesses would look like

  vmx(vcpu)->cr0 = 42;

which is odd, but I've seen worse.  But if you have a better solution,
let's hear it.

>> > +struct kvm_svm_data {
>> > +    struct vmcb *vmcb;
>> > +    unsigned long vmcb_pa;
>> > +    struct svm_cpu_data *svm_data;
>> > +    uint64_t asid_generation;
>> > +
>> > +    unsigned long db_regs[NUM_DB_REGS];
>> > +
>> > +    u64 next_rip;
>> > +
>> > +    u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
>> > +    u64 host_gs_base;
>> > +    unsigned long host_cr2;
>> > +    unsigned long host_db_regs[NUM_DB_REGS];
>> > +    unsigned long host_dr6;
>> > +    unsigned long host_dr7;
>> > +};
>>
>> This can remain in kvm_svm.h.
>
> I was going to move both structures out in a small follow up patch, I
> didn't in this one because of the compile issue above + not wanting to
> make this patch any larger than it already is.. :)  I can merge it
> into this one if you prefer..

Don't understand.  If it remains in kvm_svm.h, the patch gets smaller,
not larger.

>
>>
>>
>> > +
>> > +
>> >  struct kvm_vcpu {
>> >      struct kvm *kvm;
>> > +    struct mutex *mutex; /* refers to corresponding vcpu_mutex on
>> kvm */
>>
>> Please keep this as a real structure, not a pointer.  Existence testing
>> of the vcpu is now simply if (kvm->vcpus[slot]).
>
> Some of the existing code makes the assumption that locking the cpu
> locks the slot as well; also if we don't have an associated lock/mutex
> then we'd have to take a global lock on slot updates/checks.  Finally
> you'd still have a race in between checking it's a valid vcpu and
> trying to acquire it's mutex..

The only place the race matters is in vcpu creation.  There, we can do
something like

    vcpu = kvm_arch_ops->vcpu_create(...);
    spin_lock(kvm);
    if (kvm->vcpus[slot]) {
        r = -EEXIST;
        vcpu_free(vcpu);
    } else
        kvm->vcpus[slot] = vcpu;
    spin_unlock(kvm);

In the other places, if the user has a thread creating a vcpu and
another thread performing an operation on it, it's perfectly legitimate
to return -ENOENT.

>> > -    page = alloc_page(GFP_KERNEL | __GFP_ZERO);
>> > +    vcpu->mutex = &kvm->vcpu_mutex[n];
>> > +    vcpu->cpu = -1;
>> > +    vcpu->kvm = kvm;
>> > +    vcpu->mmu.root_hpa = INVALID_PAGE;
>> > +
>> > +    vcpu->vcpu_id = n;
>> > +    kvm->vcpus[n] = vcpu;
>> > +
>> > +    run_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
>> >      r = -ENOMEM;
>> > -    if (!page)
>> > -        goto out_unlock;
>> > -    vcpu->run = page_address(page);
>> > +    if (!run_page)
>> > +        goto out_deallocate;
>> > +    vcpu->run = page_address(run_page);
>> >
>>
>> This cleanup is good, but makes the patch larger.  Please defer it.
>>
>
> this needs to be done on vcpu creation (it was part of vm init
> before), if you're concerned about patch size I can break up the
> structure separation and dynamic allocation fairly easily since they
> are different commits in my repository (I just didn't originally want
> to rebase them both :)

Yes, you're right -- it is necessary.  It can live in the main patch.

>
> please advise on splits/etc as above and ill resubmit
>

One patch is okay.  We should aim for kvm_main.c not knowing (including)
anything about vmx or svm.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to 
panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to