Skip to contentSkip to conversation

KVM paravirt_ops implementation

PATCH In review Anthony Liguori 14 participants 40 messages May 30, 2007 – May 31, 2007 16 messages not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover KVM paravirt_ops implementation

This is the start of a paravirt_ops implementation for KVM. Most of it was done by Ingo Molnar, I just moved things around a bit. I don't think there's a measurable performance benefit just yet but there are a few more optimizations that I think we can get in time for 2.6.23 that will be measurable.

Regards,

Anthony Liguori

#1 lore raw

PATCH 1/3 KVM paravirt_ops infrastructure

Regards,

Anthony Liguori

Subject: [PATCH] Add KVM paravirt_ops implementation
From: Anthony Liguori <[email protected]>

This patch adds the basic infrastructure for paravirtualizing a KVM guest. Discovery of running under KVM is done by sharing a page of memory between the guest and host (initially through an MSR write).

This is based on a patch written by Ingo Molnar.

arch/i386/Kconfig +7 -0
Index: kvm/arch/i386/Kconfig
===================================================================
@@ -231,6 +231,13 @@
 	  at the moment), by linking the kernel to a GPL-ed ROM module
 	  provided by the hypervisor.
 
+config KVM_GUEST
+	bool "KVM paravirt-ops support"
+	depends on PARAVIRT
+	help
+	  This option enables various optimizations for running under the KVM
+          hypervisor.
+
 config ACPI_SRAT
 	bool
 	default y
arch/i386/kernel/Makefile +1 -0
Index: kvm/arch/i386/kernel/Makefile
===================================================================
@@ -41,6 +41,7 @@
 obj-$(CONFIG_K8_NB)		+= k8.o
 
 obj-$(CONFIG_VMI)		+= vmi.o vmiclock.o
+obj-$(CONFIG_KVM_GUEST)		+= kvm.o
 obj-$(CONFIG_PARAVIRT)		+= paravirt.o
 obj-y				+= pcspeaker.o
 
arch/i386/kernel/kvm.c new file +100 -0

100 lines not on this page · raw message

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#2 lore raw

RE: [kvm-devel] [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 3 lines · Anthony Liguori

Regards,

Anthony Liguori

I think we should use the CPUID instruction (leaf 0x40000000) to detect the hypervosor as we are doing in Xen.

Jun
---
Intel Open Source Technology Center

A message that is not in the archive (sent off-list or not yet received): 97D612E30E1F88419025B06CB4CF1BE10259AAD7-1a9uaKK1+wJcIJlls4ac1rfspsVTdybXVpNB7YpNyf8@public.gmane.org

#4 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 10 lines · Jun
Quoted 4 lines · Anthony Liguori

Regards,

Anthony Liguori

I think we should use the CPUID instruction (leaf 0x40000000) to detect the hypervosor as we are doing in Xen.

Is that leaf reserved for such use by Intel?

Regards,

Anthony Liguori

Quoted 4 lines

Jun
---
Intel Open Source Technology Center

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): 465DBE3A.6030908-r/[email protected]

#6 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 9 lines · Anthony Liguori
Quoted 8 lines · Jun
Quoted 4 lines · Anthony Liguori

Regards,

Anthony Liguori

I think we should use the CPUID instruction (leaf 0x40000000) to

detect

Quoted 5 lines
Quoted 2 lines

the hypervosor as we are doing in Xen.

Is that leaf reserved for such use by Intel?

What I can say is that we (including the H/W teams) reviewed it internally.

Quoted 4 lines

Regards,

Anthony Liguori

Jun
---
Intel Open Source Technology Center

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): 97D612E30E1F88419025B06CB4CF1BE10259AD83-1a9uaKK1+wJcIJlls4ac1rfspsVTdybXVpNB7YpNyf8@public.gmane.org

#8 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 19 lines · Jun
Quoted 5 lines · Anthony Liguori
Quoted 3 lines · Jun

Anthony Liguori wrote:

Quoted 7 lines
Quoted 7 lines
Quoted 5 lines

Regards,

Anthony Liguori

I think we should use the CPUID instruction (leaf 0x40000000) to

detect

Quoted 3 lines
Quoted 3 lines

the hypervosor as we are doing in Xen.

Quoted 7 lines
Quoted 3 lines

Is that leaf reserved for such use by Intel?

What I can say is that we (including the H/W teams) reviewed it internally.

I've switched to using CPUID. I noticed that Xen also uses 0x400000001 so I'm presuming that that is okay too?

Regards,

Anthony Liguori

Quoted 11 lines
Quoted 5 lines

Regards,

Anthony Liguori

Jun
---
Intel Open Source Technology Center

Quoted 11 lines

-------------------------------------------------------------------------
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 [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): 465F0688.1050702-r/[email protected]

#10 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 2 lines · Anthony Liguori
Quoted 1 line · Jun

What I can say is that we (including the H/W teams) reviewed it

internally.

Quoted 3 lines
Quoted 1 line

I've switched to using CPUID. I noticed that Xen also uses

0x400000001

Quoted 1 line

so I'm presuming that that is okay too?

Yes.

Quoted 4 lines

Regards,

Anthony Liguori

Jun
---
Intel Open Source Technology Center

-------------------------------------------------------------------------
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/

#11 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

In reply to Anthony Liguori
Quoted 2 lines · Anthony Liguori

This patch adds the basic infrastructure for paravirtualizing a KVM guest.

Hi Anthony!

Nice patch, comments below.

Quoted 3 lines

Discovery of running under KVM is done by sharing a page of memory between
the guest and host (initially through an MSR write).

I missed the shared page in this patch? If you are going to do that, perhaps putting the hypercall magic in that page is a good idea?

Quoted 1 line

+extern unsigned char hypercall_addr[4];

Perhaps in a header?

arch/i386/kernel/kvm.c line 47

Quoted 7 lines
arch/i386/kernel/kvm.c new file +7 -0
+asm (
+       ".globl hypercall_addr\n"
+       ".align 4\n"
+       "hypercall_addr:\n"
+       "movl $-38, %eax\n"
+       "ret\n"
+);

I don't think we want the hypercall returning Linux error numbers, and magic numbers are bad too. ud2 here I think.

arch/i386/kernel/kvm.c line 65

Quoted 5 lines
arch/i386/kernel/kvm.c new file +5 -0
+       para_state->guest_version = KVM_PARA_API_VERSION;
+       para_state->host_version = -1;
+       para_state->size = sizeof(*para_state);
+       para_state->ret = 0;
+       para_state->hypercall_gpa = __pa(hypercall_addr);

Two versions, size *and* ret? This seems like overkill...

arch/i386/kernel/kvm.c line 70

Quoted 4 lines
arch/i386/kernel/kvm.c new file +4 -0
+       if (wrmsr_safe(MSR_KVM_API_MAGIC, __pa(para_state), 0)) {
+               printk(KERN_INFO "KVM guest: WRMSR probe failed.\n");
+               return -ENOENT;
+       }

How about printk(KERN_INFO "I am not a KVM guest\n");?

arch/i386/kernel/kvm.c line 92

