Skip to contentSkip to conversation

Clean up unloved invlpg: remove kvm_arch_ops.invlpg and tweak emulator.

PATCH Applied Rusty Russell 3 participants 18 messages Sep 5, 2007 – Sep 9, 2007 10 messages not in the archive

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

PATCH 1/5 Clean up unloved invlpg: remove kvm_arch_ops.invlpg and tweak emulator.

invlpg shouldn't fetch the "src" address, since it may not be valid, however SVM's "solution" which neuters emulation of all group 7 instruction is horrible and breaks kvm-lite. The simplest fix is to put a special check in for invlpg.

Also, remove the unused invlpg member of struct kvm_arch_ops.

drivers/kvm/kvm.h +0 -3
diff -r 01dea2154ac6 drivers/kvm/kvm.h
@@ -459,7 +460,6 @@ struct kvm_arch_ops {
 	unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
 	void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
 
-	void (*invlpg)(struct kvm_vcpu *vcpu, gva_t addr);
 	void (*tlb_flush)(struct kvm_vcpu *vcpu);
 	void (*inject_page_fault)(struct kvm_vcpu *vcpu,
 				  unsigned long addr, u32 err_code);
@@ -509,8 +513,6 @@ static inline int is_error_hpa(hpa_t hpa
 static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; }
 hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva);
 struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva);
-
-void kvm_emulator_want_group7_invlpg(void);
 
 extern hpa_t bad_page_address;
 
drivers/kvm/svm.c +0 -6
diff -r 01dea2154ac6 drivers/kvm/svm.c
@@ -817,11 +809,6 @@ static void new_asid(struct vcpu_svm *sv
 	svm->vcpu.cpu = svm_data->cpu;
 	svm->asid_generation = svm_data->asid_generation;
 	svm->vmcb->control.asid = svm_data->next_asid++;
-}
-
-static void svm_invlpg(struct kvm_vcpu *vcpu, gva_t address)
-{
-	invlpga(address, to_svm(vcpu)->vmcb->control.asid); // is needed?
 }
 
 static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
@@ -1668,7 +1655,6 @@ static struct kvm_arch_ops svm_arch_ops 
 	.get_rflags = svm_get_rflags,
 	.set_rflags = svm_set_rflags,
 
-	.invlpg = svm_invlpg,
 	.tlb_flush = svm_flush_tlb,
 	.inject_page_fault = svm_inject_page_fault,
 
