Clean up unloved invlpg: remove kvm_arch_ops.invlpg and tweak emulator.
Subsystems (3)
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
@@ -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 hpastatic 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
@@ -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
@@ -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]
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
@@ -530,6 +530,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsireturn ; } 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 *vcpuint 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]
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
@@ -558,6 +560,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsivoid 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
@@ -2086,6 +2087,16 @@ static int kvm_vcpu_ioctl_set_sregs(strureturn 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
@@ -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]
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -530,6 +530,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsireturn ; } 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, gfset_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 *vcpuint 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
@@ -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 )
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]
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]
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/
Re: [PATCH 5/5] kvm-lite qemu patch
In reply to a message not in the archiveQuoted 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]
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]
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/
Re: [PATCH 4/5] kvm-lite: "The Unbearable Liteness"
In reply to a message not in the archiveQuoted 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/
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.cought to end up inarch/i386/kernel/kvm.cwith 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]
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.cought to end up inarch/i386/kernel/kvm.cwith 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/
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/
Re: [PATCH 4/5] kvm-lite: "The Unbearable Liteness"
In reply to a message not in the archiveQuoted 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 forinject_pfanyway).
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/
Avi Kivity
AppliedRe: [PATCH 3/5] Hoist SVM's get_cs_db_l_bits into core code.
In reply to a message not in the archiveQuoted 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/
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]
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
@@ -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
@@ -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
@@ -509,8 +513,6 @@ static inline int is_error_hpa(hpa_t hpastatic 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
@@ -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]
Avi Kivity
AppliedQuoted 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/