Quoted 7 lines
arch/i386/kernel/kvm.c new file +7 -0
+static int __init kvm_guest_init(void)
+{
+       int rc;
+
+       rc = kvm_guest_register_para(smp_processor_id());
+       if (rc) {
+               printk(KERN_INFO "paravirt KVM unavailable\n");

Double-printk when KVM isn't detected seems overkill. Perhaps you could just fold this all into one function...

(Personal gripe: I consider a variable named "rc" to be an admission of semantic defeat... "err" would be better here...)

Thanks!
Rusty.

#12 lore raw

Re: [kvm-devel] [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 11 lines · Rusty Russell
Quoted 3 lines · Anthony Liguori

This patch adds the basic infrastructure for paravirtualizing a KVM guest.

Hi Anthony!

Nice patch, comments below.

Quoted 8 lines
Quoted 4 lines

Discovery of running under KVM is done by sharing a page of memory between
the guest and host (initially through an MSR write).

I missed the shared page in this patch? If you are going to do that, perhaps putting the hypercall magic in that page is a good idea?

para_state is the shared page. The address is passed to the KVM via the MSR (so it's a shared page owned by the guest).

Quoted 6 lines
Quoted 2 lines

+extern unsigned char hypercall_addr[4];

Perhaps in a header?

Quoted 12 lines

arch/i386/kernel/kvm.c line 47

Quoted 8 lines
arch/i386/kernel/kvm.c new file +7 -0
+asm (
+       ".globl hypercall_addr\n"
+       ".align 4\n"
+       "hypercall_addr:\n"
+       "movl $-38, %eax\n"
+       "ret\n"
+);

I don't think we want the hypercall returning Linux error numbers, and magic numbers are bad too. ud2 here I think.

Yeah, you're not the first one to suggest this. The thing is, KVM already has host-side support for a hypercall API. I didn't want to change that unless I had to. However, based on the prior feedback re: using CPUID, I will be changing it so I'll update this too.

Quoted 9 lines

arch/i386/kernel/kvm.c line 65

Quoted 6 lines
arch/i386/kernel/kvm.c new file +5 -0
+       para_state->guest_version = KVM_PARA_API_VERSION;
+       para_state->host_version = -1;
+       para_state->size = sizeof(*para_state);
+       para_state->ret = 0;
+       para_state->hypercall_gpa = __pa(hypercall_addr);

Two versions, size *and* ret? This seems like overkill...

Yeah, I agree :-) I actually am not a huge fan of using version numbers. I think I'm going to try the next patch using a single version number and a feature bitmap. Some of the optimizations (like MMU batching) don't make sense in a NPT/EPT environment but the guest shouldn't have to be aware of that.

Quoted 9 lines

arch/i386/kernel/kvm.c line 70

Quoted 5 lines
arch/i386/kernel/kvm.c new file +4 -0
+       if (wrmsr_safe(MSR_KVM_API_MAGIC, __pa(para_state), 0)) {
+               printk(KERN_INFO "KVM guest: WRMSR probe failed.\n");
+               return -ENOENT;
+       }

How about printk(KERN_INFO "I am not a KVM guest\n");?

Quoted 12 lines

arch/i386/kernel/kvm.c line 92

Quoted 8 lines
arch/i386/kernel/kvm.c new file +7 -0
+static int __init kvm_guest_init(void)
+{
+       int rc;
+
+       rc = kvm_guest_register_para(smp_processor_id());
+       if (rc) {
+               printk(KERN_INFO "paravirt KVM unavailable\n");

Double-printk when KVM isn't detected seems overkill. Perhaps you could just fold this all into one function...

Already have.

Quoted 3 lines

(Personal gripe: I consider a variable named "rc" to be an admission of semantic defeat... "err" would be better here...)

I'm not sure I agree that's one's better than the other. Although I guess if (err) { reads a little better...

Regards,

Anthony Liguori

Quoted 15 lines

Thanks!
Rusty.

-------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): 1180573347.30202.135.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#14 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 3 lines · Rusty Russell

Two versions, size *and* ret? This seems like overkill...

I think we ought to move away from version numbers and use feature availability flags instead.

Quoted 10 lines

arch/i386/kernel/kvm.c line 92

Quoted 3 lines
arch/i386/kernel/kvm.c new file +2 -0
+       if (rc) {
+               printk(KERN_INFO "paravirt KVM unavailable\n");

Double-printk when KVM isn't detected seems overkill. Perhaps you could just fold this all into one function...

(Personal gripe: I consider a variable named "rc" to be an admission of semantic defeat... "err" would be better here...)

I just use 'r' (short for 'argh').

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
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/
#15 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

In reply to a message not in the archive
Quoted 7 lines

arch/i386/kernel/kvm.c line 70

Quoted 5 lines
arch/i386/kernel/kvm.c new file +4 -0
+       if (wrmsr_safe(MSR_KVM_API_MAGIC, __pa(para_state), 0)) {
+               printk(KERN_INFO "KVM guest: WRMSR probe failed.\n");
+               return -ENOENT;
+       }

How about printk(KERN_INFO "I am not a KVM guest\n");?

Actually paravirt probes that fail should be silent; similar like drivers that don't find their hardware should do the same. Otherwise if there are later distro kernels with various of those compiled in the boot log would become quite noisy

-andi

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): [email protected]

#17 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 6 lines · Andi Kleen
Quoted 6 lines
Quoted 5 lines
arch/i386/kernel/kvm.c new file +4 -0
+       if (wrmsr_safe(MSR_KVM_API_MAGIC, __pa(para_state), 0)) {
+               printk(KERN_INFO "KVM guest: WRMSR probe failed.\n");
+               return -ENOENT;
+       }
Quoted 6 lines
Quoted 1 line

How about printk(KERN_INFO "I am not a KVM guest\n");?

Actually paravirt probes that fail should be silent; similar like drivers that don't find their hardware should do the same. Otherwise if there are later distro kernels with various of those compiled in the boot log would become quite noisy

yeah. I suspect printing that it's executing in native mode is OK.

Ingo

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): [email protected]

#19 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 9 lines · On Thursday 31 May 2007 12:11:16 Ingo Molnar wrote:
Quoted 6 lines · Andi Kleen
Quoted 6 lines
Quoted 5 lines
(quoted diff) +4 -0
+       if (wrmsr_safe(MSR_KVM_API_MAGIC, __pa(para_state), 0)) {
+               printk(KERN_INFO "KVM guest: WRMSR probe failed.\n");
+               return -ENOENT;
+       }
Quoted 8 lines
Quoted 6 lines
Quoted 1 line

How about printk(KERN_INFO "I am not a KVM guest\n");?

Actually paravirt probes that fail should be silent; similar like drivers that don't find their hardware should do the same. Otherwise if there are later distro kernels with various of those compiled in the boot log would become quite noisy

yeah. I suspect printing that it's executing in native mode is OK.

But only a single printk for that please

-Andi

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): [email protected]

#21 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 12 lines · Andi Kleen
Quoted 11 lines · On Thursday 31 May 2007 12:11:16 Ingo Molnar wrote:
Quoted 8 lines · Andi Kleen
Quoted 7 lines

Review

Quoted 5 lines
(quoted diff) +4 -0
+       if (wrmsr_safe(MSR_KVM_API_MAGIC, __pa(para_state), 0)) {
+               printk(KERN_INFO "KVM guest: WRMSR probe failed.\n");
+               return -ENOENT;
+       }

How about printk(KERN_INFO "I am not a KVM guest\n");?

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

Actually paravirt probes that fail should be silent; similar like drivers that don't find their hardware should do the same. Otherwise if there are later distro kernels with various of those compiled in the boot log would become quite noisy

yeah. I suspect printing that it's executing in native mode is OK.

But only a single printk for that please

Which already exists in paravirt.c:

static void __init default_banner(void)

{
	printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
	       paravirt_ops.name);
}
...
static int __init print_banner(void)
{
	paravirt_ops.banner();
	return 0;
}

core_initcall(print_banner);

Hmm, this will predate your kvm initcall tho, and making that a pure_initcall is pretty gross...

Cheers,
Rusty.

-------------------------------------------------------------------------
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/

#22 lore raw

Re: [kvm-devel] [PATCH 1/3] KVM paravirt_ops infrastructure

Quoted 34 lines · Rusty Russell
Quoted 10 lines · Andi Kleen
Quoted 8 lines · On Thursday 31 May 2007 12:11:16 Ingo Molnar wrote:
Quoted 5 lines · Andi Kleen
Quoted 5 lines
Quoted 5 lines
(quoted diff) +4 -0
+       if (wrmsr_safe(MSR_KVM_API_MAGIC, __pa(para_state), 0)) {
+               printk(KERN_INFO "KVM guest: WRMSR probe failed.\n");
+               return -ENOENT;
+       }
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

How about printk(KERN_INFO "I am not a KVM guest\n");?

Actually paravirt probes that fail should be silent; similar like drivers that don't find their hardware should do the same. Otherwise if there are later distro kernels with various of those compiled in the boot log would become quite noisy

yeah. I suspect printing that it's executing in native mode is OK.

But only a single printk for that please

Which already exists in paravirt.c:

static void __init default_banner(void)

{
	printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
	       paravirt_ops.name);
}
...
static int __init print_banner(void)
{
	paravirt_ops.banner();
	return 0;
}
Quoted 5 lines