drivers/kvm/x86_emulate.c +3 -13
diff -r 01dea2154ac6 drivers/kvm/x86_emulate.c
@@ -212,19 +212,6 @@ static u16 twobyte_table[256] = {
 	/* 0xF0 - 0xFF */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
-
-/*
- * Tell the emulator that of the Group 7 instructions (sgdt, lidt, etc.) we
- * are interested only in invlpg and not in any of the rest.
- *
- * invlpg is a special instruction in that the data it references may not
- * be mapped.
- */
-void kvm_emulator_want_group7_invlpg(void)
-{
-	twobyte_table[1] &= ~SrcMem;
-}
-EXPORT_SYMBOL_GPL(kvm_emulator_want_group7_invlpg);
 
 /* Type, address-of, and value of an instruction's operand. */
 struct operand {
@@ -791,6 +778,9 @@ done_prefixes:
 		goto srcmem_common;
 	case SrcMem:
 		src.bytes = (d & ByteOp) ? 1 : op_bytes;
+		/* Don't fetch the address for invlpg: it could be unmapped. */
+		if (twobyte && b == 0x01 && modrm_reg == 7)
+			break;
 	      srcmem_common:
 		src.type = OP_MEM;
 		src.ptr = (unsigned long *)cr2;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

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

#2 lore raw

PATCH 2/5 Keep control regs in sync

We don't update the vcpu control registers in various places. We should do so.

drivers/kvm/kvm_main.c +4 -4
diff -r 039995825488 drivers/kvm/kvm_main.c
@@ -530,6 +530,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsi
 		return;
 	}
 	kvm_arch_ops->set_cr4(vcpu, cr4);
+	vcpu->cr4 = cr4;
 	mutex_lock(&vcpu->kvm->lock);
 	kvm_mmu_reset_context(vcpu);
 	mutex_unlock(&vcpu->kvm->lock);
@@ -1146,10 +1148,8 @@ int emulate_invlpg(struct kvm_vcpu *vcpu
 
 int emulate_clts(struct kvm_vcpu *vcpu)
 {
-	unsigned long cr0;
-
-	cr0 = vcpu->cr0 & ~X86_CR0_TS;
-	kvm_arch_ops->set_cr0(vcpu, cr0);
+	vcpu->cr0 &= ~X86_CR0_TS;
+	kvm_arch_ops->set_cr0(vcpu, vcpu->cr0);
 	return X86EMUL_CONTINUE;
 }
 
@@ -2033,6 +2033,7 @@ static int kvm_vcpu_ioctl_set_sregs(stru
 	kvm_arch_ops->decache_cr4_guest_bits(vcpu);
 
 	mmu_reset_needed |= vcpu->cr0 != sregs->cr0;
+	vcpu->cr0 = sregs->cr0;
 	kvm_arch_ops->set_cr0(vcpu, sregs->cr0);
 
 	mmu_reset_needed |= vcpu->cr4 != sregs->cr4;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

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

#4 lore raw

PATCH 3/5 Hoist SVM's get_cs_db_l_bits into core code.

SVM gets the DB and L bits for the cs by decoding the segment. This is in fact the completely generic code, so hoist it for kvm-lite to use.

drivers/kvm/kvm.h +1 -0
diff -r 01dea2154ac6 drivers/kvm/kvm.h
@@ -558,6 +560,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsi
 void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0);
 void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
 void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
+void generic_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l);
 
 int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
drivers/kvm/kvm_main.c +10 -0
diff -r 01dea2154ac6 drivers/kvm/kvm_main.c
@@ -2086,6 +2087,16 @@ static int kvm_vcpu_ioctl_set_sregs(stru
 
 	return 0;
 }
+
+void generic_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
+{
+	struct kvm_segment cs;
+
+	get_segment(vcpu, &cs, VCPU_SREG_CS);
+	*db = cs.db;
+	*l = cs.l;
+}
+EXPORT_SYMBOL_GPL(generic_get_cs_db_l_bits);
 
 /*
  * List of msr numbers which we expose to userspace through KVM_GET_MSRS
drivers/kvm/svm.c +1 -9
diff -r 01dea2154ac6 drivers/kvm/svm.c
@@ -674,14 +674,6 @@ static void svm_get_segment(struct kvm_v
 	var->unusable = !var->present;
 }
 
-static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
-{
-	struct vmcb_seg *s = svm_seg(vcpu, VCPU_SREG_CS);
-
-	*db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1;
-	*l = (s->attrib >> SVM_SELECTOR_L_SHIFT) & 1;
-}
-
 static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -1651,7 +1638,7 @@ static struct kvm_arch_ops svm_arch_ops 
 	.get_segment_base = svm_get_segment_base,
 	.get_segment = svm_get_segment,
 	.set_segment = svm_set_segment,
-	.get_cs_db_l_bits = svm_get_cs_db_l_bits,
+	.get_cs_db_l_bits = generic_get_cs_db_l_bits,
 	.decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
 	.set_cr0 = svm_set_cr0,
 	.set_cr3 = svm_set_cr3,

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

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

#6 lore raw

PATCH 4/5 kvm-lite: "The Unbearable Liteness"

This patch is not for serious application, but makes interesting reading. Requires Anthony's new hypercall patches.

Comments:

1) asm-offsets are required for lite's switcher/trampoline (lite_switcher.S) and for guest's assembler code.
2) Includes proposed "platform_type" extension for boot protocol. May not be necessary.
3) kvm/ now contains guest code, so needs to be obj-y.
4) Debugging flags just to prove code isn't ready
5) Changes emulator not to try to restore regs after inject_gp. May refactor (we need to deal with this for inject_pf anyway).
6) Fixes "first_cpu()" macro.
7) Temporary hcalls, deliberately sucky.

arch/i386/kernel/asm-offsets.c +20 -0
diff -r 039995825488 arch/i386/kernel/asm-offsets.c
@@ -22,6 +22,11 @@
 #ifdef CONFIG_LGUEST_GUEST
 #include <linux/lguest.h>
 #include "../../../drivers/lguest/lg.h"
+#endif
+
+#if defined(CONFIG_KVM_LITE) || defined(CONFIG_KVM_LITE_MODULE)
+#include <linux/kvm_lite.h>
+#include "../../../drivers/kvm/lite.h"
 #endif
 
 #define DEFINE(sym, val) \
@@ -144,4 +149,19 @@ void foo(void)
 	OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode);
 	OFFSET(LGUEST_PAGES_regs, lguest_pages, regs);
 #endif
+
+#if defined(CONFIG_KVM_LITE) || defined(CONFIG_KVM_LITE_MODULE)
+	BLANK();
+	OFFSET(LITE_DATA_irq_enabled, kvm_lite_data, irq_enabled);
+	OFFSET(LITE_PAGES_host_gdt_desc, lite_pages, state.host_gdt_desc);
+	OFFSET(LITE_PAGES_host_idt_desc, lite_pages, state.host_idt_desc);
+	OFFSET(LITE_PAGES_host_cr3, lite_pages, state.host_cr3);
+	OFFSET(LITE_PAGES_host_sp, lite_pages, state.host_sp);
+	OFFSET(LITE_PAGES_guest_gdt_desc, lite_pages,state.guest_gdt_desc);
+	OFFSET(LITE_PAGES_guest_idt_desc, lite_pages,state.guest_idt_desc);
+	OFFSET(LITE_PAGES_guest_gdt, lite_pages, state.guest_gdt);
+	OFFSET(LITE_PAGES_regs_trapnum, lite_pages, regs.trapnum);
+	OFFSET(LITE_PAGES_regs_errcode, lite_pages, regs.errcode);
+	OFFSET(LITE_PAGES_regs, lite_pages, regs);
+#endif
 }
arch/i386/kernel/head.S +8 -1
diff -r 039995825488 arch/i386/kernel/head.S
@@ -70,7 +70,14 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + 
  */
 .section .text.head,"ax",@progbits
 ENTRY(startup_32)
-
+/*
+ * Check if we're some special platform type.
+ * FIXME: check header version first!
+ */
+#ifdef CONFIG_KVM_LITE_GUEST
+	cmpl	$2, 0x23c(%esi)
+	je	kvm_lite_init_asm
+#endif
 /*
  * Set segments to known values.
  */
drivers/Makefile +1 -1
diff -r 039995825488 drivers/Makefile
@@ -48,7 +48,7 @@ obj-$(CONFIG_PCCARD)		+= pcmcia/
 obj-$(CONFIG_PCCARD)		+= pcmcia/
 obj-$(CONFIG_DIO)		+= dio/
 obj-$(CONFIG_SBUS)		+= sbus/
-obj-$(CONFIG_KVM)		+= kvm/
+obj-y				+= kvm/
 obj-$(CONFIG_ZORRO)		+= zorro/
 obj-$(CONFIG_MAC)		+= macintosh/
 obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
drivers/kvm/Kconfig +18 -0
diff -r 039995825488 drivers/kvm/Kconfig
@@ -41,4 +41,22 @@ config KVM_AMD
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config KVM_LITE
+	tristate "KVM-lite for unsupported processors"
+	depends on KVM
+	select X86_PAE
+	---help---
+	  Provides minimal support for booting paravirtualized guests.
+	  Does not require Intel VT or AMD AMD-V extensions, but does require
+	  a processor which support PAE (Pentium Pro and better).  If you say
+	  Y or M here, your kernel will not boot on a processor without PAE
+	  support.
+
+config KVM_LITE_GUEST
+	bool "KVM-lite guest support"
+	depends on PARAVIRT && EXPERIMENTAL
+	select HVC_DRIVER
+	---help---
+	  Allows this kernel to run under kvm-lite.
+
 endif # VIRTUALIZATION
drivers/kvm/Makefile +8 -0
diff -r 039995825488 drivers/kvm/Makefile
@@ -8,3 +8,11 @@ obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
 obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
 kvm-amd-objs = svm.o
 obj-$(CONFIG_KVM_AMD) += kvm-amd.o
+kvm-lite-objs = lite.o lite_switcher.o
+obj-$(CONFIG_KVM_LITE) += kvm-lite.o
+obj-$(CONFIG_KVM_LITE_GUEST) += lite_guest.o lite_guest_asm.o
+CFLAGS_lite.o += -O0 -g
+CFLAGS_lite_guest.o += -O0 -g
+CFLAGS_mmu.o += -O0 -g
+CFLAGS_kvm_main.o += -O0 -g
+CFLAGS_x86_emulate.o += -O0 -g
drivers/kvm/kvm.h +5 -0
diff -r 039995825488 drivers/kvm/kvm.h
@@ -153,6 +153,7 @@ struct kvm_mmu {
 	hpa_t root_hpa;
 	int root_level;
 	int shadow_root_level;
+	int nailed;
 
 	u64 *pae_root;
 };
@@ -491,10 +492,14 @@ void kvm_exit_arch(void);
 
 int kvm_mmu_module_init(void);
 void kvm_mmu_module_exit(void);
+int kvm_mmu_init_nailed_mapping(int cpu, struct page *page[], unsigned num);
+void kvm_mmu_free_nailed_mapping(int cpu);
 
 void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
 int kvm_mmu_create(struct kvm_vcpu *vcpu);
 int kvm_mmu_setup(struct kvm_vcpu *vcpu);
+void kvm_use_nailed_mappings(struct kvm_vcpu *vcpu);
+void kvm_remove_nailed_mappings(struct kvm_vcpu *vcpu);
 
 int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
 void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
drivers/kvm/kvm_main.c +5 -4
diff -r 039995825488 drivers/kvm/kvm_main.c
@@ -530,6 +530,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsi
 		return;
 	}
 	kvm_arch_ops->set_cr4(vcpu, cr4);
