You can subscribe to this list here.
2008 |
Jan
(41) |
Feb
(101) |
Mar
(164) |
Apr
(94) |
May
(27) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|
From: Zhang, X. <xia...@in...> - 2008-01-31 10:29:54
|
From: Zhang Xiantao <xia...@in...> Date: Tue, 29 Jan 2008 13:15:05 +0800 Subject: [PATCH] kvm/ia64: Add kvm sal/pal virtulization support. Some sal/pal calls would be traped to kvm for virtulization from guest firmware. Signed-off-by: Xiantao Zhang<xia...@in...> --- arch/ia64/kvm/kvm_fw.c | 500 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 500 insertions(+), 0 deletions(-) create mode 100644 arch/ia64/kvm/kvm_fw.c diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c new file mode 100644 index 0000000..e6f9f29 --- /dev/null +++ b/arch/ia64/kvm/kvm_fw.c @@ -0,0 +1,500 @@ +/* + * PAL/SAL call delegation + * + * Copyright (c) 2004 Li Susie <sus...@in...> + * Copyright (c) 2005 Yu Ke <ke...@in...> + * Copyright (c) 2007 Zhang Xiantao <xia...@in...> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <linux/kvm_host.h> +#include <linux/smp.h> + +#include "vti.h" +#include "misc.h" + +#include <asm/pal.h> +#include <asm/sal.h> +#include <asm/tlb.h> + +/* + * Handy macros to make sure that the PAL return values start out + * as something meaningful. + */ +#define INIT_PAL_STATUS_UNIMPLEMENTED(x) \ + { \ + x.status =3D PAL_STATUS_UNIMPLEMENTED; \ + x.v0 =3D 0; \ + x.v1 =3D 0; \ + x.v2 =3D 0; \ + } + +#define INIT_PAL_STATUS_SUCCESS(x) \ + { \ + x.status =3D PAL_STATUS_SUCCESS; \ + x.v0 =3D 0; \ + x.v1 =3D 0; \ + x.v2 =3D 0; \ + } + +static void kvm_get_pal_call_data(struct kvm_vcpu *vcpu, + u64 *gr28, u64 *gr29, u64 *gr30, u64 *gr31) { + struct exit_ctl_data *p; + + if (vcpu) { + p =3D &vcpu->arch.exit_data; + if (p->exit_reason =3D=3D EXIT_REASON_PAL_CALL) { + *gr28 =3D p->u.pal_data.gr28; + *gr29 =3D p->u.pal_data.gr29; + *gr30 =3D p->u.pal_data.gr30; + *gr31 =3D p->u.pal_data.gr31; + return ; + } + } + printk(KERN_DEBUG"Error occurs in kvm_get_pal_call_data!!\n"); +} + +static void set_pal_result(struct kvm_vcpu *vcpu, + struct ia64_pal_retval result) { + + struct exit_ctl_data *p; + + p =3D kvm_get_exit_data(vcpu); + if (p && p->exit_reason =3D=3D EXIT_REASON_PAL_CALL) { + p->u.pal_data.ret =3D result; + return ; + } + INIT_PAL_STATUS_UNIMPLEMENTED(p->u.pal_data.ret); +} + +static void set_sal_result(struct kvm_vcpu *vcpu, + struct sal_ret_values result) { + struct exit_ctl_data *p; + + p =3D kvm_get_exit_data(vcpu); + if (p && p->exit_reason =3D=3D EXIT_REASON_SAL_CALL) { + p->u.sal_data.ret =3D result; + return ; + } + printk(KERN_WARNING"Error occurs!!!\n"); +} + +struct cache_flush_args { + u64 cache_type; + u64 operation; + u64 progress; + long status; +}; + +cpumask_t cpu_cache_coherent_map; + +static void remote_pal_cache_flush(void *data) +{ + struct cache_flush_args *args =3D data; + long status; + u64 progress =3D args->progress; + + status =3D ia64_pal_cache_flush(args->cache_type, args->operation, + &progress, NULL); + if (status !=3D 0) + args->status =3D status; +} + +static struct ia64_pal_retval pal_cache_flush(struct kvm_vcpu *vcpu) +{ + u64 gr28, gr29, gr30, gr31; + struct ia64_pal_retval result =3D {0, 0, 0, 0}; + struct cache_flush_args args =3D {0, 0, 0, 0}; + long psr; + + gr28 =3D gr29 =3D gr30 =3D gr31 =3D 0; + kvm_get_pal_call_data(vcpu, &gr28, &gr29, &gr30, &gr31); + + if (gr31 !=3D 0) + printk(KERN_ERR"vcpu:%p called cache_flush error!\n", vcpu); + + /* Always call Host Pal in int=3D1 */ + gr30 &=3D ~PAL_CACHE_FLUSH_CHK_INTRS; + args.cache_type =3D gr29; + args.operation =3D gr30; + smp_call_function(remote_pal_cache_flush, + (void *)&args, 1, 1); + if (args.status !=3D 0) + printk(KERN_ERR"pal_cache_flush error!," + "status:0x%lx\n", args.status); + /* + * Call Host PAL cache flush + * Clear psr.ic when call PAL_CACHE_FLUSH + */ + local_irq_save(psr); + result.status =3D ia64_pal_cache_flush(gr29, gr30, &result.v1, + &result.v0); + local_irq_restore(psr); + if (result.status !=3D 0) + printk(KERN_ERR"vcpu:%p crashed due to cache_flush err:%ld" + "in1:%lx,in2:%lx\n", + vcpu, result.status, gr29, gr30); + +#if 0 + if (gr29 =3D=3D PAL_CACHE_TYPE_COHERENT) { + cpus_setall(vcpu->arch.cache_coherent_map); + cpu_clear(vcpu->cpu, vcpu->arch.cache_coherent_map); + cpus_setall(cpu_cache_coherent_map); + cpu_clear(vcpu->cpu, cpu_cache_coherent_map); + } +#endif + return result; +} + +struct ia64_pal_retval pal_cache_summary(struct kvm_vcpu *vcpu) +{ + + struct ia64_pal_retval result; + + PAL_CALL(result, PAL_CACHE_SUMMARY, 0, 0, 0); + return result; +} + +static struct ia64_pal_retval pal_freq_base(struct kvm_vcpu *vcpu) +{ + + struct ia64_pal_retval result; + + PAL_CALL(result, PAL_FREQ_BASE, 0, 0, 0); + + /* + * PAL_FREQ_BASE may not be implemented in some platforms, + * call SAL instead. + */ + if (result.v0 =3D=3D 0) { + result.status =3D ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, + &result.v0, + &result.v1); + result.v2 =3D 0; + } + + return result; +} + +static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu) +{ + + struct ia64_pal_retval result; + + PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0); + return result; +} + +static struct ia64_pal_retval pal_logical_to_physica(struct kvm_vcpu *vcpu) +{ + struct ia64_pal_retval result; + + INIT_PAL_STATUS_UNIMPLEMENTED(result); + return result; +} + +static struct ia64_pal_retval pal_platform_addr(struct kvm_vcpu *vcpu) +{ + + struct ia64_pal_retval result; + + INIT_PAL_STATUS_SUCCESS(result); + return result; +} + +static struct ia64_pal_retval pal_proc_get_features(struct kvm_vcpu *vcpu) +{ + + struct ia64_pal_retval result =3D {0, 0, 0, 0}; + long in0, in1, in2, in3; + + kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); + result.status =3D ia64_pal_proc_get_features(&result.v0, &result.v1, + &result.v2, in2); + + return result; +} + +static struct ia64_pal_retval pal_cache_info(struct kvm_vcpu *vcpu) +{ + + pal_cache_config_info_t ci; + long status; + unsigned long in0, in1, in2, in3, r9, r10; + + kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); + status =3D ia64_pal_cache_config_info(in1, in2, &ci); + r9 =3D ci.pcci_info_1.pcci1_data; + r10 =3D ci.pcci_info_2.pcci2_data; + return ((struct ia64_pal_retval){status, r9, r10, 0}); +} + +#define GUEST_IMPL_VA_MSB 59 +#define GUEST_RID_BITS 18 + +static struct ia64_pal_retval pal_vm_summary(struct kvm_vcpu *vcpu) +{ + + pal_vm_info_1_u_t vminfo1; + pal_vm_info_2_u_t vminfo2; + struct ia64_pal_retval result; + + PAL_CALL(result, PAL_VM_SUMMARY, 0, 0, 0); + if (!result.status) { + vminfo1.pvi1_val =3D result.v0; + vminfo1.pal_vm_info_1_s.max_itr_entry =3D 8; + vminfo1.pal_vm_info_1_s.max_dtr_entry =3D 8; + result.v0 =3D vminfo1.pvi1_val; + vminfo2.pal_vm_info_2_s.impl_va_msb =3D GUEST_IMPL_VA_MSB; + vminfo2.pal_vm_info_2_s.rid_size =3D GUEST_RID_BITS; + result.v1 =3D vminfo2.pvi2_val; + } + + return result; +} + +static struct ia64_pal_retval pal_vm_info(struct kvm_vcpu *vcpu) +{ + struct ia64_pal_retval result; + + INIT_PAL_STATUS_UNIMPLEMENTED(result); + + return result; +} + +static u64 kvm_get_pal_call_index(struct kvm_vcpu *vcpu) +{ + u64 index =3D 0; + struct exit_ctl_data *p; + + p =3D kvm_get_exit_data(vcpu); + if (p && (p->exit_reason =3D=3D EXIT_REASON_PAL_CALL)) { + index =3D p->u.pal_data.gr28; + } + return index; +} + +int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + + u64 gr28; + struct ia64_pal_retval result; + int ret =3D 1; + + gr28 =3D kvm_get_pal_call_index(vcpu); + /*printk("pal_call index:%lx\n",gr28);*/ + switch (gr28) { + case PAL_CACHE_FLUSH: + result =3D pal_cache_flush(vcpu); + break; + case PAL_CACHE_SUMMARY: + result =3D pal_cache_summary(vcpu); + break; + case PAL_HALT_LIGHT: + { + if (kvm_highest_pending_irq(vcpu) =3D=3D -1) { + ret =3D kvm_emulate_halt(vcpu); + } + vcpu->arch.timer_pending =3D 1; + INIT_PAL_STATUS_SUCCESS(result); + } + break; + + case PAL_FREQ_RATIOS: + result =3D pal_freq_ratios(vcpu); + break; + + case PAL_FREQ_BASE: + result =3D pal_freq_base(vcpu); + break; + + case PAL_LOGICAL_TO_PHYSICAL : + result =3D pal_logical_to_physica(vcpu); + break; + + case PAL_VM_SUMMARY : + result =3D pal_vm_summary(vcpu); + break; + + case PAL_VM_INFO : + result =3D pal_vm_info(vcpu); + break; + case PAL_PLATFORM_ADDR : + result =3D pal_platform_addr(vcpu); + break; + case PAL_CACHE_INFO: + result =3D pal_cache_info(vcpu); + break; + case PAL_PTCE_INFO: + INIT_PAL_STATUS_SUCCESS(result); + result.v1 =3D (1L << 32) | 1L; + break; + case PAL_VM_PAGE_SIZE: + result.status =3D ia64_pal_vm_page_size(&result.v0, + &result.v1); + break; + case PAL_RSE_INFO: + result.status =3D ia64_pal_rse_info(&result.v0, + (pal_hints_u_t *)&result.v1); + break; + case PAL_PROC_GET_FEATURES: + result =3D pal_proc_get_features(vcpu); + break; + case PAL_DEBUG_INFO: + result.status =3D ia64_pal_debug_info(&result.v0, + &result.v1); + break; + case PAL_VERSION: + result.status =3D ia64_pal_version( + (pal_version_u_t *)&result.v0, + (pal_version_u_t *)&result.v1); + + break; + case PAL_FIXED_ADDR: + result.status =3D PAL_STATUS_SUCCESS; + result.v0 =3D vcpu->vcpu_id; + break; + default: + INIT_PAL_STATUS_UNIMPLEMENTED(result); + printk(KERN_WARNING"kvm: Unsupported pal call," + " index:0x%lx\n", gr28); + } + set_pal_result(vcpu, result); + return ret; +} + +static struct sal_ret_values sal_emulator(struct kvm *kvm, + long index, unsigned long in1, + unsigned long in2, unsigned long in3, + unsigned long in4, unsigned long in5, + unsigned long in6, unsigned long in7) +{ + unsigned long r9 =3D 0; + unsigned long r10 =3D 0; + long r11 =3D 0; + long status; + + status =3D 0; + switch (index) { + case SAL_FREQ_BASE: + status =3D ia64_sal_freq_base(in1, &r9, &r10); + break; + case SAL_PCI_CONFIG_READ: + printk(KERN_WARNING"kvm: Not allowed to call here!" + " SAL_PCI_CONFIG_READ\n"); + break; + case SAL_PCI_CONFIG_WRITE: + printk(KERN_WARNING"kvm: Not allowed to call here!" + " SAL_PCI_CONFIG_WRITE\n"); + break; + case SAL_SET_VECTORS: + if (in1 =3D=3D SAL_VECTOR_OS_BOOT_RENDEZ) { + if (in4 !=3D 0 || in5 !=3D 0 || in6 !=3D 0 || in7 !=3D 0) { + status =3D -2; + } else { + kvm->arch.rdv_sal_data.boot_ip =3D in2; + kvm->arch.rdv_sal_data.boot_gp =3D in3; + } + printk("Rendvous called! iip:%lx\n\n", in2); + } else + printk(KERN_WARNING"kvm: CALLED SAL_SET_VECTORS %lu." + "ignored...\n", in1); + break; + case SAL_GET_STATE_INFO: + /* No more info. */ + status =3D -5; + r9 =3D 0; + break; + case SAL_GET_STATE_INFO_SIZE: + /* Return a dummy size. */ + status =3D 0; + r9 =3D 128; + break; + case SAL_CLEAR_STATE_INFO: + /* Noop. */ + break; + case SAL_MC_RENDEZ: + printk(KERN_WARNING + "kvm: called SAL_MC_RENDEZ. ignored...\n"); + break; + case SAL_MC_SET_PARAMS: + printk(KERN_WARNING + "kvm: called SAL_MC_SET_PARAMS.ignored!\n"); + break; + case SAL_CACHE_FLUSH: + if (1) { + /*Flush using SAL. + This method is faster but has a side + effect on other vcpu running on + this cpu. */ + status =3D ia64_sal_cache_flush(in1); + } else { + /*Maybe need to implement the method + without side effect!*/ + status =3D 0; + } + break; + case SAL_CACHE_INIT: + printk(KERN_WARNING + "kvm: called SAL_CACHE_INIT. ignored...\n"); + break; + case SAL_UPDATE_PAL: + printk(KERN_WARNING + "kvm: CALLED SAL_UPDATE_PAL. ignored...\n"); + break; + default: + printk(KERN_WARNING"kvm: called SAL_CALL with unknown index." + " index:%ld\n", index); + status =3D -1; + break; + } + return ((struct sal_ret_values) {status, r9, r10, r11}); +} + +static void kvm_get_sal_call_data(struct kvm_vcpu *vcpu, u64 *in0, u64 *in1, + u64 *in2, u64 *in3, u64 *in4, u64 *in5, u64 *in6, u64 *in7){ + + struct exit_ctl_data *p; + + p =3D kvm_get_exit_data(vcpu); + + if (p) { + if (p->exit_reason =3D=3D EXIT_REASON_SAL_CALL) { + *in0 =3D p->u.sal_data.in0; + *in1 =3D p->u.sal_data.in1; + *in2 =3D p->u.sal_data.in2; + *in3 =3D p->u.sal_data.in3; + *in4 =3D p->u.sal_data.in4; + *in5 =3D p->u.sal_data.in5; + *in6 =3D p->u.sal_data.in6; + *in7 =3D p->u.sal_data.in7; + return ; + } + } + *in0 =3D 0; +} + +void kvm_sal_emul(struct kvm_vcpu *vcpu) +{ + + struct sal_ret_values result; + u64 index, in1, in2, in3, in4, in5, in6, in7; + + kvm_get_sal_call_data(vcpu, &index, &in1, &in2, + &in3, &in4, &in5, &in6, &in7); + result =3D sal_emulator(vcpu->kvm, index, in1, in2, in3, + in4, in5, in6, in7); + set_sal_result(vcpu, result); +} --=20 1.5.1 |
From: Zhang, X. <xia...@in...> - 2008-01-31 10:29:36
|
From: Zhang Xiantao <xia...@in...> Date: Tue, 29 Jan 2008 13:31:55 +0800 Subject: [PATCH] kvm/ia64: VMM module interfaces. vmm.c adds the interfaces with kvm/module, and initialize global data area. Signed-off-by: Xiantao Zhang<xia...@in...> --- arch/ia64/kvm/vmm.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 57 insertions(+), 0 deletions(-) create mode 100644 arch/ia64/kvm/vmm.c diff --git a/arch/ia64/kvm/vmm.c b/arch/ia64/kvm/vmm.c new file mode 100644 index 0000000..0973c68 --- /dev/null +++ b/arch/ia64/kvm/vmm.c @@ -0,0 +1,57 @@ +/* + * vmm.c: vmm module interface with kvm module + * + * Copyright (c) 2007, Intel Corporation. + * + * Xiantao Zhang (xia...@in...) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ + + +#include<linux/module.h> +#include<asm/fpswa.h> + +#include "vcpu.h" + +MODULE_AUTHOR("Intel"); +MODULE_LICENSE("GPL"); + +extern char kvm_ia64_ivt; +extern fpswa_interface_t *vmm_fpswa_interface; + +struct kvm_vmm_info vmm_info =3D { + .module =3D THIS_MODULE, + .vmm_entry =3D vmm_entry, + .tramp_entry =3D vmm_trampoline, + .vmm_ivt =3D (unsigned long)&kvm_ia64_ivt, +}; + +static int __init kvm_vmm_init(void) +{ + + vmm_fpswa_interface =3D fpswa_interface; + + /*Register vmm data to kvm side*/ + return kvm_init(&vmm_info, 1024, THIS_MODULE); +} + +static void __exit kvm_vmm_exit(void) +{ + kvm_exit(); + return ; +} + +module_init(kvm_vmm_init) +module_exit(kvm_vmm_exit) --=20 1.5.1 |
From: Zhang, X. <xia...@in...> - 2008-01-31 10:29:21
|
From: Xiantao Zhang <xia...@in...> Date: Thu, 31 Jan 2008 17:46:09 +0800 Subject: [PATCH] IA64: ia64_set_psr may need srlz.i sometimes. Once psr.ic changes by ia64_set_psr, srlz.i is needed here. Signed-off-by: Xiantao Zhang <xia...@in...> --- arch/ia64/kernel/efi.c | 1 - include/asm-ia64/processor.h | 2 +- 2 files changed, 1 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 242d793..f3823db 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -405,7 +405,6 @@ efi_map_pal_code (void) pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)), IA64_GRANULE_SHIFT); ia64_set_psr(psr); /* restore psr */ - ia64_srlz_i(); } =20 void __init diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index be3b0ae..038642f 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -472,7 +472,7 @@ ia64_set_psr (__u64 psr) { ia64_stop(); ia64_setreg(_IA64_REG_PSR_L, psr); - ia64_srlz_d(); + ia64_srlz_i(); } =20 /* --=20 1.5.1 |
From: Zhang, X. <xia...@in...> - 2008-01-31 10:29:11
|
From: Xiantao Zhang <xia...@in...> Date: Thu, 31 Jan 2008 15:40:12 +0800 Subject: [PATCH] kvm/ia64: Add kvm arch-specific core code for kvm/ia64. kvm_ia64.c is added to handle ia64-specific core logic. Signed-off-by: Xiantao Zhang <xia...@in...> --- arch/ia64/kvm/kvm_ia64.c | 1596 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1596 insertions(+), 0 deletions(-) create mode 100644 arch/ia64/kvm/kvm_ia64.c diff --git a/arch/ia64/kvm/kvm_ia64.c b/arch/ia64/kvm/kvm_ia64.c new file mode 100644 index 0000000..f1a0a93 --- /dev/null +++ b/arch/ia64/kvm/kvm_ia64.c @@ -0,0 +1,1596 @@ +/* + * kvm_ia64.c: Basic KVM suppport On Itanium series processors + * + * + * Copyright (C) 2007, Intel Corporation. + * Xiantao Zhang (xia...@in...) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#include <linux/module.h> +#include <linux/vmalloc.h> +#include <linux/errno.h> +#include <linux/percpu.h> +#include <linux/gfp.h> +#include <linux/fs.h> +#include <linux/smp.h> +#include <linux/kvm_host.h> +#include <linux/kvm.h> +#include <linux/bitops.h> +#include <linux/hrtimer.h> + +#include <asm/pgtable.h> +#include <asm/gcc_intrin.h> +#include <asm/pal.h> +#include <asm/uaccess.h> +#include <asm/cacheflush.h> +#include <asm/div64.h> +#include <asm/tlb.h> + +#include "ia64_regs.h" +#include "misc.h" +#include "vti.h" +#include "iodev.h" +#include "ioapic.h" +#include "lapic.h" + +static unsigned long kvm_vmm_base; +static unsigned long kvm_vsa_base; +static unsigned long kvm_vm_buffer; +static unsigned long kvm_vm_buffer_size; +unsigned long kvm_vmm_gp; + +static long vp_env_info; + +static struct kvm_vmm_info *kvm_vmm_info; + +static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu); + +struct kvm_stats_debugfs_item debugfs_entries[] =3D { + { NULL } +}; + + +struct fdesc{ + unsigned long ip; + unsigned long gp; +}; + +static void kvm_flush_icache(unsigned long start, unsigned long len) +{ + int l; + + for (l =3D 0; l < (len + 32); l +=3D 32) + ia64_fc(start + l); + + ia64_sync_i(); + ia64_srlz_i(); +} + +static void kvm_flush_tlb_all(void) +{ + unsigned long i, j, count0, count1, stride0, stride1, addr; + long flags; + + addr =3D local_cpu_data->ptce_base; + count0 =3D local_cpu_data->ptce_count[0]; + count1 =3D local_cpu_data->ptce_count[1]; + stride0 =3D local_cpu_data->ptce_stride[0]; + stride1 =3D local_cpu_data->ptce_stride[1]; + + local_irq_save(flags); + for (i =3D 0; i < count0; ++i) { + for (j =3D 0; j < count1; ++j) { + ia64_ptce(addr); + addr +=3D stride1; + } + addr +=3D stride0; + } + local_irq_restore(flags); + ia64_srlz_i(); /* srlz.i implies srlz.d */ +} + +long ia64_pal_vp_create(u64 *vpd, u64 *host_iva, u64 *opt_handler) +{ + struct ia64_pal_retval iprv; + + PAL_CALL_STK(iprv, PAL_VP_CREATE, (u64)vpd, (u64)host_iva, + (u64)opt_handler); + + return iprv.status; +} + +static DEFINE_SPINLOCK(vp_lock); + +void kvm_arch_hardware_enable(void *garbage) +{ + long status; + long tmp_base; + unsigned long pte; + unsigned long saved_psr; + + pte =3D pte_val(mk_pte_phys(__pa(kvm_vmm_base), + PAGE_KERNEL)); + local_irq_save(saved_psr); + ia64_itr_entry(0x3, KVM_VMM_BASE, + pte, KVM_VMM_SHIFT); + local_irq_restore(saved_psr); + + spin_lock(&vp_lock); + status =3D ia64_pal_vp_init_env(kvm_vsa_base ? + VP_INIT_ENV : VP_INIT_ENV_INITALIZE, + __pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base); + if (status !=3D 0) { + printk(KERN_WARNING"kvm:Failed to Enable VT Support!!!!\n"); + return ; + } + + if (!kvm_vsa_base) { + kvm_vsa_base =3D tmp_base; + printk(KERN_INFO"kvm:kvm_vsa_base:0x%lx\n", kvm_vsa_base); + } + spin_unlock(&vp_lock); + ia64_ptr_entry(0x3, KVM_VMM_BASE, KVM_VMM_SHIFT); +} + +void kvm_arch_hardware_disable(void *garbage) +{ + + long status; + unsigned long pte; + unsigned long saved_psr; + unsigned long host_iva =3D ia64_getreg(_IA64_REG_CR_IVA); + + pte =3D pte_val(mk_pte_phys(__pa(kvm_vmm_base), + PAGE_KERNEL)); + + local_irq_save(saved_psr); + ia64_itr_entry(0x3, KVM_VMM_BASE, + pte, KVM_VMM_SHIFT); + local_irq_restore(saved_psr); + + status =3D ia64_pal_vp_exit_env(host_iva); + if (status) + printk(KERN_DEBUG"kvm: Failed to disable VT support! :%ld\n", + status); + ia64_ptr_entry(0x3, KVM_VMM_BASE, KVM_VMM_SHIFT); +} + +void kvm_arch_check_processor_compat(void *rtn) +{ + *(int *)rtn =3D 0; +} + +int kvm_dev_ioctl_check_extension(long ext) +{ + + int r; + + switch (ext) { + case KVM_CAP_IRQCHIP: + case KVM_CAP_USER_MEMORY: + + r =3D 1; + break; + default: + r =3D 0; + } + return r; + +} + +static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, + gpa_t addr) +{ + struct kvm_io_device *dev; + + dev =3D kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr); + + return dev; +} + +static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + kvm_run->exit_reason =3D KVM_EXIT_UNKNOWN; + kvm_run->hw.hardware_exit_reason =3D 1; + return 0; +} + +static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + ioreq_t *p; + struct kvm_io_device *mmio_dev; + + p =3D kvm_get_vcpu_ioreq(vcpu); + + if ((p->addr & PAGE_MASK) =3D=3D IOAPIC_DEFAULT_BASE_ADDRESS) + goto mmio; + vcpu->mmio_needed =3D 1; + vcpu->mmio_phys_addr =3D kvm_run->mmio.phys_addr =3D p->addr; + vcpu->mmio_size =3D kvm_run->mmio.len =3D p->size; + vcpu->mmio_is_write =3D kvm_run->mmio.is_write =3D !p->dir; + + if (vcpu->mmio_is_write) + memcpy(vcpu->mmio_data, &p->data, p->size); + memcpy(kvm_run->mmio.data, &p->data, p->size); + kvm_run->exit_reason =3D KVM_EXIT_MMIO; + return 0; +mmio: + mmio_dev =3D vcpu_find_mmio_dev(vcpu, p->addr); + if (mmio_dev) { + if (!p->dir) + kvm_iodevice_write(mmio_dev, p->addr, p->size, + &p->data); + else + kvm_iodevice_read(mmio_dev, p->addr, p->size, + &p->data); + + } else + printk(KERN_ERR"kvm: No iodevice found !\n"); + p->state =3D STATE_IORESP_READY; + + return 1; +} + +static int handle_pal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + struct exit_ctl_data *p; + + p =3D kvm_get_exit_data(vcpu); + + if (p->exit_reason =3D=3D EXIT_REASON_PAL_CALL) + return kvm_pal_emul(vcpu, kvm_run); + else { + kvm_run->exit_reason =3D KVM_EXIT_UNKNOWN; + kvm_run->hw.hardware_exit_reason =3D 2; + return 0; + } +} + +static int handle_sal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + struct exit_ctl_data *p; + + p =3D kvm_get_exit_data(vcpu); + + if (p->exit_reason =3D=3D EXIT_REASON_SAL_CALL) { + kvm_sal_emul(vcpu); + return 1; + } else { + kvm_run->exit_reason =3D KVM_EXIT_UNKNOWN; + kvm_run->hw.hardware_exit_reason =3D 3; + return 0; + } + +} + +/* + * offset: address offset to IPI space. + * value: deliver value. + */ +static void vcpu_deliver_ipi(struct kvm_vcpu *vcpu, uint64_t dm, + uint64_t vector) +{ + switch (dm) { + case SAPIC_FIXED: + kvm_apic_set_irq(vcpu, vector, 0); + break; + case SAPIC_NMI: + kvm_apic_set_irq(vcpu, 2, 0); + break; + case SAPIC_EXTINT: + kvm_apic_set_irq(vcpu, 0, 0); + break; + case SAPIC_INIT: + case SAPIC_PMI: + default: + printk(KERN_ERR"kvm:Unimplemented Deliver reserved IPI!\n"); + break; + } +} + +static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id, + unsigned long eid) +{ + ia64_lid_t lid; + int i; + + for (i =3D 0; i < KVM_MAX_VCPUS; i++) { + if (kvm->vcpus[i]) { + lid.val =3D VCPU_LID(kvm->vcpus[i]); + if (lid.id =3D=3D id && lid.eid =3D=3D eid) + return kvm->vcpus[i]; + } + } + + return NULL; +} + +static int handle_ipi(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + struct exit_ctl_data *p =3D kvm_get_exit_data(vcpu); + struct kvm_vcpu *target_vcpu; + struct kvm_pt_regs *regs; + ia64_ipi_a addr =3D p->u.ipi_data.addr; + ia64_ipi_d data =3D p->u.ipi_data.data; + + target_vcpu =3D lid_to_vcpu(vcpu->kvm, addr.id, addr.eid); + if (!target_vcpu) + return handle_vm_error(vcpu, kvm_run); + + if (!target_vcpu->arch.launched) { + regs =3D vcpu_regs(target_vcpu); + + regs->cr_iip =3D vcpu->kvm->arch.rdv_sal_data.boot_ip; + regs->r1 =3D vcpu->kvm->arch.rdv_sal_data.boot_gp; + + target_vcpu->arch.mp_state =3D VCPU_MP_STATE_RUNNABLE; + if (waitqueue_active(&target_vcpu->wq)) + wake_up_interruptible(&target_vcpu->wq); + } else { + vcpu_deliver_ipi(target_vcpu, data.dm, data.vector); + if (target_vcpu !=3D vcpu) + kvm_vcpu_kick(target_vcpu); + } + + return 1; +} + +struct call_data { + struct kvm_ptc_g ptc_g_data; + struct kvm_vcpu *vcpu; +}; + +static void vcpu_global_purge(void *info) +{ + struct call_data *p =3D (struct call_data *)info; + struct kvm_vcpu *vcpu =3D p->vcpu; + + if (test_bit(KVM_REQ_FLUSH_ALL, &vcpu->requests)) + return; + + set_bit(KVM_REQ_PTC_G, &vcpu->requests); + if (vcpu->arch.ptc_g_count < MAX_PTC_G_NUM) { + vcpu->arch.ptc_g_data[vcpu->arch.ptc_g_count++] =3D + p->ptc_g_data; + } else { + clear_bit(KVM_REQ_PTC_G, &vcpu->requests); + vcpu->arch.ptc_g_count =3D 0; + set_bit(KVM_REQ_FLUSH_ALL, &vcpu->requests); + } +} + +static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + struct exit_ctl_data *p =3D kvm_get_exit_data(vcpu); + struct kvm *kvm =3D vcpu->kvm; + struct call_data call_data; + int i; + call_data.ptc_g_data =3D p->u.ptc_g_data; + + for (i =3D 0; i < KVM_MAX_VCPUS; i++) { + if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state =3D=3D + VCPU_MP_STATE_UNINITIALIZED || + vcpu =3D=3D kvm->vcpus[i]) + continue; + + if (waitqueue_active(&kvm->vcpus[i]->wq)) { + wake_up_interruptible(&kvm->vcpus[i]->wq); + } + + if (kvm->vcpus[i]->cpu !=3D -1) { + call_data.vcpu =3D kvm->vcpus[i]; + smp_call_function_single(kvm->vcpus[i]->cpu, + vcpu_global_purge, &call_data, 0, 1); + } else + printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n"); + + } + return 1; +} + +static int handle_switch_rr6(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + return 1; +} + +int kvm_emulate_halt(struct kvm_vcpu *vcpu) +{ + + ktime_t kt; + long itc_diff; + unsigned long vcpu_now_itc; + + unsigned long expires; + struct hrtimer *p_ht =3D &vcpu->arch.hlt_timer; + unsigned long cyc_per_usec =3D local_cpu_data->cyc_per_usec; + struct vpd *vpd =3D to_host(vcpu->kvm, vcpu->arch.vpd); + + vcpu_now_itc =3D ia64_get_itc() + vcpu->arch.itc_offset; + + if (time_after(vcpu_now_itc, vpd->itm)) { + vcpu->arch.timer_check =3D 1; + return 1; + } + itc_diff =3D vpd->itm - vcpu_now_itc; + if (itc_diff < 0) + itc_diff =3D -itc_diff; + + expires =3D div64_64(itc_diff, cyc_per_usec); + kt =3D ktime_set(0, 1000 * expires); + vcpu->arch.ht_active =3D 1; + hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); + + if (irqchip_in_kernel(vcpu->kvm)) { + vcpu->arch.mp_state =3D VCPU_MP_STATE_HALTED; + kvm_vcpu_block(vcpu); + hrtimer_cancel(p_ht); + vcpu->arch.ht_active =3D 0; + + if (vcpu->arch.mp_state !=3D VCPU_MP_STATE_RUNNABLE) + return -EINTR; + return 1; + } else { + printk(KERN_ERR"kvm: Unsupported userspace halt!"); + return 0; + } +} + +static int handle_vm_shutdown(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + kvm_run->exit_reason =3D KVM_EXIT_SHUTDOWN; + return 0; +} + +static int handle_external_interrupt(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + return 1; +} + +static int (*kvm_vti_exit_handlers[])(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) =3D { + [EXIT_REASON_VM_PANIC] =3D handle_vm_error, + [EXIT_REASON_MMIO_INSTRUCTION] =3D handle_mmio, + [EXIT_REASON_PAL_CALL] =3D handle_pal_call, + [EXIT_REASON_SAL_CALL] =3D handle_sal_call, + [EXIT_REASON_SWITCH_RR6] =3D handle_switch_rr6, + [EXIT_REASON_VM_DESTROY] =3D handle_vm_shutdown, + [EXIT_REASON_EXTERNAL_INTERRUPT] =3D handle_external_interrupt, + [EXIT_REASON_IPI] =3D handle_ipi, + [EXIT_REASON_PTC_G] =3D handle_global_purge, + +}; + +static const int kvm_vti_max_exit_handlers =3D + sizeof(kvm_vti_exit_handlers)/sizeof(*kvm_vti_exit_handlers); + +static void kvm_prepare_guest_switch(struct kvm_vcpu *vcpu) +{ +} + +static uint32_t kvm_get_exit_reason(struct kvm_vcpu *vcpu) +{ + struct exit_ctl_data *p_exit_data; + + p_exit_data =3D kvm_get_exit_data(vcpu); + return p_exit_data->exit_reason; +} + +/* + * The guest has exited. See if we can fix it or if we need userspace + * assistance. + */ +static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) +{ + u32 exit_reason =3D kvm_get_exit_reason(vcpu); + vcpu->arch.last_exit =3D exit_reason; + + if (exit_reason < kvm_vti_max_exit_handlers + && kvm_vti_exit_handlers[exit_reason]) + return kvm_vti_exit_handlers[exit_reason](vcpu, kvm_run); + else { + kvm_run->exit_reason =3D KVM_EXIT_UNKNOWN; + kvm_run->hw.hardware_exit_reason =3D exit_reason; + } + return 0; +} + +static inline void vti_set_rr6(unsigned long rr6) +{ + ia64_set_rr(RR6, rr6); + ia64_srlz_i(); +} + +/*Ensure no TR entries in slot 6 and slot 7 before getting called.*/ +static void kvm_insert_vmm_mapping(struct kvm_vcpu *vcpu) +{ + unsigned long pte; + struct kvm *kvm =3D vcpu->kvm; + + /*Insert a pair of tr to map vmm*/ + pte =3D pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL)); + ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); + + /*Insert a pairt of tr to map data of vm*/ + pte =3D pte_val(mk_pte_phys(__pa(kvm->arch.vm_base), PAGE_KERNEL)); + ia64_itr_entry(0x3, KVM_VM_DATA_BASE, + pte, KVM_VM_DATA_SHIFT); + +} + +static void kvm_purge_vmm_mapping(void) +{ + + unsigned long ps; + + /*Purge itr and dtr in slot 6.*/ + ps =3D KVM_VMM_SHIFT; + ia64_ptr_entry(0x3, KVM_VMM_BASE, ps); + + /*Purge itr and dtr in slot 7.*/ + ps =3D KVM_VM_DATA_SHIFT; + ia64_ptr_entry(0x3, KVM_VM_DATA_BASE, ps); + +} + +static void kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu) +{ + int cpu =3D smp_processor_id(); + + if (vcpu->arch.last_run_cpu !=3D cpu || + per_cpu(last_vcpu, cpu) !=3D vcpu) { + per_cpu(last_vcpu, cpu) =3D vcpu; + vcpu->arch.last_run_cpu =3D cpu; + kvm_flush_tlb_all(); + } + + vcpu->arch.host_rr6 =3D ia64_get_rr(RR6); + vti_set_rr6(vcpu->arch.vmm_rr); + kvm_insert_vmm_mapping(vcpu); +} +static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu) +{ + kvm_purge_vmm_mapping(); + vti_set_rr6(vcpu->arch.host_rr6); +} + +void vti_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + context_t *host_ctx, *guest_ctx; + + /*Get host and guest context with guest address space.*/ + host_ctx =3D kvm_get_host_context(vcpu); + guest_ctx =3D kvm_get_guest_context(vcpu); + + kvm_vcpu_pre_transition(vcpu); + kvm_vmm_info->tramp_entry(host_ctx, guest_ctx); + kvm_vcpu_post_transition(vcpu); +} + +static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + int r; + +again: + preempt_disable(); + + kvm_prepare_guest_switch(vcpu); + local_irq_disable(); + + if (signal_pending(current)) { + local_irq_enable(); + preempt_enable(); + r =3D -EINTR; + kvm_run->exit_reason =3D KVM_EXIT_INTR; + goto out; + } + + vcpu->guest_mode =3D 1; + kvm_guest_enter(); + + vti_vcpu_run(vcpu, kvm_run); + + vcpu->arch.launched =3D 1; + vcpu->guest_mode =3D 0; + local_irq_enable(); + + /* + * We must have an instruction between local_irq_enable() and + * kvm_guest_exit(), so the timer interrupt isn't delayed by + * the interrupt shadow. The stat.exits increment will do nicely. + * But we need to prevent reordering, hence this barrier(): + */ + barrier(); + + kvm_guest_exit(); + + preempt_enable(); + + r =3D kvm_handle_exit(kvm_run, vcpu); + + if (r > 0) { + if (!need_resched()) + goto again; + } + +out: + if (r > 0) { + kvm_resched(vcpu); + goto again; + } + + return r; +} + +static void kvm_set_mmio_data(struct kvm_vcpu *vcpu) +{ + ioreq_t *p =3D kvm_get_vcpu_ioreq(vcpu); + if (!vcpu->mmio_is_write) + memcpy(&p->data, vcpu->mmio_data, 8); + p->state =3D STATE_IORESP_READY; +} + +int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + int r; + sigset_t sigsaved; + + vcpu_load(vcpu); + + if (unlikely(vcpu->arch.mp_state =3D=3D VCPU_MP_STATE_UNINITIALIZED)) { + kvm_vcpu_block(vcpu); + vcpu_put(vcpu); + return -EAGAIN; + } + + if (vcpu->sigset_active) + sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); + + if (vcpu->mmio_needed) { + memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); + kvm_set_mmio_data(vcpu); + vcpu->mmio_read_completed =3D 1; + vcpu->mmio_needed =3D 0; + } + r =3D __vcpu_run(vcpu, kvm_run); + + if (vcpu->sigset_active) + sigprocmask(SIG_SETMASK, &sigsaved, NULL); + + vcpu_put(vcpu); + return r; +} + +/* + * Allocate 16M memory for every vm to hold its specific data. + * Its memory map is defined in kvm_host.h. + */ +static struct kvm *kvm_alloc_kvm(void) +{ + + struct kvm *kvm; + uint64_t vm_base; + + vm_base =3D __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE)); + + if (!vm_base) + return ERR_PTR(-ENOMEM); + printk(KERN_DEBUG"kvm:vm data base address:0x%lx\n", vm_base); + + /* Zero all pages before use! */ + memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); + + kvm =3D (struct kvm *)(vm_base + KVM_VM_OFS); + kvm->arch.vm_base =3D vm_base; + + return kvm; +} + +typedef struct kvm_io_range { + unsigned long start; + unsigned long size; + unsigned long type; +} kvm_io_range_t; + +static const kvm_io_range_t io_ranges[] =3D { + {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER}, + {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO}, + {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO}, + {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC}, + {PIB_START, PIB_SIZE, GPFN_PIB}, +}; + +static void kvm_build_io_pmt(struct kvm *kvm) +{ + unsigned long i, j; + + /* Mark I/O ranges */ + for (i =3D 0; i < (sizeof(io_ranges) / sizeof(kvm_io_range_t)); i++) { + for (j =3D io_ranges[i].start; + j < io_ranges[i].start + io_ranges[i].size; + j +=3D PAGE_SIZE) + kvm_set_pmt_entry(kvm, j >> PAGE_SHIFT, + io_ranges[i].type, 0); + } + +} + +/*Use unused rids to virtualize guest rid.*/ +#define GUEST_PHYSICAL_RR0 0x1739 +#define GUEST_PHYSICAL_RR4 0x2739 +#define VMM_INIT_RR 0x1660 + +static void kvm_init_vm(struct kvm *kvm) +{ + long vm_base; + + BUG_ON(!kvm); + + kvm->arch.metaphysical_rr0 =3D GUEST_PHYSICAL_RR0; + kvm->arch.metaphysical_rr4 =3D GUEST_PHYSICAL_RR4; + kvm->arch.vmm_init_rr =3D VMM_INIT_RR; + + vm_base =3D kvm->arch.vm_base; + if (vm_base) { + kvm->arch.vhpt_base =3D vm_base + KVM_VHPT_OFS; + kvm->arch.vtlb_base =3D vm_base + KVM_VTLB_OFS; + kvm->arch.vpd_base =3D vm_base + KVM_VPD_OFS; + } + + /* + *Fill P2M entries for MMIO/IO ranges + */ + kvm_build_io_pmt(kvm); + +} + +struct kvm *kvm_arch_create_vm(void) +{ + struct kvm *kvm =3D kvm_alloc_kvm(); + + if (IS_ERR(kvm)) + return ERR_PTR(-ENOMEM); + kvm_init_vm(kvm); + + return kvm; + +} + +static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, + struct kvm_irqchip *chip) +{ + int r; + + r =3D 0; + switch (chip->chip_id) { + case KVM_IRQCHIP_IOAPIC: + memcpy(&chip->chip.ioapic, ioapic_irqchip(kvm), + sizeof(struct kvm_ioapic_state)); + break; + default: + r =3D -EINVAL; + break; + } + return r; +} + +static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) +{ + int r; + + r =3D 0; + switch (chip->chip_id) { + case KVM_IRQCHIP_IOAPIC: + memcpy(ioapic_irqchip(kvm), + &chip->chip.ioapic, + sizeof(struct kvm_ioapic_state)); + break; + default: + r =3D -EINVAL; + break; + } + return r; +} + +int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) +{ + printk(KERN_WARNING"Doesn't support it yet!!\n"); + return 0; +} + +long kvm_arch_vm_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + struct kvm *kvm =3D filp->private_data; + void __user *argp =3D (void __user *)arg; + int r =3D -EINVAL; + + switch (ioctl) { + case KVM_SET_MEMORY_REGION: { + struct kvm_memory_region kvm_mem; + struct kvm_userspace_memory_region kvm_userspace_mem; + + r =3D -EFAULT; + if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem)) + goto out; + kvm_userspace_mem.slot =3D kvm_mem.slot; + kvm_userspace_mem.flags =3D kvm_mem.flags; + kvm_userspace_mem.guest_phys_addr =3D + kvm_mem.guest_phys_addr; + kvm_userspace_mem.memory_size =3D kvm_mem.memory_size; + r =3D kvm_vm_ioctl_set_memory_region(kvm, + &kvm_userspace_mem, 0); + if (r) + goto out; + break; + } + case KVM_CREATE_IRQCHIP: + r =3D -EFAULT; + r =3D kvm_ioapic_init(kvm); + if (r) + goto out; + break; + case KVM_IRQ_LINE: { + struct kvm_irq_level irq_event; + + r =3D -EFAULT; + if (copy_from_user(&irq_event, argp, sizeof irq_event)) + goto out; + if (irqchip_in_kernel(kvm)) { + mutex_lock(&kvm->lock); + kvm_ioapic_set_irq(kvm->arch.vioapic, + irq_event.irq, + irq_event.level); + mutex_unlock(&kvm->lock); + r =3D 0; + } + break; + } + case KVM_GET_IRQCHIP: { + /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ + struct kvm_irqchip chip; + + r =3D -EFAULT; + if (copy_from_user(&chip, argp, sizeof chip)) + goto out; + r =3D -ENXIO; + if (!irqchip_in_kernel(kvm)) + goto out; + r =3D kvm_vm_ioctl_get_irqchip(kvm, &chip); + if (r) + goto out; + r =3D -EFAULT; + if (copy_to_user(argp, &chip, sizeof chip)) + goto out; + r =3D 0; + break; + } + case KVM_SET_IRQCHIP: { + /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ + struct kvm_irqchip chip; + + r =3D -EFAULT; + if (copy_from_user(&chip, argp, sizeof chip)) + goto out; + r =3D -ENXIO; + if (!irqchip_in_kernel(kvm)) + goto out; + r =3D kvm_vm_ioctl_set_irqchip(kvm, &chip); + if (r) + goto out; + r =3D 0; + break; + } + default: + ; + } +out: + return r; +} + +int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + printk(KERN_WARNING"kvm:kvm_arch_vcpu_ioctl_set_sregs called!!\n"); + return 0; +} + +int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + printk(KERN_WARNING"kvm:kvm_arch_vcpu_ioctl_get_sregs called!!\n"); + return 0; + +} +int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, + struct kvm_translation *tr) +{ + printk(KERN_WARNING"kvm:kvm_arch_vcpu_ioctl_translate called!!\n"); + + return 0; +} + +static int kvm_alloc_vmm_area(void) +{ + if (!kvm_vmm_base && (kvm_vm_buffer_size < KVM_VM_BUFFER_SIZE)) { + kvm_vmm_base =3D __get_free_pages(GFP_KERNEL, + get_order(KVM_VMM_SIZE)); + if (!kvm_vmm_base) + return -ENOMEM; + + memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE); + kvm_vm_buffer =3D kvm_vmm_base + VMM_SIZE; + + printk(KERN_DEBUG"kvm:kvm_vmm_base:0x%lx, vm_buffer:0x%lx\n", + kvm_vmm_base, kvm_vm_buffer); + } + + return 0; +} + +static void kvm_free_vmm_area(void) +{ + if (kvm_vmm_base) { + /*Zero this area before free to avoid bits leak!!*/ + memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE); + free_pages(kvm_vmm_base, get_order(KVM_VMM_SIZE)); + kvm_vmm_base =3D 0; + kvm_vm_buffer =3D 0; + kvm_vsa_base =3D 0; + } +} + +/* + * Make sure that a cpu that is being hot-unplugged does not have any vcpus + * cached on it. Leave it as blank for IA64. + */ +void decache_vcpus_on_cpu(int cpu) +{ +} + +static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ +} + +static int vti_init_vpd(struct kvm_vcpu *vcpu) +{ + int i; + cpuid3_t cpuid3; + struct vpd *vpd =3D to_host(vcpu->kvm, vcpu->arch.vpd); + + if (IS_ERR(vpd)) + return PTR_ERR(vpd); + + /* CPUID init */ + for (i =3D 0; i < 5; i++) + vpd->vcpuid[i] =3D ia64_get_cpuid(i); + + /* Limit the CPUID number to 5 */ + cpuid3.value =3D vpd->vcpuid[3]; + cpuid3.number =3D 4; /* 5 - 1 */ + vpd->vcpuid[3] =3D cpuid3.value; + + /*Set vac and vdc fields*/ + vpd->vac.a_from_int_cr =3D 1; + vpd->vac.a_to_int_cr =3D 1; + vpd->vac.a_from_psr =3D 1; + vpd->vac.a_from_cpuid =3D 1; + vpd->vac.a_cover =3D 1; + vpd->vac.a_bsw =3D 1; + vpd->vac.a_int =3D 1; + vpd->vdc.d_vmsw =3D 1; + + /*Set virtual buffer*/ + vpd->virt_env_vaddr =3D KVM_VM_BUFFER_BASE; + + return 0; +} + +static int vti_create_vp(struct kvm_vcpu *vcpu) +{ + long ret; + vpd_t *vpd =3D vcpu->arch.vpd; + unsigned long vmm_ivt; + + vmm_ivt =3D kvm_vmm_info->vmm_ivt; + + printk(KERN_DEBUG "kvm: vcpu:%p,ivt: 0x%lx\n", vcpu, vmm_ivt); + + ret =3D ia64_pal_vp_create((u64 *)vpd, (u64 *)vmm_ivt, 0); + + if (ret) { + printk(KERN_ERR"kvm: ia64_pal_vp_create failed!\n"); + return -EINVAL; + } + return 0; +} + +static void init_ptce_info(struct kvm_vcpu *vcpu) +{ + ia64_ptce_info_t ptce =3D {0}; + + ia64_get_ptce(&ptce); + vcpu->arch.ptce_base =3D ptce.base; + vcpu->arch.ptce_count[0] =3D ptce.count[0]; + vcpu->arch.ptce_count[1] =3D ptce.count[1]; + vcpu->arch.ptce_stride[0] =3D ptce.stride[0]; + vcpu->arch.ptce_stride[1] =3D ptce.stride[1]; +} + +static int kvm_migrate_hlt_timer(struct kvm_vcpu *vcpu) +{ + struct hrtimer *p_ht =3D &vcpu->arch.hlt_timer; + + if (hrtimer_cancel(p_ht)) + hrtimer_start(p_ht, p_ht->expires, HRTIMER_MODE_ABS); +} + +static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data) +{ + struct kvm_vcpu *vcpu; + wait_queue_head_t *q; + + vcpu =3D container_of(data, struct kvm_vcpu, arch.hlt_timer); + if (vcpu->arch.mp_state !=3D VCPU_MP_STATE_HALTED) + goto out; + + q =3D &vcpu->wq; + if (waitqueue_active(q)) { + vcpu->arch.mp_state =3D VCPU_MP_STATE_RUNNABLE; + wake_up_interruptible(q); + } +out: + vcpu->arch.timer_check =3D 1; + return HRTIMER_NORESTART; +} + +#define PALE_RESET_ENTRY 0x80000000ffffffb0UL + +int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) +{ + struct page *page; + int r; + struct kvm *kvm =3D vcpu->kvm; + struct kvm_pt_regs *regs =3D vcpu_regs(vcpu); + + context_t *p_ctx =3D &vcpu->arch.guest; + struct kvm_vcpu *vmm_vcpu =3D to_guest(vcpu->kvm, vcpu); + + /*Init vcpu context for first run.*/ + if (IS_ERR(vmm_vcpu)) + return PTR_ERR(vmm_vcpu); + + page =3D alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!page) { + r =3D -ENOMEM; + goto fail; + } + + if (vcpu->vcpu_id =3D=3D 0) { + vcpu->arch.mp_state =3D VCPU_MP_STATE_RUNNABLE; + regs->cr_iip =3D PALE_RESET_ENTRY; + } + + else + vcpu->arch.mp_state =3D VCPU_MP_STATE_UNINITIALIZED; + /*FIXME:Need to removed it later!!\n*/ + vcpu->arch.apic =3D kzalloc(sizeof(struct kvm_lapic), GFP_KERNEL); + vcpu->arch.apic->vcpu =3D vcpu; + + p_ctx->gr[1] =3D 0; + p_ctx->gr[12] =3D (unsigned long)((char *)vmm_vcpu + IA64_STK_OFFSET); + p_ctx->gr[13] =3D (unsigned long)vmm_vcpu; + p_ctx->psr =3D 0x1008522000UL; + p_ctx->ar[40] =3D FPSR_DEFAULT; /*fpsr*/ + p_ctx->caller_unat =3D 0; + p_ctx->pr =3D 0x0; + p_ctx->ar[36] =3D 0x0; /*unat*/ + p_ctx->ar[19] =3D 0x0; /*rnat*/ + p_ctx->ar[18] =3D (unsigned long)vmm_vcpu + + ((sizeof(struct kvm_vcpu)+15) & ~15); + p_ctx->ar[64] =3D 0x0; /*pfs*/ + p_ctx->cr[0] =3D 0x7e04UL; + p_ctx->cr[2] =3D (unsigned long)kvm_vmm_info->vmm_ivt; + p_ctx->cr[8] =3D 0x3c; + + /*Initilize region register*/ + p_ctx->rr[0] =3D 0x30; + p_ctx->rr[1] =3D 0x30; + p_ctx->rr[2] =3D 0x30; + p_ctx->rr[3] =3D 0x30; + p_ctx->rr[4] =3D 0x30; + p_ctx->rr[5] =3D 0x30; + p_ctx->rr[7] =3D 0x30; + + /*Initilize branch register 0*/ + p_ctx->br[0] =3D *(unsigned long *)kvm_vmm_info->vmm_entry; + + vcpu->arch.vmm_rr =3D kvm->arch.vmm_init_rr; + vcpu->arch.metaphysical_rr0 =3D kvm->arch.metaphysical_rr0; + vcpu->arch.metaphysical_rr4 =3D kvm->arch.metaphysical_rr4; + + hrtimer_init(&vcpu->arch.hlt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + vcpu->arch.hlt_timer.function =3D hlt_timer_fn; + + vcpu->arch.vpd =3D (vpd_t *)VPD_ADDR(vcpu->vcpu_id); + vcpu->arch.vsa_base =3D kvm_vsa_base; + vcpu->arch.__gp =3D kvm_vmm_gp; + vcpu->arch.vhpt.hash =3D (thash_data_t *)VHPT_ADDR(vcpu->vcpu_id); + vcpu->arch.vtlb.hash =3D (thash_data_t *)VTLB_ADDR(vcpu->vcpu_id); + init_ptce_info(vcpu); + + return 0; +fail: + return r; +} + +static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id) +{ + unsigned long psr; + int r; + + local_irq_save(psr); + kvm_insert_vmm_mapping(vcpu); + + r =3D kvm_vcpu_init(vcpu, vcpu->kvm, id); + if (r) + goto fail; + + r =3D vti_init_vpd(vcpu); + if (r) { + printk(KERN_DEBUG"kvm: vpd init error!!\n"); + goto uninit; + } + + r =3D vti_create_vp(vcpu); + if (r) + goto uninit; + + kvm_purge_vmm_mapping(); + local_irq_restore(psr); + + return 0; +uninit: + kvm_vcpu_uninit(vcpu); +fail: + return r; +} + +struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, + unsigned int id) +{ + struct kvm_vcpu *vcpu; + unsigned long vm_base =3D kvm->arch.vm_base; + int r; + int cpu; + + r =3D -ENOMEM; + if (!vm_base) { + printk(KERN_ERR"kvm: Create vcpu[%d] error!\n", id); + goto fail; + } + vcpu =3D (struct kvm_vcpu *)(vm_base + KVM_VCPU_OFS + VCPU_SIZE * id); + vcpu->kvm =3D kvm; + + cpu =3D get_cpu(); + vti_vcpu_load(vcpu, cpu); + r =3D vti_vcpu_setup(vcpu, id); + put_cpu(); + + if (r) { + printk(KERN_DEBUG"kvm: vcpu_setup error!!\n"); + goto fail; + } + + return vcpu; +fail: + return ERR_PTR(r); +} + +int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) +{ + return 0; +} + +int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) +{ + printk(KERN_WARNING"kvm:IA64 doesn't need to export" + "fpu to userspace!\n"); + return 0; +} + +int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) +{ + printk(KERN_WARNING"kvm:IA64 doesn't need to export" + "fpu to userspace !\n"); + return 0; +} + +int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, + struct kvm_debug_guest *dbg) +{ + printk(KERN_INFO"Not Implemented yet!\n"); + return 0; +} + +static void free_kvm(struct kvm *kvm) +{ + unsigned long vm_base =3D kvm->arch.vm_base; + + if (vm_base) { + memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); + free_pages(vm_base, get_order(KVM_VM_DATA_SIZE)); + } + +} + +/*FIXME:Remove it once swapping ready!*/ +static void kvm_release_vm_pages(struct kvm *kvm) +{ + struct kvm_memory_slot *memslot; + int i, j; + unsigned long base_gfn; + + for (i =3D 0; i < kvm->nmemslots; i++) { + memslot =3D &kvm->memslots[i]; + base_gfn =3D memslot->base_gfn; + + for (j =3D 0; j < memslot->npages; j++) { + if (memslot->rmap[j]) + put_page((struct page *)memslot->rmap[j]); + } + } +} + +void kvm_arch_destroy_vm(struct kvm *kvm) +{ + kfree(kvm->arch.vioapic); + kvm_release_vm_pages(kvm); + kvm_free_physmem(kvm); + free_kvm(kvm); +} + +void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) +{ + /*FIXME: To Implement!!*/ +} + +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + if (cpu !=3D vcpu->cpu) { + vcpu->cpu =3D cpu; + if (vcpu->arch.ht_active) + kvm_migrate_hlt_timer(vcpu); + } +} + +int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) +{ + printk(KERN_INFO"No need to implment on IA64!\n"); + return 0; +} + +void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) +{ + + hrtimer_cancel(&vcpu->arch.hlt_timer); + kfree(vcpu->arch.apic); +} + + +long kvm_arch_vcpu_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + return -EINVAL; +} + +int kvm_arch_set_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot old, + int user_alloc) +{ + unsigned long i; + struct page *page; + int npages =3D mem->memory_size >> PAGE_SHIFT; + struct kvm_memory_slot *memslot =3D &kvm->memslots[mem->slot]; + unsigned long base_gfn =3D memslot->base_gfn; + + for (i =3D 0; i < npages; i++) { + page =3D gfn_to_page(kvm, base_gfn + i); + kvm_set_pmt_entry(kvm, base_gfn + i, + page_to_pfn(page) << PAGE_SHIFT, + _PAGE_AR_RWX|_PAGE_MA_WB); + memslot->rmap[i] =3D (unsigned long)page; + } + + return 0; +} + + +long kvm_arch_dev_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + return -EINVAL; +} + +void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) +{ + kvm_vcpu_uninit(vcpu); +} + +static int vti_cpu_has_kvm_support(void) +{ + long avail =3D 1, status =3D 1, control =3D 1; + long ret; + + ret =3D ia64_pal_proc_get_features(&avail, &status, &control, 0); + if (ret) + goto out; + + if (!(avail & PAL_PROC_VM_BIT)) + goto out; + + printk(KERN_DEBUG"kvm: Hardware Supports VT\n"); + + ret =3D ia64_pal_vp_env_info(&kvm_vm_buffer_size, &vp_env_info); + if (ret) + goto out; + printk(KERN_DEBUG"kvm: vm buffer size:0x%lx\n", kvm_vm_buffer_size); + + if (!(vp_env_info & VP_OPCODE)) { + printk(KERN_WARNING"No opcode ability on hardware,\ + vm_env_info:0x%lx\n",vp_env_info); + } + + return 1; +out: + return 0; +} + +static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info, + struct module *module) +{ + unsigned long module_base; + unsigned long vmm_size; + + unsigned long vmm_offset, func_offset, fdesc_offset; + struct fdesc *p_fdesc; + + BUG_ON(!module); + + if (!kvm_vmm_base) { + printk("kvm: kvm area didn't initilize yet!!\n"); + return -EINVAL; + } + + /*Calculate new position of relocated vmm module.*/ + module_base =3D (unsigned long)module->module_core; + vmm_size =3D module->core_size; + if (unlikely(vmm_size > KVM_VMM_SIZE)) + return -EFAULT; + + memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size); + kvm_flush_icache(kvm_vmm_base, vmm_size); + + /*Recalculate kvm_vmm_info based on new VMM*/ + vmm_offset =3D vmm_info->vmm_ivt - module_base; + kvm_vmm_info->vmm_ivt =3D KVM_VMM_BASE + vmm_offset; + printk(KERN_DEBUG"kvm: Relocated VMM ivt base addr:%lx\n", + kvm_vmm_info->vmm_ivt); + + fdesc_offset =3D (unsigned long)vmm_info->vmm_entry - module_base; + kvm_vmm_info->vmm_entry =3D (kvm_vmm_entry *)(KVM_VMM_BASE + + fdesc_offset); + func_offset =3D *(unsigned long *)vmm_info->vmm_entry - module_base; + p_fdesc =3D (struct fdesc *)(kvm_vmm_base + fdesc_offset); + p_fdesc->ip =3D KVM_VMM_BASE + func_offset; + p_fdesc->gp =3D KVM_VMM_BASE+(p_fdesc->gp - module_base); + + printk(KERN_DEBUG"Guest VMM init entry addr:%lx\n", + KVM_VMM_BASE+func_offset); + + fdesc_offset =3D (unsigned long)vmm_info->tramp_entry - module_base; + kvm_vmm_info->tramp_entry =3D (kvm_tramp_entry *)(KVM_VMM_BASE + + fdesc_offset); + func_offset =3D *(unsigned long *)vmm_info->tramp_entry - module_base; + p_fdesc =3D (struct fdesc *)(kvm_vmm_base + fdesc_offset); + p_fdesc->ip =3D KVM_VMM_BASE + func_offset; + p_fdesc->gp =3D KVM_VMM_BASE + (p_fdesc->gp - module_base); + + kvm_vmm_gp =3D p_fdesc->gp; + + printk(KERN_DEBUG"kvm: vmm's fdesc:%p\n", p_fdesc); + printk(KERN_DEBUG"kvm: vmm_entry ip:%p\n", kvm_vmm_info->vmm_entry); + printk(KERN_DEBUG"kvm: vmm trampoline entry ip:0x%lx\n", + KVM_VMM_BASE + func_offset); + + return 0; +} + +int kvm_arch_init(void *opaque) +{ + int r; + struct kvm_vmm_info *vmm_info =3D (struct kvm_vmm_info *)opaque; + + if (!vti_cpu_has_kvm_support()) { + printk(KERN_ERR "kvm: no hardware support\n"); + r =3D -EOPNOTSUPP; + goto out; + } + + if (kvm_vmm_info) { + printk(KERN_ERR "kvm: already loaded the other module!\n"); + r =3D -EEXIST; + goto out; + } + + r =3D -ENOMEM; + kvm_vmm_info =3D kzalloc(sizeof(struct kvm_vmm_info), GFP_KERNEL); + if (!kvm_vmm_info) + goto out; + + if (kvm_alloc_vmm_area()) + goto out_free0; + + r =3D kvm_relocate_vmm(vmm_info, vmm_info->module); + if (r) + goto out_free1; + + return 0; + +out_free1: + kvm_free_vmm_area(); +out_free0: + kfree(kvm_vmm_info); +out: + return r; +} + +void kvm_arch_exit(void) +{ + kvm_free_vmm_area(); + kfree(kvm_vmm_info); + kvm_vmm_info =3D NULL; +} + +int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, + struct kvm_dirty_log *log) +{ + printk(KERN_WARNING"Need to implement later!\n"); + return 0; +} + +int kvm_arch_hardware_setup(void) +{ + return 0; +} + +void kvm_arch_hardware_unsetup(void) +{ +} + +static void vcpu_kick_intr(void *info) +{ +#ifdef DEBUG + struct kvm_vcpu *vcpu =3D (struct kvm_vcpu *)info; + printk(KERN_DEBUG"vcpu_kick_intr %p \n", vcpu); +#endif +} + +void kvm_vcpu_kick(struct kvm_vcpu *vcpu) +{ + int ipi_pcpu =3D vcpu->cpu; + + if (waitqueue_active(&vcpu->wq)) { + wake_up_interruptible(&vcpu->wq); + } + if (vcpu->guest_mode) + smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0); +} + +int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig) +{ + + struct vpd *vpd =3D to_host(vcpu->kvm, vcpu->arch.vpd); + + if (!test_and_set_bit(vec, &vpd->irr[0])) { + vcpu->arch.irq_new_pending =3D 1; + if (vcpu->arch.mp_state =3D=3D VCPU_MP_STATE_RUNNABLE) + kvm_vcpu_kick(vcpu); + else if (vcpu->arch.mp_state =3D=3D VCPU_MP_STATE_HALTED) { + vcpu->arch.mp_state =3D VCPU_MP_STATE_RUNNABLE; + if (waitqueue_active(&vcpu->wq)) + wake_up_interruptible(&vcpu->wq); + } + return 1; + } + return 0; +} + +int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) +{ + return apic->vcpu->vcpu_id =3D=3D dest; +} + +int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) +{ + return 0; +} + +struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, + unsigned long bitmap) +{ + struct kvm_vcpu *lvcpu =3D kvm->vcpus[0]; + int i; + + for (i =3D 1; i < KVM_MAX_VCPUS; i++) { + if (!kvm->vcpus[i]) + continue; + if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp) + lvcpu =3D kvm->vcpus[i]; + } + + return lvcpu; +} + +static int find_highest_bits(int *dat) +{ + u32 bits, bitnum; + int i; + + /* loop for all 256 bits */ + for (i =3D 7; i >=3D 0 ; i--) { + bits =3D dat[i]; + if (bits) { + bitnum =3D fls(bits); + return i * 32 + bitnum - 1; + } + } + + return -1; +} + +int kvm_highest_pending_irq(struct kvm_vcpu *vcpu) +{ + struct vpd *vpd =3D to_host(vcpu->kvm, vcpu->arch.vpd); + + if (vpd->irr[0] & (1UL << NMI_VECTOR)) + return NMI_VECTOR; + if (vpd->irr[0] & (1UL << ExtINT_VECTOR)) + return ExtINT_VECTOR; + + return find_highest_bits((int *)&vpd->irr[0]); +} + +int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) +{ + if (kvm_highest_pending_irq(vcpu) !=3D -1) + return 1; + return 0; +} + +gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) +{ + return gfn; +} + +int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.mp_state =3D=3D VCPU_MP_STATE_RUNNABLE; +} + --=20 1.5.1 |
From: Zhang, X. <xia...@in...> - 2008-01-31 10:28:15
|
From: Zhang Xiantao <xia...@in...> Date: Thu, 31 Jan 2008 12:03:39 +0800 Subject: [PATCH] Appoint kvm/ia64 Maintainers Signed-off-by Anthony Xu <ant...@in...> Signed-off-by Xiantao Zhang <xia...@in...> --- MAINTAINERS | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3c7db62..8c54fc3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2219,6 +2219,15 @@ L: kvm...@li... W: kvm.sourceforge.net S: Supported =20 +KERNEL VIRTUAL MACHINE For Itanium(KVM/IA64) +P: Anthony Xu +M: ant...@in... +P: Xiantao Zhang +M: xia...@in... +L: kvm...@li... +W: kvm.sourceforge.net +S: Supported + KEXEC P: Eric Biederman M: ebi...@xm... --=20 1.5.1 |
From: Zhang, X. <xia...@in...> - 2008-01-31 08:28:18
|
Unfortunately, it can's apply on tip. Could you attach the diff ? Thanks Xiantao |
From: Avi K. <av...@qu...> - 2008-01-31 08:03:35
|
Zhang, Xiantao wrote: > Avi Kivity wrote: > >> Zhang, Xiantao wrote: >> >>> +#define TO_LEGACY_IO(addr) (((addr&0x3ffffff) >> 12 << 2)|((addr) >>> & 0x3)) >>> >>> >> Please change to a function. Other than that, patch looks good. >> > Thanks ! Attached. :) > Xiantao > > From: Zhang Xiantao <xia...@in...> > Date: Thu, 31 Jan 2008 15:35:10 +0800 > Subject: [PATCH] kvm: qemu: Covert the mmio address space to port io in > userspace. > > IA64 also have no port io, but chipset is responsible for converting > some mmio to port io for keeping compatibility with legacy device. > Signed-off-by: Xiantao Zhang <xia...@in...> > Applied, thanks. -- error compiling committee.c: too many arguments to function |
From: Zhang, X. <xia...@in...> - 2008-01-31 07:57:56
|
Avi Kivity wrote: > Zhang, Xiantao wrote: >>=20 >> +#define TO_LEGACY_IO(addr) (((addr&0x3ffffff) >> 12 << 2)|((addr) >> & 0x3))=20 >>=20 >=20 > Please change to a function. Other than that, patch looks good. Thanks ! Attached. :) Xiantao=20 From: Zhang Xiantao <xia...@in...> Date: Thu, 31 Jan 2008 15:35:10 +0800 Subject: [PATCH] kvm: qemu: Covert the mmio address space to port io in userspace. IA64 also have no port io, but chipset is responsible for converting some mmio to port io for keeping compatibility with legacy device. Signed-off-by: Xiantao Zhang <xia...@in...> --- qemu/hw/ipf.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 64 insertions(+), 0 deletions(-) diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c index b1c1389..8769208 100644 --- a/qemu/hw/ipf.c +++ b/qemu/hw/ipf.c @@ -56,6 +56,64 @@ static fdctrl_t *floppy_controller; static RTCState *rtc_state; static PCIDevice *i440fx_state; =20 +static uint32_t ipf_to_legacy_io(target_phys_addr_t addr) +{ + return (uint32_t)(((addr&0x3ffffff) >> 12 << 2)|((addr) & 0x3)); +} + +static void ipf_legacy_io_writeb(void *opaque, target_phys_addr_t addr, + uint32_t val) { + uint32_t port =3D ipf_to_legacy_io(addr); + cpu_outb(0, port, val); +} + +static void ipf_legacy_io_writew(void *opaque, target_phys_addr_t addr, + uint32_t val) { + uint32_t port =3D ipf_to_legacy_io(addr); + + cpu_outw(0, port, val); +} + +static void ipf_legacy_io_writel(void *opaque, target_phys_addr_t addr, + uint32_t val) { + uint32_t port =3D ipf_to_legacy_io(addr); + + cpu_outl(0, port, val); +} + +static uint32_t ipf_legacy_io_readb(void *opaque, target_phys_addr_t addr) +{ + uint32_t port =3D ipf_to_legacy_io(addr); + + return cpu_inb(0, port);=20 +} + +static uint32_t ipf_legacy_io_readw(void *opaque, target_phys_addr_t addr) +{ + uint32_t port =3D ipf_to_legacy_io(addr); + + return cpu_inw(0, port);=20 +} + +static uint32_t ipf_legacy_io_readl(void *opaque, target_phys_addr_t addr) +{ + uint32_t port =3D ipf_to_legacy_io(addr); + + return cpu_inl(0, port);=20 +} + +static CPUReadMemoryFunc *ipf_legacy_io_read[3] =3D { + ipf_legacy_io_readb, + ipf_legacy_io_readw, + ipf_legacy_io_readl, +}; + +static CPUWriteMemoryFunc *ipf_legacy_io_write[3] =3D { + ipf_legacy_io_writeb, + ipf_legacy_io_writew, + ipf_legacy_io_writel, +}; + static void pic_irq_request(void *opaque, int irq, int level) { fprintf(stderr,"pic_irq_request called!\n"); @@ -333,6 +391,7 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, qemu_irq *i8259; int page_size; int index; + unsigned long ipf_legacy_io_base, ipf_legacy_io_mem; BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BlockDriverState *fd[MAX_FD]; =20 @@ -447,6 +506,11 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start); } #endif + /*Register legacy io address space, size:64M*/ + ipf_legacy_io_base =3D 0xE0000000; + ipf_legacy_io_mem =3D cpu_register_io_memory(0, ipf_legacy_io_read, + ipf_legacy_io_write, NULL); + cpu_register_physical_memory(ipf_legacy_io_base, 64*1024*1024, ipf_legacy_io_mem); =20 cpu_irq =3D qemu_allocate_irqs(pic_irq_request, first_cpu, 1); i8259 =3D i8259_init(cpu_irq[0]); --=20 1.5.2 |
From: Avi K. <av...@qu...> - 2008-01-31 07:15:35
|
Zhang, Xiantao wrote: > From: Zhang Xiantao <xia...@in...> > Date: Thu, 31 Jan 2008 09:06:21 +0800 > Subject: [PATCH] kvm: qemu: Covert the mmio address space to port io in > userspace. > > IA64 also have no port io, but chipset is responsible for converting > some mmio to port io for keeping compatibility with legacy deviceS. > @@ -56,6 +56,60 @@ static fdctrl_t *floppy_controller; > static RTCState *rtc_state; > static PCIDevice *i440fx_state; > > +#define TO_LEGACY_IO(addr) (((addr&0x3ffffff) >> 12 << 2)|((addr) & > 0x3)) > Please change to a function. Other than that, patch looks good. -- error compiling committee.c: too many arguments to function |
From: Zhang, X. <xia...@in...> - 2008-01-31 01:28:33
|
From: Zhang Xiantao <xia...@in...> Date: Thu, 31 Jan 2008 09:06:21 +0800 Subject: [PATCH] kvm: qemu: Covert the mmio address space to port io in userspace. IA64 also have no port io, but chipset is responsible for converting some mmio to port io for keeping compatibility with legacy deviceS. Signed-off-by: Zhang Xiantao <xia...@in...> --- qemu/hw/ipf.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 60 insertions(+), 0 deletions(-) diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c index b1c1389..bbce0c5 100644 --- a/qemu/hw/ipf.c +++ b/qemu/hw/ipf.c @@ -56,6 +56,60 @@ static fdctrl_t *floppy_controller; static RTCState *rtc_state; static PCIDevice *i440fx_state; =20 +#define TO_LEGACY_IO(addr) (((addr&0x3ffffff) >> 12 << 2)|((addr) & 0x3)) +static void ipf_legacy_io_writeb(void *opaque, target_phys_addr_t addr, + uint32_t val) { + uint32_t port =3D TO_LEGACY_IO(addr); + cpu_outb(0, port, val); +} + +static void ipf_legacy_io_writew(void *opaque, target_phys_addr_t addr, + uint32_t val) { + uint32_t port =3D TO_LEGACY_IO(addr); + + cpu_outw(0, port, val); +} + +static void ipf_legacy_io_writel(void *opaque, target_phys_addr_t addr, + uint32_t val) { + uint32_t port =3D TO_LEGACY_IO(addr); + + cpu_outl(0, port, val); +} + +static uint32_t ipf_legacy_io_readb(void *opaque, target_phys_addr_t addr) +{ + uint32_t port =3D TO_LEGACY_IO(addr); + + return cpu_inb(0, port);=20 +} + +static uint32_t ipf_legacy_io_readw(void *opaque, target_phys_addr_t addr) +{ + uint32_t port =3D TO_LEGACY_IO(addr); + + return cpu_inw(0, port);=20 +} + +static uint32_t ipf_legacy_io_readl(void *opaque, target_phys_addr_t addr) +{ + uint32_t port =3D TO_LEGACY_IO(addr); + + return cpu_inl(0, port);=20 +} + +static CPUReadMemoryFunc *ipf_legacy_io_read[3] =3D { + ipf_legacy_io_readb, + ipf_legacy_io_readw, + ipf_legacy_io_readl, +}; + +static CPUWriteMemoryFunc *ipf_legacy_io_write[3] =3D { + ipf_legacy_io_writeb, + ipf_legacy_io_writew, + ipf_legacy_io_writel, +}; + static void pic_irq_request(void *opaque, int irq, int level) { fprintf(stderr,"pic_irq_request called!\n"); @@ -333,6 +387,7 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, qemu_irq *i8259; int page_size; int index; + unsigned long ipf_legacy_io_base, ipf_legacy_io_mem; BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BlockDriverState *fd[MAX_FD]; =20 @@ -447,6 +502,11 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start); } #endif + /*Register legacy io address space, size:64M*/ + ipf_legacy_io_base =3D 0xE0000000; + ipf_legacy_io_mem =3D cpu_register_io_memory(0, ipf_legacy_io_read, + ipf_legacy_io_write, NULL); + cpu_register_physical_memory(ipf_legacy_io_base, 64*1024*1024, ipf_legacy_io_mem); =20 cpu_irq =3D qemu_allocate_irqs(pic_irq_request, first_cpu, 1); i8259 =3D i8259_init(cpu_irq[0]); --=20 1.5.2 |
From: Blue S. <bla...@gm...> - 2008-01-30 17:10:41
|
On 1/30/08, Scott Pakin <pa...@la...> wrote: > Zhang, Xiantao wrote: > > Scott Pakin wrote: > >> The attached patch corrects a bug in qemu/slirp/tcp_var.h that defines > >> the seg_next field in struct tcpcb to be 32 bits wide regardless of > >> 32/64-bitness. seg_next is assigned a pointer value in > >> qemu/slirp/tcp_subr.c, then cast back to a pointer in > >> qemu/slirp/tcp_input.c and dereferenced. That produces a SIGSEGV on > >> my system. > > > > > > I still hit it on IA64 platform with your patch, once configured with > > slirp. > > Okay, here's a more thorough patch that fixes *all* of the "cast from/to > pointer to/from integer of a different size" mistakes that gcc warns > about. Does it also solve the SIGSEGV problem on IA64? The SLIRP code is much, much more subtle than that. Please see this thread: http://lists.gnu.org/archive/html/qemu-devel/2007-10/msg00542.html |
From: Scott P. <pa...@la...> - 2008-01-30 16:48:47
|
Zhang, Xiantao wrote: > Scott Pakin wrote: >> The attached patch corrects a bug in qemu/slirp/tcp_var.h that defines >> the seg_next field in struct tcpcb to be 32 bits wide regardless of >> 32/64-bitness. seg_next is assigned a pointer value in >> qemu/slirp/tcp_subr.c, then cast back to a pointer in >> qemu/slirp/tcp_input.c and dereferenced. That produces a SIGSEGV on >> my system. > > > I still hit it on IA64 platform with your patch, once configured with > slirp. Okay, here's a more thorough patch that fixes *all* of the "cast from/to pointer to/from integer of a different size" mistakes that gcc warns about. Does it also solve the SIGSEGV problem on IA64? -- Scott ================== BEGIN tcp_int32_pointer_cast.patch ================== diff -Naur kvm-60-ORIG/qemu/exec-all.h kvm-60/qemu/exec-all.h --- kvm-60-ORIG/qemu/exec-all.h 2008-01-20 05:35:04.000000000 -0700 +++ kvm-60/qemu/exec-all.h 2008-01-29 19:19:45.000000000 -0700 @@ -169,7 +169,7 @@ #ifdef USE_DIRECT_JUMP uint16_t tb_jmp_offset[4]; /* offset of jump instruction */ #else - uint32_t tb_next[2]; /* address of jump generated code */ + uintptr_t tb_next[2]; /* address of jump generated code */ #endif /* list of TBs jumping to this one. This is a circular list using the two least significant bits of the pointers to tell what is diff -Naur kvm-60-ORIG/qemu/slirp/ip.h kvm-60/qemu/slirp/ip.h --- kvm-60-ORIG/qemu/slirp/ip.h 2008-01-20 05:35:04.000000000 -0700 +++ kvm-60/qemu/slirp/ip.h 2008-01-29 19:13:09.000000000 -0700 @@ -183,23 +183,9 @@ #define IP_MSS 576 /* default maximum segment size */ -#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */ -#include <sys/types32.h> -#else -#if SIZEOF_CHAR_P == 4 typedef caddr_t caddr32_t; -#else -typedef u_int32_t caddr32_t; -#endif -#endif - -#if SIZEOF_CHAR_P == 4 typedef struct ipq *ipqp_32; typedef struct ipasfrag *ipasfragp_32; -#else -typedef caddr32_t ipqp_32; -typedef caddr32_t ipasfragp_32; -#endif /* * Overlay for ip header used by other protocols (tcp, udp). diff -Naur kvm-60-ORIG/qemu/slirp/misc.c kvm-60/qemu/slirp/misc.c --- kvm-60-ORIG/qemu/slirp/misc.c 2008-01-20 05:35:04.000000000 -0700 +++ kvm-60/qemu/slirp/misc.c 2008-01-29 11:36:15.000000000 -0700 @@ -97,39 +97,6 @@ our_addr.s_addr = loopback_addr.s_addr; } -#if SIZEOF_CHAR_P == 8 - -struct quehead_32 { - u_int32_t qh_link; - u_int32_t qh_rlink; -}; - -inline void -insque_32(a, b) - void *a; - void *b; -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - register struct quehead_32 *head = (struct quehead_32 *) b; - element->qh_link = head->qh_link; - head->qh_link = (u_int32_t)element; - element->qh_rlink = (u_int32_t)head; - ((struct quehead_32 *)(element->qh_link))->qh_rlink - = (u_int32_t)element; -} - -inline void -remque_32(a) - void *a; -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#endif /* SIZEOF_CHAR_P == 8 */ - struct quehead { struct quehead *qh_link; struct quehead *qh_rlink; diff -Naur kvm-60-ORIG/qemu/slirp/slirp.h kvm-60/qemu/slirp/slirp.h --- kvm-60-ORIG/qemu/slirp/slirp.h 2008-01-20 05:35:04.000000000 -0700 +++ kvm-60/qemu/slirp/slirp.h 2008-01-29 11:37:19.000000000 -0700 @@ -265,13 +265,8 @@ void lprint _P((const char *, ...)); -#if SIZEOF_CHAR_P == 4 -# define insque_32 insque -# define remque_32 remque -#else - inline void insque_32 _P((void *, void *)); - inline void remque_32 _P((void *)); -#endif +#define insque_32 insque +#define remque_32 remque #ifndef _WIN32 #include <netdb.h> diff -Naur kvm-60-ORIG/qemu/slirp/tcp_var.h kvm-60/qemu/slirp/tcp_var.h --- kvm-60-ORIG/qemu/slirp/tcp_var.h 2008-01-20 05:35:04.000000000 -0700 +++ kvm-60/qemu/slirp/tcp_var.h 2008-01-28 21:12:22.000000000 -0700 @@ -40,11 +40,7 @@ #include "tcpip.h" #include "tcp_timer.h" -#if SIZEOF_CHAR_P == 4 - typedef struct tcpiphdr *tcpiphdrp_32; -#else - typedef u_int32_t tcpiphdrp_32; -#endif +typedef struct tcpiphdr *tcpiphdrp_32; /* * Tcp control block, one per tcp; fields: @@ -178,11 +174,7 @@ * port numbers (which are no longer needed once we've located the * tcpcb) are overlayed with an mbuf pointer. */ -#if SIZEOF_CHAR_P == 4 typedef struct mbuf *mbufp_32; -#else -typedef u_int32_t mbufp_32; -#endif #define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) #ifdef LOG_ENABLED =================== END tcp_int32_pointer_cast.patch =================== |
From: Anthony L. <an...@co...> - 2008-01-30 14:42:16
|
Avi Kivity wrote: > Anthony Liguori wrote: > >> This patch attempts to clean up the interactions between KVM and QEMU. Sorry >> for such a big patch, but I don't think there's a better way to approach this >> such that it's still bisect friendly. I think this is most of what's needed to >> get basic KVM support into QEMU though. >> >> Right now, there's a mix of #ifdef USE_KVM, if (kvm_allowed), and various >> extern declarations. It's all pretty fugly and there's a lot of mistakes due >> to it. >> >> The following patch eliminates almost all uses of #ifdef USE_KVM by introducing >> a kvm_enabled() macro. If USE_KVM is set, this macro evaluates to kvm_allowed. >> If USE_KVM isn't set, the macro evaluates to 0. >> >> Since GCC eliminates if (0) blocks, this is just as good as using #ifdef. By >> making sure that we never call into libkvm directly from QEMU, we can also just >> not link qemu-kvm when USE_KVM isn't set instead of having the entire file >> wrapped in a USE_KVM. >> >> >> > > It might not when optimizations are disabled. Please test. > I did. It works even without -O. > Also, long term (when we're fully merged into qemu), we need to be able > to build without libkvm or linux/kvm.h installed. With this patch (and the follow-ups), we can build without libkvm. There are only two places we call libkvm directly: in qemu-kvm-*.c or in some blocks guarded with KVM_CAP_* I'll clean up the later with a follow up patch. > That means we can't > use any of the kvm.h defines and data structures. So for example, > kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) needs to be changed to > kvm_qemu_supports_userspace_memory(). > Every place that makes that sort of call is guarded at the moment so it works. Regards, Anthony Liguori |
From: Avi K. <av...@qu...> - 2008-01-30 10:16:19
|
Avi Kivity wrote: > Anthony Liguori wrote: > >> This patch attempts to clean up the interactions between KVM and QEMU. Sorry >> for such a big patch, but I don't think there's a better way to approach this >> such that it's still bisect friendly. I think this is most of what's needed to >> get basic KVM support into QEMU though. >> >> Right now, there's a mix of #ifdef USE_KVM, if (kvm_allowed), and various >> extern declarations. It's all pretty fugly and there's a lot of mistakes due >> to it. >> >> The following patch eliminates almost all uses of #ifdef USE_KVM by introducing >> a kvm_enabled() macro. If USE_KVM is set, this macro evaluates to kvm_allowed. >> If USE_KVM isn't set, the macro evaluates to 0. >> >> Since GCC eliminates if (0) blocks, this is just as good as using #ifdef. By >> making sure that we never call into libkvm directly from QEMU, we can also just >> not link qemu-kvm when USE_KVM isn't set instead of having the entire file >> wrapped in a USE_KVM. >> >> >> [snip objections] I guess I ought to merge this regardless. This type of patch ages quickly, so it's better to apply it now and fix any issues later. I'll wait a few more hours to see if anyone has issues and then apply. -- error compiling committee.c: too many arguments to function |
From: Avi K. <av...@qu...> - 2008-01-30 09:47:40
|
Anthony Liguori wrote: > This patch attempts to clean up the interactions between KVM and QEMU. Sorry > for such a big patch, but I don't think there's a better way to approach this > such that it's still bisect friendly. I think this is most of what's needed to > get basic KVM support into QEMU though. > > Right now, there's a mix of #ifdef USE_KVM, if (kvm_allowed), and various > extern declarations. It's all pretty fugly and there's a lot of mistakes due > to it. > > The following patch eliminates almost all uses of #ifdef USE_KVM by introducing > a kvm_enabled() macro. If USE_KVM is set, this macro evaluates to kvm_allowed. > If USE_KVM isn't set, the macro evaluates to 0. > > Since GCC eliminates if (0) blocks, this is just as good as using #ifdef. By > making sure that we never call into libkvm directly from QEMU, we can also just > not link qemu-kvm when USE_KVM isn't set instead of having the entire file > wrapped in a USE_KVM. > > It might not when optimizations are disabled. Please test. Also, long term (when we're fully merged into qemu), we need to be able to build without libkvm or linux/kvm.h installed. That means we can't use any of the kvm.h defines and data structures. So for example, kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) needs to be changed to kvm_qemu_supports_userspace_memory(). -- error compiling committee.c: too many arguments to function |
From: Jerone Y. <jy...@us...> - 2008-01-30 05:39:10
|
Tested the patch, as somewhat mentioned in the email. Works great for us in PowerPC Embedded land. Signed-off-by: Jerone Young <jy...@us...> On Tue, 2008-01-29 at 16:46 -0600, Anthony Liguori wrote: > This patch attempts to clean up the interactions between KVM and QEMU. Sorry > for such a big patch, but I don't think there's a better way to approach this > such that it's still bisect friendly. I think this is most of what's needed to > get basic KVM support into QEMU though. > > Right now, there's a mix of #ifdef USE_KVM, if (kvm_allowed), and various > extern declarations. It's all pretty fugly and there's a lot of mistakes due > to it. > > The following patch eliminates almost all uses of #ifdef USE_KVM by introducing > a kvm_enabled() macro. If USE_KVM is set, this macro evaluates to kvm_allowed. > If USE_KVM isn't set, the macro evaluates to 0. > > Since GCC eliminates if (0) blocks, this is just as good as using #ifdef. By > making sure that we never call into libkvm directly from QEMU, we can also just > not link qemu-kvm when USE_KVM isn't set instead of having the entire file > wrapped in a USE_KVM. > > We also change the --enable-kvm configure option to --disable-kvm since KVM is > enabled by default. > > I've tested this patch on x86 with 32-bit and 64-bit Linux guests and a 32-bit > Windows guest. I've also tested with USE_KVM not set. Jerone has also > verified that it doesn't PPC. My apologies if it breaks ia64 but I have no > way of testing that. > > Signed-off-by: Anthony Liguori <ali...@us...> > > diff --git a/configure b/configure > index a000c62..6b20c2f 100755 > --- a/configure > +++ b/configure > @@ -115,7 +115,7 @@ fi > --disable-kqemu \ > --extra-cflags="-I $PWD/../libkvm $qemu_cflags" \ > --extra-ldflags="-L $PWD/../libkvm $qemu_ldflags" \ > - --enable-kvm --kernel-path="$libkvm_kerneldir" \ > + --kernel-path="$libkvm_kerneldir" \ > --prefix="$prefix" \ > ${qemu_cc:+"--cc=$qemu_cc"} \ > ${cross_prefix:+"--cross-prefix=$cross_prefix"} \ > diff --git a/qemu/Makefile.target b/qemu/Makefile.target > index df43716..4458971 100644 > --- a/qemu/Makefile.target > +++ b/qemu/Makefile.target > @@ -295,8 +295,12 @@ SRCS:= $(OBJS:.o=.c) > OBJS+= libqemu.a > > # cpu emulator library > -LIBOBJS=exec.o kqemu.o qemu-kvm.o translate-op.o translate-all.o cpu-exec.o\ > +LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\ > translate.o op.o host-utils.o > +ifeq ($(USE_KVM), 1) > +LIBOBJS+=qemu-kvm.o > +endif > + > ifdef CONFIG_SOFTFLOAT > LIBOBJS+=fpu/softfloat.o > else > @@ -306,20 +310,26 @@ CPPFLAGS+=-I$(SRC_PATH)/fpu > > ifeq ($(TARGET_ARCH), i386) > LIBOBJS+=helper.o helper2.o > +ifeq ($(USE_KVM), 1) > LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o > LIBOBJS+=qemu-kvm-helper.o > endif > +endif > > ifeq ($(TARGET_ARCH), x86_64) > LIBOBJS+=helper.o helper2.o > +ifeq ($(USE_KVM), 1) > LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o > LIBOBJS+=qemu-kvm-helper.o > endif > +endif > > ifeq ($(TARGET_BASE_ARCH), ppc) > LIBOBJS+= op_helper.o helper.o > +ifeq ($(USE_KVM), 1) > LIBOBJS+= qemu-kvm-powerpc.o > endif > +endif > > ifeq ($(TARGET_BASE_ARCH), mips) > LIBOBJS+= op_helper.o helper.o > @@ -347,8 +357,10 @@ endif > > ifeq ($(TARGET_BASE_ARCH), ia64) > LIBOBJS+=op_helper.o firmware.o > +ifeq ($(USE_KVM), 1) > LIBOBJS+=qemu-kvm-ia64.o > endif > +endif > > ifeq ($(TARGET_BASE_ARCH), cris) > LIBOBJS+= op_helper.o helper.o > diff --git a/qemu/block-raw-posix.c b/qemu/block-raw-posix.c > index 7e0c39e..74657fb 100644 > --- a/qemu/block-raw-posix.c > +++ b/qemu/block-raw-posix.c > @@ -346,8 +346,8 @@ void qemu_aio_wait_start(void) > > if (!aio_initialized) > qemu_aio_init(); > -#ifdef USE_KVM > - if (kvm_allowed) { > +#ifndef QEMU_IMG > + if (kvm_enabled()) { > qemu_kvm_aio_wait_start(); > return; > } > @@ -365,9 +365,7 @@ void qemu_aio_wait(void) > #ifndef QEMU_IMG > if (qemu_bh_poll()) > return; > -#endif > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > qemu_kvm_aio_wait(); > qemu_aio_poll(); > return; > @@ -381,8 +379,8 @@ void qemu_aio_wait(void) > > void qemu_aio_wait_end(void) > { > -#ifdef USE_KVM > - if (kvm_allowed) { > +#ifndef QEMU_IMG > + if (kvm_enabled()) { > qemu_kvm_aio_wait_end(); > return; > } > diff --git a/qemu/configure b/qemu/configure > index 78c35a4..bf624ed 100755 > --- a/qemu/configure > +++ b/qemu/configure > @@ -300,7 +300,7 @@ for opt do > ;; > --disable-kqemu) kqemu="no" > ;; > - --enable-kvm) kvm="yes" > + --disable-kvm) kvm="no" > ;; > --enable-profiler) profiler="yes" > ;; > @@ -415,7 +415,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]" > @@ -1100,6 +1100,7 @@ configure_kvm() { > if test $kvm = "yes" -a "$target_softmmu" = "yes" -a \ > \( "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "ia64" -o "$cpu" = "powerpc" \); then > echo "#define USE_KVM 1" >> $config_h > + echo "USE_KVM=1" >> $config_mak > echo "CONFIG_KVM_KERNEL_INC=$kernel_path/include" >> $config_mak > fi > } > diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c > index 42be8ec..9d05ef9 100644 > --- a/qemu/cpu-exec.c > +++ b/qemu/cpu-exec.c > @@ -36,10 +36,7 @@ > #include <sys/ucontext.h> > #endif > > -#ifdef USE_KVM > #include "qemu-kvm.h" > -extern int kvm_allowed; > -#endif > > int tb_invalidated_flag; > > @@ -487,12 +484,10 @@ int cpu_exec(CPUState *env1) > } > #endif > > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > kvm_cpu_exec(env); > longjmp(env->jmp_env, 1); > } > -#endif > T0 = 0; /* force lookup of first TB */ > for(;;) { > SAVE_GLOBALS(); > diff --git a/qemu/exec.c b/qemu/exec.c > index f8e6713..06eaf62 100644 > --- a/qemu/exec.c > +++ b/qemu/exec.c > @@ -35,10 +35,8 @@ > > #include "cpu.h" > #include "exec-all.h" > -#ifdef USE_KVM > #include "dyngen.h" > #include "qemu-kvm.h" > -#endif > #if defined(CONFIG_USER_ONLY) > #include <qemu.h> > #endif > @@ -88,11 +86,6 @@ > #define TARGET_PHYS_ADDR_SPACE_BITS 32 > #endif > > -#ifdef USE_KVM > -extern int kvm_allowed; > -extern kvm_context_t kvm_context; > -#endif > - > TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; > TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; > int nb_tbs; > @@ -1147,10 +1140,8 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc) > return -1; > env->breakpoints[env->nb_breakpoints++] = pc; > > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_update_debugger(env); > -#endif > > breakpoint_invalidate(env, pc); > return 0; > @@ -1174,10 +1165,8 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc) > if (i < env->nb_breakpoints) > env->breakpoints[i] = env->breakpoints[env->nb_breakpoints]; > > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_update_debugger(env); > -#endif > > breakpoint_invalidate(env, pc); > return 0; > @@ -1197,11 +1186,9 @@ void cpu_single_step(CPUState *env, int enabled) > /* XXX: only flush what is necessary */ > tb_flush(env); > } > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_update_debugger(env); > #endif > -#endif > } > > /* enable or disable low levels log */ > @@ -1248,10 +1235,9 @@ void cpu_interrupt(CPUState *env, int mask) > static int interrupt_lock; > > env->interrupt_request |= mask; > -#ifdef USE_KVM > - if (kvm_allowed && !kvm_irqchip_in_kernel(kvm_context)) > + if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel()) > kvm_update_interrupt_request(env); > -#endif > + > /* if the cpu is currently executing code, we must unlink it and > all the potentially executing TB */ > tb = env->current_tb; > @@ -1599,9 +1585,8 @@ int cpu_physical_memory_set_dirty_tracking(int enable) > { > int r=0; > > -#ifdef USE_KVM > - r = kvm_physical_memory_set_dirty_tracking(enable); > -#endif > + if (kvm_enabled()) > + r = kvm_physical_memory_set_dirty_tracking(enable); > in_migration = enable; > return r; > } > @@ -2662,11 +2647,11 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, > phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |= > (0xff & ~CODE_DIRTY_FLAG); > } > -#ifdef USE_KVM > /* qemu doesn't execute guest code directly, but kvm does > therefore fluch instruction caches */ > - flush_icache_range((unsigned long)ptr, ((unsigned long)ptr)+l); > -#endif > + if (kvm_enabled()) > + flush_icache_range((unsigned long)ptr, > + ((unsigned long)ptr)+l); > } > } else { > if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && > diff --git a/qemu/gdbstub.c b/qemu/gdbstub.c > index 38b699f..2252084 100644 > --- a/qemu/gdbstub.c > +++ b/qemu/gdbstub.c > @@ -894,9 +894,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) > addr = strtoull(p, (char **)&p, 16); > #if defined(TARGET_I386) > env->eip = addr; > -#ifdef USE_KVM > - kvm_load_registers(env); > -#endif > + if (kvm_enabled()) > + kvm_load_registers(env); > #elif defined (TARGET_PPC) > env->nip = addr; > #elif defined (TARGET_SPARC) > @@ -923,9 +922,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) > addr = strtoull(p, (char **)&p, 16); > #if defined(TARGET_I386) > env->eip = addr; > -#ifdef USE_KVM > - kvm_load_registers(env); > -#endif > + if (kvm_enabled()) > + kvm_load_registers(env); > #elif defined (TARGET_PPC) > env->nip = addr; > #elif defined (TARGET_SPARC) > @@ -977,9 +975,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) > } > break; > case 'g': > -#ifdef USE_KVM > - kvm_save_registers(env); > -#endif > + if (kvm_enabled()) > + kvm_save_registers(env); > reg_size = cpu_gdb_read_registers(env, mem_buf); > memtohex(buf, mem_buf, reg_size); > put_packet(s, buf); > @@ -989,9 +986,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) > len = strlen(p) / 2; > hextomem((uint8_t *)registers, p, len); > cpu_gdb_write_registers(env, mem_buf, len); > -#ifdef USE_KVM > - kvm_load_registers(env); > -#endif > + if (kvm_enabled()) > + kvm_load_registers(env); > put_packet(s, "OK"); > break; > case 'm': > diff --git a/qemu/hw/apic.c b/qemu/hw/apic.c > index a47c366..c26a18d 100644 > --- a/qemu/hw/apic.c > +++ b/qemu/hw/apic.c > @@ -21,11 +21,7 @@ > #include "pc.h" > #include "qemu-timer.h" > > -#ifdef USE_KVM > #include "qemu-kvm.h" > -extern int kvm_allowed; > -extern kvm_context_t kvm_context; > -#endif > > //#define DEBUG_APIC > //#define DEBUG_IOAPIC > @@ -407,11 +403,10 @@ static void apic_init_ipi(APICState *s) > s->initial_count = 0; > s->initial_count_load_time = 0; > s->next_time = 0; > -#ifdef USE_KVM > - if (kvm_allowed && !kvm_irqchip_in_kernel(kvm_context)) > + > + if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel()) > if (s->cpu_env) > kvm_apic_init(s->cpu_env); > -#endif > } > > /* send a SIPI message to the CPU to start it */ > @@ -424,10 +419,8 @@ static void apic_startup(APICState *s, int vector_num) > cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12, > 0xffff, 0); > env->hflags &= ~HF_HALTED_MASK; > -#if USE_KVM > - if (kvm_allowed && !kvm_irqchip_in_kernel(kvm_context)) > + if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel()) > kvm_update_after_sipi(env); > -#endif > } > > static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, > @@ -753,8 +746,6 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) > } > } > > -#ifdef USE_KVM > - > #ifdef KVM_CAP_IRQCHIP > > static inline uint32_t kapic_reg(struct kvm_lapic_state *kapic, int reg_id) > @@ -832,20 +823,16 @@ static void kvm_kernel_lapic_load_from_user(APICState *s) > > #endif > > -#endif > - > static void apic_save(QEMUFile *f, void *opaque) > { > APICState *s = opaque; > int i; > > -#ifdef USE_KVM > #ifdef KVM_CAP_IRQCHIP > - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { > + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { > kvm_kernel_lapic_save_to_user(s); > } > #endif > -#endif > > qemu_put_be32s(f, &s->apicbase); > qemu_put_8s(f, &s->id); > @@ -910,13 +897,11 @@ static int apic_load(QEMUFile *f, void *opaque, int version_id) > if (version_id >= 2) > qemu_get_timer(f, s->timer); > > -#ifdef USE_KVM > #ifdef KVM_CAP_IRQCHIP > - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { > + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { > kvm_kernel_lapic_load_from_user(s); > } > #endif > -#endif > > return 0; > } > @@ -932,13 +917,11 @@ static void apic_reset(void *opaque) > * processor when local APIC is enabled. > */ > s->lvt[APIC_LVT_LINT0] = 0x700; > -#ifdef USE_KVM > #ifdef KVM_CAP_IRQCHIP > - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { > + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { > kvm_kernel_lapic_load_from_user(s); > } > #endif > -#endif > } > > static CPUReadMemoryFunc *apic_mem_read[3] = { > @@ -1131,7 +1114,6 @@ static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va > } > } > > -#ifdef USE_KVM > static void kvm_kernel_ioapic_save_to_user(IOAPICState *s) > { > #if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386) > @@ -1170,18 +1152,15 @@ static void kvm_kernel_ioapic_load_from_user(IOAPICState *s) > kvm_set_irqchip(kvm_context, &chip); > #endif > } > -#endif > > static void ioapic_save(QEMUFile *f, void *opaque) > { > IOAPICState *s = opaque; > int i; > > -#ifdef USE_KVM > - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { > + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { > kvm_kernel_ioapic_save_to_user(s); > } > -#endif > > qemu_put_8s(f, &s->id); > qemu_put_8s(f, &s->ioregsel); > @@ -1204,11 +1183,9 @@ static int ioapic_load(QEMUFile *f, void *opaque, int version_id) > qemu_get_be64s(f, &s->ioredtbl[i]); > } > > -#ifdef USE_KVM > - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { > + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { > kvm_kernel_ioapic_load_from_user(s); > } > -#endif > > return 0; > } > diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c > index ee7ec1c..1915c73 100644 > --- a/qemu/hw/cirrus_vga.c > +++ b/qemu/hw/cirrus_vga.c > @@ -34,6 +34,7 @@ > #ifndef _WIN32 > #include <sys/mman.h> > #endif > +#include "qemu-kvm.h" > > /* > * TODO: > @@ -237,13 +238,11 @@ typedef struct CirrusVGAState { > int cirrus_linear_io_addr; > int cirrus_linear_bitblt_io_addr; > int cirrus_mmio_io_addr; > -#ifdef USE_KVM > unsigned long cirrus_lfb_addr; > unsigned long cirrus_lfb_end; > int aliases_enabled; > uint32_t aliased_bank_base[2]; > uint32_t aliased_bank_limit[2]; > -#endif > uint32_t cirrus_addr_mask; > uint32_t linear_mmio_mask; > uint8_t cirrus_shadow_gr0; > @@ -2601,12 +2600,6 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = { > cirrus_linear_bitblt_writel, > }; > > -#ifdef USE_KVM > - > -#include "qemu-kvm.h" > - > -extern kvm_context_t kvm_context; > - > void *set_vram_mapping(unsigned long begin, unsigned long end) > { > void *vram_pointer = NULL; > @@ -2616,8 +2609,8 @@ void *set_vram_mapping(unsigned long begin, unsigned long end) > end = begin + VGA_RAM_SIZE; > end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK; > > - vram_pointer = kvm_create_phys_mem(kvm_context, begin, end - begin, > - 1, 1); > + if (kvm_enabled()) > + vram_pointer = kvm_cpu_create_phys_mem(begin, end - begin, 1, 1); > > if (vram_pointer == NULL) { > printf("set_vram_mapping: cannot allocate memory: %m\n"); > @@ -2636,7 +2629,8 @@ int unset_vram_mapping(unsigned long begin, unsigned long end) > begin = begin & TARGET_PAGE_MASK; > end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK; > > - kvm_destroy_phys_mem(kvm_context, begin, end - begin); > + if (kvm_enabled()) > + kvm_cpu_destroy_phys_mem(begin, end - begin); > > return 0; > } > @@ -2669,20 +2663,19 @@ static void kvm_update_vga_alias(CirrusVGAState *s, int ok, int bank, > > static void kvm_update_vga_aliases(CirrusVGAState *s, int ok) > { > - if (kvm_allowed) { > + if (kvm_enabled()) { > kvm_update_vga_alias(s, ok, 0, 0xc0000); > kvm_update_vga_alias(s, ok, 1, s->map_addr); > } > s->aliases_enabled = ok; > } > #endif > -#endif > > /* Compute the memory access functions */ > static void cirrus_update_memory_access(CirrusVGAState *s) > { > unsigned mode; > -#if defined(USE_KVM) && defined(CONFIG_X86) > +#ifdef CONFIG_X86 > int want_vga_alias = 0; > #endif > > @@ -2699,8 +2692,7 @@ static void cirrus_update_memory_access(CirrusVGAState *s) > > mode = s->gr[0x05] & 0x7; > if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { > -#ifdef USE_KVM > - if (kvm_allowed && s->cirrus_lfb_addr && s->cirrus_lfb_end && > + if (kvm_enabled() && s->cirrus_lfb_addr && s->cirrus_lfb_end && > !s->map_addr) { > void *vram_pointer, *old_vram; > > @@ -2717,21 +2709,19 @@ static void cirrus_update_memory_access(CirrusVGAState *s) > s->map_end = s->cirrus_lfb_end; > } > #ifdef CONFIG_X86 > - if (kvm_allowed > + if (kvm_enabled() > && !(s->cirrus_srcptr != s->cirrus_srcptr_end) > && !((s->sr[0x07] & 0x01) == 0) > && !((s->gr[0x0B] & 0x14) == 0x14) > && !(s->gr[0x0B] & 0x02)) > want_vga_alias = 1; > #endif > -#endif > s->cirrus_linear_write[0] = cirrus_linear_mem_writeb; > s->cirrus_linear_write[1] = cirrus_linear_mem_writew; > s->cirrus_linear_write[2] = cirrus_linear_mem_writel; > } else { > generic_io: > -#ifdef USE_KVM > - if (kvm_allowed && s->cirrus_lfb_addr && s->cirrus_lfb_end && > + if (kvm_enabled() && s->cirrus_lfb_addr && s->cirrus_lfb_end && > s->map_addr) { > int error; > void *old_vram = NULL; > @@ -2745,13 +2735,12 @@ static void cirrus_update_memory_access(CirrusVGAState *s) > munmap(old_vram, s->map_end - s->map_addr); > s->map_addr = s->map_end = 0; > } > -#endif > s->cirrus_linear_write[0] = cirrus_linear_writeb; > s->cirrus_linear_write[1] = cirrus_linear_writew; > s->cirrus_linear_write[2] = cirrus_linear_writel; > } > } > -#if defined(USE_KVM) && defined(CONFIG_X86) > +#if defined(CONFIG_X86) > kvm_update_vga_aliases(s, want_vga_alias); > #endif > > @@ -3149,12 +3138,10 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque) > /* XXX: we do not save the bitblt state - we assume we do not save > the state when the blitter is active */ > > -#ifdef USE_KVM > - if (kvm_allowed) { /* XXX: KVM images ought to be loadable in QEMU */ > + if (kvm_enabled()) { /* XXX: KVM images ought to be loadable in QEMU */ > qemu_put_be32s(f, &s->real_vram_size); > qemu_put_buffer(f, s->vram_ptr, s->real_vram_size); > } > -#endif > } > > static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) > @@ -3205,8 +3192,7 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) > qemu_get_be32s(f, &s->hw_cursor_x); > qemu_get_be32s(f, &s->hw_cursor_y); > > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > int real_vram_size; > qemu_get_be32s(f, &real_vram_size); > if (real_vram_size != s->real_vram_size) { > @@ -3218,7 +3204,6 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) > qemu_get_buffer(f, s->vram_ptr, real_vram_size); > cirrus_update_memory_access(s); > } > -#endif > > > /* force refresh */ > @@ -3376,8 +3361,7 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, > /* XXX: add byte swapping apertures */ > cpu_register_physical_memory(addr, s->vram_size, > s->cirrus_linear_io_addr); > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > s->cirrus_lfb_addr = addr; > s->cirrus_lfb_end = addr + VGA_RAM_SIZE; > > @@ -3385,7 +3369,6 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, > (s->cirrus_lfb_end != s->map_end)) > printf("cirrus vga map change while on lfb mode\n"); > } > -#endif > > cpu_register_physical_memory(addr + 0x1000000, 0x400000, > s->cirrus_linear_bitblt_io_addr); > diff --git a/qemu/hw/i8259.c b/qemu/hw/i8259.c > index 071f9f1..b266119 100644 > --- a/qemu/hw/i8259.c > +++ b/qemu/hw/i8259.c > @@ -26,9 +26,7 @@ > #include "isa.h" > #include "console.h" > > -#ifdef USE_KVM > #include "qemu-kvm.h" > -#endif > > /* debug PIC */ > //#define DEBUG_PIC > @@ -185,15 +183,11 @@ int64_t irq_time[16]; > static void i8259_set_irq(void *opaque, int irq, int level) > { > PicState2 *s = opaque; > -#ifdef USE_KVM > #ifdef KVM_CAP_IRQCHIP > - extern int kvm_set_irq(int irq, int level); > - > - if (kvm_allowed) > + if (kvm_enabled()) > if (kvm_set_irq(irq, level)) > return; > #endif > -#endif > #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) > if (level != irq_level[irq]) { > #if defined(DEBUG_PIC) > @@ -477,11 +471,6 @@ static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1) > return s->elcr; > } > > -#ifdef USE_KVM > -#include "qemu-kvm.h" > -extern int kvm_allowed; > -extern kvm_context_t kvm_context; > - > static void kvm_kernel_pic_save_to_user(PicState *s) > { > #if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386) > @@ -544,17 +533,14 @@ static void kvm_kernel_pic_load_from_user(PicState *s) > kvm_set_irqchip(kvm_context, &chip); > #endif > } > -#endif > > static void pic_save(QEMUFile *f, void *opaque) > { > PicState *s = opaque; > > -#ifdef USE_KVM > - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { > + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { > kvm_kernel_pic_save_to_user(s); > } > -#endif > > qemu_put_8s(f, &s->last_irr); > qemu_put_8s(f, &s->irr); > @@ -598,11 +584,9 @@ static int pic_load(QEMUFile *f, void *opaque, int version_id) > qemu_get_8s(f, &s->single_mode); > qemu_get_8s(f, &s->elcr); > > -#ifdef USE_KVM > - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { > + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { > kvm_kernel_pic_load_from_user(s); > } > -#endif > > return 0; > } > diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c > index b1c1389..b5b48ac 100644 > --- a/qemu/hw/ipf.c > +++ b/qemu/hw/ipf.c > @@ -40,10 +40,7 @@ > #include "dyngen.h" > #include <unistd.h> > > -#ifdef USE_KVM > #include "qemu-kvm.h" > -extern int kvm_allowed; > -#endif > > #define FW_FILENAME "Flash.fd" > > @@ -309,11 +306,6 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) > nb_ne2k++; > } > > -#ifdef USE_KVM > -extern kvm_context_t kvm_context; > -extern int kvm_allowed; > -#endif > - > /* Itanium hardware initialisation */ > static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, > const char *boot_device, DisplayState *ds, > @@ -367,9 +359,8 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, > } > > /* allocate RAM */ > -#ifdef USE_KVM > #ifdef KVM_CAP_USER_MEMORY > - if (kvm_allowed && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { > + if (kvm_enabled() && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { > ram_addr = qemu_ram_alloc(0xa0000); > cpu_register_physical_memory(0, 0xa0000, ram_addr); > kvm_cpu_register_physical_memory(0, 0xa0000, ram_addr); > @@ -386,7 +377,6 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, > ram_addr); > } else > #endif > -#endif > { > ram_addr = qemu_ram_alloc(ram_size); > cpu_register_physical_memory(0, ram_size, ram_addr); > @@ -398,16 +388,13 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, > if (above_4g_mem_size > 0) { > ram_addr = qemu_ram_alloc(above_4g_mem_size); > cpu_register_physical_memory(0x100000000, above_4g_mem_size, ram_addr); > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_cpu_register_physical_memory(0x100000000, above_4g_mem_size, > ram_addr); > -#endif > } > > /*Load firware to its proper position.*/ > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > int r; > unsigned long image_size; > char *image = NULL; > @@ -446,7 +433,6 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, > (unsigned long)fw_image_start + image_size); > kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start); > } > -#endif > > cpu_irq = qemu_allocate_irqs(pic_irq_request, first_cpu, 1); > i8259 = i8259_init(cpu_irq[0]); > diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c > index 652b263..0e0d051 100644 > --- a/qemu/hw/pc.c > +++ b/qemu/hw/pc.c > @@ -32,10 +32,7 @@ > #include "smbus.h" > #include "boards.h" > > -#ifdef USE_KVM > #include "qemu-kvm.h" > -extern int kvm_allowed; > -#endif > > /* output Bochs bios info messages */ > //#define DEBUG_BIOS > @@ -711,11 +708,6 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) > nb_ne2k++; > } > > -#ifdef USE_KVM > -extern kvm_context_t kvm_context; > -extern int kvm_allowed; > -#endif > - > static int load_option_rom(const char *filename, int offset) > { > ram_addr_t option_rom_offset; > @@ -738,12 +730,10 @@ static int load_option_rom(const char *filename, int offset) > size = (size + 4095) & ~4095; > cpu_register_physical_memory(0xd0000 + offset, > size, option_rom_offset | IO_MEM_ROM); > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_cpu_register_physical_memory(0xd0000 + offset, > size, option_rom_offset | > IO_MEM_ROM); > -#endif > return size; > } > > @@ -806,9 +796,8 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, > } > > /* allocate RAM */ > -#ifdef USE_KVM > - #ifdef KVM_CAP_USER_MEMORY > - if (kvm_allowed && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { > +#ifdef KVM_CAP_USER_MEMORY > + if (kvm_enabled() && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { > ram_addr = qemu_ram_alloc(0xa0000); > cpu_register_physical_memory(0, 0xa0000, ram_addr); > kvm_cpu_register_physical_memory(0, 0xa0000, ram_addr); > @@ -819,7 +808,6 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, > kvm_cpu_register_physical_memory(0x100000, ram_size - 0x100000, > ram_addr); > } else > - #endif > #endif > { > ram_addr = qemu_ram_alloc(ram_size); > @@ -867,21 +855,19 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, > if (above_4g_mem_size > 0) { > ram_addr = qemu_ram_alloc(above_4g_mem_size); > cpu_register_physical_memory(0x100000000, above_4g_mem_size, ram_addr); > -#ifdef USE_KVM > - if (kvm_allowed) > - kvm_cpu_register_physical_memory(0x100000000, above_4g_mem_size, > - ram_addr); > -#endif > + > + if (kvm_enabled()) > + kvm_cpu_register_physical_memory(0x100000000, > + above_4g_mem_size, > + ram_addr); > } > > /* setup basic memory access */ > cpu_register_physical_memory(0xc0000, 0x10000, > vga_bios_offset | IO_MEM_ROM); > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_cpu_register_physical_memory(0xc0000, 0x10000, > vga_bios_offset | IO_MEM_ROM); > -#endif > > /* map the last 128KB of the BIOS in ISA space */ > isa_bios_size = bios_size; > @@ -893,12 +879,10 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, > cpu_register_physical_memory(0x100000 - isa_bios_size, > isa_bios_size, > (bios_offset + bios_size - isa_bios_size) /* | IO_MEM_ROM */); > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_cpu_register_physical_memory(0x100000 - isa_bios_size, > isa_bios_size, > (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); > -#endif > > opt_rom_offset = 0; > for (i = 0; i < nb_option_roms; i++) > @@ -912,8 +896,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, > /* map all the bios at the top of memory */ > cpu_register_physical_memory((uint32_t)(-bios_size), > bios_size, bios_offset | IO_MEM_ROM); > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > int r; > #ifdef KVM_CAP_USER_MEMORY > r = kvm_qemu_check_extension(KVM_CAP_USER_MEMORY); > @@ -923,14 +906,13 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, > else > #endif > { > - bios_mem = kvm_create_phys_mem(kvm_context, (uint32_t)(-bios_size), > - bios_size, 0, 1); > + bios_mem = kvm_cpu_create_phys_mem((uint32_t)(-bios_size), > + bios_size, 0, 1); > if (!bios_mem) > exit(1); > memcpy(bios_mem, phys_ram_base + bios_offset, bios_size); > } > } > -#endif > > bochs_bios_init(); > > diff --git a/qemu/hw/ppc440_bamboo.c b/qemu/hw/ppc440_bamboo.c > index 29c2efc..d3c2bfd 100644 > --- a/qemu/hw/ppc440_bamboo.c > +++ b/qemu/hw/ppc440_bamboo.c > @@ -12,9 +12,7 @@ > > #define KERNEL_LOAD_ADDR 0x400000 /* uboot loader puts kernel at 4MB */ > > -#if USE_KVM > #include "qemu-kvm.h" > -#endif > > /* PPC 440 refrence demo board > * > @@ -75,9 +73,9 @@ void bamboo_init(ram_addr_t ram_size, int vga_ram_size, > > /* Register mem */ > cpu_register_physical_memory(0, ram_size, 0); > -#if USE_KVM > - kvm_cpu_register_physical_memory(0, ram_size, 0); > -#endif > + if (kvm_enabled()) > + kvm_cpu_register_physical_memory(0, ram_size, 0); > + > /* load kernel with uboot loader */ > printf("%s: load kernel\n", __func__); > kernel_size = load_uboot(kernel_filename, &ep, &is_linux); > @@ -101,18 +99,18 @@ void bamboo_init(ram_addr_t ram_size, int vga_ram_size, > } > } > > -#if USE_KVM > - /* XXX insert TLB entries */ > - env->gpr[1] = (16<<20) - 8; > - env->gpr[4] = initrd_base; > - env->gpr[5] = initrd_size; > + if (kvm_enabled()) { > + /* XXX insert TLB entries */ > + env->gpr[1] = (16<<20) - 8; > + env->gpr[4] = initrd_base; > + env->gpr[5] = initrd_size; > > - env->nip = ep; > + env->nip = ep; > > - env->cpu_index = 0; > - printf("%s: loading kvm registers\n", __func__); > - kvm_load_registers(env); > -#endif > + env->cpu_index = 0; > + printf("%s: loading kvm registers\n", __func__); > + kvm_load_registers(env); > + } > > printf("%s: DONE\n", __func__); > } > diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c > index 44e6834..222a39c 100644 > --- a/qemu/hw/vga.c > +++ b/qemu/hw/vga.c > @@ -27,6 +27,7 @@ > #include "pci.h" > #include "vga_int.h" > #include "pixel_ops.h" > +#include "qemu-kvm.h" > > #include <sys/mman.h> > > @@ -1414,11 +1415,6 @@ void vga_invalidate_scanlines(VGAState *s, int y1, int y2) > } > } > > -#ifdef USE_KVM > - > -#include "libkvm.h" > -extern kvm_context_t kvm_context; > - > static int bitmap_get_dirty(unsigned long *bitmap, unsigned nr) > { > unsigned word = nr / ((sizeof bitmap[0]) * 8); > @@ -1428,11 +1424,6 @@ static int bitmap_get_dirty(unsigned long *bitmap, unsigned nr) > return (bitmap[word] >> bit) & 1; > } > > -#endif > - > -#ifdef USE_KVM > -extern int kvm_allowed; > -#endif > > /* > * graphic modes > @@ -1446,24 +1437,20 @@ static void vga_draw_graphic(VGAState *s, int full_update) > uint32_t v, addr1, addr; > long page0, page1, page_min, page_max; > vga_draw_line_func *vga_draw_line; > - > -#ifdef USE_KVM > - > /* HACK ALERT */ > -#define BITMAP_SIZE ((8*1024*1024) / 4096 / 8 / sizeof(long)) > - unsigned long bitmap[BITMAP_SIZE]; > +#define VGA_BITMAP_SIZE ((8*1024*1024) / 4096 / 8 / sizeof(long)) > + unsigned long bitmap[VGA_BITMAP_SIZE]; > #ifndef TARGET_IA64 > int r; > - if (kvm_allowed) { > - r = kvm_get_dirty_pages(kvm_context, s->map_addr, &bitmap); > + if (kvm_enabled()) { > + r = qemu_kvm_get_dirty_pages(s->map_addr, &bitmap); > if (r < 0) > fprintf(stderr, "kvm: get_dirty_pages returned %d\n", r); > } > #else > - memset(bitmap, 0xff, BITMAP_SIZE*sizeof(long)); > + memset(bitmap, 0xff, VGA_BITMAP_SIZE*sizeof(long)); > //FIXME:Always flush full screen before log dirty ready!! > #endif > -#endif > > full_update |= update_basic_params(s); > > @@ -1571,20 +1558,17 @@ static void vga_draw_graphic(VGAState *s, int full_update) > update = full_update | > cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | > cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS); > update |= bitmap_get_dirty(bitmap, (page1 - s->vram_offset) >> TARGET_PAGE_BITS); > } > -#endif > + > if ((page1 - page0) > TARGET_PAGE_SIZE) { > /* if wide line, can use another page */ > update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, > VGA_DIRTY_FLAG); > -#ifdef USE_KVM > - if (kvm_allowed) > - update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS); > -#endif > + if (kvm_enabled()) > + update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS); > } > /* explicit invalidation for the hardware cursor */ > update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; > @@ -1838,8 +1822,7 @@ static void vga_map(PCIDevice *pci_dev, int region_num, > cpu_register_physical_memory(addr, s->bios_size, s->bios_offset); > } else { > cpu_register_physical_memory(addr, s->vram_size, s->vram_offset); > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > unsigned long vga_ram_begin, vga_ram_end; > void *vram_pointer, *old_vram; > > @@ -1870,7 +1853,6 @@ static void vga_map(PCIDevice *pci_dev, int region_num, > s->map_end = vga_ram_end; > } > } > -#endif > } > } > > @@ -2037,14 +2019,10 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, > > vga_reset(s); > > -#ifndef USE_KVM > - s->vram_ptr = vga_ram_base; > -#else > - if (kvm_allowed) > - s->vram_ptr = qemu_malloc(vga_ram_size); > + if (kvm_enabled()) > + s->vram_ptr = qemu_malloc(vga_ram_size); > else > - s->vram_ptr = vga_ram_base; > -#endif > + s->vram_ptr = vga_ram_base; > s->vram_offset = vga_ram_offset; > s->vram_size = vga_ram_size; > s->ds = ds; > diff --git a/qemu/hw/vga_int.h b/qemu/hw/vga_int.h > index f08700e..912d977 100644 > --- a/qemu/hw/vga_int.h > +++ b/qemu/hw/vga_int.h > @@ -79,14 +79,6 @@ > #define CH_ATTR_SIZE (160 * 100) > #define VGA_MAX_HEIGHT 2048 > > -#ifdef USE_KVM > -#define VGA_KVM_STATE \ > - unsigned long map_addr; \ > - unsigned long map_end; > -#else > -#define VGA_KVM_STATE > -#endif > - > #define VGA_STATE_COMMON \ > uint8_t *vram_ptr; \ > unsigned long vram_offset; \ > @@ -154,18 +146,17 @@ > /* tell for each page if it has been updated since the last time */ \ > uint32_t last_palette[256]; \ > uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */ \ > - VGA_KVM_STATE > + unsigned long map_addr; \ > + unsigned long map_end; > > > typedef struct VGAState { > VGA_STATE_COMMON > > -#ifdef USE_KVM > int32_t aliases_enabled; > int32_t pad1; > uint32_t aliased_bank_base[2]; > uint32_t aliased_bank_limit[2]; > -#endif > > > } VGAState; > @@ -200,11 +191,9 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, > unsigned int color0, unsigned int color1, > unsigned int color_xor); > > -#ifdef USE_KVM > /* let kvm create vga memory */ > void *set_vram_mapping(unsigned long begin, unsigned long end); > int unset_vram_mapping(unsigned long begin, unsigned long end); > -#endif > > void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size); > extern const uint8_t sr_mask[8]; > diff --git a/qemu/hw/vmport.c b/qemu/hw/vmport.c > index c225308..c09227d 100644 > --- a/qemu/hw/vmport.c > +++ b/qemu/hw/vmport.c > @@ -26,7 +26,6 @@ > #include "isa.h" > #include "pc.h" > #include "sysemu.h" > -#include "libkvm.h" > #include "qemu-kvm.h" > > #define VMPORT_CMD_GETVERSION 0x0a > @@ -60,16 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) > uint32_t eax; > uint32_t ret; > > -#ifdef USE_KVM > - struct kvm_regs regs; > - extern kvm_context_t kvm_context; > - if (kvm_allowed) { > - kvm_get_regs(kvm_context, s->env->cpu_index, ®s); > - s->env->regs[R_EAX] = regs.rax; s->env->regs[R_EBX] = regs.rbx; > - s->env->regs[R_ECX] = regs.rcx; s->env->regs[R_EDX] = regs.rdx; > - s->env->regs[R_ESI] = regs.rsi; s->env->regs[R_EDI] = regs.rdi; > - } > -#endif > + if (kvm_enabled()) > + kvm_save_registers(s->env); > > eax = s->env->regs[R_EAX]; > if (eax != VMPORT_MAGIC) > @@ -86,14 +77,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) > > ret = s->func[command](s->opaque[command], addr); > > -#ifdef USE_KVM > - if (kvm_allowed) { > - regs.rax = s->env->regs[R_EAX]; regs.rbx = s->env->regs[R_EBX]; > - regs.rcx = s->env->regs[R_ECX]; regs.rdx = s->env->regs[R_EDX]; > - regs.rsi = s->env->regs[R_ESI]; regs.rdi = s->env->regs[R_EDI]; > - kvm_set_regs(kvm_context, s->env->cpu_index, ®s); > - } > -#endif > + if (kvm_enabled()) > + kvm_load_registers(s->env); > > return ret; > } > diff --git a/qemu/migration.c b/qemu/migration.c > index df0acf9..23cff1e 100644 > --- a/qemu/migration.c > +++ b/qemu/migration.c > @@ -29,9 +29,7 @@ > #include "qemu-timer.h" > #include "migration.h" > #include "qemu_socket.h" > -#ifdef USE_KVM > #include "qemu-kvm.h" > -#endif > > #include <sys/wait.h> > > @@ -185,10 +183,10 @@ static void migrate_finish(MigrationState *s) > qemu_aio_flush(); > } while (qemu_bh_poll()); > bdrv_flush_all(); > -#ifdef USE_KVM > - if (kvm_allowed && !*s->has_error && kvm_update_dirty_pages_log()) > + > + if (kvm_enabled() && !*s->has_error && kvm_update_dirty_pages_log()) > *s->has_error = MIG_STAT_KVM_UPDATE_DIRTY_PAGES_LOG_FAILED; > -#endif > + > qemu_put_be32(f, 1); > ret = qemu_live_savevm_state(f); > #ifdef MIGRATION_VERIFY > @@ -260,10 +258,8 @@ static int migrate_check_convergence(MigrationState *s) > } > > for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > continue; > -#endif > if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) > dirty_count++; > } > @@ -319,10 +315,8 @@ static void migrate_write(void *opaque) > if (migrate_write_buffer(s)) > return; > > -#ifdef USE_KVM > - if (kvm_allowed && !*s->has_error && kvm_update_dirty_pages_log()) > + if (kvm_enabled() && !*s->has_error && kvm_update_dirty_pages_log()) > *s->has_error = MIG_STAT_KVM_UPDATE_DIRTY_PAGES_LOG_FAILED; > -#endif > > if (migrate_check_convergence(s) || *s->has_error) { > qemu_del_timer(s->timer); > @@ -333,10 +327,8 @@ static void migrate_write(void *opaque) > } > > while (s->addr < phys_ram_size) { > -#ifdef USE_KVM > - if (kvm_allowed && (s->addr>=0xa0000) && (s->addr<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (s->addr>=0xa0000) && (s->addr<0xc0000)) /* do not access video-addresses */ > s->addr = 0xc0000; > -#endif > > if (cpu_physical_memory_get_dirty(s->addr, MIGRATION_DIRTY_FLAG)) { > migrate_prepare_page(s); > @@ -404,11 +396,10 @@ static int start_migration(MigrationState *s) > target_phys_addr_t addr; > int r; > unsigned char running = vm_running?2:1; /* 1 + vm_running */ > - > -#ifdef USE_KVM > int n = 0; > unsigned char *phys_ram_page_exist_bitmap = NULL; > - if (kvm_allowed) { > + > + if (kvm_enabled()) { > n = BITMAP_SIZE(phys_ram_size); > phys_ram_page_exist_bitmap = qemu_malloc(n); > if (!phys_ram_page_exist_bitmap) { > @@ -422,7 +413,6 @@ static int start_migration(MigrationState *s) > goto out; > } > } > -#endif > > r = MIG_STAT_WRITE_FAILED; > if (write_whole_buffer(s->fd, &running, sizeof(running))) { > @@ -434,8 +424,7 @@ static int start_migration(MigrationState *s) > goto out; > } > > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > value = cpu_to_be32(n); > if (write_whole_buffer(s->fd, &value, sizeof(value))) { > perror("phys_ram_size_bitmap size write failed"); > @@ -446,18 +435,16 @@ static int start_migration(MigrationState *s) > goto out; > } > } > -#endif > + > fcntl(s->fd, F_SETFL, O_NONBLOCK); > > for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && !bit_is_set(addr>>TARGET_PAGE_BITS, phys_ram_page_exist_bitmap)) { > + if (kvm_enabled() && !bit_is_set(addr>>TARGET_PAGE_BITS, phys_ram_page_exist_bitmap)) { > cpu_physical_memory_reset_dirty(addr, > addr + TARGET_PAGE_SIZE, > MIGRATION_DIRTY_FLAG); > continue; > } > -#endif > if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) > cpu_physical_memory_set_dirty(addr); > } > @@ -482,10 +469,8 @@ static int start_migration(MigrationState *s) > r = 0; > > out: > -#ifdef USE_KVM > - if (phys_ram_page_exist_bitmap) > + if (kvm_enabled() && phys_ram_page_exist_bitmap) > qemu_free(phys_ram_page_exist_bitmap); > -#endif > return r; > } > > @@ -825,8 +810,7 @@ static int migrate_incoming_fd(int fd) > return MIG_STAT_DST_MEM_SIZE_MISMATCH; > } > > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > int n, m; > unsigned char *phys_ram_page_exist_bitmap = NULL; > > @@ -848,7 +832,6 @@ static int migrate_incoming_fd(int fd) > > qemu_free(phys_ram_page_exist_bitmap); > } > -#endif > > do { > addr = qemu_get_be32(f); > @@ -1118,10 +1101,8 @@ static int save_verify_memory(QEMUFile *f, void *opaque) > unsigned int sum; > > for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > continue; > -#endif > sum = calc_page_checksum(addr); > qemu_put_be32(f, addr); > qemu_put_be32(f, sum); > @@ -1136,10 +1117,8 @@ static int load_verify_memory(QEMUFile *f, void *opaque, int version_id) > int num_errors = 0; > > for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > continue; > -#endif > sum = calc_page_checksum(addr); > raddr = qemu_get_be32(f); > rsum = qemu_get_be32(f); > diff --git a/qemu/monitor.c b/qemu/monitor.c > index e03c473..e8022c8 100644 > --- a/qemu/monitor.c > +++ b/qemu/monitor.c > @@ -286,9 +286,8 @@ static CPUState *mon_get_cpu(void) > mon_set_cpu(0); > } > > -#ifdef USE_KVM > - kvm_save_registers(mon_cpu); > -#endif > + if (kvm_enabled()) > + kvm_save_registers(mon_cpu); > > return mon_cpu; > } > diff --git a/qemu/osdep.c b/qemu/osdep.c > index 6131438..0ec6446 100644 > --- a/qemu/osdep.c > +++ b/qemu/osdep.c > @@ -113,7 +113,7 @@ static void *kqemu_vmalloc(size_t size) > int64_t free_space; > int ram_mb; > > - extern int ram_size; > + extern int64_t ram_size; > free_space = (int64_t)stfs.f_bavail * stfs.f_bsize; > if ((ram_size + 8192 * 1024) >= free_space) { > ram_mb = (ram_size / (1024 * 1024)); > diff --git a/qemu/qemu-kvm-ia64.c b/qemu/qemu-kvm-ia64.c > index d3d6ac7..a17e032 100644 > --- a/qemu/qemu-kvm-ia64.c > +++ b/qemu/qemu-kvm-ia64.c > @@ -2,11 +2,6 @@ > #include "config.h" > #include "config-host.h" > > -extern int kvm_allowed; > -extern int kvm_irqchip; > - > -#ifdef USE_KVM > - > #include <string.h> > > #include "hw/hw.h" > @@ -68,4 +63,3 @@ int kvm_arch_try_push_interrupts(void *opaque) > void kvm_arch_update_regs_for_sipi(CPUState *env) > { > } > -#endif > diff --git a/qemu/qemu-kvm-powerpc.c b/qemu/qemu-kvm-powerpc.c > index 92aeada..60b0d87 100644 > --- a/qemu/qemu-kvm-powerpc.c > +++ b/qemu/qemu-kvm-powerpc.c > @@ -2,11 +2,6 @@ > #include "config.h" > #include "config-host.h" > > -extern int kvm_allowed; > -extern int kvm_irqchip; > - > -#ifdef USE_KVM > - > #include <string.h> > #include "hw/hw.h" > #include "sysemu.h" > @@ -194,5 +189,3 @@ int handle_powerpc_dcr_write(int vcpu, uint32_t dcrn, uint32_t data) > ppc_dcr_write(env->dcr_env, dcrn, data); > return 0; /* XXX ignore failed DCR ops */ > } > - > -#endif > diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c > index d1838f1..1880290 100644 > --- a/qemu/qemu-kvm-x86.c > +++ b/qemu/qemu-kvm-x86.c > @@ -2,11 +2,6 @@ > #include "config.h" > #include "config-host.h" > > -extern int kvm_allowed; > -extern int kvm_irqchip; > - > -#ifdef USE_KVM > - > #include <string.h> > #include "hw/hw.h" > > @@ -631,5 +626,3 @@ int handle_tpr_access(void *opaque, int vcpu, > kvm_tpr_access_report(cpu_single_env, rip, is_write); > return 0; > } > - > -#endif > diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c > index ec05027..3f12eda 100644 > --- a/qemu/qemu-kvm.c > +++ b/qemu/qemu-kvm.c > @@ -2,17 +2,9 @@ > #include "config.h" > #include "config-host.h" > > -#ifdef USE_KVM > - #define KVM_ALLOWED_DEFAULT 1 > -#else > - #define KVM_ALLOWED_DEFAULT 0 > -#endif > - > -int kvm_allowed = KVM_ALLOWED_DEFAULT; > +int kvm_allowed = 1; > int kvm_irqchip = 1; > > -#ifdef USE_KVM > - > #include <string.h> > #include "hw/hw.h" > #include "sysemu.h" > @@ -112,13 +104,13 @@ static int pre_kvm_run(void *opaque, int vcpu) > > void kvm_load_registers(CPUState *env) > { > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_arch_load_regs(env); > } > > void kvm_save_registers(CPUState *env) > { > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_arch_save_regs(env); > } > > @@ -647,7 +639,7 @@ int kvm_physical_memory_set_dirty_tracking(int enable) > { > int r = 0; > > - if (!kvm_allowed) > + if (!kvm_enabled()) > return 0; > > if (enable) { > @@ -767,4 +759,19 @@ void qemu_kvm_aio_wait_end(void) > { > } > > -#endif > +int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf) > +{ > + return kvm_get_dirty_pages(kvm_context, phys_addr, buf); > +} > + > +void *kvm_cpu_create_phys_mem(target_phys_addr_t start_addr, > + unsigned long size, int log, int writable) > +{ > + return kvm_create_phys_mem(kvm_context, start_addr, size, log, writable); > +} > + > +void kvm_cpu_destroy_phys_mem(target_phys_addr_t start_addr, > + unsigned long size) > +{ > + kvm_destroy_phys_mem(kvm_context, start_addr, size); > +} > diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h > index 9b96951..a48efa3 100644 > --- a/qemu/qemu-kvm.h > +++ b/qemu/qemu-kvm.h > @@ -2,7 +2,6 @@ > #define QEMU_KVM_H > > #include "cpu.h" > -#include "libkvm.h" > > int kvm_main_loop(void); > int kvm_qemu_init(void); > @@ -16,6 +15,7 @@ int kvm_update_debugger(CPUState *env); > int kvm_qemu_init_env(CPUState *env); > int kvm_qemu_check_extension(int ext); > void kvm_apic_init(CPUState *env); > +int kvm_set_irq(int irq, int level); > > int kvm_physical_memory_set_dirty_tracking(int enable); > int kvm_update_dirty_pages_log(void); > @@ -28,6 +28,12 @@ void kvm_update_interrupt_request(CPUState *env); > void kvm_cpu_register_physical_memory(target_phys_addr_t start_addr, > unsigned long size, > unsigned long phys_offset); > +void *kvm_cpu_create_phys_mem(target_phys_addr_t start_addr, > + unsigned long size, int log, int writable); > + > +void kvm_cpu_destroy_phys_mem(target_phys_addr_t start_addr, > + unsigned long size); > + > int kvm_arch_qemu_create_context(void); > > void kvm_arch_save_regs(CPUState *env); > @@ -46,14 +52,13 @@ void qemu_kvm_aio_wait_start(void); > void qemu_kvm_aio_wait(void); > void qemu_kvm_aio_wait_end(void); > > -extern int kvm_allowed; > -extern int kvm_irqchip; > - > void kvm_tpr_opt_setup(CPUState *env); > void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write); > int handle_tpr_access(void *opaque, int vcpu, > uint64_t rip, int is_write); > > +int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf); > + > #ifdef TARGET_PPC > int handle_powerpc_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data); > int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data); > @@ -62,5 +67,17 @@ int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data); > #define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1)) > #define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8) > > +#ifdef USE_KVM > +#include "libkvm.h" > + > +extern int kvm_allowed; > +extern kvm_context_t kvm_context; > + > +#define kvm_enabled() (kvm_allowed) > +#define qemu_kvm_irqchip_in_kernel() kvm_irqchip_in_kernel(kvm_context) > +#else > +#define kvm_enabled() (0) > +#define qemu_kvm_irqchip_in_kernel() (0) > +#endif > > #endif > diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h > index 7143ab3..600464c 100644 > --- a/qemu/target-i386/cpu.h > +++ b/qemu/target-i386/cpu.h > @@ -555,10 +555,8 @@ typedef struct CPUX86State { > target_ulong kernelgsbase; > #endif > > -#ifdef USE_KVM > uint64_t tsc; /* time stamp counter */ > uint8_t ready_for_interrupt_injection; > -#endif > uint64_t pat; > > /* exception/interrupt handling */ > @@ -594,11 +592,9 @@ typedef struct CPUX86State { > int last_io_time; > #endif > > -#ifdef USE_KVM > #define BITS_PER_LONG (8 * sizeof (uint32_t)) > #define NR_IRQ_WORDS (256/ BITS_PER_LONG) > uint32_t kvm_interrupt_bitmap[NR_IRQ_WORDS]; > -#endif > > /* in order to simplify APIC support, we leave this pointer to the > user */ > diff --git a/qemu/target-i386/helper2.c b/qemu/target-i386/helper2.c > index ac663aa..3ada676 100644 > --- a/qemu/target-i386/helper2.c > +++ b/qemu/target-i386/helper2.c > @@ -29,9 +29,7 @@ > #include "exec-all.h" > #include "svm.h" > > -#ifdef USE_KVM > -#include "../qemu-kvm.h" > -#endif > +#include "qemu-kvm.h" > > //#define DEBUG_MMU > > diff --git a/qemu/target-ia64/cpu.h b/qemu/target-ia64/cpu.h > index 2d91cb9..97358ee 100644 > --- a/qemu/target-ia64/cpu.h > +++ b/qemu/target-ia64/cpu.h > @@ -51,9 +51,7 @@ typedef struct CPUIA64State { > int user_mode_only; > uint32_t hflags; > > -#ifdef USE_KVM > - uint8_t ready_for_interrupt_injection; > -#endif > + uint8_t ready_for_interrupt_injection; > > } CPUIA64State; > > diff --git a/qemu/target-ia64/op_helper.c b/qemu/target-ia64/op_helper.c > index 5138af5..8660b17 100644 > --- a/qemu/target-ia64/op_helper.c > +++ b/qemu/target-ia64/op_helper.c > @@ -24,7 +24,7 @@ > #include "cpu.h" > #include "exec-all.h" > > -extern int kvm_allowed; > +#include "qemu-kvm.h" > > CPUState *cpu_ia64_init(char *cpu_model){ > CPUState *env; > @@ -33,14 +33,10 @@ CPUState *cpu_ia64_init(char *cpu_model){ > return NULL; > cpu_exec_init(env); > cpu_reset(env); > -#ifdef USE_KVM > - { > - if (kvm_allowed) { > - kvm_qemu_init_env(env); > - env->ready_for_interrupt_injection = 1; > - } > + if (kvm_enabled()) { > + kvm_qemu_init_env(env); > + env->ready_for_interrupt_injection = 1; > } > -#endif > return env; > } > > @@ -74,12 +70,10 @@ void switch_mode(CPUState *env, int mode) > /* Handle a CPU exception. */ > void do_interrupt(CPUIA64State *env) > { > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > printf("%s: unexpect\n", __FUNCTION__); > exit(-1); > } > -#endif > } > > > diff --git a/qemu/target-ppc/cpu.h b/qemu/target-ppc/cpu.h > index 020f6de..53df331 100644 > --- a/qemu/target-ppc/cpu.h > +++ b/qemu/target-ppc/cpu.h > @@ -574,9 +574,7 @@ struct CPUPPCState { > /* temporary general purpose registers */ > ppc_gpr_t tgpr[4]; /* Used to speed-up TLB assist handlers */ > > -#ifdef USE_KVM > uint8_t ready_for_interrupt_injection; > -#endif > > /* Floating point execution context */ > /* temporary float registers */ > diff --git a/qemu/vl.c b/qemu/vl.c > index 4b44312..5f7f8d1 100644 > --- a/qemu/vl.c > +++ b/qemu/vl.c > @@ -133,9 +133,7 @@ int inet_aton(const char *cp, struct in_addr *ia); > > #include "exec-all.h" > > -#if USE_KVM > #include "qemu-kvm.h" > -#endif > > #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" > #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown" > @@ -265,15 +263,13 @@ extern char *logfilename; > > void decorate_application_name(char *appname, int max_len) > { > -#if USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > { > int remain = max_len - strlen(appname) - 1; > > if (remain > 0) > strncat(appname, "/KVM", remain); > } > -#endif > } > > /***********************************************************/ > @@ -6548,10 +6544,8 @@ void cpu_save(QEMUFile *f, void *opaque) > uint32_t hflags; > int i; > > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_save_registers(env); > -#endif > > for(i = 0; i < CPU_NB_REGS; i++) > qemu_put_betls(f, &env->regs[i]); > @@ -6638,15 +6632,12 @@ void cpu_save(QEMUFile *f, void *opaque) > #endif > qemu_put_be32s(f, &env->smbase); > > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > for (i = 0; i < NR_IRQ_WORDS ; i++) { > qemu_put_be32s(f, &env->kvm_interrupt_bitmap[i]); > } > qemu_put_be64s(f, &env->tsc); > } > -#endif > - > } > > #ifdef USE_X86LDOUBLE > @@ -6789,8 +6780,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) > /* XXX: compute hflags from scratch, except for CPL and IIF */ > env->hflags = hflags; > tlb_flush(env, 1); > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > /* when in-kernel irqchip is used, HF_HALTED_MASK causes deadlock > because no userspace IRQs will ever clear this flag */ > env->hflags &= ~HF_HALTED_MASK; > @@ -6800,7 +6790,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) > qemu_get_be64s(f, &env->tsc); > kvm_load_registers(env); > } > -#endif > return 0; > } > > @@ -7137,10 +7126,8 @@ static int ram_load_v1(QEMUFile *f, void *opaque) > if (qemu_get_be32(f) != phys_ram_size) > return -EINVAL; > for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ > continue; > -#endif > ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE); > if (ret) > return ret; > @@ -7275,10 +7262,8 @@ static void ram_save_live(QEMUFile *f, void *opaque) > target_ulong addr; > > for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ > continue; > -#endif > if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) { > qemu_put_be32(f, addr); > qemu_put_buffer(f, phys_ram_base + addr, TARGET_PAGE_SIZE); > @@ -7297,10 +7282,8 @@ static void ram_save_static(QEMUFile *f, void *opaque) > if (ram_compress_open(s, f) < 0) > return; > for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ > continue; > -#endif > #if 0 > if (tight_savevm_enabled) { > int64_t sector_num; > @@ -7372,10 +7355,8 @@ static int ram_load_static(QEMUFile *f, void *opaque) > if (ram_decompress_open(s, f) < 0) > return -EINVAL; > for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) { > -#ifdef USE_KVM > - if (kvm_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ > + if (kvm_enabled() && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ > continue; > -#endif > if (ram_decompress_buf(s, buf, 1) < 0) { > fprintf(stderr, "Error while reading ram block header\n"); > goto error; > @@ -7871,13 +7852,12 @@ static int main_loop(void) > CPUState *env; > > > -#ifdef USE_KVM > - if (kvm_allowed) { > + if (kvm_enabled()) { > kvm_main_loop(); > cpu_disable_ticks(); > return 0; > } > -#endif > + > cur_cpu = first_cpu; > next_cpu = cur_cpu->next_cpu ?: first_cpu; > for(;;) { > @@ -7919,10 +7899,8 @@ static int main_loop(void) > if (reset_requested) { > reset_requested = 0; > qemu_system_reset(); > -#ifdef USE_KVM > - if (kvm_allowed) > + if (kvm_enabled()) > kvm_load_register... [truncated message content] |
From: Zhang, X. <xia...@in...> - 2008-01-30 04:28:10
|
Scott Pakin wrote: > The attached patch corrects a bug in qemu/slirp/tcp_var.h that defines > the seg_next field in struct tcpcb to be 32 bits wide regardless of > 32/64-bitness. seg_next is assigned a pointer value in > qemu/slirp/tcp_subr.c, then cast back to a pointer in > qemu/slirp/tcp_input.c and dereferenced. That produces a SIGSEGV on > my system.=20 I still hit it on IA64 platform with your patch, once configured with slirp. =20 Thanks Xiantao |
From: Zhang, X. <xia...@in...> - 2008-01-30 02:36:59
|
Anthony Liguori wrote: > This patch attempts to clean up the interactions between KVM and > QEMU. Sorry=20 > for such a big patch, but I don't think there's a better way to > approach this=20 > such that it's still bisect friendly. I think this is most of what's > needed to=20 > get basic KVM support into QEMU though. >=20 > Right now, there's a mix of #ifdef USE_KVM, if (kvm_allowed), and > various=20 > extern declarations. It's all pretty fugly and there's a lot of > mistakes due=20 > to it. >=20 > The following patch eliminates almost all uses of #ifdef USE_KVM by > introducing=20 > a kvm_enabled() macro. If USE_KVM is set, this macro evaluates to > kvm_allowed.=20 > If USE_KVM isn't set, the macro evaluates to 0. >=20 > Since GCC eliminates if (0) blocks, this is just as good as using > #ifdef. By=20 > making sure that we never call into libkvm directly from QEMU, we can > also just=20 > not link qemu-kvm when USE_KVM isn't set instead of having the entire > file=20 > wrapped in a USE_KVM. >=20 > We also change the --enable-kvm configure option to --disable-kvm > since KVM is=20 > enabled by default. >=20 > I've tested this patch on x86 with 32-bit and 64-bit Linux guests and > a 32-bit=20 > Windows guest. I've also tested with USE_KVM not set. Jerone has > also=20 > verified that it doesn't PPC. My apologies if it breaks ia64 but I > have no=20 > way of testing that. Hi, Anthony=20 Good patch indeed! I have checked ia64 side, and It shouldn't break ia64. Thanks! Xiantao |
From: Hollis B. <ho...@us...> - 2008-01-29 23:20:30
|
On Tue, 2008-01-29 at 16:46 -0600, Anthony Liguori wrote: > The following patch eliminates almost all uses of #ifdef USE_KVM by > introducing a kvm_enabled() macro. If USE_KVM is set, this macro > evaluates to kvm_allowed. If USE_KVM isn't set, the macro evaluates to > 0. This is badly needed IMHO. Qemu seems to conform to the broken window theory... -- Hollis Blanchard IBM Linux Technology Center |
From: Anthony L. <ali...@us...> - 2008-01-29 22:46:55
|
This patch attempts to clean up the interactions between KVM and QEMU. Sorry for such a big patch, but I don't think there's a better way to approach this such that it's still bisect friendly. I think this is most of what's needed to get basic KVM support into QEMU though. Right now, there's a mix of #ifdef USE_KVM, if (kvm_allowed), and various extern declarations. It's all pretty fugly and there's a lot of mistakes due to it. The following patch eliminates almost all uses of #ifdef USE_KVM by introducing a kvm_enabled() macro. If USE_KVM is set, this macro evaluates to kvm_allowed. If USE_KVM isn't set, the macro evaluates to 0. Since GCC eliminates if (0) blocks, this is just as good as using #ifdef. By making sure that we never call into libkvm directly from QEMU, we can also just not link qemu-kvm when USE_KVM isn't set instead of having the entire file wrapped in a USE_KVM. We also change the --enable-kvm configure option to --disable-kvm since KVM is enabled by default. I've tested this patch on x86 with 32-bit and 64-bit Linux guests and a 32-bit Windows guest. I've also tested with USE_KVM not set. Jerone has also verified that it doesn't PPC. My apologies if it breaks ia64 but I have no way of testing that. Signed-off-by: Anthony Liguori <ali...@us...> diff --git a/configure b/configure index a000c62..6b20c2f 100755 --- a/configure +++ b/configure @@ -115,7 +115,7 @@ fi --disable-kqemu \ --extra-cflags="-I $PWD/../libkvm $qemu_cflags" \ --extra-ldflags="-L $PWD/../libkvm $qemu_ldflags" \ - --enable-kvm --kernel-path="$libkvm_kerneldir" \ + --kernel-path="$libkvm_kerneldir" \ --prefix="$prefix" \ ${qemu_cc:+"--cc=$qemu_cc"} \ ${cross_prefix:+"--cross-prefix=$cross_prefix"} \ diff --git a/qemu/Makefile.target b/qemu/Makefile.target index df43716..4458971 100644 --- a/qemu/Makefile.target +++ b/qemu/Makefile.target @@ -295,8 +295,12 @@ SRCS:= $(OBJS:.o=.c) OBJS+= libqemu.a # cpu emulator library -LIBOBJS=exec.o kqemu.o qemu-kvm.o translate-op.o translate-all.o cpu-exec.o\ +LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\ translate.o op.o host-utils.o +ifeq ($(USE_KVM), 1) +LIBOBJS+=qemu-kvm.o +endif + ifdef CONFIG_SOFTFLOAT LIBOBJS+=fpu/softfloat.o else @@ -306,20 +310,26 @@ CPPFLAGS+=-I$(SRC_PATH)/fpu ifeq ($(TARGET_ARCH), i386) LIBOBJS+=helper.o helper2.o +ifeq ($(USE_KVM), 1) LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o LIBOBJS+=qemu-kvm-helper.o endif +endif ifeq ($(TARGET_ARCH), x86_64) LIBOBJS+=helper.o helper2.o +ifeq ($(USE_KVM), 1) LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o LIBOBJS+=qemu-kvm-helper.o endif +endif ifeq ($(TARGET_BASE_ARCH), ppc) LIBOBJS+= op_helper.o helper.o +ifeq ($(USE_KVM), 1) LIBOBJS+= qemu-kvm-powerpc.o endif +endif ifeq ($(TARGET_BASE_ARCH), mips) LIBOBJS+= op_helper.o helper.o @@ -347,8 +357,10 @@ endif ifeq ($(TARGET_BASE_ARCH), ia64) LIBOBJS+=op_helper.o firmware.o +ifeq ($(USE_KVM), 1) LIBOBJS+=qemu-kvm-ia64.o endif +endif ifeq ($(TARGET_BASE_ARCH), cris) LIBOBJS+= op_helper.o helper.o diff --git a/qemu/block-raw-posix.c b/qemu/block-raw-posix.c index 7e0c39e..74657fb 100644 --- a/qemu/block-raw-posix.c +++ b/qemu/block-raw-posix.c @@ -346,8 +346,8 @@ void qemu_aio_wait_start(void) if (!aio_initialized) qemu_aio_init(); -#ifdef USE_KVM - if (kvm_allowed) { +#ifndef QEMU_IMG + if (kvm_enabled()) { qemu_kvm_aio_wait_start(); return; } @@ -365,9 +365,7 @@ void qemu_aio_wait(void) #ifndef QEMU_IMG if (qemu_bh_poll()) return; -#endif -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { qemu_kvm_aio_wait(); qemu_aio_poll(); return; @@ -381,8 +379,8 @@ void qemu_aio_wait(void) void qemu_aio_wait_end(void) { -#ifdef USE_KVM - if (kvm_allowed) { +#ifndef QEMU_IMG + if (kvm_enabled()) { qemu_kvm_aio_wait_end(); return; } diff --git a/qemu/configure b/qemu/configure index 78c35a4..bf624ed 100755 --- a/qemu/configure +++ b/qemu/configure @@ -300,7 +300,7 @@ for opt do ;; --disable-kqemu) kqemu="no" ;; - --enable-kvm) kvm="yes" + --disable-kvm) kvm="no" ;; --enable-profiler) profiler="yes" ;; @@ -415,7 +415,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]" @@ -1100,6 +1100,7 @@ configure_kvm() { if test $kvm = "yes" -a "$target_softmmu" = "yes" -a \ \( "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "ia64" -o "$cpu" = "powerpc" \); then echo "#define USE_KVM 1" >> $config_h + echo "USE_KVM=1" >> $config_mak echo "CONFIG_KVM_KERNEL_INC=$kernel_path/include" >> $config_mak fi } diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c index 42be8ec..9d05ef9 100644 --- a/qemu/cpu-exec.c +++ b/qemu/cpu-exec.c @@ -36,10 +36,7 @@ #include <sys/ucontext.h> #endif -#ifdef USE_KVM #include "qemu-kvm.h" -extern int kvm_allowed; -#endif int tb_invalidated_flag; @@ -487,12 +484,10 @@ int cpu_exec(CPUState *env1) } #endif -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { kvm_cpu_exec(env); longjmp(env->jmp_env, 1); } -#endif T0 = 0; /* force lookup of first TB */ for(;;) { SAVE_GLOBALS(); diff --git a/qemu/exec.c b/qemu/exec.c index f8e6713..06eaf62 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -35,10 +35,8 @@ #include "cpu.h" #include "exec-all.h" -#ifdef USE_KVM #include "dyngen.h" #include "qemu-kvm.h" -#endif #if defined(CONFIG_USER_ONLY) #include <qemu.h> #endif @@ -88,11 +86,6 @@ #define TARGET_PHYS_ADDR_SPACE_BITS 32 #endif -#ifdef USE_KVM -extern int kvm_allowed; -extern kvm_context_t kvm_context; -#endif - TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; int nb_tbs; @@ -1147,10 +1140,8 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc) return -1; env->breakpoints[env->nb_breakpoints++] = pc; -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_update_debugger(env); -#endif breakpoint_invalidate(env, pc); return 0; @@ -1174,10 +1165,8 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc) if (i < env->nb_breakpoints) env->breakpoints[i] = env->breakpoints[env->nb_breakpoints]; -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_update_debugger(env); -#endif breakpoint_invalidate(env, pc); return 0; @@ -1197,11 +1186,9 @@ void cpu_single_step(CPUState *env, int enabled) /* XXX: only flush what is necessary */ tb_flush(env); } -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_update_debugger(env); #endif -#endif } /* enable or disable low levels log */ @@ -1248,10 +1235,9 @@ void cpu_interrupt(CPUState *env, int mask) static int interrupt_lock; env->interrupt_request |= mask; -#ifdef USE_KVM - if (kvm_allowed && !kvm_irqchip_in_kernel(kvm_context)) + if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel()) kvm_update_interrupt_request(env); -#endif + /* if the cpu is currently executing code, we must unlink it and all the potentially executing TB */ tb = env->current_tb; @@ -1599,9 +1585,8 @@ int cpu_physical_memory_set_dirty_tracking(int enable) { int r=0; -#ifdef USE_KVM - r = kvm_physical_memory_set_dirty_tracking(enable); -#endif + if (kvm_enabled()) + r = kvm_physical_memory_set_dirty_tracking(enable); in_migration = enable; return r; } @@ -2662,11 +2647,11 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |= (0xff & ~CODE_DIRTY_FLAG); } -#ifdef USE_KVM /* qemu doesn't execute guest code directly, but kvm does therefore fluch instruction caches */ - flush_icache_range((unsigned long)ptr, ((unsigned long)ptr)+l); -#endif + if (kvm_enabled()) + flush_icache_range((unsigned long)ptr, + ((unsigned long)ptr)+l); } } else { if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && diff --git a/qemu/gdbstub.c b/qemu/gdbstub.c index 38b699f..2252084 100644 --- a/qemu/gdbstub.c +++ b/qemu/gdbstub.c @@ -894,9 +894,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) addr = strtoull(p, (char **)&p, 16); #if defined(TARGET_I386) env->eip = addr; -#ifdef USE_KVM - kvm_load_registers(env); -#endif + if (kvm_enabled()) + kvm_load_registers(env); #elif defined (TARGET_PPC) env->nip = addr; #elif defined (TARGET_SPARC) @@ -923,9 +922,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) addr = strtoull(p, (char **)&p, 16); #if defined(TARGET_I386) env->eip = addr; -#ifdef USE_KVM - kvm_load_registers(env); -#endif + if (kvm_enabled()) + kvm_load_registers(env); #elif defined (TARGET_PPC) env->nip = addr; #elif defined (TARGET_SPARC) @@ -977,9 +975,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) } break; case 'g': -#ifdef USE_KVM - kvm_save_registers(env); -#endif + if (kvm_enabled()) + kvm_save_registers(env); reg_size = cpu_gdb_read_registers(env, mem_buf); memtohex(buf, mem_buf, reg_size); put_packet(s, buf); @@ -989,9 +986,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); cpu_gdb_write_registers(env, mem_buf, len); -#ifdef USE_KVM - kvm_load_registers(env); -#endif + if (kvm_enabled()) + kvm_load_registers(env); put_packet(s, "OK"); break; case 'm': diff --git a/qemu/hw/apic.c b/qemu/hw/apic.c index a47c366..c26a18d 100644 --- a/qemu/hw/apic.c +++ b/qemu/hw/apic.c @@ -21,11 +21,7 @@ #include "pc.h" #include "qemu-timer.h" -#ifdef USE_KVM #include "qemu-kvm.h" -extern int kvm_allowed; -extern kvm_context_t kvm_context; -#endif //#define DEBUG_APIC //#define DEBUG_IOAPIC @@ -407,11 +403,10 @@ static void apic_init_ipi(APICState *s) s->initial_count = 0; s->initial_count_load_time = 0; s->next_time = 0; -#ifdef USE_KVM - if (kvm_allowed && !kvm_irqchip_in_kernel(kvm_context)) + + if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel()) if (s->cpu_env) kvm_apic_init(s->cpu_env); -#endif } /* send a SIPI message to the CPU to start it */ @@ -424,10 +419,8 @@ static void apic_startup(APICState *s, int vector_num) cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12, 0xffff, 0); env->hflags &= ~HF_HALTED_MASK; -#if USE_KVM - if (kvm_allowed && !kvm_irqchip_in_kernel(kvm_context)) + if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel()) kvm_update_after_sipi(env); -#endif } static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, @@ -753,8 +746,6 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) } } -#ifdef USE_KVM - #ifdef KVM_CAP_IRQCHIP static inline uint32_t kapic_reg(struct kvm_lapic_state *kapic, int reg_id) @@ -832,20 +823,16 @@ static void kvm_kernel_lapic_load_from_user(APICState *s) #endif -#endif - static void apic_save(QEMUFile *f, void *opaque) { APICState *s = opaque; int i; -#ifdef USE_KVM #ifdef KVM_CAP_IRQCHIP - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { kvm_kernel_lapic_save_to_user(s); } #endif -#endif qemu_put_be32s(f, &s->apicbase); qemu_put_8s(f, &s->id); @@ -910,13 +897,11 @@ static int apic_load(QEMUFile *f, void *opaque, int version_id) if (version_id >= 2) qemu_get_timer(f, s->timer); -#ifdef USE_KVM #ifdef KVM_CAP_IRQCHIP - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { kvm_kernel_lapic_load_from_user(s); } #endif -#endif return 0; } @@ -932,13 +917,11 @@ static void apic_reset(void *opaque) * processor when local APIC is enabled. */ s->lvt[APIC_LVT_LINT0] = 0x700; -#ifdef USE_KVM #ifdef KVM_CAP_IRQCHIP - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { kvm_kernel_lapic_load_from_user(s); } #endif -#endif } static CPUReadMemoryFunc *apic_mem_read[3] = { @@ -1131,7 +1114,6 @@ static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va } } -#ifdef USE_KVM static void kvm_kernel_ioapic_save_to_user(IOAPICState *s) { #if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386) @@ -1170,18 +1152,15 @@ static void kvm_kernel_ioapic_load_from_user(IOAPICState *s) kvm_set_irqchip(kvm_context, &chip); #endif } -#endif static void ioapic_save(QEMUFile *f, void *opaque) { IOAPICState *s = opaque; int i; -#ifdef USE_KVM - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { kvm_kernel_ioapic_save_to_user(s); } -#endif qemu_put_8s(f, &s->id); qemu_put_8s(f, &s->ioregsel); @@ -1204,11 +1183,9 @@ static int ioapic_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be64s(f, &s->ioredtbl[i]); } -#ifdef USE_KVM - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { kvm_kernel_ioapic_load_from_user(s); } -#endif return 0; } diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c index ee7ec1c..1915c73 100644 --- a/qemu/hw/cirrus_vga.c +++ b/qemu/hw/cirrus_vga.c @@ -34,6 +34,7 @@ #ifndef _WIN32 #include <sys/mman.h> #endif +#include "qemu-kvm.h" /* * TODO: @@ -237,13 +238,11 @@ typedef struct CirrusVGAState { int cirrus_linear_io_addr; int cirrus_linear_bitblt_io_addr; int cirrus_mmio_io_addr; -#ifdef USE_KVM unsigned long cirrus_lfb_addr; unsigned long cirrus_lfb_end; int aliases_enabled; uint32_t aliased_bank_base[2]; uint32_t aliased_bank_limit[2]; -#endif uint32_t cirrus_addr_mask; uint32_t linear_mmio_mask; uint8_t cirrus_shadow_gr0; @@ -2601,12 +2600,6 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = { cirrus_linear_bitblt_writel, }; -#ifdef USE_KVM - -#include "qemu-kvm.h" - -extern kvm_context_t kvm_context; - void *set_vram_mapping(unsigned long begin, unsigned long end) { void *vram_pointer = NULL; @@ -2616,8 +2609,8 @@ void *set_vram_mapping(unsigned long begin, unsigned long end) end = begin + VGA_RAM_SIZE; end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK; - vram_pointer = kvm_create_phys_mem(kvm_context, begin, end - begin, - 1, 1); + if (kvm_enabled()) + vram_pointer = kvm_cpu_create_phys_mem(begin, end - begin, 1, 1); if (vram_pointer == NULL) { printf("set_vram_mapping: cannot allocate memory: %m\n"); @@ -2636,7 +2629,8 @@ int unset_vram_mapping(unsigned long begin, unsigned long end) begin = begin & TARGET_PAGE_MASK; end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK; - kvm_destroy_phys_mem(kvm_context, begin, end - begin); + if (kvm_enabled()) + kvm_cpu_destroy_phys_mem(begin, end - begin); return 0; } @@ -2669,20 +2663,19 @@ static void kvm_update_vga_alias(CirrusVGAState *s, int ok, int bank, static void kvm_update_vga_aliases(CirrusVGAState *s, int ok) { - if (kvm_allowed) { + if (kvm_enabled()) { kvm_update_vga_alias(s, ok, 0, 0xc0000); kvm_update_vga_alias(s, ok, 1, s->map_addr); } s->aliases_enabled = ok; } #endif -#endif /* Compute the memory access functions */ static void cirrus_update_memory_access(CirrusVGAState *s) { unsigned mode; -#if defined(USE_KVM) && defined(CONFIG_X86) +#ifdef CONFIG_X86 int want_vga_alias = 0; #endif @@ -2699,8 +2692,7 @@ static void cirrus_update_memory_access(CirrusVGAState *s) mode = s->gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { -#ifdef USE_KVM - if (kvm_allowed && s->cirrus_lfb_addr && s->cirrus_lfb_end && + if (kvm_enabled() && s->cirrus_lfb_addr && s->cirrus_lfb_end && !s->map_addr) { void *vram_pointer, *old_vram; @@ -2717,21 +2709,19 @@ static void cirrus_update_memory_access(CirrusVGAState *s) s->map_end = s->cirrus_lfb_end; } #ifdef CONFIG_X86 - if (kvm_allowed + if (kvm_enabled() && !(s->cirrus_srcptr != s->cirrus_srcptr_end) && !((s->sr[0x07] & 0x01) == 0) && !((s->gr[0x0B] & 0x14) == 0x14) && !(s->gr[0x0B] & 0x02)) want_vga_alias = 1; #endif -#endif s->cirrus_linear_write[0] = cirrus_linear_mem_writeb; s->cirrus_linear_write[1] = cirrus_linear_mem_writew; s->cirrus_linear_write[2] = cirrus_linear_mem_writel; } else { generic_io: -#ifdef USE_KVM - if (kvm_allowed && s->cirrus_lfb_addr && s->cirrus_lfb_end && + if (kvm_enabled() && s->cirrus_lfb_addr && s->cirrus_lfb_end && s->map_addr) { int error; void *old_vram = NULL; @@ -2745,13 +2735,12 @@ static void cirrus_update_memory_access(CirrusVGAState *s) munmap(old_vram, s->map_end - s->map_addr); s->map_addr = s->map_end = 0; } -#endif s->cirrus_linear_write[0] = cirrus_linear_writeb; s->cirrus_linear_write[1] = cirrus_linear_writew; s->cirrus_linear_write[2] = cirrus_linear_writel; } } -#if defined(USE_KVM) && defined(CONFIG_X86) +#if defined(CONFIG_X86) kvm_update_vga_aliases(s, want_vga_alias); #endif @@ -3149,12 +3138,10 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque) /* XXX: we do not save the bitblt state - we assume we do not save the state when the blitter is active */ -#ifdef USE_KVM - if (kvm_allowed) { /* XXX: KVM images ought to be loadable in QEMU */ + if (kvm_enabled()) { /* XXX: KVM images ought to be loadable in QEMU */ qemu_put_be32s(f, &s->real_vram_size); qemu_put_buffer(f, s->vram_ptr, s->real_vram_size); } -#endif } static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) @@ -3205,8 +3192,7 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be32s(f, &s->hw_cursor_x); qemu_get_be32s(f, &s->hw_cursor_y); -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { int real_vram_size; qemu_get_be32s(f, &real_vram_size); if (real_vram_size != s->real_vram_size) { @@ -3218,7 +3204,6 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) qemu_get_buffer(f, s->vram_ptr, real_vram_size); cirrus_update_memory_access(s); } -#endif /* force refresh */ @@ -3376,8 +3361,7 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, /* XXX: add byte swapping apertures */ cpu_register_physical_memory(addr, s->vram_size, s->cirrus_linear_io_addr); -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { s->cirrus_lfb_addr = addr; s->cirrus_lfb_end = addr + VGA_RAM_SIZE; @@ -3385,7 +3369,6 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, (s->cirrus_lfb_end != s->map_end)) printf("cirrus vga map change while on lfb mode\n"); } -#endif cpu_register_physical_memory(addr + 0x1000000, 0x400000, s->cirrus_linear_bitblt_io_addr); diff --git a/qemu/hw/i8259.c b/qemu/hw/i8259.c index 071f9f1..b266119 100644 --- a/qemu/hw/i8259.c +++ b/qemu/hw/i8259.c @@ -26,9 +26,7 @@ #include "isa.h" #include "console.h" -#ifdef USE_KVM #include "qemu-kvm.h" -#endif /* debug PIC */ //#define DEBUG_PIC @@ -185,15 +183,11 @@ int64_t irq_time[16]; static void i8259_set_irq(void *opaque, int irq, int level) { PicState2 *s = opaque; -#ifdef USE_KVM #ifdef KVM_CAP_IRQCHIP - extern int kvm_set_irq(int irq, int level); - - if (kvm_allowed) + if (kvm_enabled()) if (kvm_set_irq(irq, level)) return; #endif -#endif #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) if (level != irq_level[irq]) { #if defined(DEBUG_PIC) @@ -477,11 +471,6 @@ static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1) return s->elcr; } -#ifdef USE_KVM -#include "qemu-kvm.h" -extern int kvm_allowed; -extern kvm_context_t kvm_context; - static void kvm_kernel_pic_save_to_user(PicState *s) { #if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386) @@ -544,17 +533,14 @@ static void kvm_kernel_pic_load_from_user(PicState *s) kvm_set_irqchip(kvm_context, &chip); #endif } -#endif static void pic_save(QEMUFile *f, void *opaque) { PicState *s = opaque; -#ifdef USE_KVM - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { kvm_kernel_pic_save_to_user(s); } -#endif qemu_put_8s(f, &s->last_irr); qemu_put_8s(f, &s->irr); @@ -598,11 +584,9 @@ static int pic_load(QEMUFile *f, void *opaque, int version_id) qemu_get_8s(f, &s->single_mode); qemu_get_8s(f, &s->elcr); -#ifdef USE_KVM - if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) { + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { kvm_kernel_pic_load_from_user(s); } -#endif return 0; } diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c index b1c1389..b5b48ac 100644 --- a/qemu/hw/ipf.c +++ b/qemu/hw/ipf.c @@ -40,10 +40,7 @@ #include "dyngen.h" #include <unistd.h> -#ifdef USE_KVM #include "qemu-kvm.h" -extern int kvm_allowed; -#endif #define FW_FILENAME "Flash.fd" @@ -309,11 +306,6 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) nb_ne2k++; } -#ifdef USE_KVM -extern kvm_context_t kvm_context; -extern int kvm_allowed; -#endif - /* Itanium hardware initialisation */ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, @@ -367,9 +359,8 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, } /* allocate RAM */ -#ifdef USE_KVM #ifdef KVM_CAP_USER_MEMORY - if (kvm_allowed && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { + if (kvm_enabled() && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { ram_addr = qemu_ram_alloc(0xa0000); cpu_register_physical_memory(0, 0xa0000, ram_addr); kvm_cpu_register_physical_memory(0, 0xa0000, ram_addr); @@ -386,7 +377,6 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, ram_addr); } else #endif -#endif { ram_addr = qemu_ram_alloc(ram_size); cpu_register_physical_memory(0, ram_size, ram_addr); @@ -398,16 +388,13 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, if (above_4g_mem_size > 0) { ram_addr = qemu_ram_alloc(above_4g_mem_size); cpu_register_physical_memory(0x100000000, above_4g_mem_size, ram_addr); -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_cpu_register_physical_memory(0x100000000, above_4g_mem_size, ram_addr); -#endif } /*Load firware to its proper position.*/ -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { int r; unsigned long image_size; char *image = NULL; @@ -446,7 +433,6 @@ static void ipf_init1(ram_addr_t ram_size, int vga_ram_size, (unsigned long)fw_image_start + image_size); kvm_ia64_build_hob(ram_size + above_4g_mem_size, smp_cpus, fw_start); } -#endif cpu_irq = qemu_allocate_irqs(pic_irq_request, first_cpu, 1); i8259 = i8259_init(cpu_irq[0]); diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c index 652b263..0e0d051 100644 --- a/qemu/hw/pc.c +++ b/qemu/hw/pc.c @@ -32,10 +32,7 @@ #include "smbus.h" #include "boards.h" -#ifdef USE_KVM #include "qemu-kvm.h" -extern int kvm_allowed; -#endif /* output Bochs bios info messages */ //#define DEBUG_BIOS @@ -711,11 +708,6 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) nb_ne2k++; } -#ifdef USE_KVM -extern kvm_context_t kvm_context; -extern int kvm_allowed; -#endif - static int load_option_rom(const char *filename, int offset) { ram_addr_t option_rom_offset; @@ -738,12 +730,10 @@ static int load_option_rom(const char *filename, int offset) size = (size + 4095) & ~4095; cpu_register_physical_memory(0xd0000 + offset, size, option_rom_offset | IO_MEM_ROM); -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_cpu_register_physical_memory(0xd0000 + offset, size, option_rom_offset | IO_MEM_ROM); -#endif return size; } @@ -806,9 +796,8 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, } /* allocate RAM */ -#ifdef USE_KVM - #ifdef KVM_CAP_USER_MEMORY - if (kvm_allowed && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { +#ifdef KVM_CAP_USER_MEMORY + if (kvm_enabled() && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) { ram_addr = qemu_ram_alloc(0xa0000); cpu_register_physical_memory(0, 0xa0000, ram_addr); kvm_cpu_register_physical_memory(0, 0xa0000, ram_addr); @@ -819,7 +808,6 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, kvm_cpu_register_physical_memory(0x100000, ram_size - 0x100000, ram_addr); } else - #endif #endif { ram_addr = qemu_ram_alloc(ram_size); @@ -867,21 +855,19 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, if (above_4g_mem_size > 0) { ram_addr = qemu_ram_alloc(above_4g_mem_size); cpu_register_physical_memory(0x100000000, above_4g_mem_size, ram_addr); -#ifdef USE_KVM - if (kvm_allowed) - kvm_cpu_register_physical_memory(0x100000000, above_4g_mem_size, - ram_addr); -#endif + + if (kvm_enabled()) + kvm_cpu_register_physical_memory(0x100000000, + above_4g_mem_size, + ram_addr); } /* setup basic memory access */ cpu_register_physical_memory(0xc0000, 0x10000, vga_bios_offset | IO_MEM_ROM); -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_cpu_register_physical_memory(0xc0000, 0x10000, vga_bios_offset | IO_MEM_ROM); -#endif /* map the last 128KB of the BIOS in ISA space */ isa_bios_size = bios_size; @@ -893,12 +879,10 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, cpu_register_physical_memory(0x100000 - isa_bios_size, isa_bios_size, (bios_offset + bios_size - isa_bios_size) /* | IO_MEM_ROM */); -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_cpu_register_physical_memory(0x100000 - isa_bios_size, isa_bios_size, (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); -#endif opt_rom_offset = 0; for (i = 0; i < nb_option_roms; i++) @@ -912,8 +896,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, /* map all the bios at the top of memory */ cpu_register_physical_memory((uint32_t)(-bios_size), bios_size, bios_offset | IO_MEM_ROM); -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { int r; #ifdef KVM_CAP_USER_MEMORY r = kvm_qemu_check_extension(KVM_CAP_USER_MEMORY); @@ -923,14 +906,13 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, else #endif { - bios_mem = kvm_create_phys_mem(kvm_context, (uint32_t)(-bios_size), - bios_size, 0, 1); + bios_mem = kvm_cpu_create_phys_mem((uint32_t)(-bios_size), + bios_size, 0, 1); if (!bios_mem) exit(1); memcpy(bios_mem, phys_ram_base + bios_offset, bios_size); } } -#endif bochs_bios_init(); diff --git a/qemu/hw/ppc440_bamboo.c b/qemu/hw/ppc440_bamboo.c index 29c2efc..d3c2bfd 100644 --- a/qemu/hw/ppc440_bamboo.c +++ b/qemu/hw/ppc440_bamboo.c @@ -12,9 +12,7 @@ #define KERNEL_LOAD_ADDR 0x400000 /* uboot loader puts kernel at 4MB */ -#if USE_KVM #include "qemu-kvm.h" -#endif /* PPC 440 refrence demo board * @@ -75,9 +73,9 @@ void bamboo_init(ram_addr_t ram_size, int vga_ram_size, /* Register mem */ cpu_register_physical_memory(0, ram_size, 0); -#if USE_KVM - kvm_cpu_register_physical_memory(0, ram_size, 0); -#endif + if (kvm_enabled()) + kvm_cpu_register_physical_memory(0, ram_size, 0); + /* load kernel with uboot loader */ printf("%s: load kernel\n", __func__); kernel_size = load_uboot(kernel_filename, &ep, &is_linux); @@ -101,18 +99,18 @@ void bamboo_init(ram_addr_t ram_size, int vga_ram_size, } } -#if USE_KVM - /* XXX insert TLB entries */ - env->gpr[1] = (16<<20) - 8; - env->gpr[4] = initrd_base; - env->gpr[5] = initrd_size; + if (kvm_enabled()) { + /* XXX insert TLB entries */ + env->gpr[1] = (16<<20) - 8; + env->gpr[4] = initrd_base; + env->gpr[5] = initrd_size; - env->nip = ep; + env->nip = ep; - env->cpu_index = 0; - printf("%s: loading kvm registers\n", __func__); - kvm_load_registers(env); -#endif + env->cpu_index = 0; + printf("%s: loading kvm registers\n", __func__); + kvm_load_registers(env); + } printf("%s: DONE\n", __func__); } diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c index 44e6834..222a39c 100644 --- a/qemu/hw/vga.c +++ b/qemu/hw/vga.c @@ -27,6 +27,7 @@ #include "pci.h" #include "vga_int.h" #include "pixel_ops.h" +#include "qemu-kvm.h" #include <sys/mman.h> @@ -1414,11 +1415,6 @@ void vga_invalidate_scanlines(VGAState *s, int y1, int y2) } } -#ifdef USE_KVM - -#include "libkvm.h" -extern kvm_context_t kvm_context; - static int bitmap_get_dirty(unsigned long *bitmap, unsigned nr) { unsigned word = nr / ((sizeof bitmap[0]) * 8); @@ -1428,11 +1424,6 @@ static int bitmap_get_dirty(unsigned long *bitmap, unsigned nr) return (bitmap[word] >> bit) & 1; } -#endif - -#ifdef USE_KVM -extern int kvm_allowed; -#endif /* * graphic modes @@ -1446,24 +1437,20 @@ static void vga_draw_graphic(VGAState *s, int full_update) uint32_t v, addr1, addr; long page0, page1, page_min, page_max; vga_draw_line_func *vga_draw_line; - -#ifdef USE_KVM - /* HACK ALERT */ -#define BITMAP_SIZE ((8*1024*1024) / 4096 / 8 / sizeof(long)) - unsigned long bitmap[BITMAP_SIZE]; +#define VGA_BITMAP_SIZE ((8*1024*1024) / 4096 / 8 / sizeof(long)) + unsigned long bitmap[VGA_BITMAP_SIZE]; #ifndef TARGET_IA64 int r; - if (kvm_allowed) { - r = kvm_get_dirty_pages(kvm_context, s->map_addr, &bitmap); + if (kvm_enabled()) { + r = qemu_kvm_get_dirty_pages(s->map_addr, &bitmap); if (r < 0) fprintf(stderr, "kvm: get_dirty_pages returned %d\n", r); } #else - memset(bitmap, 0xff, BITMAP_SIZE*sizeof(long)); + memset(bitmap, 0xff, VGA_BITMAP_SIZE*sizeof(long)); //FIXME:Always flush full screen before log dirty ready!! #endif -#endif full_update |= update_basic_params(s); @@ -1571,20 +1558,17 @@ static void vga_draw_graphic(VGAState *s, int full_update) update = full_update | cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS); update |= bitmap_get_dirty(bitmap, (page1 - s->vram_offset) >> TARGET_PAGE_BITS); } -#endif + if ((page1 - page0) > TARGET_PAGE_SIZE) { /* if wide line, can use another page */ update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, VGA_DIRTY_FLAG); -#ifdef USE_KVM - if (kvm_allowed) - update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS); -#endif + if (kvm_enabled()) + update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS); } /* explicit invalidation for the hardware cursor */ update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; @@ -1838,8 +1822,7 @@ static void vga_map(PCIDevice *pci_dev, int region_num, cpu_register_physical_memory(addr, s->bios_size, s->bios_offset); } else { cpu_register_physical_memory(addr, s->vram_size, s->vram_offset); -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { unsigned long vga_ram_begin, vga_ram_end; void *vram_pointer, *old_vram; @@ -1870,7 +1853,6 @@ static void vga_map(PCIDevice *pci_dev, int region_num, s->map_end = vga_ram_end; } } -#endif } } @@ -2037,14 +2019,10 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, vga_reset(s); -#ifndef USE_KVM - s->vram_ptr = vga_ram_base; -#else - if (kvm_allowed) - s->vram_ptr = qemu_malloc(vga_ram_size); + if (kvm_enabled()) + s->vram_ptr = qemu_malloc(vga_ram_size); else - s->vram_ptr = vga_ram_base; -#endif + s->vram_ptr = vga_ram_base; s->vram_offset = vga_ram_offset; s->vram_size = vga_ram_size; s->ds = ds; diff --git a/qemu/hw/vga_int.h b/qemu/hw/vga_int.h index f08700e..912d977 100644 --- a/qemu/hw/vga_int.h +++ b/qemu/hw/vga_int.h @@ -79,14 +79,6 @@ #define CH_ATTR_SIZE (160 * 100) #define VGA_MAX_HEIGHT 2048 -#ifdef USE_KVM -#define VGA_KVM_STATE \ - unsigned long map_addr; \ - unsigned long map_end; -#else -#define VGA_KVM_STATE -#endif - #define VGA_STATE_COMMON \ uint8_t *vram_ptr; \ unsigned long vram_offset; \ @@ -154,18 +146,17 @@ /* tell for each page if it has been updated since the last time */ \ uint32_t last_palette[256]; \ uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */ \ - VGA_KVM_STATE + unsigned long map_addr; \ + unsigned long map_end; typedef struct VGAState { VGA_STATE_COMMON -#ifdef USE_KVM int32_t aliases_enabled; int32_t pad1; uint32_t aliased_bank_base[2]; uint32_t aliased_bank_limit[2]; -#endif } VGAState; @@ -200,11 +191,9 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, unsigned int color0, unsigned int color1, unsigned int color_xor); -#ifdef USE_KVM /* let kvm create vga memory */ void *set_vram_mapping(unsigned long begin, unsigned long end); int unset_vram_mapping(unsigned long begin, unsigned long end); -#endif void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size); extern const uint8_t sr_mask[8]; diff --git a/qemu/hw/vmport.c b/qemu/hw/vmport.c index c225308..c09227d 100644 --- a/qemu/hw/vmport.c +++ b/qemu/hw/vmport.c @@ -26,7 +26,6 @@ #include "isa.h" #include "pc.h" #include "sysemu.h" -#include "libkvm.h" #include "qemu-kvm.h" #define VMPORT_CMD_GETVERSION 0x0a @@ -60,16 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) uint32_t eax; uint32_t ret; -#ifdef USE_KVM - struct kvm_regs regs; - extern kvm_context_t kvm_context; - if (kvm_allowed) { - kvm_get_regs(kvm_context, s->env->cpu_index, ®s); - s->env->regs[R_EAX] = regs.rax; s->env->regs[R_EBX] = regs.rbx; - s->env->regs[R_ECX] = regs.rcx; s->env->regs[R_EDX] = regs.rdx; - s->env->regs[R_ESI] = regs.rsi; s->env->regs[R_EDI] = regs.rdi; - } -#endif + if (kvm_enabled()) + kvm_save_registers(s->env); eax = s->env->regs[R_EAX]; if (eax != VMPORT_MAGIC) @@ -86,14 +77,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) ret = s->func[command](s->opaque[command], addr); -#ifdef USE_KVM - if (kvm_allowed) { - regs.rax = s->env->regs[R_EAX]; regs.rbx = s->env->regs[R_EBX]; - regs.rcx = s->env->regs[R_ECX]; regs.rdx = s->env->regs[R_EDX]; - regs.rsi = s->env->regs[R_ESI]; regs.rdi = s->env->regs[R_EDI]; - kvm_set_regs(kvm_context, s->env->cpu_index, ®s); - } -#endif + if (kvm_enabled()) + kvm_load_registers(s->env); return ret; } diff --git a/qemu/migration.c b/qemu/migration.c index df0acf9..23cff1e 100644 --- a/qemu/migration.c +++ b/qemu/migration.c @@ -29,9 +29,7 @@ #include "qemu-timer.h" #include "migration.h" #include "qemu_socket.h" -#ifdef USE_KVM #include "qemu-kvm.h" -#endif #include <sys/wait.h> @@ -185,10 +183,10 @@ static void migrate_finish(MigrationState *s) qemu_aio_flush(); } while (qemu_bh_poll()); bdrv_flush_all(); -#ifdef USE_KVM - if (kvm_allowed && !*s->has_error && kvm_update_dirty_pages_log()) + + if (kvm_enabled() && !*s->has_error && kvm_update_dirty_pages_log()) *s->has_error = MIG_STAT_KVM_UPDATE_DIRTY_PAGES_LOG_FAILED; -#endif + qemu_put_be32(f, 1); ret = qemu_live_savevm_state(f); #ifdef MIGRATION_VERIFY @@ -260,10 +258,8 @@ static int migrate_check_convergence(MigrationState *s) } for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ continue; -#endif if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) dirty_count++; } @@ -319,10 +315,8 @@ static void migrate_write(void *opaque) if (migrate_write_buffer(s)) return; -#ifdef USE_KVM - if (kvm_allowed && !*s->has_error && kvm_update_dirty_pages_log()) + if (kvm_enabled() && !*s->has_error && kvm_update_dirty_pages_log()) *s->has_error = MIG_STAT_KVM_UPDATE_DIRTY_PAGES_LOG_FAILED; -#endif if (migrate_check_convergence(s) || *s->has_error) { qemu_del_timer(s->timer); @@ -333,10 +327,8 @@ static void migrate_write(void *opaque) } while (s->addr < phys_ram_size) { -#ifdef USE_KVM - if (kvm_allowed && (s->addr>=0xa0000) && (s->addr<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (s->addr>=0xa0000) && (s->addr<0xc0000)) /* do not access video-addresses */ s->addr = 0xc0000; -#endif if (cpu_physical_memory_get_dirty(s->addr, MIGRATION_DIRTY_FLAG)) { migrate_prepare_page(s); @@ -404,11 +396,10 @@ static int start_migration(MigrationState *s) target_phys_addr_t addr; int r; unsigned char running = vm_running?2:1; /* 1 + vm_running */ - -#ifdef USE_KVM int n = 0; unsigned char *phys_ram_page_exist_bitmap = NULL; - if (kvm_allowed) { + + if (kvm_enabled()) { n = BITMAP_SIZE(phys_ram_size); phys_ram_page_exist_bitmap = qemu_malloc(n); if (!phys_ram_page_exist_bitmap) { @@ -422,7 +413,6 @@ static int start_migration(MigrationState *s) goto out; } } -#endif r = MIG_STAT_WRITE_FAILED; if (write_whole_buffer(s->fd, &running, sizeof(running))) { @@ -434,8 +424,7 @@ static int start_migration(MigrationState *s) goto out; } -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { value = cpu_to_be32(n); if (write_whole_buffer(s->fd, &value, sizeof(value))) { perror("phys_ram_size_bitmap size write failed"); @@ -446,18 +435,16 @@ static int start_migration(MigrationState *s) goto out; } } -#endif + fcntl(s->fd, F_SETFL, O_NONBLOCK); for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && !bit_is_set(addr>>TARGET_PAGE_BITS, phys_ram_page_exist_bitmap)) { + if (kvm_enabled() && !bit_is_set(addr>>TARGET_PAGE_BITS, phys_ram_page_exist_bitmap)) { cpu_physical_memory_reset_dirty(addr, addr + TARGET_PAGE_SIZE, MIGRATION_DIRTY_FLAG); continue; } -#endif if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) cpu_physical_memory_set_dirty(addr); } @@ -482,10 +469,8 @@ static int start_migration(MigrationState *s) r = 0; out: -#ifdef USE_KVM - if (phys_ram_page_exist_bitmap) + if (kvm_enabled() && phys_ram_page_exist_bitmap) qemu_free(phys_ram_page_exist_bitmap); -#endif return r; } @@ -825,8 +810,7 @@ static int migrate_incoming_fd(int fd) return MIG_STAT_DST_MEM_SIZE_MISMATCH; } -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { int n, m; unsigned char *phys_ram_page_exist_bitmap = NULL; @@ -848,7 +832,6 @@ static int migrate_incoming_fd(int fd) qemu_free(phys_ram_page_exist_bitmap); } -#endif do { addr = qemu_get_be32(f); @@ -1118,10 +1101,8 @@ static int save_verify_memory(QEMUFile *f, void *opaque) unsigned int sum; for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ continue; -#endif sum = calc_page_checksum(addr); qemu_put_be32(f, addr); qemu_put_be32(f, sum); @@ -1136,10 +1117,8 @@ static int load_verify_memory(QEMUFile *f, void *opaque, int version_id) int num_errors = 0; for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ continue; -#endif sum = calc_page_checksum(addr); raddr = qemu_get_be32(f); rsum = qemu_get_be32(f); diff --git a/qemu/monitor.c b/qemu/monitor.c index e03c473..e8022c8 100644 --- a/qemu/monitor.c +++ b/qemu/monitor.c @@ -286,9 +286,8 @@ static CPUState *mon_get_cpu(void) mon_set_cpu(0); } -#ifdef USE_KVM - kvm_save_registers(mon_cpu); -#endif + if (kvm_enabled()) + kvm_save_registers(mon_cpu); return mon_cpu; } diff --git a/qemu/osdep.c b/qemu/osdep.c index 6131438..0ec6446 100644 --- a/qemu/osdep.c +++ b/qemu/osdep.c @@ -113,7 +113,7 @@ static void *kqemu_vmalloc(size_t size) int64_t free_space; int ram_mb; - extern int ram_size; + extern int64_t ram_size; free_space = (int64_t)stfs.f_bavail * stfs.f_bsize; if ((ram_size + 8192 * 1024) >= free_space) { ram_mb = (ram_size / (1024 * 1024)); diff --git a/qemu/qemu-kvm-ia64.c b/qemu/qemu-kvm-ia64.c index d3d6ac7..a17e032 100644 --- a/qemu/qemu-kvm-ia64.c +++ b/qemu/qemu-kvm-ia64.c @@ -2,11 +2,6 @@ #include "config.h" #include "config-host.h" -extern int kvm_allowed; -extern int kvm_irqchip; - -#ifdef USE_KVM - #include <string.h> #include "hw/hw.h" @@ -68,4 +63,3 @@ int kvm_arch_try_push_interrupts(void *opaque) void kvm_arch_update_regs_for_sipi(CPUState *env) { } -#endif diff --git a/qemu/qemu-kvm-powerpc.c b/qemu/qemu-kvm-powerpc.c index 92aeada..60b0d87 100644 --- a/qemu/qemu-kvm-powerpc.c +++ b/qemu/qemu-kvm-powerpc.c @@ -2,11 +2,6 @@ #include "config.h" #include "config-host.h" -extern int kvm_allowed; -extern int kvm_irqchip; - -#ifdef USE_KVM - #include <string.h> #include "hw/hw.h" #include "sysemu.h" @@ -194,5 +189,3 @@ int handle_powerpc_dcr_write(int vcpu, uint32_t dcrn, uint32_t data) ppc_dcr_write(env->dcr_env, dcrn, data); return 0; /* XXX ignore failed DCR ops */ } - -#endif diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c index d1838f1..1880290 100644 --- a/qemu/qemu-kvm-x86.c +++ b/qemu/qemu-kvm-x86.c @@ -2,11 +2,6 @@ #include "config.h" #include "config-host.h" -extern int kvm_allowed; -extern int kvm_irqchip; - -#ifdef USE_KVM - #include <string.h> #include "hw/hw.h" @@ -631,5 +626,3 @@ int handle_tpr_access(void *opaque, int vcpu, kvm_tpr_access_report(cpu_single_env, rip, is_write); return 0; } - -#endif diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c index ec05027..3f12eda 100644 --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -2,17 +2,9 @@ #include "config.h" #include "config-host.h" -#ifdef USE_KVM - #define KVM_ALLOWED_DEFAULT 1 -#else - #define KVM_ALLOWED_DEFAULT 0 -#endif - -int kvm_allowed = KVM_ALLOWED_DEFAULT; +int kvm_allowed = 1; int kvm_irqchip = 1; -#ifdef USE_KVM - #include <string.h> #include "hw/hw.h" #include "sysemu.h" @@ -112,13 +104,13 @@ static int pre_kvm_run(void *opaque, int vcpu) void kvm_load_registers(CPUState *env) { - if (kvm_allowed) + if (kvm_enabled()) kvm_arch_load_regs(env); } void kvm_save_registers(CPUState *env) { - if (kvm_allowed) + if (kvm_enabled()) kvm_arch_save_regs(env); } @@ -647,7 +639,7 @@ int kvm_physical_memory_set_dirty_tracking(int enable) { int r = 0; - if (!kvm_allowed) + if (!kvm_enabled()) return 0; if (enable) { @@ -767,4 +759,19 @@ void qemu_kvm_aio_wait_end(void) { } -#endif +int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf) +{ + return kvm_get_dirty_pages(kvm_context, phys_addr, buf); +} + +void *kvm_cpu_create_phys_mem(target_phys_addr_t start_addr, + unsigned long size, int log, int writable) +{ + return kvm_create_phys_mem(kvm_context, start_addr, size, log, writable); +} + +void kvm_cpu_destroy_phys_mem(target_phys_addr_t start_addr, + unsigned long size) +{ + kvm_destroy_phys_mem(kvm_context, start_addr, size); +} diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h index 9b96951..a48efa3 100644 --- a/qemu/qemu-kvm.h +++ b/qemu/qemu-kvm.h @@ -2,7 +2,6 @@ #define QEMU_KVM_H #include "cpu.h" -#include "libkvm.h" int kvm_main_loop(void); int kvm_qemu_init(void); @@ -16,6 +15,7 @@ int kvm_update_debugger(CPUState *env); int kvm_qemu_init_env(CPUState *env); int kvm_qemu_check_extension(int ext); void kvm_apic_init(CPUState *env); +int kvm_set_irq(int irq, int level); int kvm_physical_memory_set_dirty_tracking(int enable); int kvm_update_dirty_pages_log(void); @@ -28,6 +28,12 @@ void kvm_update_interrupt_request(CPUState *env); void kvm_cpu_register_physical_memory(target_phys_addr_t start_addr, unsigned long size, unsigned long phys_offset); +void *kvm_cpu_create_phys_mem(target_phys_addr_t start_addr, + unsigned long size, int log, int writable); + +void kvm_cpu_destroy_phys_mem(target_phys_addr_t start_addr, + unsigned long size); + int kvm_arch_qemu_create_context(void); void kvm_arch_save_regs(CPUState *env); @@ -46,14 +52,13 @@ void qemu_kvm_aio_wait_start(void); void qemu_kvm_aio_wait(void); void qemu_kvm_aio_wait_end(void); -extern int kvm_allowed; -extern int kvm_irqchip; - void kvm_tpr_opt_setup(CPUState *env); void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write); int handle_tpr_access(void *opaque, int vcpu, uint64_t rip, int is_write); +int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf); + #ifdef TARGET_PPC int handle_powerpc_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data); int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data); @@ -62,5 +67,17 @@ int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data); #define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1)) #define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8) +#ifdef USE_KVM +#include "libkvm.h" + +extern int kvm_allowed; +extern kvm_context_t kvm_context; + +#define kvm_enabled() (kvm_allowed) +#define qemu_kvm_irqchip_in_kernel() kvm_irqchip_in_kernel(kvm_context) +#else +#define kvm_enabled() (0) +#define qemu_kvm_irqchip_in_kernel() (0) +#endif #endif diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h index 7143ab3..600464c 100644 --- a/qemu/target-i386/cpu.h +++ b/qemu/target-i386/cpu.h @@ -555,10 +555,8 @@ typedef struct CPUX86State { target_ulong kernelgsbase; #endif -#ifdef USE_KVM uint64_t tsc; /* time stamp counter */ uint8_t ready_for_interrupt_injection; -#endif uint64_t pat; /* exception/interrupt handling */ @@ -594,11 +592,9 @@ typedef struct CPUX86State { int last_io_time; #endif -#ifdef USE_KVM #define BITS_PER_LONG (8 * sizeof (uint32_t)) #define NR_IRQ_WORDS (256/ BITS_PER_LONG) uint32_t kvm_interrupt_bitmap[NR_IRQ_WORDS]; -#endif /* in order to simplify APIC support, we leave this pointer to the user */ diff --git a/qemu/target-i386/helper2.c b/qemu/target-i386/helper2.c index ac663aa..3ada676 100644 --- a/qemu/target-i386/helper2.c +++ b/qemu/target-i386/helper2.c @@ -29,9 +29,7 @@ #include "exec-all.h" #include "svm.h" -#ifdef USE_KVM -#include "../qemu-kvm.h" -#endif +#include "qemu-kvm.h" //#define DEBUG_MMU diff --git a/qemu/target-ia64/cpu.h b/qemu/target-ia64/cpu.h index 2d91cb9..97358ee 100644 --- a/qemu/target-ia64/cpu.h +++ b/qemu/target-ia64/cpu.h @@ -51,9 +51,7 @@ typedef struct CPUIA64State { int user_mode_only; uint32_t hflags; -#ifdef USE_KVM - uint8_t ready_for_interrupt_injection; -#endif + uint8_t ready_for_interrupt_injection; } CPUIA64State; diff --git a/qemu/target-ia64/op_helper.c b/qemu/target-ia64/op_helper.c index 5138af5..8660b17 100644 --- a/qemu/target-ia64/op_helper.c +++ b/qemu/target-ia64/op_helper.c @@ -24,7 +24,7 @@ #include "cpu.h" #include "exec-all.h" -extern int kvm_allowed; +#include "qemu-kvm.h" CPUState *cpu_ia64_init(char *cpu_model){ CPUState *env; @@ -33,14 +33,10 @@ CPUState *cpu_ia64_init(char *cpu_model){ return NULL; cpu_exec_init(env); cpu_reset(env); -#ifdef USE_KVM - { - if (kvm_allowed) { - kvm_qemu_init_env(env); - env->ready_for_interrupt_injection = 1; - } + if (kvm_enabled()) { + kvm_qemu_init_env(env); + env->ready_for_interrupt_injection = 1; } -#endif return env; } @@ -74,12 +70,10 @@ void switch_mode(CPUState *env, int mode) /* Handle a CPU exception. */ void do_interrupt(CPUIA64State *env) { -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { printf("%s: unexpect\n", __FUNCTION__); exit(-1); } -#endif } diff --git a/qemu/target-ppc/cpu.h b/qemu/target-ppc/cpu.h index 020f6de..53df331 100644 --- a/qemu/target-ppc/cpu.h +++ b/qemu/target-ppc/cpu.h @@ -574,9 +574,7 @@ struct CPUPPCState { /* temporary general purpose registers */ ppc_gpr_t tgpr[4]; /* Used to speed-up TLB assist handlers */ -#ifdef USE_KVM uint8_t ready_for_interrupt_injection; -#endif /* Floating point execution context */ /* temporary float registers */ diff --git a/qemu/vl.c b/qemu/vl.c index 4b44312..5f7f8d1 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -133,9 +133,7 @@ int inet_aton(const char *cp, struct in_addr *ia); #include "exec-all.h" -#if USE_KVM #include "qemu-kvm.h" -#endif #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown" @@ -265,15 +263,13 @@ extern char *logfilename; void decorate_application_name(char *appname, int max_len) { -#if USE_KVM - if (kvm_allowed) + if (kvm_enabled()) { int remain = max_len - strlen(appname) - 1; if (remain > 0) strncat(appname, "/KVM", remain); } -#endif } /***********************************************************/ @@ -6548,10 +6544,8 @@ void cpu_save(QEMUFile *f, void *opaque) uint32_t hflags; int i; -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_save_registers(env); -#endif for(i = 0; i < CPU_NB_REGS; i++) qemu_put_betls(f, &env->regs[i]); @@ -6638,15 +6632,12 @@ void cpu_save(QEMUFile *f, void *opaque) #endif qemu_put_be32s(f, &env->smbase); -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { for (i = 0; i < NR_IRQ_WORDS ; i++) { qemu_put_be32s(f, &env->kvm_interrupt_bitmap[i]); } qemu_put_be64s(f, &env->tsc); } -#endif - } #ifdef USE_X86LDOUBLE @@ -6789,8 +6780,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) /* XXX: compute hflags from scratch, except for CPL and IIF */ env->hflags = hflags; tlb_flush(env, 1); -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { /* when in-kernel irqchip is used, HF_HALTED_MASK causes deadlock because no userspace IRQs will ever clear this flag */ env->hflags &= ~HF_HALTED_MASK; @@ -6800,7 +6790,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be64s(f, &env->tsc); kvm_load_registers(env); } -#endif return 0; } @@ -7137,10 +7126,8 @@ static int ram_load_v1(QEMUFile *f, void *opaque) if (qemu_get_be32(f) != phys_ram_size) return -EINVAL; for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ continue; -#endif ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE); if (ret) return ret; @@ -7275,10 +7262,8 @@ static void ram_save_live(QEMUFile *f, void *opaque) target_ulong addr; for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (addr>=0xa0000) && (addr<0xc0000)) /* do not access video-addresses */ continue; -#endif if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) { qemu_put_be32(f, addr); qemu_put_buffer(f, phys_ram_base + addr, TARGET_PAGE_SIZE); @@ -7297,10 +7282,8 @@ static void ram_save_static(QEMUFile *f, void *opaque) if (ram_compress_open(s, f) < 0) return; for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ continue; -#endif #if 0 if (tight_savevm_enabled) { int64_t sector_num; @@ -7372,10 +7355,8 @@ static int ram_load_static(QEMUFile *f, void *opaque) if (ram_decompress_open(s, f) < 0) return -EINVAL; for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) { -#ifdef USE_KVM - if (kvm_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ + if (kvm_enabled() && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */ continue; -#endif if (ram_decompress_buf(s, buf, 1) < 0) { fprintf(stderr, "Error while reading ram block header\n"); goto error; @@ -7871,13 +7852,12 @@ static int main_loop(void) CPUState *env; -#ifdef USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { kvm_main_loop(); cpu_disable_ticks(); return 0; } -#endif + cur_cpu = first_cpu; next_cpu = cur_cpu->next_cpu ?: first_cpu; for(;;) { @@ -7919,10 +7899,8 @@ static int main_loop(void) if (reset_requested) { reset_requested = 0; qemu_system_reset(); -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_load_registers(env); -#endif ret = EXCP_INTERRUPT; } if (powerdown_requested) { @@ -9118,9 +9096,11 @@ int main(int argc, char **argv) case QEMU_OPTION_no_kvm: kvm_allowed = 0; break; - case QEMU_OPTION_no_kvm_irqchip: + case QEMU_OPTION_no_kvm_irqchip: { + extern int kvm_irqchip; kvm_irqchip = 0; break; + } #endif case QEMU_OPTION_usb: usb_enabled = 1; @@ -9301,8 +9281,9 @@ int main(int argc, char **argv) #endif #if USE_KVM - if (kvm_allowed) { + if (kvm_enabled()) { if (kvm_qemu_init() < 0) { + extern int kvm_allowed; fprintf(stderr, "Could not initialize KVM, will disable KVM support\n"); kvm_allowed = 0; } @@ -9403,14 +9384,13 @@ int main(int argc, char **argv) /* init the memory */ phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE; -#if USE_KVM /* Initialize kvm */ #if defined(TARGET_I386) || defined(TARGET_X86_64) #define KVM_EXTRA_PAGES 3 #else #define KVM_EXTRA_PAGES 0 #endif - if (kvm_allowed) { + if (kvm_enabled()) { phys_ram_size += KVM_EXTRA_PAGES * TARGET_PAGE_SIZE; if (kvm_qemu_create_context() < 0) { fprintf(stderr, "Could not create KVM context\n"); @@ -9437,13 +9417,6 @@ int main(int argc, char **argv) exit(1); } } -#else - phys_ram_base = qemu_vmalloc(phys_ram_size); - if (!phys_ram_base) { - fprintf(stderr, "Could not allocate physical memory\n"); - exit(1); - } -#endif bdrv_init(); @@ -9585,10 +9558,8 @@ int main(int argc, char **argv) qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock)); } -#ifdef USE_KVM - if (kvm_allowed) + if (kvm_enabled()) kvm_init_ap(); -#endif #ifdef CONFIG_GDBSTUB if (use_gdbstub) { |
From: Zhang, X. <xia...@in...> - 2008-01-28 03:49:59
|
Sure, Changed, Thanks:) Xiantao Akio Takebe wrote: > Hi, Xiantao and Anthony >=20 > Good news! > Could you update lists page of wiki? > http://kvm.qumranet.com/kvmwiki/Lists%2C_IRC >=20 > Best Regards, >=20 > Akio Takebe >=20 >> Hi, guys >> We have created kvm-ia64-devel mailing list for discussing >> ia64-specific topics. Cheers!! If you have topics which only >> belongs to ia64, please use this list! But if you have any >> cross-arch questions or topics, please cc kvm-devel for involving >> more persons in. We will open the latest source to Avi's tree in >> near future. But considering possible stability issues, we will put >> them in a separate branch for a while(Thanks Avi!). From the long >> run, we will create a separate git repo after the first merge. If >> you would like to contribute kvm/ia64, please send the patches or >> fixes to this list, and had better cc to Anthony >> Xu(ant...@in...) and Xiantao Zhang (xia...@in...) >> for review. Hope to work happily with you guys in future!=20 >>=20 >> BTW, Anthony and I will co-maintain kvm/ia64 project, and please >> extend your hands to help us, and make kvm/ia64 stronger and >> stronger!=20 >> Thank you for your interest & Appreciate your contributions! :) >>=20 >> Thanks >> Xiantao >>=20 >> ------------------------------------------------------------------------ - >> This SF.net email is sponsored by: Microsoft >> Defy all challenges. Microsoft(R) Visual Studio 2008. >> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ >> _______________________________________________ >> kvm-devel mailing list >> kvm...@li... >> https://lists.sourceforge.net/lists/listinfo/kvm-devel >=20 >=20 > ------------------------------------------------------------------------ - > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > kvm-ia64-devel mailing list > kvm...@li... > https://lists.sourceforge.net/lists/listinfo/kvm-ia64-devel |
From: Akio T. <tak...@jp...> - 2008-01-28 03:00:32
|
Hi, Xiantao and Anthony Good news! Could you update lists page of wiki? http://kvm.qumranet.com/kvmwiki/Lists%2C_IRC Best Regards, Akio Takebe >Hi, guys > We have created kvm-ia64-devel mailing list for discussing >ia64-specific topics. Cheers!! If you have topics which only belongs to >ia64, please use this list! But if you have any cross-arch questions or >topics, please cc kvm-devel for involving more persons in. > We will open the latest source to Avi's tree in near future. But >considering possible stability issues, we will put them in a separate >branch for a while(Thanks Avi!). From the long run, we will create a >separate git repo after the first merge. If you would like to >contribute kvm/ia64, please send the patches or fixes to this list, and >had better cc to Anthony Xu(ant...@in...) and Xiantao Zhang >(xia...@in...) for review. Hope to work happily with you >guys in future! > >BTW, Anthony and I will co-maintain kvm/ia64 project, and please extend >your hands to help us, and make kvm/ia64 stronger and stronger! >Thank you for your interest & Appreciate your contributions! :) > >Thanks >Xiantao > >------------------------------------------------------------------------- >This SF.net email is sponsored by: Microsoft >Defy all challenges. Microsoft(R) Visual Studio 2008. >http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ >_______________________________________________ >kvm-devel mailing list >kvm...@li... >https://lists.sourceforge.net/lists/listinfo/kvm-devel |
From: Zhang, X. <xia...@in...> - 2008-01-28 02:19:17
|
Hi, guys We have created kvm-ia64-devel mailing list for discussing ia64-specific topics. Cheers!! If you have topics which only belongs to ia64, please use this list! But if you have any cross-arch questions or topics, please cc kvm-devel for involving more persons in. We will open the latest source to Avi's tree in near future. But considering possible stability issues, we will put them in a separate branch for a while(Thanks Avi!). From the long run, we will create a separate git repo after the first merge. If you would like to contribute kvm/ia64, please send the patches or fixes to this list, and had better cc to Anthony Xu(ant...@in...) and Xiantao Zhang (xia...@in...) for review. Hope to work happily with you guys in future! BTW, Anthony and I will co-maintain kvm/ia64 project, and please extend your hands to help us, and make kvm/ia64 stronger and stronger! Thank you for your interest & Appreciate your contributions! :) Thanks Xiantao |