core_initcall(print_banner);

Hmm, this will predate your kvm initcall tho, and making that a pure_initcall is pretty gross...

My current patch uses core_initcall() and presumably works by magic of linking order.

Any other suggestions over core_initcall()?

Regards,

Anthony Liguori

Quoted 15 lines

Cheers,
Rusty.

-------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#23 lore raw

Re: [PATCH 1/3] KVM paravirt_ops infrastructure

In reply to a message not in the archive
Quoted 7 lines · Andi Kleen
Quoted 2 lines · On Thursday 31 May 2007 12:11:16 Ingo Molnar wrote:

yeah. I suspect printing that it's executing in native mode is OK.

But only a single printk for that please

This will be taken care of in the next round of patches.

Regards,

Anthony Liguori

Quoted 13 lines

-Andi

-------------------------------------------------------------------------
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 [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

-------------------------------------------------------------------------
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/

#24 lore raw

PATCH 2/3 Make IO delay a NOP

In reply to Anthony Liguori

Regards,

Anthony Liguori

Subject: [PATCH][PARAVIRT] Make IO delay a NOP for paravirt guests

No delay is required in between PIO operations under KVM guests so make IO delay a NOP. This was originally part of Ingo Molnar's paravirt series.

arch/i386/kernel/kvm.c +8 -0
Index: kvm/arch/i386/kernel/kvm.c
===================================================================
@@ -28,9 +28,17 @@
 static DEFINE_PER_CPU(struct kvm_vcpu_para_state, para_state);
 extern unsigned char hypercall_addr[4];
 
+/*
+ * No need for any "IO delay" on KVM
+ */
+static void kvm_io_delay(void)
+{
+}
+
 static void kvm_guest_setup(void)
 {
 	paravirt_ops.name = "KVM";
+	paravirt_ops.io_delay = kvm_io_delay;
 	paravirt_ops.paravirt_enabled = 1;
 }
 

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

A message that is not in the archive (sent off-list or not yet received): 465D8F03.7000201-r/[email protected]

#26 lore raw

PATCH 3/3 Eliminate read_cr3 on TLB flush

Regards,

Anthony Liguori

Subject: [PATCH][PARAVIRT] Eliminate unnecessary CR3 read in TLB flush

This patch eliminates the CR3 read (which would cause a VM exit) in the TLB flush path. The patch is based on Ingo Molnar's paravirt series.

arch/i386/kernel/kvm.c +26 -0
Index: kvm/arch/i386/kernel/kvm.c
===================================================================
@@ -24,11 +24,35 @@
 #include <linux/kernel.h>
 #include <linux/kvm_para.h>
 #include <linux/cpu.h>
+#include <linux/mm.h>
+#include <asm/processor.h>
+#include <asm/tlbflush.h>
 
 static DEFINE_PER_CPU(struct kvm_vcpu_para_state, para_state);
 extern unsigned char hypercall_addr[4];
 
 /*
+ * Avoid the VM exit upon cr3 load by using the cached
+ * ->active_mm->pgd value:
+ */
+static void kvm_flush_tlb_user(void)
+{
+	write_cr3(__pa(current->active_mm->pgd));
+}
+
+/*
+ * Avoid VM exit for cr3 read by calling into kvm_flush_tlb_user
+ */
+static fastcall void kvm_flush_tlb_kernel(void)
+{
+	unsigned long orig_cr4 = read_cr4();
+
+	write_cr4(orig_cr4 & ~X86_CR4_PGE);
+	kvm_flush_tlb_user();
+	write_cr4(orig_cr4);
+}
+
+/*
  * No need for any "IO delay" on KVM
  */
 static void kvm_io_delay(void)
@@ -38,6 +62,8 @@
 static void kvm_guest_setup(void)
 {
 	paravirt_ops.name = "KVM";
+	paravirt_ops.flush_tlb_user = kvm_flush_tlb_user;
+	paravirt_ops.flush_tlb_kernel = kvm_flush_tlb_kernel;
 	paravirt_ops.io_delay = kvm_io_delay;
 	paravirt_ops.paravirt_enabled = 1;
 }

-------------------------------------------------------------------------
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 [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): 465D8FF5.6040804-r/[email protected]

#28 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 5 lines · On Wednesday 30 May 2007 16:53:41 Anthony Liguori wrote:

Subject: [PATCH][PARAVIRT] Eliminate unnecessary CR3 read in TLB flush

This patch eliminates the CR3 read (which would cause a VM exit) in the TLB flush path.  The patch is based on Ingo Molnar's paravirt series.

This change could be just done generically for the native architecture, couldn't it?

-Andi

-------------------------------------------------------------------------
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/

#29 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 11 lines · Andi Kleen
Quoted 6 lines · On Wednesday 30 May 2007 16:53:41 Anthony Liguori wrote:

Subject: [PATCH][PARAVIRT] Eliminate unnecessary CR3 read in TLB flush

This patch eliminates the CR3 read (which would cause a VM exit) in the TLB flush path. The patch is based on Ingo Molnar's paravirt series.

This change could be just done generically for the native architecture, couldn't it?

Sure. It adds a few more cycles onto native though (two memory reads, and some math). How does the following look?

Regards,

Anthony Liguori

Quoted 2 lines

-Andi

Subject: [PATCH] Avoid reading CR3 on TLB flush
From: Anthony Liguori <[email protected]>

In a virtualized environment, there is significant overhead in reading and writing control registers. Since we already have the value of CR3 in current->active_mm->pgd, we can avoid taking the exit on CR3 read when doing a TLB flush.

include/asm-i386/tlbflush.h +13 -14
Index: kvm/include/asm-i386/tlbflush.h
===================================================================
@@ -14,13 +14,12 @@
 
 #define __native_flush_tlb()						\
 	do {								\
-		unsigned int tmpreg;					\
+		unsigned int cr3 = __pa(current->active_mm->pgd);	\
 									\
 		__asm__ __volatile__(					\
-			"movl %%cr3, %0;              \n"		\
 			"movl %0, %%cr3;  # flush TLB \n"		\
-			: "=r" (tmpreg)					\
-			:: "memory");					\
+			:: "r" (cr3)				       	\
+			: "memory");					\
 	} while (0)
 
 /*
@@ -29,18 +28,18 @@
  */
 #define __native_flush_tlb_global()					\
 	do {								\
-		unsigned int tmpreg, cr4, cr4_orig;			\
+		unsigned int cr3 = __pa(current->active_mm->pgd);	\
+		unsigned int cr4, cr4_orig;				\
 									\
 		__asm__ __volatile__(					\
-			"movl %%cr4, %2;  # turn off PGE     \n"	\
-			"movl %2, %1;                        \n"	\
-			"andl %3, %1;                        \n"	\
-			"movl %1, %%cr4;                     \n"	\
-			"movl %%cr3, %0;                     \n"	\
-			"movl %0, %%cr3;  # flush TLB        \n"	\
-			"movl %2, %%cr4;  # turn PGE back on \n"	\
-			: "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig)	\
-			: "i" (~X86_CR4_PGE)				\
+			"movl %%cr4, %1;  # turn off PGE     \n"	\
+			"movl %1, %0;                        \n"	\
+			"andl %2, %0;                        \n"	\
+			"movl %0, %%cr4;                     \n"	\
+			"movl %3, %%cr3;  # flush TLB        \n"	\
+			"movl %1, %%cr4;  # turn PGE back on \n"	\
+			: "=&r" (cr4), "=&r" (cr4_orig)			\
+			: "i" (~X86_CR4_PGE), "r" (cr3)			\
 			: "memory");					\
 	} while (0)
 

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#30 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 2 lines · Anthony Liguori