+	vcpu->cr4 = cr4;
 	mutex_lock(&vcpu->kvm->lock);
 	kvm_mmu_reset_context(vcpu);
 	mutex_unlock(&vcpu->kvm->lock);
@@ -918,6 +919,7 @@ void mark_page_dirty(struct kvm *kvm, gf
 			set_bit(rel_gfn, memslot->dirty_bitmap);
 	}
 }
+EXPORT_SYMBOL_GPL(mark_page_dirty);
 
 int emulator_read_std(unsigned long addr,
 			     void *val,
@@ -1146,10 +1148,8 @@ int emulate_invlpg(struct kvm_vcpu *vcpu
 
 int emulate_clts(struct kvm_vcpu *vcpu)
 {
-	unsigned long cr0;
-
-	cr0 = vcpu->cr0 & ~X86_CR0_TS;
-	kvm_arch_ops->set_cr0(vcpu, cr0);
+	vcpu->cr0 &= ~X86_CR0_TS;
+	kvm_arch_ops->set_cr0(vcpu, vcpu->cr0);
 	return X86EMUL_CONTINUE;
 }
 
@@ -2033,6 +2033,7 @@ static int kvm_vcpu_ioctl_set_sregs(stru
 	kvm_arch_ops->decache_cr4_guest_bits(vcpu);
 
 	mmu_reset_needed |= vcpu->cr0 != sregs->cr0;
+	vcpu->cr0 = sregs->cr0;
 	kvm_arch_ops->set_cr0(vcpu, sregs->cr0);
 
 	mmu_reset_needed |= vcpu->cr4 != sregs->cr4;
drivers/kvm/lite.c new file +1716 -0

1,716 lines not on this page · raw message

drivers/kvm/lite.h new file +65 -0

65 lines not on this page · raw message

drivers/kvm/lite_guest.c new file +527 -0

527 lines not on this page · raw message

drivers/kvm/lite_guest_asm.S new file +92 -0

92 lines not on this page · raw message

drivers/kvm/lite_switcher.S new file +309 -0

309 lines not on this page · raw message

drivers/kvm/mmu.c +127 -0

145 lines not on this page · raw message

drivers/kvm/paging_tmpl.h +5 -0
diff -r 039995825488 drivers/kvm/paging_tmpl.h
@@ -86,6 +86,11 @@ static int FNAME(walk_addr)(struct guest
 	walker->page = NULL;
 	walker->ptep = NULL;
 	root = vcpu->cr3;
+
+	/* Don't let them do anything with the nailed area. */
+	if (vcpu->mmu.nailed && addr >= SHADOW_NAILED_RESERVE)
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

drivers/kvm/x86_emulate.c +6 -2
diff -r 039995825488 drivers/kvm/x86_emulate.c

Lines of this file are not shown. View the raw message.

include/linux/cpumask.h +2 -2
diff -r 039995825488 include/linux/cpumask.h

Lines of this file are not shown. View the raw message.

include/linux/kvm_lite.h new file +33 -0
diff -r 039995825488 include/linux/kvm_lite.h

Lines of this file are not shown. View the raw message.

include/linux/kvm_para.h +7 -0
diff -r 039995825488 include/linux/kvm_para.h

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

Part of the diff is not shown here. View the raw message.

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

#8 lore raw

PATCH 5/5 kvm-lite qemu patch

"-M pclite" requires -kernel, requires kvm. Also changes --enable-kvm to --disable-kvm (it's enabled on supported archs, so we need a disable not an enable flag).

index d9292fe..bf4c8ba 100755

configure +1 -1
@@ -84,7 +84,7 @@ target_cpu() {
 (cd qemu; ./configure --target-list=$(target_cpu)-softmmu --cc="$qemu_cc" \
     --disable-kqemu --extra-cflags="-I $PWD/../user" \
     --extra-ldflags="-L $PWD/../user" \
-    --enable-kvm --kernel-path="$libkvm_kerneldir" \
+    --kernel-path="$libkvm_kerneldir" \
     --enable-alsa \
     ${disable_gcc_check:+"--disable-gcc-check"} \
     --prefix="$prefix"

index 365b7fb..9455e3c 100755

qemu/configure +2 -2
@@ -236,7 +236,7 @@ for opt do
   ;;
   --disable-kqemu) kqemu="no"
   ;;
-  --enable-kvm) kvm="yes"
+  --disable-kvm) kvm="no"
   ;;
   --enable-profiler) profiler="yes"
   ;;
@@ -286,7 +286,7 @@ echo ""
 echo "kqemu kernel acceleration support:"
 echo "  --disable-kqemu          disable kqemu support"
 echo "  --kernel-path=PATH       set the kernel path (configure probes it)"
-echo "  --enable-kvm             enable kernel virtual machine support"
+echo "  --disable-kvm            disable kernel virtual machine support"
 echo ""
 echo "Advanced options (experts only):"
 echo "  --source-path=PATH       path of source code [$source_path]"

index ae92173..c8520a6 100644

qemu/hw/pc.c +231 -0

240 lines not on this page · raw message

index 4ba93d8..a91eaa6 100644

qemu/qemu-kvm.c +1 -0
@@ -9,6 +9,7 @@
 #endif
 
 int kvm_allowed = KVM_ALLOWED_DEFAULT;
+int kvm_lite = 0;
 
 #ifdef USE_KVM
 

index bacda22..c27fcbb 100644

qemu/qemu-kvm.h +1 -0
@@ -24,6 +24,7 @@ void qemu_kvm_cpuid_on_env(CPUState *env);
 void kvm_update_after_sipi(CPUState *env);
 void kvm_update_interrupt_request(CPUState *env);
 
+extern int kvm_lite;
 
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
 #define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8)

index 4ad39f1..cc43d06 100644

qemu/vl.c +10 -0
@@ -6576,6 +6576,8 @@ enum {
     QEMU_OPTION_no_rtc,
 #endif
     QEMU_OPTION_cpu_vendor,
+/* FIXME: Better to probe for this. */
+    QEMU_OPTION_kvm_lite,
 };
 
 typedef struct QEMUOption {
@@ -6635,6 +6637,7 @@ const QEMUOption qemu_options[] = {
 #endif
 #ifdef USE_KVM
     { "no-kvm", 0, QEMU_OPTION_no_kvm },
+    { "kvm-lite", 0, QEMU_OPTION_kvm_lite },
 #endif
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
     { "g", 1, QEMU_OPTION_g },
@@ -6728,6 +6731,9 @@ void register_machines(void)
 #if defined(TARGET_I386)
     qemu_register_machine(&pc_machine);
     qemu_register_machine(&isapc_machine);
+#if defined(USE_KVM)
+    qemu_register_machine(&pclite_machine);
+#endif
 #elif defined(TARGET_PPC)
     qemu_register_machine(&heathrow_machine);
     qemu_register_machine(&core99_machine);
@@ -7344,6 +7350,9 @@ int main(int argc, char **argv)
 	    case QEMU_OPTION_no_kvm:
 		kvm_allowed = 0;
 		break;
+	    case QEMU_OPTION_kvm_lite:
+		kvm_lite = 1;
+		break;
 #endif
             case QEMU_OPTION_usb:
                 usb_enabled = 1;
@@ -7450,6 +7459,7 @@ int main(int argc, char **argv)
 	if (kvm_qemu_init() < 0) {
 	    fprintf(stderr, "Could not initialize KVM, will disable KVM support\n");
 	    kvm_allowed = 0;
+	    kvm_lite = 0;
 	}
     }
 #endif

index 43f56bd..9fd38ba 100644

qemu/vl.h +1 -0
@@ -1099,6 +1099,7 @@ SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
 /* pc.c */
 extern QEMUMachine pc_machine;
 extern QEMUMachine isapc_machine;
+extern QEMUMachine pclite_machine;
 extern int fd_bootchk;
 
 void ioport_set_a20(int enable);

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

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

#10 lore raw

Re: [PATCH 5/5] kvm-lite qemu patch

Quoted 224 lines · Rusty Russell

"-M pclite" requires -kernel, requires kvm. Also changes --enable-kvm to --disable-kvm (it's enabled on supported archs, so we need a disable not an enable flag).

qemu/hw/pc.c +220 -0
+#ifdef USE_KVM
+/* FIXME: Run without paging and then turn it on, like normal Guest. */
+/* Once we know how much memory we have, we can construct simple linear page
+ * tables which set virtual == physical which will get the Guest far enough
+ * into the boot to create its own.
+ *
+ * We lay them out of the way, just below the initrd, which is why we need to
+ * know its offset (== mem if no initrd). */
+static unsigned long linear_pagetables(unsigned long mem,
+				       unsigned long initrd_offset)
+{
+	unsigned long pgdir, linear;
+	unsigned int mapped_pages, i, linear_pages;
+	unsigned int ptes_per_page = 1024;
+	unsigned long pageflags = PG_PRESENT_MASK|PG_RW_MASK;
+
+	mapped_pages = mem/TARGET_PAGE_SIZE;
+
+	/* Each PTE page can map ptes_per_page pages: how many do we need? */
+	linear_pages = (mapped_pages + ptes_per_page-1)/ptes_per_page;
+
+	/* We put the toplevel page directory page at the top of memory. */
+	pgdir = initrd_offset - TARGET_PAGE_SIZE;
+
+	/* Now we use the next linear_pages pages as pte pages */
+	linear = pgdir - linear_pages*TARGET_PAGE_SIZE;
+
+	/* Linear mapping is easy: put every page's address into the mapping in
+	 * order. */
+	for (i = 0; i < mapped_pages; i++)
+	    stl_raw(phys_ram_base + linear + i * sizeof(long),
+		    (i * TARGET_PAGE_SIZE) | pageflags);
+
+	/* The top level points to the linear page table pages above. */
+	for (i = 0; i < mapped_pages; i += ptes_per_page)
+	    stl_raw(phys_ram_base + pgdir + i/ptes_per_page * sizeof(long),
+		    (linear + i*4) | pageflags);
+
+	/* We return the top level (guest-physical) address: the kernel needs
+	 * to know where it is. */
+	return (unsigned long)pgdir;
+}
+
+static void hack_console_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    printf("%c", val); fflush(stdout);
+}
+
+static void hack_timer_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    QEMUTimer *irq_timer = opaque;
+
+    if (val == 0)
+        qemu_del_timer(irq_timer);
+    else
+	qemu_mod_timer(irq_timer, qemu_get_clock(vm_clock) + val);
+}
+
+/* FIXME: I don't think this is the right way to do an interrupt. */
+static void hack_timer_tick(void *opaque)
+{
+    first_cpu->hflags &= ~HF_HALTED_MASK;
+    if (kvm_inject_irq(kvm_context, 0, 32) != 0)
+	fprintf(stderr, "Failed to inject timer irq: %m\n");
+}
+
+static void pc_init_lite(int ram_size, int vga_ram_size, int boot_device,
+                        DisplayState *ds, const char **fd_filename, 
+                        int snapshot, 
+                        const char *kernel_filename, 
+                        const char *kernel_cmdline,
+                        const char *initrd_filename)
+{
+    int ret, initrd_size, i;
+    ram_addr_t initrd_offset;
+    CPUState *env;
+    uint8_t *video_mem;
+    QEMUTimer *irq_timer;
+
+    printf("Starting pc lite init\n");
+
+    if (!kernel_filename) {
+        fprintf(stderr, "qemu: pclite needs -kernel\n");
+        exit(1);
+    }
+
+    /* init CPUs */
+    for(i = 0; i < smp_cpus; i++) {
+        env = cpu_init();
+        if (i != 0)
+            env->hflags |= HF_HALTED_MASK;
+        if (smp_cpus > 1) {
+            /* XXX: enable it in all cases */
+            env->cpuid_features |= CPUID_APIC;
+	    /* FIXME */
+	    fprintf(stderr, "Sorry, SMP not supported");
+	    exit(1);
+        }
+	apic_init(env);
+        register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
+        qemu_register_reset(main_cpu_reset, env);
+    }
+
+    printf("pc lite init: %u\n", __LINE__);
+    /* allocate RAM */
+    cpu_register_physical_memory(0, ram_size, 0);
+
+    /* FIXME: Wire this in somewhere? */
+    ioapic_init();
+
+#if 0
+    isa_pic = pic_init(pic_irq_request, first_cpu);
+    pit = pit_init(0x40, 0);
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+        if (serial_hds[i]) {
+            serial_init(&pic_set_irq_new, isa_pic,
+                        serial_io[i], serial_irq[i], serial_hds[i]);
+        }
+    }
+#endif
+
+    irq_timer = qemu_new_timer(vm_clock, hack_timer_tick, NULL);
+
+    register_ioport_write(0x1, 1, 1, hack_console_write, NULL);
+    register_ioport_write(0x2, 1, 4, hack_timer_write, irq_timer);
+
+    /* FIXME: kvm_create() "knows" the layout of x86 and doesn't map
+     * all the memory.  Map the video memory here. */
+    video_mem = kvm_create_phys_mem(kvm_context, 0xA0000, 0x20000, 2, 0, 1);
+    if (!video_mem)
+	exit(1);
+
+#if 0
+    register_ioport_write(0x3d4, 1, 1, hack_vga_console_write,
+			  phys_ram_base + 0xB8000);
+    register_ioport_write(0x3d5, 1, 1, hack_vga_console_write,
+			  phys_ram_base + 0xB8000);
+#endif
+
+    /* now we can load the kernel */
+    ret = load_kernel(kernel_filename, 
+		      phys_ram_base + KERNEL_LOAD_ADDR,
+		      phys_ram_base + KERNEL_PARAMS_ADDR);
+    if (ret < 0) {
+	fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
+	exit(1);
+    }
+
+    /* load initrd */
+    initrd_size = 0;
+    initrd_offset = ram_size;
+    if (initrd_filename) {
+	initrd_size = get_image_size (initrd_filename);
+	if (initrd_size > 0) {
+	    initrd_offset = (ram_size - initrd_size) & TARGET_PAGE_MASK;
+	    if (initrd_offset > MAX_INITRD_LOAD_ADDR)
+		initrd_offset = MAX_INITRD_LOAD_ADDR;
+
+	    if (initrd_size > ram_size
+		|| initrd_offset < KERNEL_LOAD_ADDR + ret) {
+		fprintf(stderr,
+			"qemu: memory too small for initial ram disk '%s'\n",
+			initrd_filename);
+		exit(1);
+	    }
+	    initrd_size = load_image(initrd_filename,
+				     phys_ram_base + initrd_offset);
+	}
+	if (initrd_size < 0) {
+	    fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
+		    initrd_filename);
+	    exit(1);
+	}
+    }
+    if (initrd_size > 0) {
+	stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, initrd_offset);
+	stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
+    }
+    printf("pc lite init: %u\n", __LINE__);
+
+    /* Mug screen_info */
+    memset(phys_ram_base + KERNEL_PARAMS_ADDR, 0, 0x40);
+    pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
+	    kernel_cmdline);
+    stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
+    stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
+	    KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
+    /* loader type */
+    stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
+    
+    /* Platform: kvm-lite */
+    stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x23c, 0x02);
+
+    env->eip = KERNEL_LOAD_ADDR;
+    env->eflags = 0x002;
+    env->regs[R_ESI] = KERNEL_PARAMS_ADDR;
+
+    /* The Linux boot header contains an "E820" memory map: ours is a simple,
+     * single region. */
+    stb_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x1e8, 1);
+    /* Zero it out first. */
+    memset(phys_ram_base + KERNEL_PARAMS_ADDR + 0x2d0, 0, 20);
+    stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x2d8, ram_size);
+    stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x2e0, 1 /* RAM */);
+
+    /* KERNEL_CS ring 1 */
+    cpu_x86_load_seg_cache(env, R_CS, 12*8+1, 0, 0xffffffff, 0x00cf9b00);
+    /* KERNEL_DS ring 1 */
+    cpu_x86_load_seg_cache(env, R_DS, 13*8+1, 0, 0xffffffff, 0x00cf9300);
+    cpu_x86_load_seg_cache(env, R_SS, 13*8+1, 0, 0xffffffff, 0x00cf9300);
+    cpu_x86_load_seg_cache(env, R_ES, 13*8+1, 0, 0xffffffff, 0x00cf9300);
+
+    /* Page table pointer. */
+    env->cr[3] = linear_pagetables(ram_size, initrd_offset);
+
+    /* KVM code cares that CR0 is set correctly (lite doesn't). */
+    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+
+    /* We seem to need to force KVM to get these regs now. */
+    kvm_load_registers(env);

qemu/hw/pc.c static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device, · line 1052

Quoted 10 lines
qemu/hw/pc.c +10 -0
+    printf("Done pc lite init\n");
+}
+
+QEMUMachine pclite_machine = {
+    "pclite",
+    "kvm-lite PC",
+    pc_init_lite,
+};
+#endif /* USE_KVM */
+

Most of this hunk should go into a separate file.

It would also be nice to support the hypercalls in qemu, so we can run without kernel support (on non-x86 hardware, for example).

Signature · 8 lines
Any sufficiently difficult bug is indistinguishable from a feature.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
#11 lore raw

Re: [PATCH 5/5] kvm-lite qemu patch

In reply to a message not in the archive
Quoted 224 lines · Rusty Russell

"-M pclite" requires -kernel, requires kvm. Also changes --enable-kvm to --disable-kvm (it's enabled on supported archs, so we need a disable not an enable flag).

qemu/hw/pc.c +220 -0
+#ifdef USE_KVM
+/* FIXME: Run without paging and then turn it on, like normal Guest. */
+/* Once we know how much memory we have, we can construct simple linear page
+ * tables which set virtual == physical which will get the Guest far enough
+ * into the boot to create its own.
+ *
+ * We lay them out of the way, just below the initrd, which is why we need to
+ * know its offset (== mem if no initrd). */
+static unsigned long linear_pagetables(unsigned long mem,
+				       unsigned long initrd_offset)
+{
+	unsigned long pgdir, linear;
+	unsigned int mapped_pages, i, linear_pages;
+	unsigned int ptes_per_page = 1024;
+	unsigned long pageflags = PG_PRESENT_MASK|PG_RW_MASK;
+
+	mapped_pages = mem/TARGET_PAGE_SIZE;
+
+	/* Each PTE page can map ptes_per_page pages: how many do we need? */
+	linear_pages = (mapped_pages + ptes_per_page-1)/ptes_per_page;
+
+	/* We put the toplevel page directory page at the top of memory. */
+	pgdir = initrd_offset - TARGET_PAGE_SIZE;
+
+	/* Now we use the next linear_pages pages as pte pages */
+	linear = pgdir - linear_pages*TARGET_PAGE_SIZE;
+
+	/* Linear mapping is easy: put every page's address into the mapping in
+	 * order. */
+	for (i = 0; i < mapped_pages; i++)
+	    stl_raw(phys_ram_base + linear + i * sizeof(long),
+		    (i * TARGET_PAGE_SIZE) | pageflags);
+
+	/* The top level points to the linear page table pages above. */
+	for (i = 0; i < mapped_pages; i += ptes_per_page)
+	    stl_raw(phys_ram_base + pgdir + i/ptes_per_page * sizeof(long),
+		    (linear + i*4) | pageflags);
+
+	/* We return the top level (guest-physical) address: the kernel needs
+	 * to know where it is. */
+	return (unsigned long)pgdir;
+}
+
+static void hack_console_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    printf("%c", val); fflush(stdout);
+}
+
+static void hack_timer_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    QEMUTimer *irq_timer = opaque;
+
+    if (val == 0)
+        qemu_del_timer(irq_timer);
+    else
+	qemu_mod_timer(irq_timer, qemu_get_clock(vm_clock) + val);
+}
+
+/* FIXME: I don't think this is the right way to do an interrupt. */
+static void hack_timer_tick(void *opaque)
+{
+    first_cpu->hflags &= ~HF_HALTED_MASK;
+    if (kvm_inject_irq(kvm_context, 0, 32) != 0)
+	fprintf(stderr, "Failed to inject timer irq: %m\n");
+}
+
+static void pc_init_lite(int ram_size, int vga_ram_size, int boot_device,
+                        DisplayState *ds, const char **fd_filename, 
+                        int snapshot, 
+                        const char *kernel_filename, 
+                        const char *kernel_cmdline,
+                        const char *initrd_filename)
+{
+    int ret, initrd_size, i;
+    ram_addr_t initrd_offset;
+    CPUState *env;
+    uint8_t *video_mem;
+    QEMUTimer *irq_timer;
+
+    printf("Starting pc lite init\n");
+
+    if (!kernel_filename) {
+        fprintf(stderr, "qemu: pclite needs -kernel\n");
+        exit(1);
+    }
+
+    /* init CPUs */
+    for(i = 0; i < smp_cpus; i++) {
+        env = cpu_init();
+        if (i != 0)
+            env->hflags |= HF_HALTED_MASK;
+        if (smp_cpus > 1) {
+            /* XXX: enable it in all cases */
+            env->cpuid_features |= CPUID_APIC;
+	    /* FIXME */
+	    fprintf(stderr, "Sorry, SMP not supported");
+	    exit(1);
+        }
+	apic_init(env);
+        register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
+        qemu_register_reset(main_cpu_reset, env);
+    }
+
+    printf("pc lite init: %u\n", __LINE__);
+    /* allocate RAM */
+    cpu_register_physical_memory(0, ram_size, 0);
+
+    /* FIXME: Wire this in somewhere? */
+    ioapic_init();
+
+#if 0
+    isa_pic = pic_init(pic_irq_request, first_cpu);
+    pit = pit_init(0x40, 0);
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+        if (serial_hds[i]) {
+            serial_init(&pic_set_irq_new, isa_pic,
+                        serial_io[i], serial_irq[i], serial_hds[i]);
+        }
+    }
+#endif
+
+    irq_timer = qemu_new_timer(vm_clock, hack_timer_tick, NULL);
+
+    register_ioport_write(0x1, 1, 1, hack_console_write, NULL);
+    register_ioport_write(0x2, 1, 4, hack_timer_write, irq_timer);
+
+    /* FIXME: kvm_create() "knows" the layout of x86 and doesn't map
+     * all the memory.  Map the video memory here. */
+    video_mem = kvm_create_phys_mem(kvm_context, 0xA0000, 0x20000, 2, 0, 1);
+    if (!video_mem)
+	exit(1);
+
+#if 0
+    register_ioport_write(0x3d4, 1, 1, hack_vga_console_write,
+			  phys_ram_base + 0xB8000);
+    register_ioport_write(0x3d5, 1, 1, hack_vga_console_write,
+			  phys_ram_base + 0xB8000);
+#endif
+
+    /* now we can load the kernel */
+    ret = load_kernel(kernel_filename, 
+		      phys_ram_base + KERNEL_LOAD_ADDR,
+		      phys_ram_base + KERNEL_PARAMS_ADDR);
+    if (ret < 0) {
+	fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
+	exit(1);
+    }
+
+    /* load initrd */
+    initrd_size = 0;
+    initrd_offset = ram_size;
+    if (initrd_filename) {
+	initrd_size = get_image_size (initrd_filename);
+	if (initrd_size > 0) {
+	    initrd_offset = (ram_size - initrd_size) & TARGET_PAGE_MASK;
+	    if (initrd_offset > MAX_INITRD_LOAD_ADDR)
+		initrd_offset = MAX_INITRD_LOAD_ADDR;
+
+	    if (initrd_size > ram_size
+		|| initrd_offset < KERNEL_LOAD_ADDR + ret) {
+		fprintf(stderr,
+			"qemu: memory too small for initial ram disk '%s'\n",
+			initrd_filename);
+		exit(1);
+	    }
+	    initrd_size = load_image(initrd_filename,
+				     phys_ram_base + initrd_offset);
+	}
+	if (initrd_size < 0) {
+	    fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
+		    initrd_filename);
+	    exit(1);
+	}
+    }
+    if (initrd_size > 0) {
+	stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, initrd_offset);
+	stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
+    }
+    printf("pc lite init: %u\n", __LINE__);
+
+    /* Mug screen_info */
+    memset(phys_ram_base + KERNEL_PARAMS_ADDR, 0, 0x40);
+    pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
+	    kernel_cmdline);
+    stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
+    stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
+	    KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
+    /* loader type */
+    stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
+    
+    /* Platform: kvm-lite */
+    stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x23c, 0x02);
+
+    env->eip = KERNEL_LOAD_ADDR;
+    env->eflags = 0x002;
+    env->regs[R_ESI] = KERNEL_PARAMS_ADDR;
+
+    /* The Linux boot header contains an "E820" memory map: ours is a simple,
+     * single region. */
+    stb_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x1e8, 1);
+    /* Zero it out first. */
+    memset(phys_ram_base + KERNEL_PARAMS_ADDR + 0x2d0, 0, 20);
+    stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x2d8, ram_size);
+    stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x2e0, 1 /* RAM */);
+
+    /* KERNEL_CS ring 1 */
+    cpu_x86_load_seg_cache(env, R_CS, 12*8+1, 0, 0xffffffff, 0x00cf9b00);
+    /* KERNEL_DS ring 1 */
+    cpu_x86_load_seg_cache(env, R_DS, 13*8+1, 0, 0xffffffff, 0x00cf9300);
+    cpu_x86_load_seg_cache(env, R_SS, 13*8+1, 0, 0xffffffff, 0x00cf9300);
+    cpu_x86_load_seg_cache(env, R_ES, 13*8+1, 0, 0xffffffff, 0x00cf9300);
+
+    /* Page table pointer. */
+    env->cr[3] = linear_pagetables(ram_size, initrd_offset);
+
+    /* KVM code cares that CR0 is set correctly (lite doesn't). */
+    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+
+    /* We seem to need to force KVM to get these regs now. */
+    kvm_load_registers(env);

