Skip to contentSkip to conversation

kvm updates for 2.6.21

PATCH In review Avi Kivity 10 participants 40 messages Feb 19, 2007 – Feb 25, 2007 10 messages not in the archive

Subsystems (2)
lore
Share & tools
lore

Avi Kivity

author
#0 lore raw

cover kvm updates for 2.6.21

Following is a series of kvm updates. Please apply to Linux 2.6.21.

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
author
#1 lore raw

PATCH 1/13 KVM: mmu: add missing dirty page tracking cases

We fail to mark a page dirty in three cases:

- setting the accessed bit in a pte
- setting the dirty bit in a pte
- emulating a write into a pagetable

This fix adds the missing cases.

drivers/kvm/paging_tmpl.h +13 -2
Index: linux-2.6/drivers/kvm/paging_tmpl.h
===================================================================
@@ -128,8 +128,10 @@ static int FNAME(walk_addr)(struct guest
 			goto access_error;
 #endif
 
-		if (!(*ptep & PT_ACCESSED_MASK))
-			*ptep |= PT_ACCESSED_MASK; 	/* avoid rmw */
+		if (!(*ptep & PT_ACCESSED_MASK)) {
+			mark_page_dirty(vcpu->kvm, table_gfn);
+			*ptep |= PT_ACCESSED_MASK;
+		}
 
 		if (walker->level == PT_PAGE_TABLE_LEVEL) {
 			walker->gfn = (*ptep & PT_BASE_ADDR_MASK)
@@ -185,6 +187,12 @@ static void FNAME(release_walker)(struct
 		kunmap_atomic(walker->table, KM_USER0);
 }
 
+static void FNAME(mark_pagetable_dirty)(struct kvm *kvm,
+					struct guest_walker *walker)
+{
+	mark_page_dirty(kvm, walker->table_gfn[walker->level - 1]);
+}
+
 static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte,
 			   u64 *shadow_pte, u64 access_bits, gfn_t gfn)
 {
@@ -348,12 +356,15 @@ static int FNAME(fix_write_pf)(struct kv
 	} else if (kvm_mmu_lookup_page(vcpu, gfn)) {
 		pgprintk("%s: found shadow page for %lx, marking ro\n",
 			 __FUNCTION__, gfn);
+		mark_page_dirty(vcpu->kvm, gfn);
+		FNAME(mark_pagetable_dirty)(vcpu->kvm, walker);
 		*guest_ent |= PT_DIRTY_MASK;
 		*write_pt = 1;
 		return 0;
 	}
 	mark_page_dirty(vcpu->kvm, gfn);
 	*shadow_ent |= PT_WRITABLE_MASK;
+	FNAME(mark_pagetable_dirty)(vcpu->kvm, walker);
 	*guest_ent |= PT_DIRTY_MASK;
 	rmap_add(vcpu, shadow_ent);
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#2 lore raw

PATCH 2/13 KVM: Move virtualization deactivation from CPU_DEAD state to CPU_DOWN_PREPARE

In reply to Avi Kivity

From: Jeremy Katz <[email protected]>

This gives it more chances of surviving suspend.

drivers/kvm/kvm_main.c +6 -2
Index: linux-2.6/drivers/kvm/kvm_main.c
===================================================================
@@ -2080,13 +2080,17 @@ static int kvm_cpu_hotplug(struct notifi
 	int cpu = (long)v;
 
 	switch (val) {
-	case CPU_DEAD:
+	case CPU_DOWN_PREPARE:
 	case CPU_UP_CANCELED:
+		printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n",
+		       cpu);
 		decache_vcpus_on_cpu(cpu);
 		smp_call_function_single(cpu, kvm_arch_ops->hardware_disable,
 					 NULL, 0, 1);
 		break;
-	case CPU_UP_PREPARE:
+	case CPU_ONLINE:
+		printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n",
+		       cpu);
 		smp_call_function_single(cpu, kvm_arch_ops->hardware_enable,
 					 NULL, 0, 1);
 		break;

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#3 lore raw

PATCH 3/13 KVM: Cosmetics

In reply to Avi Kivity
drivers/kvm/kvm_main.c +8 -13
Index: linux-2.6/drivers/kvm/kvm_main.c
===================================================================
@@ -126,10 +126,8 @@ static inline int valid_vcpu(int n)
 	return likely(n >= 0 && n < KVM_MAX_VCPUS);
 }
 
-int kvm_read_guest(struct kvm_vcpu *vcpu,
-			     gva_t addr,
-			     unsigned long size,
-			     void *dest)
+int kvm_read_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
+		   void *dest)
 {
 	unsigned char *host_buf = dest;
 	unsigned long req_size = size;
@@ -161,10 +159,8 @@ int kvm_read_guest(struct kvm_vcpu *vcpu
 }
 EXPORT_SYMBOL_GPL(kvm_read_guest);
 
-int kvm_write_guest(struct kvm_vcpu *vcpu,
-			     gva_t addr,
-			     unsigned long size,
-			     void *data)
+int kvm_write_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
+		    void *data)
 {
 	unsigned char *host_buf = data;
 	unsigned long req_size = size;
@@ -457,7 +453,7 @@ EXPORT_SYMBOL_GPL(set_cr4);
 void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
 	if (is_long_mode(vcpu)) {
-		if ( cr3 & CR3_L_MODE_RESEVED_BITS) {
+		if (cr3 & CR3_L_MODE_RESEVED_BITS) {
 			printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
 			inject_gp(vcpu);
 			return;
@@ -774,7 +770,6 @@ static int kvm_dev_ioctl_get_dirty_log(s
 	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
 		goto out;
 
-
 	if (any) {
 		cleared = 0;
 		for (i = 0; i < KVM_MAX_VCPUS; ++i) {
@@ -903,8 +898,9 @@ static int emulator_read_emulated(unsign
 		return X86EMUL_CONTINUE;
 	else {
 		gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
+
 		if (gpa == UNMAPPED_GVA)
-			return vcpu_printf(vcpu, "not present\n"), X86EMUL_PROPAGATE_FAULT;
+			return X86EMUL_PROPAGATE_FAULT;
 		vcpu->mmio_needed = 1;
 		vcpu->mmio_phys_addr = gpa;
 		vcpu->mmio_size = bytes;
@@ -1801,12 +1797,11 @@ static long kvm_dev_ioctl(struct file *f
 	case KVM_GET_API_VERSION:
 		r = KVM_API_VERSION;
 		break;
-	case KVM_CREATE_VCPU: {
+	case KVM_CREATE_VCPU:
 		r = kvm_dev_ioctl_create_vcpu(kvm, arg);
 		if (r)
 			goto out;
 		break;
-	}
 	case KVM_RUN: {
 		struct kvm_run kvm_run;
 
drivers/kvm/svm.c +5 -5
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -1042,22 +1042,22 @@ static int io_interception(struct kvm_vc
 
 		addr_mask = io_adress(vcpu, _in, &kvm_run->io.address);
 		if (!addr_mask) {
-			printk(KERN_DEBUG "%s: get io address failed\n", __FUNCTION__);
+			printk(KERN_DEBUG "%s: get io address failed\n",
+			       __FUNCTION__);
 			return 1;
 		}
 
 		if (kvm_run->io.rep) {
-			kvm_run->io.count = vcpu->regs[VCPU_REGS_RCX] & addr_mask;
+			kvm_run->io.count
+				= vcpu->regs[VCPU_REGS_RCX] & addr_mask;
 			kvm_run->io.string_down = (vcpu->svm->vmcb->save.rflags
 						   & X86_EFLAGS_DF) != 0;
 		}
-	} else {
+	} else
 		kvm_run->io.value = vcpu->svm->vmcb->save.rax;
-	}
 	return 0;
 }
 
-
 static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	return 1;
drivers/kvm/vmx.c +1 -3
Index: linux-2.6/drivers/kvm/vmx.c
===================================================================
@@ -27,7 +27,6 @@
 
 #include "segment_descriptor.h"
 
-
 MODULE_AUTHOR("Qumranet");
 MODULE_LICENSE("GPL");
 
@@ -418,10 +417,9 @@ static int vmx_set_msr(struct kvm_vcpu *
 	case MSR_IA32_SYSENTER_ESP:
 		vmcs_write32(GUEST_SYSENTER_ESP, data);
 		break;
-	case MSR_IA32_TIME_STAMP_COUNTER: {
+	case MSR_IA32_TIME_STAMP_COUNTER:
 		guest_write_tsc(data);
 		break;
-	}
 	default:
 		msr = find_msr_entry(vcpu, msr_index);
 		if (msr) {
drivers/kvm/paging_tmpl.h +1 -2
Index: linux-2.6/drivers/kvm/paging_tmpl.h
===================================================================
@@ -441,9 +441,8 @@ static int FNAME(page_fault)(struct kvm_
 	/*
 	 * mmio: emulate if accessible, otherwise its a guest fault.
 	 */
-	if (is_io_pte(*shadow_pte)) {
+	if (is_io_pte(*shadow_pte))
 		return 1;
-	}
 
 	++kvm_stat.pf_fixed;
 	kvm_mmu_audit(vcpu, "post page fault (fixed)");

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#4 lore raw

PATCH 4/13 KVM: vmx: hack set_cr0_no_modeswitch() to actually do modeswitch

In reply to Avi Kivity

From: Markus Rechberger <[email protected]>
From: Joerg Roedel <[email protected]>

The whole thing is rotten, but this allows vmx to boot with the guest reboot fix.

drivers/kvm/vmx.c +3 -0
Index: linux-2.6/drivers/kvm/vmx.c
===================================================================
@@ -791,6 +791,9 @@ static void vmx_set_cr0(struct kvm_vcpu 
  */
 static void vmx_set_cr0_no_modeswitch(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
+	if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK))
+		enter_rmode(vcpu);
+
 	vcpu->rmode.active = ((cr0 & CR0_PE_MASK) == 0);
 	update_exception_bitmap(vcpu);
 	vmcs_writel(CR0_READ_SHADOW, cr0);

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#5 lore raw

PATCH 5/13 KVM: Use ARRAY_SIZE macro instead of manual calculation.

In reply to Avi Kivity

From: Ahmed S. Darwish <[email protected]>

drivers/kvm/svm.c +3 -2
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -15,6 +15,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/vmalloc.h>
 #include <linux/highmem.h>
 #include <linux/profile.h>
@@ -75,7 +76,7 @@ struct svm_init_data {
 
 static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
 
-#define NUM_MSR_MAPS (sizeof(msrpm_ranges) / sizeof(*msrpm_ranges))
+#define NUM_MSR_MAPS ARRAY_SIZE(msrpm_ranges)
 #define MSRS_RANGE_SIZE 2048
 #define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2)
 
@@ -1297,7 +1298,7 @@ static int handle_exit(struct kvm_vcpu *
 		       __FUNCTION__, vcpu->svm->vmcb->control.exit_int_info,
 		       exit_code);
 
-	if (exit_code >= sizeof(svm_exit_handlers) / sizeof(*svm_exit_handlers)
+	if (exit_code >= ARRAY_SIZE(svm_exit_handlers)
 	    || svm_exit_handlers[exit_code] == 0) {
 		kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
 		printk(KERN_ERR "%s: 0x%x @ 0x%llx cr0 0x%lx rflags 0x%llx\n",
drivers/kvm/vmx.c +2 -1
Index: linux-2.6/drivers/kvm/vmx.c
===================================================================
@@ -19,6 +19,7 @@
 #include "vmx.h"
 #include "kvm_vmx.h"
 #include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/profile.h>
@@ -75,7 +76,7 @@ static const u32 vmx_msr_index[] = {
 #endif
 	MSR_EFER, MSR_K6_STAR,
 };
-#define NR_VMX_MSR (sizeof(vmx_msr_index) / sizeof(*vmx_msr_index))
+#define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
 
 static inline int is_page_fault(u32 intr_info)
 {
drivers/kvm/kvm_svm.h +2 -1
Index: linux-2.6/drivers/kvm/kvm_svm.h
===================================================================
@@ -1,6 +1,7 @@
 #ifndef __KVM_SVM_H
 #define __KVM_SVM_H
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <asm/msr.h>
@@ -18,7 +19,7 @@ static const u32 host_save_msrs[] = {
 	MSR_IA32_LASTBRANCHTOIP, MSR_IA32_LASTINTFROMIP,MSR_IA32_LASTINTTOIP,*/
 };
 
-#define NR_HOST_SAVE_MSRS (sizeof(host_save_msrs) / sizeof(*host_save_msrs))
+#define NR_HOST_SAVE_MSRS ARRAY_SIZE(host_save_msrs)
 #define NUM_DB_REGS 4
 
 struct vcpu_svm {

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#6 lore raw

PATCH 6/13 KVM: Use page_private()/set_page_private() apis

In reply to Avi Kivity

From: Markus Rechberger <[email protected]>

Besides using an established api, this allows using kvm in older kernels.

drivers/kvm/mmu.c +18 -18
Index: linux-2.6/drivers/kvm/mmu.c
===================================================================
@@ -298,18 +298,18 @@ static void rmap_add(struct kvm_vcpu *vc
 	if (!is_rmap_pte(*spte))
 		return;
 	page = pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT);
-	if (!page->private) {
+	if (!page_private(page)) {
 		rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte);
-		page->private = (unsigned long)spte;
-	} else if (!(page->private & 1)) {
+		set_page_private(page,(unsigned long)spte);
+	} else if (!(page_private(page) & 1)) {
 		rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte);
 		desc = mmu_alloc_rmap_desc(vcpu);
-		desc->shadow_ptes[0] = (u64 *)page->private;
+		desc->shadow_ptes[0] = (u64 *)page_private(page);
 		desc->shadow_ptes[1] = spte;
-		page->private = (unsigned long)desc | 1;
+		set_page_private(page,(unsigned long)desc | 1);
 	} else {
 		rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte);
-		desc = (struct kvm_rmap_desc *)(page->private & ~1ul);
+		desc = (struct kvm_rmap_desc *)(page_private(page) & ~1ul);
 		while (desc->shadow_ptes[RMAP_EXT-1] && desc->more)
 			desc = desc->more;
 		if (desc->shadow_ptes[RMAP_EXT-1]) {
@@ -337,12 +337,12 @@ static void rmap_desc_remove_entry(struc
 	if (j != 0)
 		return;
 	if (!prev_desc && !desc->more)
-		page->private = (unsigned long)desc->shadow_ptes[0];
+		set_page_private(page,(unsigned long)desc->shadow_ptes[0]);
 	else
 		if (prev_desc)
 			prev_desc->more = desc->more;
 		else
-			page->private = (unsigned long)desc->more | 1;
+			set_page_private(page,(unsigned long)desc->more | 1);
 	mmu_free_rmap_desc(vcpu, desc);
 }
 
@@ -356,20 +356,20 @@ static void rmap_remove(struct kvm_vcpu 
 	if (!is_rmap_pte(*spte))
 		return;
 	page = pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT);
-	if (!page->private) {
+	if (!page_private(page)) {
 		printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
 		BUG();
-	} else if (!(page->private & 1)) {
+	} else if (!(page_private(page) & 1)) {
 		rmap_printk("rmap_remove:  %p %llx 1->0\n", spte, *spte);
-		if ((u64 *)page->private != spte) {
+		if ((u64 *)page_private(page) != spte) {
 			printk(KERN_ERR "rmap_remove:  %p %llx 1->BUG\n",
 			       spte, *spte);
 			BUG();
 		}
-		page->private = 0;
+		set_page_private(page,0);
 	} else {
 		rmap_printk("rmap_remove:  %p %llx many->many\n", spte, *spte);
-		desc = (struct kvm_rmap_desc *)(page->private & ~1ul);
+		desc = (struct kvm_rmap_desc *)(page_private(page) & ~1ul);
 		prev_desc = NULL;
 		while (desc) {
 			for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i)
@@ -398,11 +398,11 @@ static void rmap_write_protect(struct kv
 	BUG_ON(!slot);
 	page = gfn_to_page(slot, gfn);
 
-	while (page->private) {
-		if (!(page->private & 1))
-			spte = (u64 *)page->private;
+	while (page_private(page)) {
+		if (!(page_private(page) & 1))
+			spte = (u64 *)page_private(page);
 		else {
-			desc = (struct kvm_rmap_desc *)(page->private & ~1ul);
+			desc = (struct kvm_rmap_desc *)(page_private(page) & ~1ul);
 			spte = desc->shadow_ptes[0];
 		}
 		BUG_ON(!spte);
@@ -1218,7 +1218,7 @@ static int alloc_mmu_pages(struct kvm_vc
 		INIT_LIST_HEAD(&page_header->link);
 		if ((page = alloc_page(GFP_KERNEL)) == NULL)
 			goto error_1;
-		page->private = (unsigned long)page_header;
+		set_page_private(page, (unsigned long)page_header);
 		page_header->page_hpa = (hpa_t)page_to_pfn(page) << PAGE_SHIFT;
 		memset(__va(page_header->page_hpa), 0, PAGE_SIZE);
 		list_add(&page_header->link, &vcpu->free_pages);
drivers/kvm/kvm_main.c +1 -1
Index: linux-2.6/drivers/kvm/kvm_main.c
===================================================================
@@ -670,7 +670,7 @@ raced:
 						     | __GFP_ZERO);
 			if (!new.phys_mem[i])
 				goto out_free;
- 			new.phys_mem[i]->private = 0;
+			set_page_private(new.phys_mem[i],0);
 		}
 	}
 
drivers/kvm/kvm.h +1 -1
Index: linux-2.6/drivers/kvm/kvm.h
===================================================================
@@ -523,7 +523,7 @@ static inline struct kvm_mmu_page *page_
 {
 	struct page *page = pfn_to_page(shadow_page >> PAGE_SHIFT);
 
-	return (struct kvm_mmu_page *)page->private;
+	return (struct kvm_mmu_page *)page_private(page);
 }
 
 static inline u16 read_fs(void)

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#7 lore raw

PATCH 7/13 KVM: add MSR based hypercall API

In reply to Avi Kivity

From: Ingo Molnar <[email protected]>

This adds a special MSR based hypercall API to KVM. This is to be used by paravirtual kernels and virtual drivers.

drivers/kvm/kvm_main.c +73 -0
Index: linux-2.6/drivers/kvm/kvm_main.c
===================================================================
@@ -1204,6 +1204,73 @@ void realmode_set_cr(struct kvm_vcpu *vc
 	}
 }
 
+/*
+ * Register the para guest with the host:
+ */
+static int vcpu_register_para(struct kvm_vcpu *vcpu, gpa_t para_state_gpa)
+{
+	struct kvm_vcpu_para_state *para_state;
+	hpa_t para_state_hpa, hypercall_hpa;
+	struct page *para_state_page;
+	unsigned char *hypercall;
+	gpa_t hypercall_gpa;
+
+	printk(KERN_DEBUG "kvm: guest trying to enter paravirtual mode\n");
+	printk(KERN_DEBUG ".... para_state_gpa: %08Lx\n", para_state_gpa);
+
+	/*
+	 * Needs to be page aligned:
+	 */
+	if (para_state_gpa != PAGE_ALIGN(para_state_gpa))
+		goto err_gp;
+
+	para_state_hpa = gpa_to_hpa(vcpu, para_state_gpa);
+	printk(KERN_DEBUG ".... para_state_hpa: %08Lx\n", para_state_hpa);
+	if (is_error_hpa(para_state_hpa))
+		goto err_gp;
+
+	para_state_page = pfn_to_page(para_state_hpa >> PAGE_SHIFT);
+	para_state = kmap_atomic(para_state_page, KM_USER0);
+
+	printk(KERN_DEBUG "....  guest version: %d\n", para_state->guest_version);
+	printk(KERN_DEBUG "....           size: %d\n", para_state->size);
+
+	para_state->host_version = KVM_PARA_API_VERSION;
+	/*
+	 * We cannot support guests that try to register themselves
+	 * with a newer API version than the host supports:
+	 */
+	if (para_state->guest_version > KVM_PARA_API_VERSION) {
+		para_state->ret = -KVM_EINVAL;
+		goto err_kunmap_skip;
+	}
+
+	hypercall_gpa = para_state->hypercall_gpa;
+	hypercall_hpa = gpa_to_hpa(vcpu, hypercall_gpa);
+	printk(KERN_DEBUG ".... hypercall_hpa: %08Lx\n", hypercall_hpa);
+	if (is_error_hpa(hypercall_hpa)) {
+		para_state->ret = -KVM_EINVAL;
+		goto err_kunmap_skip;
+	}
+
+	printk(KERN_DEBUG "kvm: para guest successfully registered.\n");
+	vcpu->para_state_page = para_state_page;
+	vcpu->para_state_gpa = para_state_gpa;
+	vcpu->hypercall_gpa = hypercall_gpa;
+
+	hypercall = kmap_atomic(pfn_to_page(hypercall_hpa >> PAGE_SHIFT),
+				KM_USER1) + (hypercall_hpa & ~PAGE_MASK);
+	kvm_arch_ops->patch_hypercall(vcpu, hypercall);
+	kunmap_atomic(hypercall, KM_USER1);
+
+	para_state->ret = 0;
+err_kunmap_skip:
+	kunmap_atomic(para_state, KM_USER0);
+	return 0;
+err_gp:
+	return 1;
+}
+
 int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 {
 	u64 data;
@@ -1312,6 +1379,12 @@ int kvm_set_msr_common(struct kvm_vcpu *
 	case MSR_IA32_MISC_ENABLE:
 		vcpu->ia32_misc_enable_msr = data;
 		break;
+	/*
+	 * This is the 'probe whether the host is KVM' logic:
+	 */
+	case MSR_KVM_API_MAGIC:
+		return vcpu_register_para(vcpu, data);
+
 	default:
 		printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr);
 		return 1;
drivers/kvm/kvm.h +6 -0
Index: linux-2.6/drivers/kvm/kvm.h
===================================================================
@@ -14,6 +14,7 @@
 
 #include "vmx.h"
 #include <linux/kvm.h>
+#include <linux/kvm_para.h>
 
 #define CR0_PE_MASK (1ULL << 0)
 #define CR0_TS_MASK (1ULL << 3)
@@ -237,6 +238,9 @@ struct kvm_vcpu {
 	unsigned long cr0;
 	unsigned long cr2;
 	unsigned long cr3;
+	gpa_t para_state_gpa;
+	struct page *para_state_page;
+	gpa_t hypercall_gpa;
 	unsigned long cr4;
 	unsigned long cr8;
 	u64 pdptrs[4]; /* pae */
@@ -382,6 +386,8 @@ struct kvm_arch_ops {
 	int (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run);
 	int (*vcpu_setup)(struct kvm_vcpu *vcpu);
 	void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
+	void (*patch_hypercall)(struct kvm_vcpu *vcpu,
+				unsigned char *hypercall_addr);
 };
 
 extern struct kvm_stat kvm_stat;
include/linux/kvm_para.h new file +55 -0

55 lines not on this page · raw message

drivers/kvm/svm.c +13 -0
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -1669,6 +1669,18 @@ static int is_disabled(void)
 	return 0;
 }
 
+static void
+svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
+{
+	/*
+	 * Patch in the VMMCALL instruction:
+	 */
+	hypercall[0] = 0x0f;
+	hypercall[1] = 0x01;
+	hypercall[2] = 0xd9;
+	hypercall[3] = 0xc3;
+}
+
 static struct kvm_arch_ops svm_arch_ops = {
 	.cpu_has_kvm_support = has_svm,
 	.disabled_by_bios = is_disabled,
@@ -1717,6 +1729,7 @@ static struct kvm_arch_ops svm_arch_ops 
 	.run = svm_vcpu_run,
 	.skip_emulated_instruction = skip_emulated_instruction,
 	.vcpu_setup = svm_vcpu_setup,
+	.patch_hypercall = svm_patch_hypercall,
 };
 
 static int __init svm_init(void)
drivers/kvm/vmx.c +13 -0
Index: linux-2.6/drivers/kvm/vmx.c
===================================================================
@@ -1469,6 +1469,18 @@ static int handle_io(struct kvm_vcpu *vc
 	return 0;
 }
 
+static void
+vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
+{
+	/*
+	 * Patch in the VMCALL instruction:
+	 */
+	hypercall[0] = 0x0f;
+	hypercall[1] = 0x01;
+	hypercall[2] = 0xc1;
+	hypercall[3] = 0xc3;
+}
+
 static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	u64 exit_qualification;
@@ -2064,6 +2076,7 @@ static struct kvm_arch_ops vmx_arch_ops 
 	.run = vmx_vcpu_run,
 	.skip_emulated_instruction = skip_emulated_instruction,
 	.vcpu_setup = vmx_vcpu_setup,
+	.patch_hypercall = vmx_patch_hypercall,
 };
 
 static int __init vmx_init(void)

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#8 lore raw

PATCH 8/13 KVM: Add host hypercall support for vmx

In reply to Avi Kivity

From: Ingo Molnar <[email protected]>

include/linux/kvm_para.h +18 -0
Index: linux-2.6/include/linux/kvm_para.h
===================================================================
@@ -52,4 +52,22 @@ struct kvm_vcpu_para_state {
 
 #define KVM_EINVAL 1
 
+/*
+ * Hypercall calling convention:
+ *
+ * Each hypercall may have 0-6 parameters.
+ *
+ * 64-bit hypercall index is in RAX, goes from 0 to __NR_hypercalls-1
+ *
+ * 64-bit parameters 1-6 are in the standard gcc x86_64 calling convention
+ * order: RDI, RSI, RDX, RCX, R8, R9.
+ *
+ * 32-bit index is EBX, parameters are: EAX, ECX, EDX, ESI, EDI, EBP.
+ * (the first 3 are according to the gcc regparm calling convention)
+ *
+ * No registers are clobbered by the hypercall, except that the
+ * return value is in RAX.
+ */
+#define __NR_hypercalls			0
+
 #endif
drivers/kvm/vmx.c +15 -0
Index: linux-2.6/drivers/kvm/vmx.c
===================================================================
@@ -1657,6 +1657,20 @@ static int handle_halt(struct kvm_vcpu *
 	return 0;
 }
 
+static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+	kvm_run->exit_reason = KVM_EXIT_DEBUG;
+	printk(KERN_DEBUG "got vmcall at RIP %08lx\n", vmcs_readl(GUEST_RIP));
+	printk(KERN_DEBUG "vmcall params: %08lx, %08lx, %08lx, %08lx\n",
+		vcpu->regs[VCPU_REGS_RAX],
+		vcpu->regs[VCPU_REGS_RCX],
+		vcpu->regs[VCPU_REGS_RDX],
+		vcpu->regs[VCPU_REGS_RBP]);
+	vcpu->regs[VCPU_REGS_RAX] = 0;
+	vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP)+3);
+	return 1;
+}
+
 /*
  * The exit handlers return 1 if the exit was handled fully and guest execution
  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
@@ -1675,6 +1689,7 @@ static int (*kvm_vmx_exit_handlers[])(st
 	[EXIT_REASON_MSR_WRITE]               = handle_wrmsr,
 	[EXIT_REASON_PENDING_INTERRUPT]       = handle_interrupt_window,
 	[EXIT_REASON_HLT]                     = handle_halt,
+	[EXIT_REASON_VMCALL]                  = handle_vmcall,
 };
 
 static const int kvm_vmx_max_exit_handlers =

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#9 lore raw

PATCH 9/13 KVM: Add hypercall host support for svm

In reply to Avi Kivity
drivers/kvm/svm.c +15 -1
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -1076,6 +1076,20 @@ static int halt_interception(struct kvm_
 	return 0;
 }
 
+static int vmmcall_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+	printk(KERN_DEBUG "got vmmcall at RIP %08llx\n",
+	       vcpu->svm->vmcb->save.rip);
+	printk(KERN_DEBUG "vmmcall params: %08llx, %08lx, %08lx, %08lx\n",
+	       vcpu->svm->vmcb->save.rax,
+	       vcpu->regs[VCPU_REGS_RCX],
+	       vcpu->regs[VCPU_REGS_RDX],
+	       vcpu->regs[VCPU_REGS_RBP]);
+	vcpu->svm->vmcb->save.rax = 0;
+	vcpu->svm->vmcb->save.rip += 3;
+	return 1;
+}
+
 static int invalid_op_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	inject_ud(vcpu);
@@ -1276,7 +1290,7 @@ static int (*svm_exit_handlers[])(struct
 	[SVM_EXIT_TASK_SWITCH]			= task_switch_interception,
 	[SVM_EXIT_SHUTDOWN]			= shutdown_interception,
 	[SVM_EXIT_VMRUN]			= invalid_op_interception,
-	[SVM_EXIT_VMMCALL]			= invalid_op_interception,
+	[SVM_EXIT_VMMCALL]			= vmmcall_interception,
 	[SVM_EXIT_VMLOAD]			= invalid_op_interception,
 	[SVM_EXIT_VMSAVE]			= invalid_op_interception,
 	[SVM_EXIT_STGI]				= invalid_op_interception,

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#10 lore raw

PATCH 10/13 KVM: Wire up hypercall handlers to a central arch-independent location

In reply to Avi Kivity
drivers/kvm/kvm_main.c +36 -0
Index: linux-2.6/drivers/kvm/kvm_main.c
===================================================================
@@ -1138,6 +1138,42 @@ int emulate_instruction(struct kvm_vcpu 
 }
 EXPORT_SYMBOL_GPL(emulate_instruction);
 
+int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	unsigned long nr, a0, a1, a2, a3, a4, a5, ret;
+
+	kvm_arch_ops->decache_regs(vcpu);
+	ret = -KVM_EINVAL;
+#ifdef CONFIG_X86_64
+	if (is_long_mode(vcpu)) {
+		nr = vcpu->regs[VCPU_REGS_RAX];
+		a0 = vcpu->regs[VCPU_REGS_RDI];
+		a1 = vcpu->regs[VCPU_REGS_RSI];
+		a2 = vcpu->regs[VCPU_REGS_RDX];
+		a3 = vcpu->regs[VCPU_REGS_RCX];
+		a4 = vcpu->regs[VCPU_REGS_R8];
+		a5 = vcpu->regs[VCPU_REGS_R9];
+	} else
+#endif
+	{
+		nr = vcpu->regs[VCPU_REGS_RBX] & -1u;
+		a0 = vcpu->regs[VCPU_REGS_RAX] & -1u;
+		a1 = vcpu->regs[VCPU_REGS_RCX] & -1u;
+		a2 = vcpu->regs[VCPU_REGS_RDX] & -1u;
+		a3 = vcpu->regs[VCPU_REGS_RSI] & -1u;
+		a4 = vcpu->regs[VCPU_REGS_RDI] & -1u;
+		a5 = vcpu->regs[VCPU_REGS_RBP] & -1u;
+	}
+	switch (nr) {
+	default:
+		;
+	}
+	vcpu->regs[VCPU_REGS_RAX] = ret;
+	kvm_arch_ops->cache_regs(vcpu);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(kvm_hypercall);
+
 static u64 mk_cr_64(u64 curr_cr, u32 new_val)
 {
 	return (curr_cr & ~((1ULL << 32) - 1)) | new_val;
drivers/kvm/kvm.h +2 -0
Index: linux-2.6/drivers/kvm/kvm.h
===================================================================
@@ -482,6 +482,8 @@ void kvm_mmu_post_write(struct kvm_vcpu 
 int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
 void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
 
+int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/svm.c +1 -9
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -1078,16 +1078,8 @@ static int halt_interception(struct kvm_
 
 static int vmmcall_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	printk(KERN_DEBUG "got vmmcall at RIP %08llx\n",
-	       vcpu->svm->vmcb->save.rip);
-	printk(KERN_DEBUG "vmmcall params: %08llx, %08lx, %08lx, %08lx\n",
-	       vcpu->svm->vmcb->save.rax,
-	       vcpu->regs[VCPU_REGS_RCX],
-	       vcpu->regs[VCPU_REGS_RDX],
-	       vcpu->regs[VCPU_REGS_RBP]);
-	vcpu->svm->vmcb->save.rax = 0;
 	vcpu->svm->vmcb->save.rip += 3;
-	return 1;
+	return kvm_hypercall(vcpu, kvm_run);
 }
 
 static int invalid_op_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
drivers/kvm/vmx.c +1 -9
Index: linux-2.6/drivers/kvm/vmx.c
===================================================================
@@ -1659,16 +1659,8 @@ static int handle_halt(struct kvm_vcpu *
 
 static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	kvm_run->exit_reason = KVM_EXIT_DEBUG;
-	printk(KERN_DEBUG "got vmcall at RIP %08lx\n", vmcs_readl(GUEST_RIP));
-	printk(KERN_DEBUG "vmcall params: %08lx, %08lx, %08lx, %08lx\n",
-		vcpu->regs[VCPU_REGS_RAX],
-		vcpu->regs[VCPU_REGS_RCX],
-		vcpu->regs[VCPU_REGS_RDX],
-		vcpu->regs[VCPU_REGS_RBP]);
-	vcpu->regs[VCPU_REGS_RAX] = 0;
 	vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP)+3);
-	return 1;
+	return kvm_hypercall(vcpu, kvm_run);
 }
 
 /*

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

#11 lore raw

Re: [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 1 line · Avi Kivity

changelog?

drivers/kvm/kvm_main.c int emulate_instruction(struct kvm_vcpu · line 1170

Quoted 4 lines
drivers/kvm/kvm_main.c +4 -0
+	switch (nr) {
+	default:
+		;
+	}

Eh?

Signature · 8 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
author
#12 lore raw

Re: [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 8 lines · Pavel Machek
Quoted 2 lines · Avi Kivity

changelog?

Well, I can't think of anything to add beyond $subject. The patch adds calls from the arch-dependent hypercall handlers to a new arch independent function.

Quoted 9 lines

drivers/kvm/kvm_main.c int emulate_instruction(struct kvm_vcpu · line 1170

Quoted 5 lines
drivers/kvm/kvm_main.c +4 -0
+	switch (nr) {
+	default:
+		;
+	}

Eh?

No hypercalls defined yet.

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#13 lore raw

RE: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 26 lines
Quoted 8 lines · Pavel Machek
Quoted 2 lines · Avi Kivity

changelog?

Well, I can't think of anything to add beyond $subject. The patch adds calls from the arch-dependent hypercall handlers to a new arch independent function.

Quoted 9 lines

drivers/kvm/kvm_main.c int emulate_instruction(struct kvm_vcpu · line 1170

Quoted 5 lines
drivers/kvm/kvm_main.c +4 -0
+	switch (nr) {
+	default:
+		;
+	}

Eh?

Quoted 2 lines

No hypercalls defined yet.

I have Ingo's network PV hypercalls to commit in my piplien. Till then we can just add the test hypercall:
case __NR_hypercall_test:
printk(KERN_DEBUG "%s __NR_hypercall_test\n",

__FUNCTION__);
		ret = 0x5a5a;
		break;
	default:
		BUG();
Quoted 6 lines

--
error compiling committee.c: too many arguments to function

-----------------------------------------------------------------------

--

Quoted 5 lines

Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVD

EV

Quoted 4 lines

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

#14 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 9 lines · Dor Laor

I have Ingo's network PV hypercalls to commit in my piplien. Till then we can just add the test hypercall:
case __NR_hypercall_test:
printk(KERN_DEBUG "%s __NR_hypercall_test\n",

__FUNCTION__);
		ret = 0x5a5a;
		break;
	default:
		BUG();

Is it a good idea to call BUG() on an undefined hypercall? I assume its better to inform the guest that is has issued an illegal call...

Joerg

Signature · 11 lines
Joerg Roedel
Operating System Research Center
AMD Saxony LLC & Co. KG



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
author
#15 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 13 lines · Joerg Roedel
Quoted 10 lines · Dor Laor

I have Ingo's network PV hypercalls to commit in my piplien. Till then we can just add the test hypercall:
case __NR_hypercall_test:
printk(KERN_DEBUG "%s __NR_hypercall_test\n",

__FUNCTION__);
		ret = 0x5a5a;
		break;
	default:
		BUG();
Quoted 4 lines

Is it a good idea to call BUG() on an undefined hypercall? I assume its better to inform the guest that is has issued an illegal call...

The code returns -KVM_EINVAL if the hypercall is not handled (and BUG() on the host as a response to something controlled by a guest is not a good idea).

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#16 lore raw

RE: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

In reply to Dor Laor
Quoted 4 lines
Quoted 2 lines

I have Ingo's network PV hypercalls to commit in my piplien.

I have 5 or so pending as well :)
can't wait for the infrastructure to be there so that it's relatively easy to add my paravirt block driver

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#17 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 7 lines · Arjan van de Ven
Quoted 2 lines

I have Ingo's network PV hypercalls to commit in my piplien.

I have 5 or so pending as well :)
can't wait for the infrastructure to be there so that it's relatively easy to add my paravirt block driver

I can't wait for your pv block driver :)

What do you think is missing? My list has:

- registration of hypercall handlers from modules
- execution of hypercall handlers outside vcpu_load() (so they are preemptible and sleepable)
- passing unhandled hypercalls to userspace for qemu-based devices

Please do post the patches to kvm-devel, even if they aren't ready, so we can get a taste of what's coming.

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#18 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 9 lines · Avi Kivity
Quoted 7 lines · Arjan van de Ven
Quoted 2 lines

I have Ingo's network PV hypercalls to commit in my piplien.

I have 5 or so pending as well :)
can't wait for the infrastructure to be there so that it's relatively easy to add my paravirt block driver

Quoted 5 lines

I can't wait for your pv block driver :)

What do you think is missing? My list has:

- registration of hypercall handlers from module

optional I think, but yeah easier for the user

Quoted 2 lines

- execution of hypercall handlers outside vcpu_load() (so they are preemptible and sleepable)

I don't need this; most of my hypercalls are non-blocking. The ones that are can already undo the load themselves, no big deal.

Quoted 1 line

- passing unhandled hypercalls to userspace for qemu-based devices

hm could do I suppose

One thing I'd like to see is some way to do batched hypercalls. I don't quite know how this will work in general, but let me explain the scenario:
The guest submits a bunch of disk IO requests into a submit queue. The host gets a hypercall and goes to process the submit queue While this is processing, the guest submits more IO
The guest would here do another hypercall..

.. but what could be done is have the host poll at the end of it's scan of the queue if there's more, and while the host is scanning, just disable the hypercall the guest would make. So that if there is a "submit while scanning/processing" going on, no need for more hypercalls.

(Otoh... the current situation isn't all that bad, there's one hypercall for an entire batch of IO's, and the blocklayer isn't all that bad at giving us nice large batches)

Signature · 9 lines
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
author
#19 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 7 lines · Arjan van de Ven

- execution of hypercall handlers outside vcpu_load() (so they are

Quoted 1 line

preemptible and sleepable)

I don't need this; most of my hypercalls are non-blocking. The ones that are can already undo the load themselves, no big deal.

I don't really like exposing the vcpu_load()/vcpu_put() interfaces.

On the other hand, sleeping in a hypercall means the guest vcpu is not doing any processing. Maybe we should declare hypercall handlers atomic and let them use a workqueue if they can't be atomic.

On the third hand, sleeping in a hypercall should be a rare event, so forcing hypercall handlers to handle the sleeping case introduces a lot of complexity for marginal gain.

Quoted 5 lines
Quoted 2 lines

- passing unhandled hypercalls to userspace for qemu-based devices

hm could do I suppose

One user would be the opengl guest to host tunneling driver/device that's being developed for qemu.

Quoted 8 lines

One thing I'd like to see is some way to do batched hypercalls. I don't quite know how this will work in general, but let me explain the scenario:
The guest submits a bunch of disk IO requests into a submit queue. The host gets a hypercall and goes to process the submit queue While this is processing, the guest submits more IO
The guest would here do another hypercall..

Quoted 6 lines

.. but what could be done is have the host poll at the end of it's scan of the queue if there's more, and while the host is scanning, just disable the hypercall the guest would make. So that if there is a "submit while scanning/processing" going on, no need for more hypercalls.

Xen does exactly that. It's actually outside the scope of hypercalls, and more related to the protocol between guest and host. Not that it can't be made generic (and the Xen rings are).

Maybe we should just copy the code.

Quoted 4 lines

(Otoh... the current situation isn't all that bad, there's one hypercall for an entire batch of IO's, and the blocklayer isn't all that bad at giving us nice large batches)

True. I expect it's more necessary with networking.

Somthing else that came up in a conversation with Dor: the need for a clean way to raise a guest interrupt. The guest may be sleeping in userspace, scheduled out, or running on another cpu (and requiring an ipi to get it out of guest mode).

Right now I'm thinking about using the signal machinery since it appears to do exactly the right thing.

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#20 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 5 lines

Somthing else that came up in a conversation with Dor: the need for a clean way to raise a guest interrupt. The guest may be sleeping in userspace, scheduled out, or running on another cpu (and requiring an ipi to get it out of guest mode).

yeah it'd be nice if I could just call a function for it rather than poking into kvm internals ;)

Quoted 2 lines

Right now I'm thinking about using the signal machinery since it appears to do exactly the right thing.

signals are *expensive* though.

If you design an interrupt interface, it'd rock if you could make it such that it is "raise <this> interrupt within <x> miliseconds from now", rather than making it mostly synchronous. That way irq mitigation becomes part of the interface rather than having to duplicate it all over the virtual drivers...

Signature · 2 lines
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org
author
#21 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 10 lines · Arjan van de Ven
Quoted 5 lines

Somthing else that came up in a conversation with Dor: the need for a clean way to raise a guest interrupt. The guest may be sleeping in userspace, scheduled out, or running on another cpu (and requiring an ipi to get it out of guest mode).

yeah it'd be nice if I could just call a function for it rather than poking into kvm internals ;)

Sure. Please report all inconveniences (they're really bugs) so we can fix them.

Poking at kvm internals means you waste your time learning them, and later we can't change them.

Quoted 7 lines
Quoted 3 lines

Right now I'm thinking about using the signal machinery since it appears to do exactly the right thing.

signals are *expensive* though.

I think the expensive part of signals is userspace delivery. If they are always blocked in userspace, they become just another IPC channel.

I plan to add a signal mask to KVM_RUN a la pselect() so that userspace can dequeue signals instead of using a signal handler.

Quoted 6 lines

If you design an interrupt interface, it'd rock if you could make it such that it is "raise <this> interrupt within <x> miliseconds from now", rather than making it mostly synchronous. That way irq mitigation becomes part of the interface rather than having to duplicate it all over the virtual drivers...

Can't it be done by a helper function using a timer and a signal (or whatever mechanism we use to wake up vcpus)?

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#22 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 3 lines

Can't it be done by a helper function using a timer and a signal (or whatever mechanism we use to wake up vcpus)?

one could do that but it's not optimal; if the process DOES get waken up earlier, it should take the interrupt then immediately, so that it doesn't have to wake up again when the timer fires.

(in fact it would be nice if the guest could somehow poll at the irq mask at waking from idle, so that it wouldn't need a vmexit/entry for every such interrupt, but just do the right thing for all pending work)

In addition, yes it'll be a helper function, but since all drivers will want the functionality its probably best off in the generic code

Signature · 9 lines
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
author
#23 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 8 lines · Arjan van de Ven
Quoted 3 lines

Can't it be done by a helper function using a timer and a signal (or whatever mechanism we use to wake up vcpus)?

one could do that but it's not optimal; if the process DOES get waken up earlier, it should take the interrupt then immediately, so that it doesn't have to wake up again when the timer fires.

Quoted 8 lines

(in fact it would be nice if the guest could somehow poll at the irq mask at waking from idle, so that it wouldn't need a vmexit/entry for every such interrupt, but just do the right thing for all pending work)

In addition, yes it'll be a helper function, but since all drivers will want the functionality its probably best off in the generic code

That's what Xen does (I'm not sure about the timer, but they do avoid unnecessary interrupts). As you can have memory shared between the guest and host, it's quite simple:

0. host puts data in ring
1. host sets interrupt timer
2. guest wakes up for unrelated reasons
3. guest sees data in ring, consumes it, and bumps the consumer pointer
4. timer fires, host sees consumer == producer, no need to issue interrupt

They have that code abstracted out and reusable by multiple drivers.

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#24 lore raw

Re: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers to a central arch-independent location

Quoted 24 lines · Avi Kivity
Quoted 8 lines · Arjan van de Ven
Quoted 4 lines

Can't it be done by a helper function using a timer and a signal (or whatever mechanism we use to wake up vcpus)?

one could do that but it's not optimal; if the process DOES get waken up earlier, it should take the interrupt then immediately, so that it doesn't have to wake up again when the timer fires.

Quoted 9 lines

(in fact it would be nice if the guest could somehow poll at the irq mask at waking from idle, so that it wouldn't need a vmexit/entry for every such interrupt, but just do the right thing for all pending work)

In addition, yes it'll be a helper function, but since all drivers will want the functionality its probably best off in the generic code

That's what Xen does (I'm not sure about the timer, but they do avoid unnecessary interrupts). As you can have memory shared between the guest and host, it's quite simple:

Quoted 6 lines

0. host puts data in ring
1. host sets interrupt timer
2. guest wakes up for unrelated reasons
3. guest sees data in ring, consumes it, and bumps the consumer pointer
4. timer fires, host sees consumer == producer, no need to issue interrupt

It's not quite a timer. It's an asynchronous notification mechanism. Guest sets a bit in the appropriate domain's shared_info and when the domain gets scheduled again, it checks it's bits.

An easy way to simulate this in KVM would be to have the guest set a bit in the paravirt page and then on the next trip down to userspace, we check the bits and dispatch appropriately. We know we'll get down to userspace at least for the next EINTR.

Quoted 2 lines

They have that code abstracted out and reusable by multiple drivers.

Why don't we see how many drivers we get first. I have my doubts that a paravirt disk driver will significantly out perform scsi emulation.

Regards,

Anthony Liguori

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

#25 lore raw

RE: [kvm-devel] [PATCH 10/13] KVM: Wire up hypercall handlers toa central arch-independent location

In reply to Arjan van de Ven
Quoted 11 lines
Quoted 6 lines

Somthing else that came up in a conversation with Dor: the need for a clean way to raise a guest interrupt. The guest may be sleeping in userspace, scheduled out, or running on another cpu (and requiring an ipi to get it out of guest mode).

yeah it'd be nice if I could just call a function for it rather than poking into kvm internals ;)

Quoted 1 line

Right now I'm thinking about using the signal machinery since it

appears

Quoted 9 lines
Quoted 1 line

to do exactly the right thing.

signals are *expensive* though.

If you design an interrupt interface, it'd rock if you could make it such that it is "raise <this> interrupt within <x> miliseconds from now", rather than making it mostly synchronous. That way irq mitigation becomes part of the interface rather than having to duplicate it all over the virtual drivers...

Why do you need to raise an interrupt within a timeout? I thought on just asking for a synchronous, as-fast-as-you-can-get interrupt. If you need an interrupt that should pop within some milliseconds you can set a timer.

Quoted 5 lines

--
if you want to mail me at work (you don't), use arjan (at)

linux.intel.com

Quoted 2 lines

Test the interaction between Linux and your BIOS via
http://www.linuxfirmwarekit.org

A message that is not in the archive (sent off-list or not yet received): 1172142081.3531.243.camel-NIQFrBLA1CpScpXdPBN83iCwEArCW2h5@public.gmane.org

#27 lore raw

Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

Hi Arjan,

Have you thought about how you'll boot from a PV disk driver? The BIOS needs support for it in some way.

The easiest thing I can think of is to have the PV disk driver show up as an actual PCI device and to use a PCI option rom to hijack the appropriate interrupt.

Are you exposing the PV disk driver as a PCI device currently?

Regards,

Anthony Liguori

Quoted 49 lines · Arjan van de Ven
Quoted 10 lines · Avi Kivity
Quoted 8 lines · Arjan van de Ven
Quoted 3 lines

I have Ingo's network PV hypercalls to commit in my piplien.

I have 5 or so pending as well :)
can't wait for the infrastructure to be there so that it's relatively easy to add my paravirt block driver

Quoted 6 lines

I can't wait for your pv block driver :)

What do you think is missing? My list has:

- registration of hypercall handlers from module

optional I think, but yeah easier for the user

Quoted 3 lines

- execution of hypercall handlers outside vcpu_load() (so they are preemptible and sleepable)

I don't need this; most of my hypercalls are non-blocking. The ones that are can already undo the load themselves, no big deal.

Quoted 2 lines

- passing unhandled hypercalls to userspace for qemu-based devices

hm could do I suppose

One thing I'd like to see is some way to do batched hypercalls. I don't quite know how this will work in general, but let me explain the scenario:
The guest submits a bunch of disk IO requests into a submit queue. The host gets a hypercall and goes to process the submit queue While this is processing, the guest submits more IO
The guest would here do another hypercall..

.. but what could be done is have the host poll at the end of it's scan of the queue if there's more, and while the host is scanning, just disable the hypercall the guest would make. So that if there is a "submit while scanning/processing" going on, no need for more hypercalls.

Quoted 7 lines

(Otoh... the current situation isn't all that bad, there's one hypercall for an entire batch of IO's, and the blocklayer isn't all that bad at giving us nice large batches)

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

#29 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

Quoted 5 lines

The easiest thing I can think of is to have the PV disk driver show up as an actual PCI device and to use a PCI option rom to hijack the appropriate interrupt.

yeah that's a good plan. Being a PCI device also helps with the OS userspace knowing which module to load; even if the device itself never gets accessed.

Quoted 2 lines

Are you exposing the PV disk driver as a PCI device currently?

Not yet; this side of things still needs work

Signature · 9 lines
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

A message that is not in the archive (sent off-list or not yet received): 1172269981.3241.57.camel-NIQFrBLA1CpScpXdPBN83iCwEArCW2h5@public.gmane.org

#31 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13]KVM: Wire up hypercall handler ..)

Quoted 1 line
Quoted 1 line

The easiest thing I can think of is to have the PV disk driver show

up

Quoted 11 lines
Quoted 2 lines

as an actual PCI device and to use a PCI option rom to hijack the appropriate interrupt.

yeah that's a good plan. Being a PCI device also helps with the OS userspace knowing which module to load; even if the device itself never gets accessed.

Quoted 2 lines

Are you exposing the PV disk driver as a PCI device currently?

Not yet; this side of things still needs work

Good idea Anthony.

Arjan, when you'll reach this part, you could take a look at the generic PCI hypercall code that we added both to qemu and the matching driver for Linux.
Now they only provide basic port IO but in the near future we will integrate them with the PV network driver.

Quoted 2 lines

--
if you want to mail me at work (you don't), use arjan (at)

linux.intel.com

Quoted 5 lines

Test the interaction between Linux and your BIOS via
http://www.linuxfirmwarekit.org

-----------------------------------------------------------------------

--

Quoted 5 lines

Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVD

EV

Quoted 4 lines

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

A message that is not in the archive (sent off-list or not yet received): 64F9B87B6B770947A9F8391472E032160A91C385-yEcIvxbTEBqsx+V+t5oei8rau4O3wl8o3fe8/T/[email protected]

#33 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13]KVM: Wire up hypercall handler ..)

Quoted 17 lines · Dor Laor
Quoted 2 lines
Quoted 2 lines

The easiest thing I can think of is to have the PV disk driver show

up

Quoted 12 lines
Quoted 3 lines

as an actual PCI device and to use a PCI option rom to hijack the appropriate interrupt.

yeah that's a good plan. Being a PCI device also helps with the OS userspace knowing which module to load; even if the device itself never gets accessed.

Quoted 2 lines

Are you exposing the PV disk driver as a PCI device currently?

Not yet; this side of things still needs work

Quoted 8 lines

Good idea Anthony.

Arjan, when you'll reach this part, you could take a look at the generic PCI hypercall code that we added both to qemu and the matching driver for Linux.
Now they only provide basic port IO but in the near future we will integrate them with the PV network driver.

The qemu part is irrelevant as he's generating the interrupts from the host kernel directly. And I think that the guest-side driver is a bit of overkill.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

#35 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13]KVM: Wire up hypercall handler ..)

Quoted 5 lines · Avi Kivity

The qemu part is irrelevant as he's generating the interrupts from the host kernel directly. And I think that the guest-side driver is a bit of overkill.

I was thinking of interrupts when I wrote this so it came out garbled. The qemu part is irrelevant because he's handling the hypercalls from the host kernel.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#36 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

In reply to a message not in the archive
Quoted 10 lines · Arjan van de Ven
Quoted 4 lines

The easiest thing I can think of is to have the PV disk driver show up as an actual PCI device and to use a PCI option rom to hijack the appropriate interrupt.

yeah that's a good plan. Being a PCI device also helps with the OS userspace knowing which module to load; even if the device itself never gets accessed.

A problem with pci, at least if you use the pci interrupts, is that your interrupt might be shared with another device. I guess a solution is not to use pci interrupts, but then we need some mechanism to allocate interrupts.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

#38 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

Quoted 12 lines · Avi Kivity
Quoted 10 lines · Arjan van de Ven
Quoted 4 lines

The easiest thing I can think of is to have the PV disk driver show up as an actual PCI device and to use a PCI option rom to hijack the appropriate interrupt.

yeah that's a good plan. Being a PCI device also helps with the OS userspace knowing which module to load; even if the device itself never gets accessed.

Quoted 4 lines

A problem with pci, at least if you use the pci interrupts, is that your interrupt might be shared with another device. I guess a solution is not to use pci interrupts, but then we need some mechanism to allocate interrupts.

shared interrupts aren't a big deal in Linux. at all. In fact, sharing all PV interrupts to one number is a performance enhancement ;)

Quoted 1 line
Signature · 9 lines
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

A message that is not in the archive (sent off-list or not yet received): 1172385067.3265.1.camel-NIQFrBLA1CpScpXdPBN83iCwEArCW2h5@public.gmane.org

#40 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

Quoted 21 lines · Arjan van de Ven
Quoted 13 lines · Avi Kivity
Quoted 11 lines · Arjan van de Ven
Quoted 5 lines

The easiest thing I can think of is to have the PV disk driver show up as an actual PCI device and to use a PCI option rom to hijack the appropriate interrupt.

yeah that's a good plan. Being a PCI device also helps with the OS userspace knowing which module to load; even if the device itself never gets accessed.

Quoted 5 lines

A problem with pci, at least if you use the pci interrupts, is that your interrupt might be shared with another device. I guess a solution is not to use pci interrupts, but then we need some mechanism to allocate interrupts.

Quoted 4 lines

shared interrupts aren't a big deal in Linux. at all. In fact, sharing all PV interrupts to one number is a performance enhancement ;)

If you share a PV interrupt with a non-PV interrupt, then for each PV interrupt you have to check whether the non-PV interrupt fired. That involves at least one expensive vmexit.

I agree that sharing PV interrupts is not very expensive (though I don't see why you call it an optimization - if you share 100 interrupts on one line you need to check 100 interrupt sources every time the interrupt fires).

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

#42 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

Quoted 9 lines
Quoted 5 lines

shared interrupts aren't a big deal in Linux. at all. In fact, sharing all PV interrupts to one number is a performance enhancement ;)

If you share a PV interrupt with a non-PV interrupt, then for each PV interrupt you have to check whether the non-PV interrupt fired. That involves at least one expensive vmexit.

hmm not really.
the completion ring lives in guest memory, the guest can check it without vmexit entirely.
The PV block driver only does 2 vm events normally (apart from boot time setup), one to inform the host new IO has been submitted in the submit ring, and one to receive an interrupt to get notified one or more completions are present in the completion ring. Nothing more....

Quoted 5 lines

I agree that sharing PV interrupts is not very expensive (though I don't see why you call it an optimization - if you share 100 interrupts on one line you need to check 100 interrupt sources every time the interrupt fires).

as long as the check is cheap that is actually fine; if in your 100 sources scenario 10 have fired, you only get 1 vm event to deliver the irq, and then 100 polls of guest memory inside the guest. That should be cheaper than doing 10 real vm interrupts.

Signature · 9 lines
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

A message that is not in the archive (sent off-list or not yet received): 1172385720.3265.12.camel-NIQFrBLA1CpScpXdPBN83iCwEArCW2h5@public.gmane.org

#44 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

Quoted 10 lines · Arjan van de Ven
Quoted 9 lines
Quoted 5 lines

shared interrupts aren't a big deal in Linux. at all. In fact, sharing all PV interrupts to one number is a performance enhancement ;)

If you share a PV interrupt with a non-PV interrupt, then for each PV interrupt you have to check whether the non-PV interrupt fired. That involves at least one expensive vmexit.

Quoted 9 lines

hmm not really.
the completion ring lives in guest memory, the guest can check it without vmexit entirely.
The PV block driver only does 2 vm events normally (apart from boot time setup), one to inform the host new IO has been submitted in the submit ring, and one to receive an interrupt to get notified one or more completions are present in the completion ring. Nothing more....

But doesn't the interrupt code have to check all interrupt sources on a shared line? That means checking the non-PV interrupt as well, which involves a vmexit (for mmio read).

Quoted 11 lines
Quoted 5 lines

I agree that sharing PV interrupts is not very expensive (though I don't see why you call it an optimization - if you share 100 interrupts on one line you need to check 100 interrupt sources every time the interrupt fires).

as long as the check is cheap that is actually fine; if in your 100 sources scenario 10 have fired, you only get 1 vm event to deliver the irq, and then 100 polls of guest memory inside the guest. That should be cheaper than doing 10 real vm interrupts.

It is possible (Xen does it) to batch interrupt delivery so that multiple interrupts can be delivered with one vmentry. So you get the best of both worlds: one check for interrupt source, and one vmentry if multiple interrupts have fired.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

#46 lore raw

Re: Booting from PV disk driver (Was: Re: [PATCH 10/13] KVM: Wire up hypercall handler ..)

Quoted 3 lines

But doesn't the interrupt code have to check all interrupt sources on a shared line?

well technically the kernel just calls all handers.

Quoted 2 lines

That means checking the non-PV interrupt as well, which
involves a vmexit (for mmio read).

ok I see what you mean. Yes agreed we should avoid sharing with one of those animals ;)
(Shouldn't be hard since we control the bios, and it's always fake hardware anyway)

Quoted 4 lines

It is possible (Xen does it) to batch interrupt delivery so that multiple interrupts can be delivered with one vmentry. So you get the best of both worlds: one check for interrupt source, and one vmentry if multiple interrupts have fired.

check for interrupt source is really cheap. I bet it's cheaper than the hacks xen does. (xen does many things that in academic 1970's hypervisors were a win but aren't on modern hardware..)

Don't get me wrong, batching is probably a win, just it shouldn't be too expensive in terms of overhead or you'll loose anyway over time.

Quoted 1 line
Signature · 9 lines
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
author
#47 lore raw

PATCH 11/13 KVM: svm: init cr0 with the wp bit set

In reply to Avi Kivity
drivers/kvm/svm.c +1 -1
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -554,7 +554,7 @@ static void init_vmcb(struct vmcb *vmcb)
 	 * cr0 val on cpu init should be 0x60000010, we enable cpu
 	 * cache by default. the orderly way is to enable cache in bios.
 	 */
-	save->cr0 = 0x00000010 | CR0_PG_MASK;
+	save->cr0 = 0x00000010 | CR0_PG_MASK | CR0_WP_MASK;
 	save->cr4 = CR4_PAE_MASK;
 	/* rdx = ?? */
 }

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

author
#48 lore raw

PATCH 12/13 KVM: SVM: intercept SMI to handle it at host level

In reply to Avi Kivity

From: Joerg Roedel <[email protected]>

This patch changes the SVM code to intercept SMIs and handle it outside the guest.

drivers/kvm/svm.c +1 -0
Index: linux-2.6/drivers/kvm/svm.c
===================================================================
@@ -486,6 +486,7 @@ static void init_vmcb(struct vmcb *vmcb)
 
 	control->intercept = 	(1ULL << INTERCEPT_INTR) |
 				(1ULL << INTERCEPT_NMI) |
+				(1ULL << INTERCEPT_SMI) |
 		/*
 		 * selective cr0 intercept bug?
 		 *    	0:   0f 22 d8                mov    %eax,%cr3
author
#49 lore raw

PATCH 13/13 KVM: More 0 -> NULL conversions

In reply to Avi Kivity
drivers/kvm/kvm_main.c +2 -2
Index: linux-2.6/drivers/kvm/kvm_main.c
===================================================================
@@ -2229,13 +2229,13 @@ static void kvm_exit_debug(void)
 static int kvm_suspend(struct sys_device *dev, pm_message_t state)
 {
 	decache_vcpus_on_cpu(raw_smp_processor_id());
-	on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1);
+	on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1);
 	return 0;
 }
 
 static int kvm_resume(struct sys_device *dev)
 {
-	on_each_cpu(kvm_arch_ops->hardware_enable, 0, 0, 1);
+	on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1);
 	return 0;
 }
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV