* [PATCH] SMP: Setup multiple tss for real mode emulation
@ 2007-07-12 7:53 He, Qing
[not found] ` <37E52D09333DE2469A03574C88DBF40F048E7C-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: He, Qing @ 2007-07-12 7:53 UTC (permalink / raw)
To: kvm-devel
[-- Attachment #1: Type: text/plain, Size: 4568 bytes --]
This patch sets up multiple TSS for real mode emulation on Intel vmx,
one for each vcpu. This is a preparation patch for full SMP real mode
support.
Signed-off-by: Qing He <qing.he-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
kvm.h | 1 +
kvm_main.c | 1 +
vmx.c | 31 +++++++++++++++++--------------
3 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 65ab268..0f7a4d9 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -328,6 +328,7 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
struct kvm_vcpu {
struct kvm *kvm;
+ int vcpu_id;
union {
struct vmcs *vmcs;
struct vcpu_svm *svm;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a4429eb..4d2ef9b 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2387,6 +2387,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm
*kvm, int n)
goto out;
vcpu = &kvm->vcpus[n];
+ vcpu->vcpu_id = n;
mutex_lock(&vcpu->mutex);
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 80628f6..beb25e3 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -32,7 +32,7 @@
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
-static int init_rmode_tss(struct kvm *kvm);
+static int init_rmode_tss(struct kvm *kvm, int vcpu_id);
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -897,9 +897,10 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
}
-static int rmode_tss_base(struct kvm* kvm)
+static int rmode_tss_base(struct kvm* kvm, int vcpu_id)
{
- gfn_t base_gfn = kvm->memslots[0].base_gfn +
kvm->memslots[0].npages - 3;
+ gfn_t base_gfn = kvm->memslots[0].base_gfn +
kvm->memslots[0].npages
+ - 3 * (vcpu_id + 1);
return base_gfn << PAGE_SHIFT;
}
@@ -923,7 +924,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vcpu->rmode.active = 1;
vcpu->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
- vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
+ vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm,
vcpu->vcpu_id));
vcpu->rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
@@ -955,7 +956,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_GS, &vcpu->rmode.gs);
fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
- init_rmode_tss(vcpu->kvm);
+ init_rmode_tss(vcpu->kvm, vcpu->vcpu_id);
}
#ifdef CONFIG_X86_64
@@ -1178,10 +1179,10 @@ static void vmx_set_gdt(struct kvm_vcpu *vcpu,
struct descriptor_table *dt)
vmcs_writel(GUEST_GDTR_BASE, dt->base);
}
-static int init_rmode_tss(struct kvm* kvm)
+static int init_rmode_tss(struct kvm* kvm, int vcpu_id)
{
struct page *p1, *p2, *p3;
- gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT;
+ gfn_t fn = rmode_tss_base(kvm, vcpu_id) >> PAGE_SHIFT;
char *page;
p1 = gfn_to_page(kvm, fn++);
@@ -1244,7 +1245,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
int ret = 0;
unsigned long kvm_vmx_return;
- if (!init_rmode_tss(vcpu->kvm)) {
+ if (!init_rmode_tss(vcpu->kvm, vcpu->vcpu_id)) {
ret = -ENOMEM;
goto out;
}
@@ -1253,7 +1254,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->regs[VCPU_REGS_RDX] = get_rdx_init_val();
vcpu->cr8 = 0;
vcpu->apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
- if (vcpu == &vcpu->kvm->vcpus[0])
+ if (vcpu->vcpu_id == 0)
vcpu->apic_base |= MSR_IA32_APICBASE_BSP;
fx_init(vcpu);
@@ -1262,10 +1263,13 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
* GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
* insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4.
Sigh.
*/
- vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
- vmcs_writel(GUEST_CS_BASE, 0x000f0000);
- vmcs_write32(GUEST_CS_LIMIT, 0xffff);
- vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
+ if (vcpu->vcpu_id == 0) {
+ vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
+ vmcs_writel(GUEST_CS_BASE, 0x000f0000);
+ vmcs_write32(GUEST_CS_LIMIT, 0xffff);
+ vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
+ vmcs_writel(GUEST_RIP, 0xfff0);
+ }
seg_setup(VCPU_SREG_DS);
seg_setup(VCPU_SREG_ES);
@@ -1288,7 +1292,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_SYSENTER_EIP, 0);
vmcs_writel(GUEST_RFLAGS, 0x02);
- vmcs_writel(GUEST_RIP, 0xfff0);
vmcs_writel(GUEST_RSP, 0);
//todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0
[-- Attachment #2: kvm-smp-vcpu-tss.patch --]
[-- Type: application/octet-stream, Size: 4057 bytes --]
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 65ab268..0f7a4d9 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -328,6 +328,7 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
struct kvm_vcpu {
struct kvm *kvm;
+ int vcpu_id;
union {
struct vmcs *vmcs;
struct vcpu_svm *svm;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a4429eb..4d2ef9b 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2387,6 +2387,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
goto out;
vcpu = &kvm->vcpus[n];
+ vcpu->vcpu_id = n;
mutex_lock(&vcpu->mutex);
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 80628f6..beb25e3 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -32,7 +32,7 @@
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
-static int init_rmode_tss(struct kvm *kvm);
+static int init_rmode_tss(struct kvm *kvm, int vcpu_id);
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -897,9 +897,10 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
}
-static int rmode_tss_base(struct kvm* kvm)
+static int rmode_tss_base(struct kvm* kvm, int vcpu_id)
{
- gfn_t base_gfn = kvm->memslots[0].base_gfn + kvm->memslots[0].npages - 3;
+ gfn_t base_gfn = kvm->memslots[0].base_gfn + kvm->memslots[0].npages
+ - 3 * (vcpu_id + 1);
return base_gfn << PAGE_SHIFT;
}
@@ -923,7 +924,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vcpu->rmode.active = 1;
vcpu->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
- vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
+ vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm, vcpu->vcpu_id));
vcpu->rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
@@ -955,7 +956,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_GS, &vcpu->rmode.gs);
fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
- init_rmode_tss(vcpu->kvm);
+ init_rmode_tss(vcpu->kvm, vcpu->vcpu_id);
}
#ifdef CONFIG_X86_64
@@ -1178,10 +1179,10 @@ static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
vmcs_writel(GUEST_GDTR_BASE, dt->base);
}
-static int init_rmode_tss(struct kvm* kvm)
+static int init_rmode_tss(struct kvm* kvm, int vcpu_id)
{
struct page *p1, *p2, *p3;
- gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT;
+ gfn_t fn = rmode_tss_base(kvm, vcpu_id) >> PAGE_SHIFT;
char *page;
p1 = gfn_to_page(kvm, fn++);
@@ -1244,7 +1245,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
int ret = 0;
unsigned long kvm_vmx_return;
- if (!init_rmode_tss(vcpu->kvm)) {
+ if (!init_rmode_tss(vcpu->kvm, vcpu->vcpu_id)) {
ret = -ENOMEM;
goto out;
}
@@ -1253,7 +1254,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->regs[VCPU_REGS_RDX] = get_rdx_init_val();
vcpu->cr8 = 0;
vcpu->apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
- if (vcpu == &vcpu->kvm->vcpus[0])
+ if (vcpu->vcpu_id == 0)
vcpu->apic_base |= MSR_IA32_APICBASE_BSP;
fx_init(vcpu);
@@ -1262,10 +1263,13 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
* GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
* insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh.
*/
- vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
- vmcs_writel(GUEST_CS_BASE, 0x000f0000);
- vmcs_write32(GUEST_CS_LIMIT, 0xffff);
- vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
+ if (vcpu->vcpu_id == 0) {
+ vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
+ vmcs_writel(GUEST_CS_BASE, 0x000f0000);
+ vmcs_write32(GUEST_CS_LIMIT, 0xffff);
+ vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
+ vmcs_writel(GUEST_RIP, 0xfff0);
+ }
seg_setup(VCPU_SREG_DS);
seg_setup(VCPU_SREG_ES);
@@ -1288,7 +1292,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_SYSENTER_EIP, 0);
vmcs_writel(GUEST_RFLAGS, 0x02);
- vmcs_writel(GUEST_RIP, 0xfff0);
vmcs_writel(GUEST_RSP, 0);
//todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0
[-- Attachment #3: Type: text/plain, Size: 286 bytes --]
-------------------------------------------------------------------------
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/
[-- Attachment #4: Type: text/plain, Size: 186 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] SMP: Setup multiple tss for real mode emulation
[not found] ` <37E52D09333DE2469A03574C88DBF40F048E7C-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2007-07-12 8:16 ` Avi Kivity
[not found] ` <4695E34E.2030506-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Avi Kivity @ 2007-07-12 8:16 UTC (permalink / raw)
To: He, Qing; +Cc: kvm-devel
He, Qing wrote:
> This patch sets up multiple TSS for real mode emulation on Intel vmx,
> one for each vcpu. This is a preparation patch for full SMP real mode
> support.
>
>
Why are separate tss's needed? Can't all vcpus use the same tss?
> Signed-off-by: Qing He <qing.he-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
>
> kvm.h | 1 +
> kvm_main.c | 1 +
> vmx.c | 31 +++++++++++++++++--------------
> 3 files changed, 19 insertions(+), 14 deletions(-)
>
>
> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
> index 65ab268..0f7a4d9 100644
> --- a/drivers/kvm/kvm.h
> +++ b/drivers/kvm/kvm.h
> @@ -328,6 +328,7 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
>
> struct kvm_vcpu {
> struct kvm *kvm;
> + int vcpu_id;
>
Switching to ->vcpu_id instead of computing (vcpu - vcpu->kvm->vcpus) is
a good idea (and necessary when separately allocating vcpus). But in
its own patch, please.
> - vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
> - vmcs_writel(GUEST_CS_BASE, 0x000f0000);
> - vmcs_write32(GUEST_CS_LIMIT, 0xffff);
> - vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
> + if (vcpu->vcpu_id == 0) {
> + vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
> + vmcs_writel(GUEST_CS_BASE, 0x000f0000);
> + vmcs_write32(GUEST_CS_LIMIT, 0xffff);
> + vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
> + vmcs_writel(GUEST_RIP, 0xfff0);
> + }
>
>
Since you're not initializing these registers for vcpu_id != 0, we might
as well not touch this code.
--
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/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] SMP: Setup multiple tss for real mode emulation
[not found] ` <4695E34E.2030506-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
@ 2007-07-12 8:53 ` He, Qing
0 siblings, 0 replies; 3+ messages in thread
From: He, Qing @ 2007-07-12 8:53 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm-devel
[-- Attachment #1: Type: text/plain, Size: 2488 bytes --]
>-----Original Message-----
>From: Avi Kivity [mailto:avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org]
>Sent: 2007年7月12日 16:16
>To: He, Qing
>Cc: kvm-devel
>Subject: Re: [kvm-devel] [PATCH] SMP: Setup multiple tss for real mode emulation
>
>He, Qing wrote:
>> This patch sets up multiple TSS for real mode emulation on Intel vmx,
>> one for each vcpu. This is a preparation patch for full SMP real mode
>> support.
>>
>>
>
>Why are separate tss's needed? Can't all vcpus use the same tss?
Yeah, I think it can. At first, I was thinking that using multiple tss is more natural, because the real mode of different vcpu are regarded as different tasks (in the guest). But now, it appears OK to me since the tss should be read only. There's no vm86 task switch inside the guest; and task switch in the kernel doesn't really affect the tss. Although I personally prefer the multiple tss, current code is OK to me.
>
>> Signed-off-by: Qing He <qing.he-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>>
>>
>> kvm.h | 1 +
>> kvm_main.c | 1 +
>> vmx.c | 31 +++++++++++++++++--------------
>> 3 files changed, 19 insertions(+), 14 deletions(-)
>>
>>
>> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
>> index 65ab268..0f7a4d9 100644
>> --- a/drivers/kvm/kvm.h
>> +++ b/drivers/kvm/kvm.h
>> @@ -328,6 +328,7 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
>>
>> struct kvm_vcpu {
>> struct kvm *kvm;
>> + int vcpu_id;
>>
>
>Switching to ->vcpu_id instead of computing (vcpu - vcpu->kvm->vcpus) is
>a good idea (and necessary when separately allocating vcpus). But in
>its own patch, please.
OK, that's fine. I'll post a separate patch.
>
>> - vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
>> - vmcs_writel(GUEST_CS_BASE, 0x000f0000);
>> - vmcs_write32(GUEST_CS_LIMIT, 0xffff);
>> - vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
>> + if (vcpu->vcpu_id == 0) {
>> + vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
>> + vmcs_writel(GUEST_CS_BASE, 0x000f0000);
>> + vmcs_write32(GUEST_CS_LIMIT, 0xffff);
>> + vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
>> + vmcs_writel(GUEST_RIP, 0xfff0);
>> + }
>>
>>
>
>Since you're not initializing these registers for vcpu_id != 0, we might
>as well not touch this code.
Agree. I also think leaving it untouched right now is better, so I'll defer this to SIPI patches.
Thanks,
Qing
>
>--
>Do not meddle in the internals of kernels, for they are subtle and quick to panic.
[-- Attachment #2: Type: text/plain, Size: 286 bytes --]
-------------------------------------------------------------------------
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/
[-- Attachment #3: Type: text/plain, Size: 186 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-07-12 8:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-12 7:53 [PATCH] SMP: Setup multiple tss for real mode emulation He, Qing
[not found] ` <37E52D09333DE2469A03574C88DBF40F048E7C-wq7ZOvIWXbM/UvCtAeCM4rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-12 8:16 ` Avi Kivity
[not found] ` <4695E34E.2030506-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-12 8:53 ` He, Qing
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.