qemu/hw/pc.c static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device, · line 1052

Quoted 10 lines
qemu/hw/pc.c +10 -0
+    printf("Done pc lite init\n");
+}
+
+QEMUMachine pclite_machine = {
+    "pclite",
+    "kvm-lite PC",
+    pc_init_lite,
+};
+#endif /* USE_KVM */
+

Most of this hunk should go into a separate file.

It would also be nice to support the hypercalls in qemu, so we can run without kernel support (on non-x86 hardware, for example).

Signature · 8 lines
Any sufficiently difficult bug is indistinguishable from a feature.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

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

#13 lore raw

Re: [PATCH 5/5] kvm-lite qemu patch

Quoted 10 lines · Avi Kivity

qemu/hw/pc.c static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device, · line 1052

Quoted 7 lines · Rusty Russell
qemu/hw/pc.c +7 -0
+QEMUMachine pclite_machine = {
+    "pclite",
+    "kvm-lite PC",
+    pc_init_lite,
+};
+#endif /* USE_KVM */
+

Most of this hunk should go into a separate file.

This currently doesn't use much of the rest of the file, but it will change as we do some emulation. It might well become a branch in the normal PC initialization.

Quoted 2 lines

It would also be nice to support the hypercalls in qemu, so we can run without kernel support (on non-x86 hardware, for example).

