From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Paul Turner <pjt-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: KVM <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Subject: Re: [PATCH] dynamically create vcpus + vmx/svm structures
Date: Sat, 14 Jul 2007 09:14:39 +0300 [thread overview]
Message-ID: <469869CF.8030106@qumranet.com> (raw)
In-Reply-To: <ed628a920707131534x7fe57ca3sfa09d9d79412d9c6-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[added back cc]
Paul Turner wrote:
> On 7/13/07, Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org> wrote:
>> Paul Turner wrote:
>> > From: Paul Turner <pjt-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
>> >
>> > - 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/
next prev parent reply other threads:[~2007-07-14 6:14 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-13 1:20 [PATCH] dynamically create vcpus + vmx/svm structures Paul Turner
[not found] ` <Pine.LNX.4.64.0707121815040.23503-hxTPNdr267xSzHKm+aFRNNkmqwFzkYv6@public.gmane.org>
2007-07-13 7:59 ` Avi Kivity
[not found] ` <ed628a920707131534x7fe57ca3sfa09d9d79412d9c6@mail.gmail.com>
[not found] ` <ed628a920707131534x7fe57ca3sfa09d9d79412d9c6-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-07-14 6:14 ` Avi Kivity [this message]
[not found] ` <469869CF.8030106-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-18 22:36 ` Paul Turner
[not found] ` <Pine.LNX.4.64.0707181528430.32400-hxTPNdr267xSzHKm+aFRNNkmqwFzkYv6@public.gmane.org>
2007-07-19 9:19 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=469869CF.8030106@qumranet.com \
--to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=pjt-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.