Sure. It adds a few more cycles onto native though (two memory reads, and some math).

As opposed to a serializing control-register read? I think that's probably a win.

J

A message that is not in the archive (sent off-list or not yet received): [email protected]

#32 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 2 lines · Jeremy Fitzhardinge
Quoted 1 line · Anthony Liguori

Sure. It adds a few more cycles onto native though (two memory

reads,

Quoted 7 lines
Quoted 1 line

and some math).

As opposed to a serializing control-register read? I think that's probably a win.

J

And actually you don't need the write to CR3 to flush TLB because the one to CR4 does it. Or does kvm_flush_tlb_kernel assume that CR3 is updated at the same time?

Jun
---
Intel Open Source Technology Center

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): 97D612E30E1F88419025B06CB4CF1BE10259AB81-1a9uaKK1+wJcIJlls4ac1rfspsVTdybXVpNB7YpNyf8@public.gmane.org

#34 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 5 lines · Jun

And actually you don't need the write to CR3 to flush TLB because the one to CR4 does it. Or does kvm_flush_tlb_kernel assume that CR3 is updated at the same time?

Jun

It should not be necessary, but I believe this was added as a workaround to a PII erratum. I can't find the erratum, however, and the history of using G bits in Linux is complicated (several bugs introduced and many intermediate versions of this code). Since this is not performance critical, I think it is probably best to leave the CR3 reload.