Yes, I look forward to your patches 8)

Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

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

#15 lore raw

Re: [PATCH 5/5] kvm-lite qemu patch

Quoted 8 lines · Rusty Russell
Quoted 4 lines

It would also be nice to support the hypercalls in qemu, so we can run without kernel support (on non-x86 hardware, for example).

Yes, I look forward to your patches 8)

Isn't dropping unsubtle hints sufficient?

I'm sure someone will pick it up eventually.

Signature · 8 lines
Any sufficiently difficult bug is indistinguishable from a feature.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
#16 lore raw

Re: [PATCH 4/5] kvm-lite: "The Unbearable Liteness"

In reply to a message not in the archive
Quoted 10 lines · Rusty Russell

This patch is not for serious application, but makes interesting reading. Requires Anthony's new hypercall patches.

Comments:

1) asm-offsets are required for lite's switcher/trampoline (lite_switcher.S) and for guest's assembler code.
2) Includes proposed "platform_type" extension for boot protocol. May not be necessary.
3) kvm/ now contains guest code, so needs to be obj-y.

I think lite_guest.c ought to end up in arch/i386/kernel/kvm.c with the rest of the PV guest code.

Regards,

Anthony Liguori

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#17 lore raw

Re: [PATCH 4/5] kvm-lite: "The Unbearable Liteness"