However, being unnecessary on modern processors, I already submitted a patch to eliminate it on 64-bit (or maybe just told Andi about it, I can't recall).

Zach

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): [email protected]

#36 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 2 lines · Zachary Amsden
Quoted 1 line · Jun

And actually you don't need the write to CR3 to flush TLB because

the

Quoted 1 line
Quoted 1 line

one to CR4 does it. Or does kvm_flush_tlb_kernel assume that CR3 is

updated

Quoted 5 lines
Quoted 3 lines

at the same time?

Jun

It should not be necessary, but I believe this was added as a

workaround

Quoted 1 line

to a PII erratum. I can't find the erratum, however, and the history

of

Quoted 3 lines

using G bits in Linux is complicated (several bugs introduced and many intermediate versions of this code). Since this is not performance critical, I think it is probably best to leave the CR3 reload.

I don't recommend this for old processors.

Quoted 6 lines

However, being unnecessary on modern processors, I already submitted a patch to eliminate it on 64-bit (or maybe just told Andi about it, I can't recall).

Zach

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

Jun
---
Intel Open Source Technology Center

-------------------------------------------------------------------------
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/

#37 lore raw

Re: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 36 lines · Jun
Quoted 4 lines · Zachary Amsden
Quoted 2 lines · Jun

And actually you don't need the write to CR3 to flush TLB because

the

Quoted 2 lines
Quoted 2 lines

one to CR4 does it. Or does kvm_flush_tlb_kernel assume that CR3 is

updated

Quoted 6 lines
Quoted 4 lines

at the same time?

Jun

It should not be necessary, but I believe this was added as a

workaround

Quoted 2 lines

to a PII erratum. I can't find the erratum, however, and the history

of

Quoted 4 lines

using G bits in Linux is complicated (several bugs introduced and many intermediate versions of this code). Since this is not performance critical, I think it is probably best to leave the CR3 reload.

I don't recommend this for old processors.

Quoted 4 lines

However, being unnecessary on modern processors, I already submitted a patch to eliminate it on 64-bit (or maybe just told Andi about it, I can't recall).

Quoted 6 lines
Quoted 2 lines

Zach

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Regards,

Anthony Liguori

Quoted 4 lines

Jun
---
Intel Open Source Technology Center

A message that is not in the archive (sent off-list or not yet received): 465DCED8.4080506-r/[email protected]

#39 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 1 line · Anthony Liguori

Nakajima, Jun wrote:

<snip>

Quoted 1 line
Quoted 1 line

For KVM, it should be okay as well. But we can replace two CR4

accesses

Quoted 6 lines
Quoted 2 lines

with just one hypercall.

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in

a

Quoted 1 line

control register. The thought here is that it would be useful not

just

Quoted 2 lines

for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Given the optimizations for CPU virtualization in the current H/W, I'm not sure if such hooks are useful. Do you have any performance data that justify such hooks?

Quoted 5 lines

Regards,

Anthony Liguori

Jun
---
Intel Open Source Technology Center

-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): 97D612E30E1F88419025B06CB4CF1BE10259AE6D-1a9uaKK1+wJcIJlls4ac1rfspsVTdybXVpNB7YpNyf8@public.gmane.org

#41 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 7 lines · Jun

Anthony Liguori wrote:

Given the optimizations for CPU virtualization in the current H/W, I'm not sure if such hooks are useful. Do you have any performance data that justify such hooks?

No, I don't. It was just a thought that was yet to be confirmed.

Regards,

Anthony Liguori

Quoted 11 lines
Quoted 5 lines

Regards,

Anthony Liguori

Jun
---
Intel Open Source Technology Center

Quoted 11 lines

-------------------------------------------------------------------------
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 [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

-------------------------------------------------------------------------
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/

#42 lore raw

Re: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Nakajima, Jun
Quoted 7 lines · Jun

Anthony Liguori wrote:

Given the optimizations for CPU virtualization in the current H/W, I'm not sure if such hooks are useful. Do you have any performance data that justify such hooks?

No, I don't. It was just a thought that was yet to be confirmed.

Regards,

Anthony Liguori

Quoted 22 lines
Quoted 5 lines

Regards,

Anthony Liguori

Jun
---
Intel Open Source Technology Center

-------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#43 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to a message not in the archive
Quoted 7 lines · Anthony Liguori

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

You don't need STTS: just cache CR0 value on writes and replace read_cr0. More paravirt_op hooks would likely be frowned upon, we've already got too many.

Zach

-------------------------------------------------------------------------
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/

#44 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to a message not in the archive
Quoted 7 lines · Anthony Liguori
Quoted 6 lines
Quoted 2 lines

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

Quoted 7 lines

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Are global tlb flushes frequent enough to warrant optimization?

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
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/

A message that is not in the archive (sent off-list or not yet received): 465E7E4F.8050208-atKUWr5tajBWk0Htik3J/[email protected]

#46 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

Quoted 8 lines · Avi Kivity
Quoted 7 lines · Anthony Liguori
Quoted 4 lines
Quoted 1 line

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

I was thinking the same thing :-)

Quoted 7 lines
Quoted 5 lines

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Are global tlb flushes frequent enough to warrant optimization?

Not very, unless you have a most unusual workload on 32-bit with highmem and suffer from kmap exhaustion.

Zach

-------------------------------------------------------------------------
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/

#47 lore raw

Re: [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to a message not in the archive
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Anthony Liguori
Quoted 8 lines
Quoted 3 lines

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

I was thinking the same thing :-)

Quoted 9 lines
Quoted 6 lines

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Are global tlb flushes frequent enough to warrant optimization?

I don't think so, so I'm going to remove this from the series. I'm adding another an MMU batching patch which should be enough measurable performance advantage to warrant the series.

Regards,

Anthony Liguori

-------------------------------------------------------------------------
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/

#48 lore raw

Re: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Avi Kivity
Quoted 10 lines · Avi Kivity
Quoted 8 lines · Anthony Liguori
Quoted 8 lines
Quoted 3 lines

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

Quoted 8 lines
Quoted 5 lines

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Are global tlb flushes frequent enough to warrant optimization?

I don't think so, so I'm going to remove this from the series. I'm adding another an MMU batching patch which should be enough measurable performance advantage to warrant the series.

Regards,

Anthony Liguori

#49 lore raw

RE: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Anthony Liguori
Quoted 1 line · Anthony Liguori

Nakajima, Jun wrote:

<snip>

Quoted 1 line
Quoted 1 line

For KVM, it should be okay as well. But we can replace two CR4

accesses

Quoted 6 lines
Quoted 2 lines

with just one hypercall.

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in

a

Quoted 1 line

control register. The thought here is that it would be useful not

just

Quoted 2 lines

for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Given the optimizations for CPU virtualization in the current H/W, I'm not sure if such hooks are useful. Do you have any performance data that justify such hooks?

Quoted 5 lines

Regards,

Anthony Liguori

Jun
---
Intel Open Source Technology Center

#50 lore raw

Re: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Anthony Liguori
Quoted 4 lines · Anthony Liguori

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

You don't need STTS: just cache CR0 value on writes and replace read_cr0. More paravirt_op hooks would likely be frowned upon, we've already got too many.

Zach

#51 lore raw

Re: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Anthony Liguori
Quoted 4 lines · Anthony Liguori

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

We don't really need one, because Linux (i386) only cares about the TS bit of cr0. From lguest (you'd want this per-cpu of course):

        static unsigned long current_cr0, current_cr3;
        static void lguest_write_cr0(unsigned long val)
        {
        	lazy_hcall(LHCALL_TS, val & 8, 0, 0);
        	current_cr0 = val;
        }
        
        static unsigned long lguest_read_cr0(void)
        {
        	return current_cr0;
        }

Cheers,
Rusty.

#52 lore raw

Re: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Anthony Liguori
Quoted 11 lines · Anthony Liguori
Quoted 6 lines
Quoted 2 lines

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

I was thinking the same thing :-)

I was actually thinking about adding a hypercall to set/clear a bit in a control register. The thought here is that it would be useful not just for the global bit but also for CR0.TS although we would need another paravirt_op hook for stts.

Are global tlb flushes frequent enough to warrant optimization?

Signature · 1 line
error compiling committee.c: too many arguments to function
#53 lore raw

RE: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Zachary Amsden
Quoted 2 lines · Zachary Amsden
Quoted 1 line · Jun

And actually you don't need the write to CR3 to flush TLB because

the

Quoted 1 line
Quoted 1 line

one to CR4 does it. Or does kvm_flush_tlb_kernel assume that CR3 is

updated

Quoted 5 lines
Quoted 3 lines

at the same time?

Jun

It should not be necessary, but I believe this was added as a

workaround

Quoted 1 line

to a PII erratum. I can't find the erratum, however, and the history

of

Quoted 3 lines

using G bits in Linux is complicated (several bugs introduced and many intermediate versions of this code). Since this is not performance critical, I think it is probably best to leave the CR3 reload.

I don't recommend this for old processors.