Quoted 6 lines · Anthony Liguori
Quoted 5 lines · Rusty Russell

This patch is not for serious application, but makes interesting reading. Requires Anthony's new hypercall patches.

Comments:

Quoted 8 lines
Quoted 5 lines

1) asm-offsets are required for lite's switcher/trampoline (lite_switcher.S) and for guest's assembler code.
2) Includes proposed "platform_type" extension for boot protocol. May not be necessary.
3) kvm/ now contains guest code, so needs to be obj-y.

I think lite_guest.c ought to end up in arch/i386/kernel/kvm.c with the rest of the PV guest code.

Agreed, but that didn't exist when this patch was made.

ISTR there was some feedback for your patches; were you going to repost?

Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

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

#19 lore raw

Re: [PATCH 4/5] kvm-lite: "The Unbearable Liteness"

Quoted 13 lines · Rusty Russell
Quoted 12 lines · Anthony Liguori
Quoted 10 lines · Rusty Russell

This patch is not for serious application, but makes interesting reading. Requires Anthony's new hypercall patches.

Comments:

1) asm-offsets are required for lite's switcher/trampoline (lite_switcher.S) and for guest's assembler code.
2) Includes proposed "platform_type" extension for boot protocol. May not be necessary.
3) kvm/ now contains guest code, so needs to be obj-y.

Quoted 6 lines
Quoted 2 lines

I think lite_guest.c ought to end up in arch/i386/kernel/kvm.c with the rest of the PV guest code.

Agreed, but that didn't exist when this patch was made.

ISTR there was some feedback for your patches; were you going to repost?

Avi had suggested that IO delay be set based on query to the kernel but ATM since no devices are in the kernel, this didn't seem like a good idea.

Was there something else that I'm missing?

Regards,

Anthony Liguori

Quoted 2 lines

Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#20 lore raw

Re: [PATCH 4/5] kvm-lite: "The Unbearable Liteness"

Quoted 10 lines · Anthony Liguori
Quoted 5 lines

Agreed, but that didn't exist when this patch was made.

ISTR there was some feedback for your patches; were you going to repost?

Avi had suggested that IO delay be set based on query to the kernel but ATM since no devices are in the kernel, this didn't seem like a good idea.

I think it was passthrough devices; in-kernel devices don't need I/O delay.

Quoted 2 lines

Was there something else that I'm missing?

It's just me backlogged. Note that I am only applying fixes to regressions until lapic is merged. Once kernel summit is over I'll get that done.