Quoted 6 lines

However, being unnecessary on modern processors, I already submitted a patch to eliminate it on 64-bit (or maybe just told Andi about it, I can't recall).

Zach

For KVM, it should be okay as well. But we can replace two CR4 accesses with just one hypercall.

Jun
---
Intel Open Source Technology Center

#54 lore raw

Re: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Nakajima, Jun
Quoted 5 lines · Jun

And actually you don't need the write to CR3 to flush TLB because the one to CR4 does it. Or does kvm_flush_tlb_kernel assume that CR3 is updated at the same time?

Jun

It should not be necessary, but I believe this was added as a workaround to a PII erratum. I can't find the erratum, however, and the history of using G bits in Linux is complicated (several bugs introduced and many intermediate versions of this code). Since this is not performance critical, I think it is probably best to leave the CR3 reload.

However, being unnecessary on modern processors, I already submitted a patch to eliminate it on 64-bit (or maybe just told Andi about it, I can't recall).

Zach

#55 lore raw

RE: [kvm-devel] [PATCH 3/3] Eliminate read_cr3 on TLB flush

In reply to Jeremy Fitzhardinge
Quoted 2 lines · Jeremy Fitzhardinge
Quoted 1 line · Anthony Liguori

Sure. It adds a few more cycles onto native though (two memory

reads,

Quoted 7 lines
Quoted 1 line

and some math).

As opposed to a serializing control-register read? I think that's probably a win.

J

And actually you don't need the write to CR3 to flush TLB because the one to CR4 does it. Or does kvm_flush_tlb_kernel assume that CR3 is updated at the same time?

Jun
---
Intel Open Source Technology Center