Signature · 8 lines
Any sufficiently difficult bug is indistinguishable from a feature.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
#21 lore raw

Re: [PATCH 4/5] kvm-lite: "The Unbearable Liteness"

In reply to a message not in the archive
Quoted 9 lines · Rusty Russell

This patch is not for serious application, but makes interesting reading. Requires Anthony's new hypercall patches.

Comments:

2) Includes proposed "platform_type" extension for boot protocol. May not be necessary.
3) kvm/ now contains guest code, so needs to be obj-y.

We'll want the guest code in a different patch for easier review.

Quoted 3 lines

5) Changes emulator not to try to restore regs after inject_gp. May refactor (we need to deal with this for inject_pf anyway).

Separate please.

Eventually we'll want kvm_arch_ops (to be renamed kvm_x86_ops) to be a member of 'struct kvm', so lite and dark guests can coexist. That's not a precondition to merging, however.

From a cursory glance, all's well. I'll do a detailed review later on.

Signature · 8 lines
Any sufficiently difficult bug is indistinguishable from a feature.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
Applied
#22 lore raw

Re: [PATCH 3/5] Hoist SVM's get_cs_db_l_bits into core code.

In reply to a message not in the archive
Quoted 4 lines · Rusty Russell

SVM gets the DB and L bits for the cs by decoding the segment. This is in fact the completely generic code, so hoist it for kvm-lite to use.

Applied this and the cr0/cr4 sync. Thanks.

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


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#23 lore raw
In reply to a message not in the archive
Quoted 8 lines · Rusty Russell

invlpg shouldn't fetch the "src" address, since it may not be valid, however SVM's "solution" which neuters emulation of all group 7 instruction is horrible and breaks kvm-lite. The simplest fix is to put a special check in for invlpg.

Also, remove the unused invlpg member of struct kvm_arch_ops.

One change, one patch.

We'll want to revert the invlpg removal in the future anyway, when/if we begin to track virtual addresses in the shadow cache.

Signature · 8 lines
Any sufficiently difficult bug is indistinguishable from a feature.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

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

#25 lore raw
Quoted 11 lines · Avi Kivity
Quoted 8 lines · Rusty Russell

invlpg shouldn't fetch the "src" address, since it may not be valid, however SVM's "solution" which neuters emulation of all group 7 instruction is horrible and breaks kvm-lite. The simplest fix is to put a special check in for invlpg.

Also, remove the unused invlpg member of struct kvm_arch_ops.

One change, one patch.

Remove the unused invlpg member of struct kvm_arch_ops.

drivers/kvm/kvm.h +0 -1
diff -r 01dea2154ac6 drivers/kvm/kvm.h
@@ -459,7 +460,6 @@ struct kvm_arch_ops {
 	unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
 	void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
 
-	void (*invlpg)(struct kvm_vcpu *vcpu, gva_t addr);
 	void (*tlb_flush)(struct kvm_vcpu *vcpu);
 	void (*inject_page_fault)(struct kvm_vcpu *vcpu,
 				  unsigned long addr, u32 err_code);
drivers/kvm/svm.c +0 -6
diff -r 01dea2154ac6 drivers/kvm/svm.c
@@ -817,11 +809,6 @@ static void new_asid(struct vcpu_svm *sv
 	svm->vcpu.cpu = svm_data->cpu;
 	svm->asid_generation = svm_data->asid_generation;
 	svm->vmcb->control.asid = svm_data->next_asid++;
-}
-
-static void svm_invlpg(struct kvm_vcpu *vcpu, gva_t address)
-{
-	invlpga(address, to_svm(vcpu)->vmcb->control.asid); // is needed?
 }
 
 static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
@@ -1668,7 +1655,6 @@ static struct kvm_arch_ops svm_arch_ops 
 	.get_rflags = svm_get_rflags,
 	.set_rflags = svm_set_rflags,
 
-	.invlpg = svm_invlpg,
 	.tlb_flush = svm_flush_tlb,
 	.inject_page_fault = svm_inject_page_fault,
 

Clean up unloved invlpg: remove kvm_arch_ops.invlpg and tweak emulator.

invlpg shouldn't fetch the "src" address, since it may not be valid, however SVM's "solution" which neuters emulation of all group 7 instruction is horrible and breaks kvm-lite. The simplest fix is to put a special check in for invlpg.

drivers/kvm/kvm.h +0 -2
diff -r 01dea2154ac6 drivers/kvm/kvm.h
@@ -509,8 +513,6 @@ static inline int is_error_hpa(hpa_t hpa
 static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; }
 hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva);
 struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva);
-
-void kvm_emulator_want_group7_invlpg(void);
 
 extern hpa_t bad_page_address;
 
drivers/kvm/x86_emulate.c +3 -13
diff -r 01dea2154ac6 drivers/kvm/x86_emulate.c
@@ -212,19 +212,6 @@ static u16 twobyte_table[256] = {
 	/* 0xF0 - 0xFF */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
-
-/*
- * Tell the emulator that of the Group 7 instructions (sgdt, lidt, etc.) we
- * are interested only in invlpg and not in any of the rest.
- *
- * invlpg is a special instruction in that the data it references may not
- * be mapped.
- */
-void kvm_emulator_want_group7_invlpg(void)
-{
-	twobyte_table[1] &= ~SrcMem;
-}
-EXPORT_SYMBOL_GPL(kvm_emulator_want_group7_invlpg);
 
 /* Type, address-of, and value of an instruction's operand. */
 struct operand {
@@ -791,6 +778,9 @@ done_prefixes:
 		goto srcmem_common;
 	case SrcMem:
 		src.bytes = (d & ByteOp) ? 1 : op_bytes;
+		/* Don't fetch the address for invlpg: it could be unmapped. */
+		if (twobyte && b == 0x01 && modrm_reg == 7)
+			break;
 	      srcmem_common:
 		src.type = OP_MEM;
 		src.ptr = (unsigned long *)cr2;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
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): 1189009359.10802.157.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

Applied
#27 lore raw
Quoted 9 lines · Rusty Russell
Quoted 7 lines · Avi Kivity
Quoted 5 lines · Rusty Russell

invlpg shouldn't fetch the "src" address, since it may not be valid, however SVM's "solution" which neuters emulation of all group 7 instruction is horrible and breaks kvm-lite. The simplest fix is to put a special check in for invlpg.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines

Also, remove the unused invlpg member of struct kvm_arch_ops.

One change, one patch.

Applied both halves, thanks.

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


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/