ia64/xen-unstable

changeset 8708:f1b361b05bf3

Big merge the HVM full-virtualisation abstractions.

This changeset contains all differences between
xen-unstable.hg and xen-unstable-hvm.hg.

All information and comments for changesets unique to
xen-unstable-hvm.hg are included below.

Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
Signed-off-by: Keir Fraser <keir@xensource.com>

> user: leendert@eserver2.watson.ibm.com
> date: Tue Jan 31 04:29:51 2006 -0400
> files: xen/include/asm-ia64/mm.h
> description:
> Fix ia64 compile.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Tue Jan 31 02:21:49 2006 -0400
> files: xen/include/xen/domain_page.h
> description:
> Eliminate unused fields (pfn,va) warnings.
>
> Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Fri Jan 27 04:31:44 2006 -0400
> files: tools/python/xen/xend/image.py
> description:
> Name cleanup. vmx refers to VT-x specific code, HVM is used for all others.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: root@xen-trw1.amd.com
> date: Sun Jan 22 18:39:58 2006 -0500
> files: xen/arch/x86/hvm/platform.c
> description:
> support prefix 0x67 in hvm decode logic, gfxboot patch causes 0x67 prefix.
>
>
> user: twoller@xen-trw1.amd.com
> date: Sun Jan 22 18:35:59 2006 -0500
> files: xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/include/asm-x86/hvm/svm/svm.h
> description:
> check for valid shared_page_va/vmcb before deallocating in SVM.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Jan 22 02:56:20 2006 -0400
> files: xen/include/asm-x86/hvm/svm/svm.h xen/include/asm-x86/hvm/svm/vmmcall.h
> description:
> Some SVM header file cleanups.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Fri Jan 20 11:50:23 2006 -0400
> files: xen/arch/x86/domain.c
> description:
> Need to be more diligent about when to call into the HVM abstraction layer
> and when not.
>
> Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Wed Jan 18 15:14:56 2006 -0400
> files: xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/x86_32/exits.S xen/arch/x86/hvm/svm/x86_64/exits.S xen/arch/x86/hvm/vmx/x86_32/exits.S xen/arch/x86/hvm/vmx/x86_64/exits.S
> description:
> Added missing copyright statements and updated svm.c's copyright to properly
> reflect that it was derived from vmx.c.
>
> Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Tue Jan 17 09:42:11 2006 -0400
> files: xen/arch/ia64/Makefile xen/arch/ia64/vmx/vlsapic.c xen/arch/ia64/vmx/vmx_init.c xen/include/asm-ia64/vmx_platform.h
> description:
> Make sure ia64 builds again with the new directory structure.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@localhost.localdomain
> date: Tue Jan 17 08:28:51 2006 -0400
> files: xen/arch/x86/Makefile xen/arch/x86/hvm/i8259.c xen/arch/x86/hvm/vioapic.c
> description:
> The device models now belong in hvm.
>
> Signed-ff-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Jan 15 16:40:58 2006 -0400
> files: xen/arch/x86/Makefile xen/arch/x86/cpu/amd.c xen/arch/x86/cpu/intel.c xen/arch/x86/dm/hvm_vioapic.c xen/arch/x86/dm/i8259.c xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/svm/emulate.c xen/arch/x86/hvm/svm/instrlen.c xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/arch/x86/hvm/svm/x86_32/exits.S xen/arch/x86/hvm/svm/x86_64/exits.S xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/io.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/hvm/vmx/x86_32/exits.S xen/arch/x86/hvm/vmx/x86_64/exits.S xen/arch/x86/i387.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/traps.c xen/include/asm-x86/domain.h xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/support.h xen/include/asm-x86/hvm/svm/emulate.h xen/include/asm-x86/hvm/svm/intr.h xen/include/asm-x86/hvm/svm/svm.h xen/include/asm-x86/hvm/svm/vmcb.h xen/include/asm-x86/hvm/svm/vmmcall.h xen/include/asm-x86/hvm/vcpu.h xen/include/asm-x86/hvm/vioapic.h xen/include/asm-x86/hvm/vlapic.h xen/include/asm-x86/hvm/vmx/cpu.h xen/include/asm-x86/hvm/vmx/vmcs.h xen/include/asm-x86/hvm/vmx/vmx.h xen/include/asm-x86/hvm/vpic.h xen/include/asm-x86/hvm/vpit.h xen/include/asm-x86/shadow.h
> description:
> As suggested by Keir, I restructured the hvm/vmx/svm tree. The new
> directory structure looks like:
>
> xen/arch/hvm/
> xen/arch/hvm/vmx
> xen/arch/hvm/vmx/x86_32
> xen/arch/hvm/vmx/x86_64
> xen/arch/hvm/svm
> xen/arch/hvm/svm/x86_32
> xen/arch/hvm/svm/x86_64
>
> xen/include/hvm/
> xen/include/hvm/vmx
> xen/include/hvm/svm
>
> Many files have been renamed and had their hvm_/vmx_/svm_ suffix removed
> because this is now clear from the directory where the file resides.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sat Jan 14 17:03:28 2006 -0400
> files: xen/arch/ia64/vmx/vlsapic.c xen/include/asm-ia64/vmx_platform.h
> description:
> Name change fix for ia64.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sat Jan 14 15:12:59 2006 -0400
> files: xen/arch/x86/dm/hvm_vioapic.c xen/arch/x86/dm/i8259.c xen/arch/x86/hvm.c xen/arch/x86/hvm_intercept.c xen/arch/x86/svm.c xen/arch/x86/svm_intr.c xen/arch/x86/svm_vmcb.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/hvm_domain.h xen/include/asm-x86/hvm_vcpu.h
> description:
> Move VMX/SVM print buffer to hvm_domain.
>
> Cleanup variable names. The suffix hvm_ is redundant in hvm_domain.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: twoller@xen-trw1.site
> date: Fri Jan 13 17:03:18 2006 -0500
> files: xen/arch/x86/svm.c
> description:
> remove unnecessary spin_unlock in asid_fetch code for svm.
>
>
> user: twoller@xen-trw1.site
> date: Wed Jan 11 20:00:36 2006 -0500
> files: xen/arch/x86/svm.c
> description:
> remove unneeded update_pagetables() during svm PF handling (resolved with ASID code rework).
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Tue Jan 10 02:45:32 2006 -0400
> files: xen/arch/x86/hvm.c xen/arch/x86/vmx_io.c
> description:
> Factor out cpu_get_interrupt(). It is used by VMX and SVM.
>
> Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Mon Jan 9 00:03:30 2006 -0400
> files: xen/arch/x86/hvm.c xen/arch/x86/svm.c xen/arch/x86/vmx.c xen/include/asm-x86/hvm_support.h xen/include/asm-x86/hvm_vcpu.h
> description:
> Introduce small print buffer per domain rather than a single global one.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Jan 8 23:07:12 2006 -0400
> files: xen/arch/x86/dom0_ops.c xen/include/asm-x86/hvm_support.h xen/include/public/arch-x86_32.h xen/include/public/arch-x86_64.h
> description:
> More cleanup. There is no point in distinguishing between SVM and VMX,
> a single HVM flag bit suffices.
>
> Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Jan 8 12:05:59 2006 -0400
> files: xen/arch/x86/svm.c xen/arch/x86/vmx.c
> description:
> Both VMX & SVM now print writes to the debug port (0xE9) on the console.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sat Jan 7 13:55:27 2006 -0400
> files: xen/arch/x86/svm.c xen/arch/x86/svm_intr.c xen/arch/x86/svm_vmcb.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_64/asm-offsets.c xen/include/asm-x86/domain.h xen/include/asm-x86/vmx.h
> description:
> Introduce shorthands to improve code legibility.
>
> Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Wed Jan 4 06:12:10 2006 -0400
> files: tools/examples/xmexample.hvm
> description:
> Minor spelling mistakes.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Wed Jan 4 03:37:55 2006 -0400
> files: xen/include/public/hvm/hvm_info_table.h xen/include/public/hvm/ioreq.h xen/include/public/hvm/vmx_assist.h
> description:
> Missed adding new files.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Mon Jan 2 01:23:54 2006 -0400
> files: tools/debugger/libxendebug/xendebug.c tools/libxc/xc_hvm_build.c
> description:
> Finalize Xin Li's patch: vmx/svm_identify is no longer necessary.
> Xen debug should test for HVM instead of VMX.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: twoller@xen-trw1.site
> date: Sun Jan 1 03:22:39 2006 -0500
> files: tools/ioemu/vl.c
> description:
> change hardcoded VTXEN to HVMXEN.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Jan 1 02:22:47 2006 -0400
> files: tools/libxc/xc_hvm_build.c tools/python/xen/xend/image.py xen/arch/x86/domain.c
> description:
> Avoid xen crash if there is no VMX support. If a platform
> doesn't support VMX, creating VMX domain will crash xen
> HV.
>
> Signed-off-by: Xin Li <xin.b.li@intel.com>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
> [ vmx/svm_identify are still needed in hvm builder, but this may not
> really be necessary. I need to check this. - lvd ]
>
>
> user: twoller@xen-trw1.site
> date: Fri Dec 30 21:38:56 2005 -0500
> files: xen/arch/x86/svm.c xen/arch/x86/svm_vmcb.c xen/arch/x86/x86_32/entry.S xen/include/asm-x86/svm.h xen/include/asm-x86/svm_vmcb.h
> description:
> add multi-core support for guest ASIDs for SVM partitions.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Dec 25 20:44:43 2005 -0400
> files: tools/firmware/vmxassist/head.S
> description:
> Make sure vmxassist still works in its debug environment.
>
> Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Fri Dec 23 18:27:57 2005 -0400
> files: tools/libxc/xc_ia64_stubs.c
> description:
> Fixed libxc ia64, xend uses xc_hvm_build instead of xc_vmx_build.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: twoller@xen-trw1.site
> date: Wed Dec 21 21:39:17 2005 -0500
> files: xen/arch/x86/svm_intr.c xen/arch/x86/svm_vmcb.c
> description:
> cleanup of svm specific code.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Wed Dec 21 17:18:25 2005 -0400
> files: tools/python/xen/xm/tests/test_create.py tools/xm-test/README
> description:
> Minor name cleanups. xm-test isn't VMX specific. Instead use HVM.
>
>
> user: twoller@xen-trw1.site
> date: Tue Dec 20 20:01:38 2005 -0500
> files: xen/arch/x86/svm_vmcb.c
> description:
> reword comments.
>
>
> user: twoller@xen-trw1.site
> date: Tue Dec 20 20:01:07 2005 -0500
> files: xen/arch/x86/svm_intr.c
> description:
> add additional VLAPIC delivery modes.
>
>
> user: twoller@xen-trw1.site
> date: Tue Dec 20 20:00:22 2005 -0500
> files: xen/arch/x86/svm.c
> description:
> reformat misaligned code.
>
>
> user: twoller@xen-trw1.site
> date: Tue Dec 20 19:59:37 2005 -0500
> files: xen/arch/x86/svm.c
> description:
> Add additional AMD SVM specific CPUID logic.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Thu Dec 15 03:06:15 2005 -0400
> files: tools/xm-test/tests/block-create/01_block_attach_device_pos.py tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py tools/xm-test/tests/block-create/06_block_attach_baddomain_neg.py tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py tools/xm-test/tests/block-create/12_block_attach_shared_domU.py tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py tools/xm-test/tests/block-list/01_block-list_pos.py tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py tools/xm-test/tests/block-list/04_block-list_nodb_pos.py tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py tools/xm-test/tests/memmax/01_memmax_badparm_neg.py tools/xm-test/tests/memset/01_memset_basic_pos.py tools/xm-test/tests/memset/02_memset_badparm_neg.py tools/xm-test/tests/memset/03_memset_random_pos.py tools/xm-test/tests/memset/04_memset_smallmem_pos.py tools/xm-test/tests/migrate/01_migrate_localhost_pos.py tools/xm-test/tests/network-attach/01_network_attach_pos.py tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py tools/xm-test/tests/restore/01_restore_basic_pos.py tools/xm-test/tests/restore/02_restore_badparm_neg.py tools/xm-test/tests/restore/03_restore_badfilename_neg.py tools/xm-test/tests/restore/04_restore_withdevices_pos.py tools/xm-test/tests/save/01_save_basic_pos.py tools/xm-test/tests/save/02_save_badparm_neg.py tools/xm-test/tests/save/03_save_bogusfile_neg.py tools/xm-test/tests/sysrq/01_sysrq_basic_neg.py tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py
> description:
> Adding SKIP() to tests that aren't supported for VMX domains.
>
> Signed-off-by: Dan Stekloff <dsteklof@us.ibm.com>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Tue Dec 13 22:43:47 2005 -0400
> files: xen/arch/x86/svm.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/include/asm-x86/hvm_vpit.h xen/include/asm-x86/msr.h
> description:
> Support VMX guest accesses to IA32_TIME_STAMP_COUNTER MSR.
>
> Signed-off-by: Haifeng Xue <haifeng.xue@intel.com>
> Signed-off-by: Leendert van Doorn <leendert@us.ibm.com>
>
>
> user: twoller@xen-trw1.site
> date: Tue Dec 13 19:49:53 2005 -0500
> files: xen/arch/x86/svm.c xen/arch/x86/svm_emulate.c xen/arch/x86/svm_instrlen.c xen/arch/x86/svm_intr.c xen/arch/x86/svm_vmcb.c xen/include/asm-x86/svm.h xen/include/asm-x86/svm_emulate.h xen/include/asm-x86/svm_intr.h xen/include/asm-x86/svm_vmcb.h xen/include/asm-x86/svm_vmmcall.h
> description:
> Add SVM base files to repository.
>
>
> user: twoller@xen-trw1.site
> date: Tue Dec 13 19:49:02 2005 -0500
> files: xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/entry.S
> description:
> Add SVM entry points for launch/resume.
>
>
> user: twoller@xen-trw1.site
> date: Tue Dec 13 19:47:38 2005 -0500
> files: .hgignore
> description:
> Add hvmloader files to ignore list.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Mon Dec 12 22:58:54 2005 -0400
> files: docs/src/user.tex tools/firmware/README xen/include/asm-x86/hvm.h
> description:
> Removed dirty words (by request).
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Mon Dec 12 05:48:22 2005 -0400
> files: tools/firmware/hvmloader/mkhex
> description:
> Fix file mode.
>
> Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Mon Dec 12 04:50:42 2005 -0400
> files: xen/Rules.mk xen/arch/x86/cpu/amd.c xen/arch/x86/cpu/intel.c xen/arch/x86/dm/hvm_vioapic.c xen/arch/x86/dm/i8259.c xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/hvm.c xen/arch/x86/hvm_intercept.c xen/arch/x86/hvm_io.c xen/arch/x86/hvm_platform.c xen/arch/x86/hvm_vlapic.c xen/arch/x86/mpparse.c xen/arch/x86/shadow.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/mm.c xen/include/asm-x86/config.h xen/include/asm-x86/cpufeature.h xen/include/asm-x86/domain.h xen/include/asm-x86/hvm_domain.h xen/include/asm-x86/hvm_io.h xen/include/asm-x86/hvm_support.h xen/include/asm-x86/hvm_vcpu.h xen/include/asm-x86/hvm_vioapic.h xen/include/asm-x86/hvm_vlapic.h xen/include/asm-x86/hvm_vpic.h xen/include/asm-x86/hvm_vpit.h xen/include/asm-x86/mpspec.h xen/include/asm-x86/msr.h xen/include/asm-x86/processor.h xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_cpu.h xen/include/asm-x86/vmx_vmcs.h
> description:
> Phase 3 of HVM integration: This patchset introduces the refactoring of
> virtualization architecture independent functions from specific ones.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Dec 11 07:02:51 2005 -0400
> files: xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/i387.c xen/arch/x86/shadow.c xen/arch/x86/vmx.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/traps.c xen/include/asm-x86/hvm.h xen/include/asm-x86/hvm_support.h xen/include/asm-x86/regs.h xen/include/asm-x86/shadow.h xen/include/asm-x86/vmx_vmcs.h
> description:
> Phase 2 of HVM integration: This patchset introduces the hvm interface
> to the hypervisor and modifies all the non-vmx specific files to use it.
>
>
> user: leendert@eserver2.watson.ibm.com
> date: Sun Dec 11 01:10:00 2005 -0400
> files: tools/examples/Makefile tools/examples/README tools/examples/xmexample.hvm tools/ioemu/exec-all.h tools/ioemu/hw/i8254.c tools/ioemu/hw/i8259.c tools/ioemu/monitor.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c tools/libxc/Makefile tools/libxc/xc_hvm_build.c tools/libxc/xc_ptrace.c tools/libxc/xc_ptrace_core.c tools/libxc/xenguest.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py tools/python/xen/xm/create.py tools/xm-test/configure.ac tools/xm-test/lib/XmTestLib/XenDomain.py tools/xm-test/lib/XmTestLib/config.py.in tools/xm-test/ramdisk/Makefile.am tools/xm-test/ramdisk/bin/create_disk_image tools/xm-test/tests/block-list/04_block-list_nodb_pos.py xen/include/public/arch-x86_32.h xen/include/public/arch-x86_64.h
> description:
> Phase 1 of HVM integration: This patchset updates the tools. Most of the
> tools are machine independent except for some detection code in the hvm
> domain builder.
author kaf24@firebug.cl.cam.ac.uk
date Tue Jan 31 11:49:51 2006 +0100 (2006-01-31)
parents e4eb12a6e003
children 4e096b31833c
files .hgignore docs/src/user.tex tools/debugger/libxendebug/xendebug.c tools/examples/Makefile tools/examples/README tools/examples/xmexample.hvm tools/firmware/Makefile tools/firmware/README tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/acpi_madt.c tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/mkhex tools/firmware/rombios/rombios.c tools/firmware/vmxassist/Makefile tools/firmware/vmxassist/head.S tools/firmware/vmxassist/setup.c tools/firmware/vmxassist/vm86.c tools/firmware/vmxassist/vmxassist.ld tools/ioemu/exec-all.h tools/ioemu/hw/i8254.c tools/ioemu/hw/i8259.c tools/ioemu/monitor.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c tools/libxc/Makefile tools/libxc/xc_hvm_build.c tools/libxc/xc_ia64_stubs.c tools/libxc/xc_linux_build.c tools/libxc/xc_ptrace.c tools/libxc/xc_ptrace_core.c tools/libxc/xenguest.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py tools/python/xen/xm/create.py tools/python/xen/xm/tests/test_create.py tools/xm-test/README tools/xm-test/configure.ac tools/xm-test/lib/XmTestLib/XenDomain.py tools/xm-test/lib/XmTestLib/config.py.in tools/xm-test/ramdisk/Makefile.am tools/xm-test/ramdisk/bin/create_disk_image tools/xm-test/tests/block-create/01_block_attach_device_pos.py tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py tools/xm-test/tests/block-create/06_block_attach_baddomain_neg.py tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py tools/xm-test/tests/block-create/12_block_attach_shared_domU.py tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py tools/xm-test/tests/block-list/01_block-list_pos.py tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py tools/xm-test/tests/block-list/04_block-list_nodb_pos.py tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py tools/xm-test/tests/create/14_create_blockroot_pos.py tools/xm-test/tests/memmax/01_memmax_badparm_neg.py tools/xm-test/tests/memset/01_memset_basic_pos.py tools/xm-test/tests/memset/02_memset_badparm_neg.py tools/xm-test/tests/memset/03_memset_random_pos.py tools/xm-test/tests/memset/04_memset_smallmem_pos.py tools/xm-test/tests/migrate/01_migrate_localhost_pos.py tools/xm-test/tests/network-attach/01_network_attach_pos.py tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py tools/xm-test/tests/restore/01_restore_basic_pos.py tools/xm-test/tests/restore/02_restore_badparm_neg.py tools/xm-test/tests/restore/03_restore_badfilename_neg.py tools/xm-test/tests/restore/04_restore_withdevices_pos.py tools/xm-test/tests/save/01_save_basic_pos.py tools/xm-test/tests/save/02_save_badparm_neg.py tools/xm-test/tests/save/03_save_bogusfile_neg.py tools/xm-test/tests/sysrq/01_sysrq_basic_neg.py tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py xen/Rules.mk xen/arch/ia64/Makefile xen/arch/ia64/vmx/mmio.c xen/arch/ia64/vmx/vlsapic.c xen/arch/ia64/vmx/vmx_init.c xen/arch/ia64/vmx/vmx_vcpu.c xen/arch/x86/Makefile xen/arch/x86/cpu/amd.c xen/arch/x86/cpu/intel.c xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/i8259.c xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/svm/emulate.c xen/arch/x86/hvm/svm/instrlen.c xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/arch/x86/hvm/svm/x86_32/exits.S xen/arch/x86/hvm/svm/x86_64/exits.S xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/io.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/hvm/vmx/x86_32/exits.S xen/arch/x86/hvm/vmx/x86_64/exits.S xen/arch/x86/i387.c xen/arch/x86/mpparse.c xen/arch/x86/shadow.c xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/mm.c xen/arch/x86/x86_64/traps.c xen/include/asm-ia64/domain.h xen/include/asm-ia64/mm.h xen/include/asm-ia64/vmx_platform.h xen/include/asm-ia64/vmx_vcpu.h xen/include/asm-x86/config.h xen/include/asm-x86/cpufeature.h xen/include/asm-x86/domain.h xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/support.h xen/include/asm-x86/hvm/svm/emulate.h xen/include/asm-x86/hvm/svm/intr.h xen/include/asm-x86/hvm/svm/svm.h xen/include/asm-x86/hvm/svm/vmcb.h xen/include/asm-x86/hvm/svm/vmmcall.h xen/include/asm-x86/hvm/vcpu.h xen/include/asm-x86/hvm/vioapic.h xen/include/asm-x86/hvm/vlapic.h xen/include/asm-x86/hvm/vmx/cpu.h xen/include/asm-x86/hvm/vmx/vmcs.h xen/include/asm-x86/hvm/vmx/vmx.h xen/include/asm-x86/hvm/vpic.h xen/include/asm-x86/hvm/vpit.h xen/include/asm-x86/mpspec.h xen/include/asm-x86/msr.h xen/include/asm-x86/processor.h xen/include/asm-x86/regs.h xen/include/asm-x86/shadow.h xen/include/public/arch-x86_32.h xen/include/public/arch-x86_64.h xen/include/xen/domain_page.h
line diff
     1.1 --- a/.hgignore	Mon Jan 30 18:51:35 2006 +0100
     1.2 +++ b/.hgignore	Tue Jan 31 11:49:51 2006 +0100
     1.3 @@ -108,6 +108,8 @@
     1.4  ^tools/firmware/.*\.sym$
     1.5  ^tools/firmware/.*bios/.*bios.*\.txt$
     1.6  ^tools/firmware/acpi/acpigen$
     1.7 +^tools/firmware/hvmloader/hvmloader$
     1.8 +^tools/firmware/hvmloader/roms\.h$
     1.9  ^tools/firmware/rombios/BIOS-bochs-latest$
    1.10  ^tools/firmware/rombios/_rombios_\.c$
    1.11  ^tools/firmware/rombios/rombios\.s$
     2.1 --- a/docs/src/user.tex	Mon Jan 30 18:51:35 2006 +0100
     2.2 +++ b/docs/src/user.tex	Tue Jan 31 11:49:51 2006 +0100
     2.3 @@ -137,7 +137,7 @@ support Xen, a key feature is that user 
     2.4  libraries \emph{do not} require modification.
     2.5  
     2.6  With hardware CPU virtualization as provided by Intel VT and AMD
     2.7 -Pacifica technology, the ability to run an unmodified guest OS kernel
     2.8 +SVM technology, the ability to run an unmodified guest OS kernel
     2.9  is available.  No porting of the OS is required, although some
    2.10  additional driver support is necessary within Xen itself.  Unlike
    2.11  traditional full virtualization hypervisors, which suffer a tremendous
     3.1 --- a/tools/debugger/libxendebug/xendebug.c	Mon Jan 30 18:51:35 2006 +0100
     3.2 +++ b/tools/debugger/libxendebug/xendebug.c	Tue Jan 31 11:49:51 2006 +0100
     3.3 @@ -355,7 +355,7 @@ xendebug_memory_page (domain_context_p c
     3.4  
     3.5      if ( (pde = ctxt->cr3_virt[vcpu][vtopdi(va)]) == 0) /* logical address */
     3.6          return 0;
     3.7 -    if (ctxt->context[vcpu].flags & VGCF_VMX_GUEST)
     3.8 +    if (ctxt->context[vcpu].flags & VGCF_HVM_GUEST)
     3.9          pde = ctxt->page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
    3.10      if (pde != ctxt->pde_phys[vcpu]) 
    3.11      {
    3.12 @@ -370,7 +370,7 @@ xendebug_memory_page (domain_context_p c
    3.13  
    3.14      if ((page = ctxt->pde_virt[vcpu][vtopti(va)]) == 0) /* logical address */
    3.15          return 0;
    3.16 -    if (ctxt->context[vcpu].flags & VGCF_VMX_GUEST)
    3.17 +    if (ctxt->context[vcpu].flags & VGCF_HVM_GUEST)
    3.18          page = ctxt->page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
    3.19      if (page != ctxt->page_phys[vcpu] || protection != ctxt->page_perm[vcpu]) 
    3.20      {
     4.1 --- a/tools/examples/Makefile	Mon Jan 30 18:51:35 2006 +0100
     4.2 +++ b/tools/examples/Makefile	Tue Jan 31 11:49:51 2006 +0100
     4.3 @@ -16,7 +16,7 @@ XEN_CONFIG_DIR = /etc/xen
     4.4  XEN_CONFIGS = xend-config.sxp
     4.5  XEN_CONFIGS += xmexample1 
     4.6  XEN_CONFIGS += xmexample2
     4.7 -XEN_CONFIGS += xmexample.vmx
     4.8 +XEN_CONFIGS += xmexample.hvm
     4.9  XEN_CONFIGS += xmexample.vti
    4.10  
    4.11  # Xen script dir and scripts to go there.
     5.1 --- a/tools/examples/README	Mon Jan 30 18:51:35 2006 +0100
     5.2 +++ b/tools/examples/README	Tue Jan 31 11:49:51 2006 +0100
     5.3 @@ -32,6 +32,6 @@ xmexample2          - a more complex con
     5.4  xmexample3          - an advanced configuration script for 'xm create' 
     5.5                        that utilizes the vmid
     5.6  xmexample.nbd       - configuration script that uses NBD filesystems
     5.7 -xmexample.vmx       - a configuration script for creating a vmx domain with
     5.8 +xmexample.hvm       - a configuration script for creating a hvm domain with
     5.9                        'xm create'
    5.10  xmexample.vti       - a configuration script for creating a domain on vti
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/examples/xmexample.hvm	Tue Jan 31 11:49:51 2006 +0100
     6.3 @@ -0,0 +1,152 @@
     6.4 +#  -*- mode: python; -*-
     6.5 +#============================================================================
     6.6 +# Python configuration setup for 'xm create'.
     6.7 +# This script sets the parameters used when a domain is created using 'xm create'.
     6.8 +# You use a separate script for each domain you want to create, or 
     6.9 +# you can set the parameters for the domain on the xm command line.
    6.10 +#============================================================================
    6.11 +
    6.12 +import os, re
    6.13 +arch = os.uname()[4]
    6.14 +if re.search('64', arch):
    6.15 +    arch_libdir = 'lib64'
    6.16 +else:
    6.17 +    arch_libdir = 'lib'
    6.18 +
    6.19 +#----------------------------------------------------------------------------
    6.20 +# Kernel image file.
    6.21 +kernel = "/usr/lib/xen/boot/hvmloader"
    6.22 +
    6.23 +# The domain build function. HVM domain uses 'hvm'.
    6.24 +builder='hvm'
    6.25 +
    6.26 +# Initial memory allocation (in megabytes) for the new domain.
    6.27 +memory = 128
    6.28 +
    6.29 +# A name for your domain. All domains must have different names.
    6.30 +name = "ExampleHVMDomain"
    6.31 +
    6.32 +#-----------------------------------------------------------------------------
    6.33 +# the number of cpus guest platform has, default=1
    6.34 +#vcpus=1
    6.35 +
    6.36 +# enable/disable HVM guest ACPI, default=0 (disabled)
    6.37 +#acpi=0
    6.38 +
    6.39 +# enable/disable HVM guest APIC, default=0 (disabled)
    6.40 +#apic=0
    6.41 +
    6.42 +# List of which CPUS this domain is allowed to use, default Xen picks
    6.43 +#cpus = ""         # leave to Xen to pick
    6.44 +#cpus = "0"        # all vcpus run on CPU0
    6.45 +#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
    6.46 +
    6.47 +# Optionally define mac and/or bridge for the network interfaces.
    6.48 +# Random MACs are assigned if not given.
    6.49 +#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
    6.50 +# type=ioemu specify the NIC is an ioemu device not netfront
    6.51 +vif = [ 'type=ioemu, bridge=xenbr0' ]
    6.52 +
    6.53 +#----------------------------------------------------------------------------
    6.54 +# Define the disk devices you want the domain to have access to, and
    6.55 +# what you want them accessible as.
    6.56 +# Each disk entry is of the form phy:UNAME,DEV,MODE
    6.57 +# where UNAME is the device, DEV is the device name the domain will see,
    6.58 +# and MODE is r for read-only, w for read-write.
    6.59 +
    6.60 +#disk = [ 'phy:hda1,hda1,r' ]
    6.61 +disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
    6.62 +
    6.63 +#----------------------------------------------------------------------------
    6.64 +# Configure the behaviour when a domain exits.  There are three 'reasons'
    6.65 +# for a domain to stop: poweroff, reboot, and crash.  For each of these you
    6.66 +# may specify:
    6.67 +#
    6.68 +#   "destroy",        meaning that the domain is cleaned up as normal;
    6.69 +#   "restart",        meaning that a new domain is started in place of the old
    6.70 +#                     one;
    6.71 +#   "preserve",       meaning that no clean-up is done until the domain is
    6.72 +#                     manually destroyed (using xm destroy, for example); or
    6.73 +#   "rename-restart", meaning that the old domain is not cleaned up, but is
    6.74 +#                     renamed and a new domain started in its place.
    6.75 +#
    6.76 +# The default is
    6.77 +#
    6.78 +#   on_poweroff = 'destroy'
    6.79 +#   on_reboot   = 'restart'
    6.80 +#   on_crash    = 'restart'
    6.81 +#
    6.82 +# For backwards compatibility we also support the deprecated option restart
    6.83 +#
    6.84 +# restart = 'onreboot' means on_poweroff = 'destroy'
    6.85 +#                            on_reboot   = 'restart'
    6.86 +#                            on_crash    = 'destroy'
    6.87 +#
    6.88 +# restart = 'always'   means on_poweroff = 'restart'
    6.89 +#                            on_reboot   = 'restart'
    6.90 +#                            on_crash    = 'restart'
    6.91 +#
    6.92 +# restart = 'never'    means on_poweroff = 'destroy'
    6.93 +#                            on_reboot   = 'destroy'
    6.94 +#                            on_crash    = 'destroy'
    6.95 +
    6.96 +#on_poweroff = 'destroy'
    6.97 +#on_reboot   = 'restart'
    6.98 +#on_crash    = 'restart'
    6.99 +
   6.100 +#============================================================================
   6.101 +
   6.102 +# New stuff
   6.103 +device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
   6.104 +
   6.105 +#-----------------------------------------------------------------------------
   6.106 +# Disk image for 
   6.107 +#cdrom=
   6.108 +
   6.109 +#-----------------------------------------------------------------------------
   6.110 +# boot on floppy (a), hard disk (c) or CD-ROM (d) 
   6.111 +#boot=[a|c|d]
   6.112 +#-----------------------------------------------------------------------------
   6.113 +#  write to temporary files instead of disk image files
   6.114 +#snapshot=1
   6.115 +
   6.116 +#----------------------------------------------------------------------------
   6.117 +# enable SDL library for graphics, default = 0
   6.118 +sdl=0
   6.119 +
   6.120 +#----------------------------------------------------------------------------
   6.121 +# enable VNC library for graphics, default = 1
   6.122 +vnc=1
   6.123 +
   6.124 +#----------------------------------------------------------------------------
   6.125 +# enable spawning vncviewer(only valid when vnc=1), default = 1
   6.126 +vncviewer=1
   6.127 +
   6.128 +#----------------------------------------------------------------------------
   6.129 +# no graphics, use serial port
   6.130 +#nographic=0
   6.131 +
   6.132 +
   6.133 +#-----------------------------------------------------------------------------
   6.134 +#   serial port re-direct to pty deivce, /dev/pts/n 
   6.135 +#   then xm console or minicom can connect
   6.136 +#serial='pty'
   6.137 +
   6.138 +#----------------------------------------------------------------------------
   6.139 +# enable ne2000, default = 0(use pcnet)
   6.140 +ne2000=0
   6.141 +
   6.142 +
   6.143 +#-----------------------------------------------------------------------------
   6.144 +#   enable audio support
   6.145 +#audio=1
   6.146 +
   6.147 +
   6.148 +#-----------------------------------------------------------------------------
   6.149 +#    set the real time clock to local time [default=0 i.e. set to utc]
   6.150 +#localtime=1
   6.151 +
   6.152 +
   6.153 +#-----------------------------------------------------------------------------
   6.154 +#    start in full screen
   6.155 +#full-screen=1   
     7.1 --- a/tools/examples/xmexample.vmx	Mon Jan 30 18:51:35 2006 +0100
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,154 +0,0 @@
     7.4 -#  -*- mode: python; -*-
     7.5 -#============================================================================
     7.6 -# Python configuration setup for 'xm create'.
     7.7 -# This script sets the parameters used when a domain is created using 'xm create'.
     7.8 -# You use a separate script for each domain you want to create, or 
     7.9 -# you can set the parameters for the domain on the xm command line.
    7.10 -#============================================================================
    7.11 -
    7.12 -import os, re
    7.13 -arch = os.uname()[4]
    7.14 -if re.search('64', arch):
    7.15 -    arch_libdir = 'lib64'
    7.16 -else:
    7.17 -    arch_libdir = 'lib'
    7.18 -
    7.19 -#----------------------------------------------------------------------------
    7.20 -# Kernel image file.
    7.21 -kernel = "/usr/lib/xen/boot/vmxloader"
    7.22 -
    7.23 -# The domain build function. VMX domain uses 'vmx'.
    7.24 -builder='vmx'
    7.25 -
    7.26 -# Initial memory allocation (in megabytes) for the new domain.
    7.27 -memory = 128
    7.28 -
    7.29 -# A name for your domain. All domains must have different names.
    7.30 -name = "ExampleVMXDomain"
    7.31 -
    7.32 -#-----------------------------------------------------------------------------
    7.33 -# the number of cpus guest platform has, default=1
    7.34 -#vcpus=1
    7.35 -
    7.36 -# enable/disalbe vmx guest ACPI, default=0 (disabled)
    7.37 -#acpi=0
    7.38 -
    7.39 -# enable/disalbe vmx guest APIC, default=0 (disabled)
    7.40 -#apic=0
    7.41 -
    7.42 -# List of which CPUS this domain is allowed to use, default Xen picks
    7.43 -#cpus = ""         # leave to Xen to pick
    7.44 -#cpus = "0"        # all vcpus run on CPU0
    7.45 -#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
    7.46 -
    7.47 -# Optionally define mac and/or bridge for the network interfaces.
    7.48 -# Random MACs are assigned if not given.
    7.49 -#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
    7.50 -# type=ioemu specify the NIC is an ioemu device not netfront
    7.51 -vif = [ 'type=ioemu, bridge=xenbr0' ]
    7.52 -# for multiple NICs in device model, 3 in this example
    7.53 -#vif = [ 'type=ioemu, bridge=xenbr0', 'type=ioemu', 'type=ioemu']
    7.54 -
    7.55 -#----------------------------------------------------------------------------
    7.56 -# Define the disk devices you want the domain to have access to, and
    7.57 -# what you want them accessible as.
    7.58 -# Each disk entry is of the form phy:UNAME,DEV,MODE
    7.59 -# where UNAME is the device, DEV is the device name the domain will see,
    7.60 -# and MODE is r for read-only, w for read-write.
    7.61 -
    7.62 -#disk = [ 'phy:hda1,hda1,r' ]
    7.63 -disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
    7.64 -
    7.65 -#----------------------------------------------------------------------------
    7.66 -# Configure the behaviour when a domain exits.  There are three 'reasons'
    7.67 -# for a domain to stop: poweroff, reboot, and crash.  For each of these you
    7.68 -# may specify:
    7.69 -#
    7.70 -#   "destroy",        meaning that the domain is cleaned up as normal;
    7.71 -#   "restart",        meaning that a new domain is started in place of the old
    7.72 -#                     one;
    7.73 -#   "preserve",       meaning that no clean-up is done until the domain is
    7.74 -#                     manually destroyed (using xm destroy, for example); or
    7.75 -#   "rename-restart", meaning that the old domain is not cleaned up, but is
    7.76 -#                     renamed and a new domain started in its place.
    7.77 -#
    7.78 -# The default is
    7.79 -#
    7.80 -#   on_poweroff = 'destroy'
    7.81 -#   on_reboot   = 'restart'
    7.82 -#   on_crash    = 'restart'
    7.83 -#
    7.84 -# For backwards compatibility we also support the deprecated option restart
    7.85 -#
    7.86 -# restart = 'onreboot' means on_poweroff = 'destroy'
    7.87 -#                            on_reboot   = 'restart'
    7.88 -#                            on_crash    = 'destroy'
    7.89 -#
    7.90 -# restart = 'always'   means on_poweroff = 'restart'
    7.91 -#                            on_reboot   = 'restart'
    7.92 -#                            on_crash    = 'restart'
    7.93 -#
    7.94 -# restart = 'never'    means on_poweroff = 'destroy'
    7.95 -#                            on_reboot   = 'destroy'
    7.96 -#                            on_crash    = 'destroy'
    7.97 -
    7.98 -#on_poweroff = 'destroy'
    7.99 -#on_reboot   = 'restart'
   7.100 -#on_crash    = 'restart'
   7.101 -
   7.102 -#============================================================================
   7.103 -
   7.104 -# New stuff
   7.105 -device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
   7.106 -
   7.107 -#-----------------------------------------------------------------------------
   7.108 -# Disk image for 
   7.109 -#cdrom=
   7.110 -
   7.111 -#-----------------------------------------------------------------------------
   7.112 -# boot on floppy (a), hard disk (c) or CD-ROM (d) 
   7.113 -#boot=[a|c|d]
   7.114 -#-----------------------------------------------------------------------------
   7.115 -#  write to temporary files instead of disk image files
   7.116 -#snapshot=1
   7.117 -
   7.118 -#----------------------------------------------------------------------------
   7.119 -# enable SDL library for graphics, default = 0
   7.120 -sdl=0
   7.121 -
   7.122 -#----------------------------------------------------------------------------
   7.123 -# enable VNC library for graphics, default = 1
   7.124 -vnc=1
   7.125 -
   7.126 -#----------------------------------------------------------------------------
   7.127 -# enable spawning vncviewer(only valid when vnc=1), default = 1
   7.128 -vncviewer=1
   7.129 -
   7.130 -#----------------------------------------------------------------------------
   7.131 -# no graphics, use serial port
   7.132 -#nographic=0
   7.133 -
   7.134 -
   7.135 -#-----------------------------------------------------------------------------
   7.136 -#   serial port re-direct to pty deivce, /dev/pts/n 
   7.137 -#   then xm console or minicom can connect
   7.138 -#serial='pty'
   7.139 -
   7.140 -#----------------------------------------------------------------------------
   7.141 -# enable ne2000, default = 0(use pcnet)
   7.142 -ne2000=0
   7.143 -
   7.144 -
   7.145 -#-----------------------------------------------------------------------------
   7.146 -#   enable audio support
   7.147 -#audio=1
   7.148 -
   7.149 -
   7.150 -#-----------------------------------------------------------------------------
   7.151 -#    set the real time clock to local time [default=0 i.e. set to utc]
   7.152 -#localtime=1
   7.153 -
   7.154 -
   7.155 -#-----------------------------------------------------------------------------
   7.156 -#    start in full screen
   7.157 -#full-screen=1   
     8.1 --- a/tools/firmware/Makefile	Mon Jan 30 18:51:35 2006 +0100
     8.2 +++ b/tools/firmware/Makefile	Tue Jan 31 11:49:51 2006 +0100
     8.3 @@ -1,9 +1,9 @@
     8.4  XEN_ROOT = ../..
     8.5  include $(XEN_ROOT)/tools/Rules.mk
     8.6  
     8.7 -# vmxloader is a 32-bit protected mode binary.
     8.8 +# hvmloader is a 32-bit protected mode binary.
     8.9  # It belongs in /usr/lib, not /usr/lib64.
    8.10 -TARGET      := vmxassist/vmxloader
    8.11 +TARGET      := hvmloader/hvmloader
    8.12  INSTALL_DIR := $(DESTDIR)/usr/lib/xen/boot
    8.13  
    8.14  SUBDIRS :=
    8.15 @@ -11,6 +11,7 @@ SUBDIRS += rombios
    8.16  SUBDIRS += vgabios
    8.17  SUBDIRS += acpi
    8.18  SUBDIRS += vmxassist
    8.19 +SUBDIRS += hvmloader
    8.20  
    8.21  .PHONY: all install clean
    8.22  
     9.1 --- a/tools/firmware/README	Mon Jan 30 18:51:35 2006 +0100
     9.2 +++ b/tools/firmware/README	Tue Jan 31 11:49:51 2006 +0100
     9.3 @@ -1,11 +1,11 @@
     9.4 -Domain FirmWare support
     9.5 +Domain firmware support
     9.6  -----------------------
     9.7  
     9.8  One of the key advantages of full virtualization hardware support (such
     9.9 -as Intel's VT or AMD's Pacifica) is the ability to run unmodified guest
    9.10 -operating systems.  However, since most OSes rely on BIOS support during
    9.11 -their early bringup, we need to provide a surrogate ROMBIOS and VGABIOS
    9.12 -firmware layer.
    9.13 +as Intel's VT or AMD's SVM extensions) is the ability to run unmodified
    9.14 +guest operating systems.  However, since most OSes rely on BIOS support
    9.15 +during their early bringup, we need to provide a surrogate ROMBIOS and
    9.16 +VGABIOS firmware layer.
    9.17  
    9.18  What's more, we need to support real-mode which is required by
    9.19  the firmware and bootstrap loaders. Real-mode support is especially
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/firmware/hvmloader/Makefile	Tue Jan 31 11:49:51 2006 +0100
    10.3 @@ -0,0 +1,56 @@
    10.4 +#
    10.5 +# Makefile
    10.6 +#
    10.7 +# Leendert van Doorn, leendert@watson.ibm.com
    10.8 +# Copyright (c) 2005, International Business Machines Corporation.
    10.9 +#
   10.10 +# This program is free software; you can redistribute it and/or modify it
   10.11 +# under the terms and conditions of the GNU General Public License,
   10.12 +# version 2, as published by the Free Software Foundation.
   10.13 +#
   10.14 +# This program is distributed in the hope it will be useful, but WITHOUT
   10.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   10.17 +# more details.
   10.18 +#
   10.19 +# You should have received a copy of the GNU General Public License along with
   10.20 +# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   10.21 +# Place - Suite 330, Boston, MA 02111-1307 USA.
   10.22 +#
   10.23 +
   10.24 +XEN_ROOT = ../../..
   10.25 +include $(XEN_ROOT)/tools/Rules.mk
   10.26 +
   10.27 +# The HVM loader is started in 32-bit mode at the address below:
   10.28 +LOADADDR = 0x100000
   10.29 +
   10.30 +DEFINES  =-DDEBUG
   10.31 +XENINC   =-I$(XEN_ROOT)/tools/libxc
   10.32 +
   10.33 +OBJECTS	 = hvmloader.o acpi_madt.o 
   10.34 +
   10.35 +CC       = gcc
   10.36 +OBJCOPY  = objcopy
   10.37 +CFLAGS   = $(DEFINES) -I. $(XENINC) -Wall -fno-builtin -O2 -msoft-float
   10.38 +CFLAGS  += -m32 -march=i686
   10.39 +LDFLAGS  = -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR)
   10.40 +
   10.41 +all: hvmloader
   10.42 +
   10.43 +hvmloader: roms.h hvmloader.c acpi_madt.c
   10.44 +	$(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c
   10.45 +	$(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o
   10.46 +	$(OBJCOPY) hvmloader.tmp hvmloader
   10.47 +	rm -f hvmloader.tmp
   10.48 +
   10.49 +roms.h:	../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
   10.50 +	./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
   10.51 +	./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
   10.52 +	./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
   10.53 +	./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
   10.54 +	./mkhex acpi ../acpi/acpi.bin >> roms.h
   10.55 +
   10.56 +clean:
   10.57 +	rm -f roms.h acpi.h
   10.58 +	rm -f hvmloader hvmloader.tmp hvmloader.o $(OBJECTS)
   10.59 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/firmware/hvmloader/acpi_madt.c	Tue Jan 31 11:49:51 2006 +0100
    11.3 @@ -0,0 +1,190 @@
    11.4 +/*
    11.5 + * acpi_madt.c: Update ACPI MADT table for multiple processor guest.
    11.6 + *
    11.7 + * Yu Ke, ke.yu@intel.com
    11.8 + * Copyright (c) 2005, Intel Corporation.
    11.9 + *
   11.10 + * This program is free software; you can redistribute it and/or modify it
   11.11 + * under the terms and conditions of the GNU General Public License,
   11.12 + * version 2, as published by the Free Software Foundation.
   11.13 + *
   11.14 + * This program is distributed in the hope it will be useful, but WITHOUT
   11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   11.17 + * more details.
   11.18 + *
   11.19 + * You should have received a copy of the GNU General Public License along with
   11.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   11.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   11.22 + */
   11.23 +
   11.24 +#include "../acpi/acpi2_0.h"
   11.25 +#include "../acpi/acpi_madt.h"
   11.26 +
   11.27 +#include <xen/hvm/hvm_info_table.h>
   11.28 +
   11.29 +#define NULL ((void*)0)
   11.30 +
   11.31 +extern int puts(const char *s);
   11.32 +
   11.33 +static struct hvm_info_table *table = NULL;
   11.34 +
   11.35 +static int validate_hvm_info(struct hvm_info_table *t)
   11.36 +{
   11.37 +	char signature[] = "HVM INFO";
   11.38 +	uint8_t *ptr = (uint8_t *)t;
   11.39 +	uint8_t sum = 0;
   11.40 +	int i;
   11.41 +
   11.42 +	/* strncmp(t->signature, "HVM INFO", 8) */
   11.43 +	for (i = 0; i < 8; i++) {
   11.44 +		if (signature[i] != t->signature[i]) {
   11.45 +			puts("Bad hvm info signature\n");
   11.46 +			return 0;
   11.47 +		}
   11.48 +	}
   11.49 +
   11.50 +	for (i = 0; i < t->length; i++)
   11.51 +		sum += ptr[i];
   11.52 +
   11.53 +	return (sum == 0);
   11.54 +}
   11.55 +
   11.56 +/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
   11.57 +static struct hvm_info_table *
   11.58 +get_hvm_info_table(void)
   11.59 +{
   11.60 +	struct hvm_info_table *t;
   11.61 +
   11.62 +	if (table != NULL)
   11.63 +		return table;
   11.64 +
   11.65 +	t = (struct hvm_info_table *)HVM_INFO_PADDR;
   11.66 +
   11.67 +	if (!validate_hvm_info(t)) {
   11.68 +		puts("Bad hvm info table\n");
   11.69 +		return NULL;
   11.70 +	}
   11.71 +
   11.72 +	table = t;
   11.73 +
   11.74 +	return table;
   11.75 +}
   11.76 +
   11.77 +int
   11.78 +get_vcpu_nr(void)
   11.79 +{
   11.80 +	struct hvm_info_table *t = get_hvm_info_table();
   11.81 +	return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
   11.82 +}
   11.83 +
   11.84 +int
   11.85 +get_acpi_enabled(void)
   11.86 +{
   11.87 +	struct hvm_info_table *t = get_hvm_info_table();
   11.88 +	return (t ? t->acpi_enabled : 0); /* default no acpi */
   11.89 +}
   11.90 +
   11.91 +
   11.92 +static void *
   11.93 +acpi_madt_get_madt(unsigned char *acpi_start)
   11.94 +{
   11.95 +	ACPI_2_0_RSDP *rsdp=NULL;
   11.96 +	ACPI_2_0_RSDT *rsdt=NULL;
   11.97 +	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
   11.98 +
   11.99 +	rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
  11.100 +	if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
  11.101 +		puts("Bad RSDP signature\n");
  11.102 +		return NULL;
  11.103 +	}
  11.104 +
  11.105 +	rsdt= (ACPI_2_0_RSDT *)
  11.106 +		(acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
  11.107 +	if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
  11.108 +		puts("Bad RSDT signature\n");
  11.109 +		return NULL;
  11.110 +	}
  11.111 +
  11.112 +	madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
  11.113 +		( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
  11.114 +	if (madt->Header.Header.Signature !=
  11.115 +	    ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
  11.116 +		puts("Bad MADT signature \n");
  11.117 +		return NULL;
  11.118 +	}
  11.119 +
  11.120 +	return madt;
  11.121 +}
  11.122 +
  11.123 +static void
  11.124 +set_checksum(void *start, int checksum_offset, int len)
  11.125 +{
  11.126 +	unsigned char sum = 0;
  11.127 +	unsigned char *ptr;
  11.128 +
  11.129 +	ptr = start;
  11.130 +	ptr[checksum_offset] = 0;
  11.131 +	while (len--)
  11.132 +		sum += *ptr++;
  11.133 +
  11.134 +	ptr = start;
  11.135 +	ptr[checksum_offset] = -sum;
  11.136 +}
  11.137 +
  11.138 +static int
  11.139 +acpi_madt_set_local_apics(
  11.140 +	int nr_vcpu,
  11.141 +	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
  11.142 +{
  11.143 +	int i;
  11.144 +
  11.145 +	if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
  11.146 +		return -1;
  11.147 +
  11.148 +	for (i = 0; i < nr_vcpu; i++) {
  11.149 +		madt->LocalApic[i].Type            = ACPI_PROCESSOR_LOCAL_APIC;
  11.150 +		madt->LocalApic[i].Length          = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
  11.151 +		madt->LocalApic[i].AcpiProcessorId = i;
  11.152 +		madt->LocalApic[i].ApicId          = i;
  11.153 +		madt->LocalApic[i].Flags           = 1;
  11.154 +	}
  11.155 +
  11.156 +	madt->Header.Header.Length =
  11.157 +		sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
  11.158 +		(MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
  11.159 +
  11.160 +	return 0;
  11.161 +}
  11.162 +
  11.163 +#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
  11.164 +
  11.165 +int acpi_madt_update(unsigned char *acpi_start)
  11.166 +{
  11.167 +	int rc;
  11.168 +	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
  11.169 +
  11.170 +	madt = acpi_madt_get_madt(acpi_start);
  11.171 +	if (!madt)
  11.172 +		return -1;
  11.173 +
  11.174 +	rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
  11.175 +	if (rc != 0)
  11.176 +		return rc;
  11.177 +
  11.178 +	set_checksum(
  11.179 +		madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
  11.180 +		madt->Header.Header.Length);
  11.181 +
  11.182 +	return 0;
  11.183 +}
  11.184 +
  11.185 +/*
  11.186 + * Local variables:
  11.187 + *  c-file-style: "linux"
  11.188 + *  indent-tabs-mode: t
  11.189 + *  c-indent-level: 8
  11.190 + *  c-basic-offset: 8
  11.191 + *  tab-width: 8
  11.192 + * End:
  11.193 + */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Tue Jan 31 11:49:51 2006 +0100
    12.3 @@ -0,0 +1,211 @@
    12.4 +/*
    12.5 + * hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader.
    12.6 + *
    12.7 + * A quicky so that we can boot rom images as if they were a Linux kernel.
    12.8 + * This code will copy the rom images (ROMBIOS/VGABIOS/VM86) into their
    12.9 + * respective spaces and transfer control to VM86 to execute the BIOSes.
   12.10 + *
   12.11 + * Leendert van Doorn, leendert@watson.ibm.com
   12.12 + * Copyright (c) 2005, International Business Machines Corporation.
   12.13 + *
   12.14 + * This program is free software; you can redistribute it and/or modify it
   12.15 + * under the terms and conditions of the GNU General Public License,
   12.16 + * version 2, as published by the Free Software Foundation.
   12.17 + *
   12.18 + * This program is distributed in the hope it will be useful, but WITHOUT
   12.19 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.20 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   12.21 + * more details.
   12.22 + *
   12.23 + * You should have received a copy of the GNU General Public License along with
   12.24 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   12.25 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   12.26 + */
   12.27 +#include "roms.h"
   12.28 +#include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
   12.29 +
   12.30 +/* memory map */
   12.31 +#define VGABIOS_PHYSICAL_ADDRESS	0x000C0000
   12.32 +#define	VMXASSIST_PHYSICAL_ADDRESS	0x000D0000
   12.33 +#define	ROMBIOS_PHYSICAL_ADDRESS	0x000F0000
   12.34 +
   12.35 +/* invoke SVM's paged realmode support */
   12.36 +#define SVM_VMMCALL_RESET_TO_REALMODE	0x00000001
   12.37 +
   12.38 +/*
   12.39 + * C runtime start off
   12.40 + */
   12.41 +asm(
   12.42 +"	.text				\n"
   12.43 +"	.globl	_start			\n"
   12.44 +"_start:				\n"
   12.45 +"	cld				\n"
   12.46 +"	cli				\n"
   12.47 +"	lgdt	gdt_desr		\n"
   12.48 +"	movl	$stack_top, %esp	\n"
   12.49 +"	movl	%esp, %ebp		\n"
   12.50 +"	call	main			\n"
   12.51 +"	jmp	halt			\n"
   12.52 +"					\n"
   12.53 +"gdt_desr:				\n"
   12.54 +"	.word	gdt_end - gdt - 1	\n"
   12.55 +"	.long	gdt			\n"
   12.56 +"					\n"
   12.57 +"	.align	8			\n"
   12.58 +"gdt:					\n"
   12.59 +"	.quad	0x0000000000000000	\n"
   12.60 +"	.quad	0x00CF92000000FFFF	\n"
   12.61 +"	.quad	0x00CF9A000000FFFF	\n"
   12.62 +"gdt_end:				\n"
   12.63 +"					\n"
   12.64 +"halt:					\n"
   12.65 +"	sti				\n"
   12.66 +"	jmp	.			\n"
   12.67 +"					\n"
   12.68 +"	.bss				\n"
   12.69 +"	.align	8			\n"
   12.70 +"stack:					\n"
   12.71 +"	.skip	0x4000			\n"
   12.72 +"stack_top:				\n"
   12.73 +);
   12.74 +
   12.75 +extern int get_acpi_enabled(void);
   12.76 +extern int acpi_madt_update(unsigned char* acpi_start);
   12.77 +
   12.78 +static inline void
   12.79 +outw(unsigned short addr, unsigned short val)
   12.80 +{
   12.81 +        __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
   12.82 +}
   12.83 +
   12.84 +static inline void
   12.85 +outb(unsigned short addr, unsigned char val)
   12.86 +{
   12.87 +        __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
   12.88 +}
   12.89 +
   12.90 +static inline unsigned char
   12.91 +inb(unsigned short addr)
   12.92 +{
   12.93 +        unsigned char val;
   12.94 +
   12.95 +        __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
   12.96 +        return val;
   12.97 +}
   12.98 +
   12.99 +void *
  12.100 +memcpy(void *dest, const void *src, unsigned n)
  12.101 +{
  12.102 +	int t0, t1, t2;
  12.103 +
  12.104 +	__asm__ __volatile__(
  12.105 +		"cld\n"
  12.106 +		"rep; movsl\n"
  12.107 +		"testb $2,%b4\n"
  12.108 +		"je 1f\n"
  12.109 +		"movsw\n"
  12.110 +		"1: testb $1,%b4\n"
  12.111 +		"je 2f\n"
  12.112 +		"movsb\n"
  12.113 +		"2:"
  12.114 +		: "=&c" (t0), "=&D" (t1), "=&S" (t2)
  12.115 +		: "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
  12.116 +		: "memory"
  12.117 +	);
  12.118 +	return dest;
  12.119 +}
  12.120 +
  12.121 +int
  12.122 +puts(const char *s)
  12.123 +{
  12.124 +	while (*s)
  12.125 +		outb(0xE9, *s++);
  12.126 +	return 0;
  12.127 +}
  12.128 +
  12.129 +int
  12.130 +cirrus_check(void)
  12.131 +{
  12.132 +	outw(0x3C4, 0x9206);
  12.133 +	return inb(0x3C5) == 0x12;
  12.134 +}
  12.135 +
  12.136 +int 
  12.137 +vmmcall(int edi, int esi, int edx, int ecx, int ebx)
  12.138 +{
  12.139 +        int eax;
  12.140 +
  12.141 +        __asm__ __volatile__(
  12.142 +		".byte 0x0F,0x01,0xD9"
  12.143 +                : "=a" (eax)
  12.144 +		: "a"(0x58454E00), /* XEN\0 key */
  12.145 +		  "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi)
  12.146 +	);
  12.147 +        return eax;
  12.148 +}
  12.149 +
  12.150 +int
  12.151 +check_amd(void)
  12.152 +{
  12.153 +	char id[12];
  12.154 +
  12.155 +        __asm__ __volatile__(
  12.156 +		"cpuid" 
  12.157 +		: "=b" (*(int *)(&id[0])),
  12.158 +		  "=c" (*(int *)(&id[8])),
  12.159 +		  "=d" (*(int *)(&id[4]))
  12.160 +		: "a" (0)
  12.161 +	);
  12.162 +	return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
  12.163 +}
  12.164 +
  12.165 +int
  12.166 +main(void)
  12.167 +{
  12.168 +	puts("HVM Loader\n");
  12.169 +
  12.170 +	puts("Loading ROMBIOS ...\n");
  12.171 +	memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
  12.172 +	if (cirrus_check()) {
  12.173 +		puts("Loading Cirrus VGABIOS ...\n");
  12.174 +		memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
  12.175 +			vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
  12.176 +	} else {
  12.177 +		puts("Loading Standard VGABIOS ...\n");
  12.178 +		memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
  12.179 +			vgabios_stdvga, sizeof(vgabios_stdvga));
  12.180 +	}
  12.181 +
  12.182 +	if (get_acpi_enabled() != 0) {
  12.183 +		puts("Loading ACPI ...\n");
  12.184 +		acpi_madt_update((unsigned char *) acpi);
  12.185 +		if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
  12.186 +			/*
  12.187 +			 * Make sure acpi table does not overlap rombios
  12.188 +			 * currently acpi less than 8K will be OK.
  12.189 +			 */
  12.190 +			 memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi,
  12.191 +			 					sizeof(acpi));
  12.192 +		}
  12.193 +	}
  12.194 +
  12.195 +	if (check_amd()) {
  12.196 +		/* AMD implies this is SVM */
  12.197 +                puts("SVM go ...\n");
  12.198 +                vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0);
  12.199 +	} else {
  12.200 +		puts("Loading VMXAssist ...\n");
  12.201 +		memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
  12.202 +				vmxassist, sizeof(vmxassist));
  12.203 +
  12.204 +		puts("VMX go ...\n");
  12.205 +		__asm__ __volatile__(
  12.206 +			"jmp *%%eax"
  12.207 +			: : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
  12.208 +		);
  12.209 +	}
  12.210 +
  12.211 +	puts("Failed to invoke ROMBIOS\n");
  12.212 +	return 0;
  12.213 +}
  12.214 +
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/firmware/hvmloader/mkhex	Tue Jan 31 11:49:51 2006 +0100
    13.3 @@ -0,0 +1,26 @@
    13.4 +#!/bin/sh
    13.5 +
    13.6 +#
    13.7 +# mkhex: Generate C embeddable hexdumps
    13.8 +#
    13.9 +# Leendert van Doorn, leendert@watson.ibm.com
   13.10 +# Copyright (c) 2005, International Business Machines Corporation.
   13.11 +#
   13.12 +# This program is free software; you can redistribute it and/or modify it
   13.13 +# under the terms and conditions of the GNU General Public License,
   13.14 +# version 2, as published by the Free Software Foundation.
   13.15 +#
   13.16 +# This program is distributed in the hope it will be useful, but WITHOUT
   13.17 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.18 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   13.19 +# more details.
   13.20 +#
   13.21 +# You should have received a copy of the GNU General Public License along with
   13.22 +# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   13.23 +# Place - Suite 330, Boston, MA 02111-1307 USA.
   13.24 +#
   13.25 +
   13.26 +echo "unsigned $1[] = {"
   13.27 +od -v -t x $2 | sed 's/^[0-9]* /0x/' | sed 's/ /, 0x/g' | sed 's/$/,/'
   13.28 +echo "};"
   13.29 +
    14.1 --- a/tools/firmware/rombios/rombios.c	Mon Jan 30 18:51:35 2006 +0100
    14.2 +++ b/tools/firmware/rombios/rombios.c	Tue Jan 31 11:49:51 2006 +0100
    14.3 @@ -26,8 +26,8 @@
    14.4  
    14.5  // ROM BIOS for use with Bochs/Plex x86 emulation environment
    14.6  
    14.7 -#define VMXASSIST
    14.8 -#undef VMXTEST
    14.9 +#define HVMASSIST
   14.10 +#undef HVMTEST
   14.11  
   14.12  // Xen full virtualization does not handle unaligned IO with page crossing.
   14.13  // Disable 32-bit PIO as a workaround.
   14.14 @@ -177,8 +177,8 @@
   14.15  #define BASE_MEM_IN_K   (640 - EBDA_SIZE)
   14.16  
   14.17    // Define the application NAME
   14.18 -#ifdef VMXASSIST
   14.19 -#  define BX_APPNAME "VMXAssist"
   14.20 +#ifdef HVMASSIST
   14.21 +#  define BX_APPNAME "HVMAssist"
   14.22  #elif PLEX86
   14.23  #  define BX_APPNAME "Plex86"
   14.24  #else
   14.25 @@ -1430,7 +1430,7 @@ ASM_START
   14.26  ASM_END
   14.27  }
   14.28  
   14.29 -#ifdef VMXASSIST
   14.30 +#ifdef HVMASSIST
   14.31  void
   14.32  copy_e820_table()
   14.33  {
   14.34 @@ -1440,7 +1440,7 @@ copy_e820_table()
   14.35    write_word(0xe000, 0x8, nr_entries);
   14.36    memcpyb(0xe000, 0x10, 0x9000, 0x2d0, nr_entries * 0x14);
   14.37  }
   14.38 -#endif /* VMXASSIST */
   14.39 +#endif /* HVMASSIST */
   14.40  
   14.41  #if BX_DEBUG_SERIAL
   14.42  /* serial debug port*/
   14.43 @@ -1520,7 +1520,7 @@ send(action, c)
   14.44    if (c == '\n') uart_tx_byte(BX_DEBUG_PORT, '\r');
   14.45    uart_tx_byte(BX_DEBUG_PORT, c);
   14.46  #endif
   14.47 -#ifdef VMXASSIST
   14.48 +#ifdef HVMASSIST
   14.49    outb(0xE9, c);
   14.50  #endif
   14.51  #if BX_VIRTUAL_PORTS
   14.52 @@ -4089,7 +4089,7 @@ ASM_END
   14.53           case 0x20: // coded by osmaker aka K.J.
   14.54              if(regs.u.r32.edx == 0x534D4150) /* SMAP */
   14.55              {
   14.56 -#ifdef VMXASSIST
   14.57 +#ifdef HVMASSIST
   14.58  		if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
   14.59  		    Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
   14.60  
   14.61 @@ -9595,7 +9595,7 @@ post_default_ints:
   14.62    ;; int 1C already points at dummy_iret_handler (above)
   14.63    mov al, #0x34 ; timer0: binary count, 16bit count, mode 2
   14.64    out 0x43, al
   14.65 -#ifdef VMXASSIST
   14.66 +#ifdef HVMASSIST
   14.67    mov al, #0x0b ; #0xe90b = 20 Hz (temporary, until we fix xen/vmx support)
   14.68    out 0x40, al ; lsb
   14.69    mov al, #0xe9
   14.70 @@ -9702,22 +9702,10 @@ post_default_ints:
   14.71    mov al, #0x11 ; send initialisation commands
   14.72    out 0x20, al
   14.73    out 0xa0, al
   14.74 -#ifdef VMXASSIST
   14.75 -  ;; The vm86 emulator expects interrupts to be mapped beyond the reserved
   14.76 -  ;; vectors (0 through 31). Since rombios fully controls the hardware, we
   14.77 -  ;; map it the way the emulator needs it and expect that it will do the
   14.78 -  ;; proper 8086 interrupt translation (that is, master pic base is at 0x8
   14.79 -  ;; and slave pic base is at 0x70).
   14.80 -  mov al, #0x20
   14.81 -  out 0x21, al
   14.82 -  mov al, #0x28
   14.83 -  out 0xa1, al
   14.84 -#else
   14.85    mov al, #0x08
   14.86    out 0x21, al
   14.87    mov al, #0x70
   14.88    out 0xa1, al
   14.89 -#endif
   14.90    mov al, #0x04
   14.91    out 0x21, al
   14.92    mov al, #0x02
   14.93 @@ -9734,7 +9722,7 @@ post_default_ints:
   14.94  #endif
   14.95    out  0xa1, AL ;slave  pic: unmask IRQ 12, 13, 14
   14.96  
   14.97 -#ifdef VMXASSIST
   14.98 +#ifdef HVMASSIST
   14.99    call _copy_e820_table
  14.100  #endif
  14.101  
  14.102 @@ -10368,13 +10356,13 @@ dummy_iret_handler:
  14.103    HALT(__LINE__)
  14.104    iret
  14.105  
  14.106 -#ifdef VMXTEST
  14.107 +#ifdef HVMTEST
  14.108  .org 0xffe0
  14.109    jmp 0xf000:post;
  14.110  #endif
  14.111  
  14.112  .org 0xfff0 ; Power-up Entry Point
  14.113 -#ifdef VMXTEST
  14.114 +#ifdef HVMTEST
  14.115    jmp 0xd000:0x0003;
  14.116  #else
  14.117    jmp 0xf000:post
    15.1 --- a/tools/firmware/rombios/rombios.diffs	Mon Jan 30 18:51:35 2006 +0100
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,206 +0,0 @@
    15.4 ---- /home/leendert/cvs/bochs/bios/rombios.c	2005-05-23 12:18:11.000000000 -0400
    15.5 -+++ rombios.c	2005-06-01 23:46:45.000000000 -0400
    15.6 -@@ -26,6 +26,7 @@
    15.7 - 
    15.8 - // ROM BIOS for use with Bochs/Plex x86 emulation environment
    15.9 - 
   15.10 -+#define VMXASSIST
   15.11 - 
   15.12 - // ROM BIOS compatability entry points:
   15.13 - // ===================================
   15.14 -@@ -170,7 +171,9 @@
   15.15 - #define BASE_MEM_IN_K   (640 - EBDA_SIZE)
   15.16 - 
   15.17 -   // Define the application NAME
   15.18 --#ifdef PLEX86
   15.19 -+#ifdef VMXASSIST
   15.20 -+#  define BX_APPNAME "VMXAssist"
   15.21 -+#elif PLEX86
   15.22 - #  define BX_APPNAME "Plex86"
   15.23 - #else
   15.24 - #  define BX_APPNAME "Bochs"
   15.25 -@@ -314,7 +317,6 @@
   15.26 -   ASM_END
   15.27 -   }
   15.28 -   
   15.29 --#if 0 
   15.30 -   // memcpy of count bytes
   15.31 -     void 
   15.32 -   memcpyb(dseg,doffset,sseg,soffset,count)
   15.33 -@@ -362,6 +364,7 @@
   15.34 -   ASM_END
   15.35 -   }
   15.36 - 
   15.37 -+#if 0 
   15.38 -   // memcpy of count dword
   15.39 -     void 
   15.40 -   memcpyd(dseg,doffset,sseg,soffset,count)
   15.41 -@@ -858,6 +861,7 @@
   15.42 - static void           write_byte();
   15.43 - static void           write_word();
   15.44 - static void           bios_printf();
   15.45 -+static void           copy_e820_table();
   15.46 - 
   15.47 - static Bit8u          inhibit_mouse_int_and_events();
   15.48 - static void           enable_mouse_int_and_events();
   15.49 -@@ -1420,6 +1424,16 @@
   15.50 - ASM_END
   15.51 - }
   15.52 - 
   15.53 -+#ifdef VMXASSIST
   15.54 -+void
   15.55 -+copy_e820_table()
   15.56 -+{
   15.57 -+  Bit8u nr_entries = read_byte(0x9000, 0x1e8);
   15.58 -+  write_word(0xe000, 0x8, nr_entries);
   15.59 -+  memcpyb(0xe000, 0x10, 0x9000, 0x2d0, nr_entries * 0x14);
   15.60 -+}
   15.61 -+#endif /* VMXASSIST */
   15.62 -+
   15.63 - #if BX_DEBUG_SERIAL
   15.64 - /* serial debug port*/
   15.65 - #define BX_DEBUG_PORT 0x03f8
   15.66 -@@ -1498,6 +1512,9 @@
   15.67 -   if (c == '\n') uart_tx_byte(BX_DEBUG_PORT, '\r');
   15.68 -   uart_tx_byte(BX_DEBUG_PORT, c);
   15.69 - #endif
   15.70 -+#ifdef VMXASSIST
   15.71 -+  outb(0xE9, c);
   15.72 -+#endif
   15.73 - #if BX_VIRTUAL_PORTS
   15.74 -   if (action & BIOS_PRINTF_DEBUG) outb(DEBUG_PORT, c);
   15.75 -   if (action & BIOS_PRINTF_INFO) outb(INFO_PORT, c);
   15.76 -@@ -4053,6 +4070,66 @@
   15.77 -          case 0x20: // coded by osmaker aka K.J.
   15.78 -             if(regs.u.r32.edx == 0x534D4150)
   15.79 -             {
   15.80 -+#ifdef VMXASSIST
   15.81 -+		if ((regs.u.r16.bx / 0x14)* 0x14 == regs.u.r16.bx) {
   15.82 -+		    Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
   15.83 -+
   15.84 -+		    if (regs.u.r16.bx + 0x14 <= e820_table_size) {
   15.85 -+			memcpyb(ES, regs.u.r16.di,
   15.86 -+				0xe000, 0x10 + regs.u.r16.bx, 0x14);
   15.87 -+		    }
   15.88 -+		    regs.u.r32.ebx += 0x14;
   15.89 -+		    if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
   15.90 -+			regs.u.r32.ebx = 0;
   15.91 -+		    regs.u.r32.eax = 0x534D4150;
   15.92 -+		    regs.u.r32.ecx = 0x14;
   15.93 -+		    CLEAR_CF();
   15.94 -+		    return;
   15.95 -+		} else if (regs.u.r16.bx == 1) {
   15.96 -+		    extended_memory_size = inb_cmos(0x35);
   15.97 -+		    extended_memory_size <<= 8;
   15.98 -+		    extended_memory_size |= inb_cmos(0x34);
   15.99 -+		    extended_memory_size *= 64;
  15.100 -+		    if (extended_memory_size > 0x3bc000) // greater than EFF00000???
  15.101 -+		    {
  15.102 -+			extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
  15.103 -+		    }
  15.104 -+		    extended_memory_size *= 1024;
  15.105 -+		    extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
  15.106 -+
  15.107 -+		    if (extended_memory_size <= 15728640)
  15.108 -+		    {
  15.109 -+			extended_memory_size = inb_cmos(0x31);
  15.110 -+			extended_memory_size <<= 8;
  15.111 -+			extended_memory_size |= inb_cmos(0x30);
  15.112 -+			extended_memory_size *= 1024;
  15.113 -+		    }
  15.114 -+
  15.115 -+		    write_word(ES, regs.u.r16.di, 0x0000);
  15.116 -+		    write_word(ES, regs.u.r16.di+2, 0x0010);
  15.117 -+		    write_word(ES, regs.u.r16.di+4, 0x0000);
  15.118 -+		    write_word(ES, regs.u.r16.di+6, 0x0000);
  15.119 -+
  15.120 -+		    write_word(ES, regs.u.r16.di+8, extended_memory_size);
  15.121 -+		    extended_memory_size >>= 16;
  15.122 -+		    write_word(ES, regs.u.r16.di+10, extended_memory_size);
  15.123 -+		    extended_memory_size >>= 16;
  15.124 -+		    write_word(ES, regs.u.r16.di+12, extended_memory_size);
  15.125 -+		    extended_memory_size >>= 16;
  15.126 -+		    write_word(ES, regs.u.r16.di+14, extended_memory_size);
  15.127 -+
  15.128 -+		    write_word(ES, regs.u.r16.di+16, 0x1);
  15.129 -+		    write_word(ES, regs.u.r16.di+18, 0x0);
  15.130 -+
  15.131 -+		    regs.u.r32.ebx = 0;
  15.132 -+		    regs.u.r32.eax = 0x534D4150;
  15.133 -+		    regs.u.r32.ecx = 0x14;
  15.134 -+		    CLEAR_CF();
  15.135 -+		    return;
  15.136 -+		} else { /* AX=E820, DX=534D4150, BX unrecognized */
  15.137 -+		    goto int15_unimplemented;
  15.138 -+		}
  15.139 -+#else
  15.140 -                 switch(regs.u.r16.bx)
  15.141 -                 {
  15.142 -                     case 0:
  15.143 -@@ -4070,6 +4147,7 @@
  15.144 -                         write_word(ES, regs.u.r16.di+18, 0x0);
  15.145 - 
  15.146 -                         regs.u.r32.ebx = 1;
  15.147 -+
  15.148 -                         regs.u.r32.eax = 0x534D4150;
  15.149 -                         regs.u.r32.ecx = 0x14;
  15.150 -                         CLEAR_CF();
  15.151 -@@ -4121,6 +4199,7 @@
  15.152 -                         goto int15_unimplemented;
  15.153 -                         break;
  15.154 -                 }
  15.155 -+#endif
  15.156 - 	    } else {
  15.157 - 	      // if DX != 0x534D4150)
  15.158 - 	      goto int15_unimplemented;
  15.159 -@@ -9497,9 +9576,16 @@
  15.160 -   ;; int 1C already points at dummy_iret_handler (above)
  15.161 -   mov al, #0x34 ; timer0: binary count, 16bit count, mode 2
  15.162 -   out 0x43, al
  15.163 -+#ifdef VMXASSIST
  15.164 -+  mov al, #0x0b ; #0xe90b = 20 Hz (temporary, until we fix xen/vmx support)
  15.165 -+  out 0x40, al ; lsb
  15.166 -+  mov al, #0xe9
  15.167 -+  out 0x40, al ; msb
  15.168 -+#else
  15.169 -   mov al, #0x00 ; maximum count of 0000H = 18.2Hz
  15.170 -   out 0x40, al
  15.171 -   out 0x40, al
  15.172 -+#endif
  15.173 - 
  15.174 -   ;; Keyboard
  15.175 -   SET_INT_VECTOR(0x09, #0xF000, #int09_handler)
  15.176 -@@ -9597,10 +9683,22 @@
  15.177 -   mov al, #0x11 ; send initialisation commands
  15.178 -   out 0x20, al
  15.179 -   out 0xa0, al
  15.180 -+#ifdef VMXASSIST
  15.181 -+  ;; The vm86 emulator expects interrupts to be mapped beyond the reserved
  15.182 -+  ;; vectors (0 through 31). Since rombios fully controls the hardware, we
  15.183 -+  ;; map it the way the emulator needs it and expect that it will do the
  15.184 -+  ;; proper 8086 interrupt translation (that is, master pic base is at 0x8
  15.185 -+  ;; and slave pic base is at 0x70).
  15.186 -+  mov al, #0x20
  15.187 -+  out 0x21, al
  15.188 -+  mov al, #0x28
  15.189 -+  out 0xa1, al
  15.190 -+#else
  15.191 -   mov al, #0x08
  15.192 -   out 0x21, al
  15.193 -   mov al, #0x70
  15.194 -   out 0xa1, al
  15.195 -+#endif
  15.196 -   mov al, #0x04
  15.197 -   out 0x21, al
  15.198 -   mov al, #0x02
  15.199 -@@ -9617,6 +9715,10 @@
  15.200 - #endif
  15.201 -   out  0xa1, AL ;slave  pic: unmask IRQ 12, 13, 14
  15.202 - 
  15.203 -+#ifdef VMXASSIST
  15.204 -+  call _copy_e820_table
  15.205 -+#endif
  15.206 -+
  15.207 -   call pcibios_init
  15.208 - 
  15.209 -   call rom_scan
    16.1 --- a/tools/firmware/vmxassist/Makefile	Mon Jan 30 18:51:35 2006 +0100
    16.2 +++ b/tools/firmware/vmxassist/Makefile	Tue Jan 31 11:49:51 2006 +0100
    16.3 @@ -37,13 +37,7 @@ LDFLAGS  = -m elf_i386
    16.4  
    16.5  OBJECTS = head.o trap.o vm86.o setup.o util.o
    16.6  
    16.7 -all: vmxloader
    16.8 -
    16.9 -vmxloader: roms.h vmxloader.c acpi.h acpi_madt.c
   16.10 -	$(CC) $(CFLAGS) $(DEFINES) -c vmxloader.c -c acpi_madt.c
   16.11 -	$(CC) -o vmxloader.tmp -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,0x100000 vmxloader.o acpi_madt.o
   16.12 -	objcopy vmxloader.tmp vmxloader
   16.13 -	rm -f vmxloader.tmp
   16.14 +all: vmxassist.bin
   16.15  
   16.16  vmxassist.bin: vmxassist.ld $(OBJECTS)
   16.17  	$(CPP) $(DEFINES) vmxassist.ld > vmxassist.tmp
   16.18 @@ -68,15 +62,6 @@ setup.o: machine.h setup.c
   16.19  util.o: machine.h util.c
   16.20  	$(CC) $(CFLAGS) -c util.c
   16.21  
   16.22 -roms.h:	../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin vmxassist.bin
   16.23 -	./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
   16.24 -	./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
   16.25 -	./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
   16.26 -	./mkhex vmxassist vmxassist.bin >> roms.h
   16.27 -
   16.28 -acpi.h: ../acpi/acpi.bin
   16.29 -	./mkhex acpi ../acpi/acpi.bin > acpi.h
   16.30 -
   16.31  offsets.h: gen
   16.32  	./gen > offsets.h
   16.33  
   16.34 @@ -84,7 +69,7 @@ gen:	gen.c
   16.35  	$(HOSTCC) $(HOSTCFLAGS) -I. $(XENINC) -o gen gen.c
   16.36  
   16.37  clean:
   16.38 -	rm -f vmxassist vmxassist.tmp vmxassist.bin vmxassist.run vmxassist.sym head.s roms.h acpi.h
   16.39 -	rm -f vmxloader vmxloader.tmp vmxloader.o $(OBJECTS)
   16.40 +	rm -f vmxassist vmxassist.tmp vmxassist.bin vmxassist.run vmxassist.sym head.s
   16.41 +	rm -f $(OBJECTS)
   16.42  	rm -f gen gen.o offsets.h
   16.43  
    17.1 --- a/tools/firmware/vmxassist/acpi_madt.c	Mon Jan 30 18:51:35 2006 +0100
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,189 +0,0 @@
    17.4 -/*
    17.5 - * acpi_madt.c: Update ACPI MADT table for multiple processor guest.
    17.6 - *
    17.7 - * Yu Ke, ke.yu@intel.com
    17.8 - * Copyright (c) 2005, Intel Corporation.
    17.9 - *
   17.10 - * This program is free software; you can redistribute it and/or modify it
   17.11 - * under the terms and conditions of the GNU General Public License,
   17.12 - * version 2, as published by the Free Software Foundation.
   17.13 - *
   17.14 - * This program is distributed in the hope it will be useful, but WITHOUT
   17.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   17.17 - * more details.
   17.18 - *
   17.19 - * You should have received a copy of the GNU General Public License along with
   17.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   17.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   17.22 - */
   17.23 -
   17.24 -#include "../acpi/acpi2_0.h"
   17.25 -#include "../acpi/acpi_madt.h"
   17.26 -
   17.27 -#include <xen/hvm/hvm_info_table.h>
   17.28 -
   17.29 -#define NULL ((void*)0)
   17.30 -
   17.31 -extern int puts(const char *s);
   17.32 -
   17.33 -static struct hvm_info_table *table = NULL;
   17.34 -
   17.35 -static int validate_hvm_info(struct hvm_info_table *t)
   17.36 -{
   17.37 -	char signature[] = "HVM INFO";
   17.38 -	uint8_t *ptr = (uint8_t *)t;
   17.39 -	uint8_t sum = 0;
   17.40 -	int i;
   17.41 -
   17.42 -	/* strncmp(t->signature, "HVM INFO", 8) */
   17.43 -	for (i = 0; i < 8; i++) {
   17.44 -		if (signature[i] != t->signature[i]) {
   17.45 -			puts("Bad hvm info signature\n");
   17.46 -			return 0;
   17.47 -		}
   17.48 -	}
   17.49 -
   17.50 -	for (i = 0; i < t->length; i++)
   17.51 -		sum += ptr[i];
   17.52 -
   17.53 -	return (sum == 0);
   17.54 -}
   17.55 -
   17.56 -/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
   17.57 -static struct hvm_info_table *
   17.58 -get_hvm_info_table(void)
   17.59 -{
   17.60 -	struct hvm_info_table *t;
   17.61 -
   17.62 -	if (table != NULL)
   17.63 -		return table;
   17.64 -
   17.65 -	t = (struct hvm_info_table *)HVM_INFO_PADDR;
   17.66 -
   17.67 -	if (!validate_hvm_info(t)) {
   17.68 -		puts("Bad hvm info table\n");
   17.69 -		return NULL;
   17.70 -	}
   17.71 -
   17.72 -	table = t;
   17.73 -
   17.74 -	return table;
   17.75 -}
   17.76 -
   17.77 -int
   17.78 -get_vcpu_nr(void)
   17.79 -{
   17.80 -	struct hvm_info_table *t = get_hvm_info_table();
   17.81 -	return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
   17.82 -}
   17.83 -
   17.84 -int
   17.85 -get_acpi_enabled(void)
   17.86 -{
   17.87 -	struct hvm_info_table *t = get_hvm_info_table();
   17.88 -	return (t ? t->acpi_enabled : 0); /* default no acpi */
   17.89 -}
   17.90 -
   17.91 -static void *
   17.92 -acpi_madt_get_madt(unsigned char *acpi_start)
   17.93 -{
   17.94 -	ACPI_2_0_RSDP *rsdp=NULL;
   17.95 -	ACPI_2_0_RSDT *rsdt=NULL;
   17.96 -	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
   17.97 -
   17.98 -	rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
   17.99 -	if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
  17.100 -		puts("Bad RSDP signature\n");
  17.101 -		return NULL;
  17.102 -	}
  17.103 -
  17.104 -	rsdt= (ACPI_2_0_RSDT *)
  17.105 -		(acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
  17.106 -	if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
  17.107 -		puts("Bad RSDT signature\n");
  17.108 -		return NULL;
  17.109 -	}
  17.110 -
  17.111 -	madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
  17.112 -		( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
  17.113 -	if (madt->Header.Header.Signature !=
  17.114 -	    ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
  17.115 -		puts("Bad MADT signature \n");
  17.116 -		return NULL;
  17.117 -	}
  17.118 -
  17.119 -	return madt;
  17.120 -}
  17.121 -
  17.122 -static void
  17.123 -set_checksum(void *start, int checksum_offset, int len)
  17.124 -{
  17.125 -	unsigned char sum = 0;
  17.126 -	unsigned char *ptr;
  17.127 -
  17.128 -	ptr = start;
  17.129 -	ptr[checksum_offset] = 0;
  17.130 -	while (len--)
  17.131 -		sum += *ptr++;
  17.132 -
  17.133 -	ptr = start;
  17.134 -	ptr[checksum_offset] = -sum;
  17.135 -}
  17.136 -
  17.137 -static int
  17.138 -acpi_madt_set_local_apics(
  17.139 -	int nr_vcpu,
  17.140 -	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
  17.141 -{
  17.142 -	int i;
  17.143 -
  17.144 -	if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
  17.145 -		return -1;
  17.146 -
  17.147 -	for (i = 0; i < nr_vcpu; i++) {
  17.148 -		madt->LocalApic[i].Type            = ACPI_PROCESSOR_LOCAL_APIC;
  17.149 -		madt->LocalApic[i].Length          = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
  17.150 -		madt->LocalApic[i].AcpiProcessorId = i;
  17.151 -		madt->LocalApic[i].ApicId          = i;
  17.152 -		madt->LocalApic[i].Flags           = 1;
  17.153 -	}
  17.154 -
  17.155 -	madt->Header.Header.Length =
  17.156 -		sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
  17.157 -		(MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
  17.158 -
  17.159 -	return 0;
  17.160 -}
  17.161 -
  17.162 -#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
  17.163 -
  17.164 -int acpi_madt_update(unsigned char *acpi_start)
  17.165 -{
  17.166 -	int rc;
  17.167 -	ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
  17.168 -
  17.169 -	madt = acpi_madt_get_madt(acpi_start);
  17.170 -	if (!madt)
  17.171 -		return -1;
  17.172 -
  17.173 -	rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
  17.174 -	if (rc != 0)
  17.175 -		return rc;
  17.176 -
  17.177 -	set_checksum(
  17.178 -		madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
  17.179 -		madt->Header.Header.Length);
  17.180 -
  17.181 -	return 0;
  17.182 -}
  17.183 -
  17.184 -/*
  17.185 - * Local variables:
  17.186 - *  c-file-style: "linux"
  17.187 - *  indent-tabs-mode: t
  17.188 - *  c-indent-level: 8
  17.189 - *  c-basic-offset: 8
  17.190 - *  tab-width: 8
  17.191 - * End:
  17.192 - */
    18.1 --- a/tools/firmware/vmxassist/head.S	Mon Jan 30 18:51:35 2006 +0100
    18.2 +++ b/tools/firmware/vmxassist/head.S	Tue Jan 31 11:49:51 2006 +0100
    18.3 @@ -111,6 +111,9 @@ 1:
    18.4  	cli
    18.5  
    18.6  	/* save register parameters to C land */
    18.7 +#ifdef TEST
    18.8 +	xorl	%edx, %edx
    18.9 +#endif
   18.10  	movl	%edx, booting_cpu
   18.11  	movl	%ebx, booting_vector
   18.12  
    19.1 --- a/tools/firmware/vmxassist/mkhex	Mon Jan 30 18:51:35 2006 +0100
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,26 +0,0 @@
    19.4 -#!/bin/sh
    19.5 -
    19.6 -#
    19.7 -# mkhex: Generate C embeddable hexdumps
    19.8 -#
    19.9 -# Leendert van Doorn, leendert@watson.ibm.com
   19.10 -# Copyright (c) 2005, International Business Machines Corporation.
   19.11 -#
   19.12 -# This program is free software; you can redistribute it and/or modify it
   19.13 -# under the terms and conditions of the GNU General Public License,
   19.14 -# version 2, as published by the Free Software Foundation.
   19.15 -#
   19.16 -# This program is distributed in the hope it will be useful, but WITHOUT
   19.17 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.18 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   19.19 -# more details.
   19.20 -#
   19.21 -# You should have received a copy of the GNU General Public License along with
   19.22 -# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   19.23 -# Place - Suite 330, Boston, MA 02111-1307 USA.
   19.24 -#
   19.25 -
   19.26 -echo "unsigned $1[] = {"
   19.27 -od -v -t x $2 | sed 's/^[0-9]* /0x/' | sed 's/ /, 0x/g' | sed 's/$/,/'
   19.28 -echo "};"
   19.29 -
    20.1 --- a/tools/firmware/vmxassist/setup.c	Mon Jan 30 18:51:35 2006 +0100
    20.2 +++ b/tools/firmware/vmxassist/setup.c	Tue Jan 31 11:49:51 2006 +0100
    20.3 @@ -194,6 +194,12 @@ setup_pic(void)
    20.4  }
    20.5  
    20.6  void
    20.7 +setiomap(int port)
    20.8 +{
    20.9 +	tss.iomap[port >> 3] |= 1 << (port & 7);
   20.10 +}
   20.11 +
   20.12 +void
   20.13  enter_real_mode(struct regs *regs)
   20.14  {
   20.15  	/* mask off TSS busy bit */
   20.16 @@ -217,6 +223,13 @@ enter_real_mode(struct regs *regs)
   20.17  		}
   20.18  		regs->uesp = 0;
   20.19  		regs->uss = 0;
   20.20 +
   20.21 +		/* intercept accesses to the PIC */
   20.22 +		setiomap(PIC_MASTER+PIC_CMD);
   20.23 +		setiomap(PIC_MASTER+PIC_IMR);
   20.24 +		setiomap(PIC_SLAVE+PIC_CMD);
   20.25 +		setiomap(PIC_SLAVE+PIC_IMR);
   20.26 +
   20.27  		printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n",
   20.28  			regs->cs, regs->eip);
   20.29  
    21.1 --- a/tools/firmware/vmxassist/vm86.c	Mon Jan 30 18:51:35 2006 +0100
    21.2 +++ b/tools/firmware/vmxassist/vm86.c	Tue Jan 31 11:49:51 2006 +0100
    21.3 @@ -738,6 +738,83 @@ interrupt(struct regs *regs, int n)
    21.4  	regs->cs = read16(address(regs, 0, n * 4 + 2));
    21.5  }
    21.6  
    21.7 +/*
    21.8 + * Most port I/O operations are passed unmodified. We do have to be
    21.9 + * careful and make sure the emulated program isn't remapping the
   21.10 + * interrupt vectors. The following simple state machine catches
   21.11 + * these attempts and rewrites them.
   21.12 + */
   21.13 +int
   21.14 +outbyte(struct regs *regs, unsigned prefix, unsigned opc)
   21.15 +{
   21.16 +	static char icw2[2] = { 0 };
   21.17 +	int al, port;
   21.18 +
   21.19 +	switch (opc) {
   21.20 +	case 0xE6: /* outb port, al */
   21.21 +		port = fetch8(regs);
   21.22 +		break;
   21.23 +	case 0xEE: /* outb (%dx), al */
   21.24 +		port = MASK16(regs->edx);
   21.25 +		break;
   21.26 +	default:
   21.27 +		return 0;
   21.28 +	}
   21.29 +
   21.30 +	al = regs->eax & 0xFF;
   21.31 +
   21.32 +	switch (port) {
   21.33 +	case PIC_MASTER + PIC_CMD:
   21.34 +		if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
   21.35 +			icw2[0] = 1;
   21.36 +		break;
   21.37 +	case PIC_MASTER + PIC_IMR:
   21.38 +		if (icw2[0]) {
   21.39 +			icw2[0] = 0;
   21.40 +			printf("Remapping master: ICW2 0x%x -> 0x%x\n",
   21.41 +				al, NR_EXCEPTION_HANDLER);
   21.42 +			al = NR_EXCEPTION_HANDLER;
   21.43 +		}
   21.44 +		break;
   21.45 +
   21.46 +	case PIC_SLAVE  + PIC_CMD:
   21.47 +		if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
   21.48 +			icw2[1] = 1;
   21.49 +		break;
   21.50 +	case PIC_SLAVE  + PIC_IMR:
   21.51 +		if (icw2[1]) {
   21.52 +			icw2[1] = 0;
   21.53 +			printf("Remapping slave: ICW2 0x%x -> 0x%x\n",
   21.54 +				al, NR_EXCEPTION_HANDLER+8);
   21.55 +			al = NR_EXCEPTION_HANDLER+8;
   21.56 +		}
   21.57 +		break;
   21.58 +	}
   21.59 +
   21.60 +	outb(port, al);
   21.61 +	return 1;
   21.62 +}
   21.63 +
   21.64 +int
   21.65 +inbyte(struct regs *regs, unsigned prefix, unsigned opc)
   21.66 +{
   21.67 +	int port;
   21.68 +
   21.69 +	switch (opc) {
   21.70 +	case 0xE4: /* inb al, port */
   21.71 +		port = fetch8(regs);
   21.72 +		break;
   21.73 +	case 0xEC: /* inb al, (%dx) */
   21.74 +		port = MASK16(regs->edx);
   21.75 +		break;
   21.76 +	default:
   21.77 +		return 0;
   21.78 +	}
   21.79 +
   21.80 +	regs->eax = (regs->eax & ~0xFF) | inb(port);
   21.81 +	return 1;
   21.82 +}
   21.83 +
   21.84  enum { OPC_INVALID, OPC_EMULATED };
   21.85  
   21.86  /*
   21.87 @@ -885,6 +962,16 @@ opcode(struct regs *regs)
   21.88  			}
   21.89  			return OPC_EMULATED;
   21.90  
   21.91 +		case 0xE4:	/* inb al, port */
   21.92 +			if (!inbyte(regs, prefix, opc))
   21.93 +				goto invalid;
   21.94 +			return OPC_EMULATED;
   21.95 +
   21.96 +		case 0xE6:	/* outb port, al */
   21.97 +			if (!outbyte(regs, prefix, opc))
   21.98 +				goto invalid;
   21.99 +			return OPC_EMULATED;
  21.100 +
  21.101  		case 0xEA: 	/* jmpl */
  21.102  			if ((mode == VM86_REAL_TO_PROTECTED) ||
  21.103  			    (mode == VM86_PROTECTED_TO_REAL)) {
  21.104 @@ -903,6 +990,16 @@ opcode(struct regs *regs)
  21.105  			}
  21.106  			goto invalid;
  21.107  
  21.108 +		case 0xEC:	/* inb al, (%dx) */
  21.109 +			if (!inbyte(regs, prefix, opc))
  21.110 +				goto invalid;
  21.111 +			return OPC_EMULATED;
  21.112 +
  21.113 +		case 0xEE:	/* outb (%dx), al */
  21.114 +			if (!outbyte(regs, prefix, opc))
  21.115 +				goto invalid;
  21.116 +			return OPC_EMULATED;
  21.117 +
  21.118  		case 0xF0:	/* lock */
  21.119  			TRACE((regs, regs->eip - eip, "lock"));
  21.120  			continue;
    22.1 --- a/tools/firmware/vmxassist/vmxassist.ld	Mon Jan 30 18:51:35 2006 +0100
    22.2 +++ b/tools/firmware/vmxassist/vmxassist.ld	Tue Jan 31 11:49:51 2006 +0100
    22.3 @@ -2,7 +2,6 @@
    22.4   * vmxassist.ld
    22.5   */
    22.6  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    22.7 -/*OUTPUT_ARCH(i386)*/
    22.8  ENTRY(_start)
    22.9  
   22.10  SECTIONS
    23.1 --- a/tools/firmware/vmxassist/vmxloader.c	Mon Jan 30 18:51:35 2006 +0100
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,140 +0,0 @@
    23.4 -/*
    23.5 - * vmxloader.c: ROM/VMXAssist image loader.
    23.6 - *
    23.7 - * A quicky so that we can boot rom images as if they were a Linux kernel.
    23.8 - * This code will copy the rom images (ROMBIOS/VGABIOS/VM86) into their
    23.9 - * respective spaces and transfer control to VM86 to execute the BIOSes.
   23.10 - *
   23.11 - * Leendert van Doorn, leendert@watson.ibm.com
   23.12 - * Copyright (c) 2005, International Business Machines Corporation.
   23.13 - *
   23.14 - * This program is free software; you can redistribute it and/or modify it
   23.15 - * under the terms and conditions of the GNU General Public License,
   23.16 - * version 2, as published by the Free Software Foundation.
   23.17 - *
   23.18 - * This program is distributed in the hope it will be useful, but WITHOUT
   23.19 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.20 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   23.21 - * more details.
   23.22 - *
   23.23 - * You should have received a copy of the GNU General Public License along with
   23.24 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   23.25 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   23.26 - */
   23.27 -#include "machine.h"
   23.28 -#include "roms.h"
   23.29 -
   23.30 -#include "acpi.h"
   23.31 -#include "../acpi/acpi2_0.h"  // for ACPI_PHYSICAL_ADDRESS
   23.32 -int acpi_madt_update(unsigned char* acpi_start);
   23.33 -int get_acpi_enabled(void);
   23.34 -
   23.35 -/*
   23.36 - * C runtime start off
   23.37 - */
   23.38 -asm(
   23.39 -"	.text				\n"
   23.40 -"	.globl	_start			\n"
   23.41 -"_start:				\n"
   23.42 -"	cld				\n"
   23.43 -"	cli				\n"
   23.44 -"	lgdt	gdt_desr		\n"
   23.45 -"	movl	$stack_top, %esp	\n"
   23.46 -"	movl	%esp, %ebp		\n"
   23.47 -"	call	main			\n"
   23.48 -"	jmp	halt			\n"
   23.49 -"					\n"
   23.50 -"gdt_desr:				\n"
   23.51 -"	.word	gdt_end - gdt - 1	\n"
   23.52 -"	.long	gdt			\n"
   23.53 -"					\n"
   23.54 -"	.align	8			\n"
   23.55 -"gdt:					\n"
   23.56 -"	.quad	0x0000000000000000	\n"
   23.57 -"	.quad	0x00CF92000000FFFF	\n"
   23.58 -"	.quad	0x00CF9A000000FFFF	\n"
   23.59 -"gdt_end:				\n"
   23.60 -"					\n"
   23.61 -"halt:					\n"
   23.62 -"	sti				\n"
   23.63 -"	jmp	.			\n"
   23.64 -"					\n"
   23.65 -"	.bss				\n"
   23.66 -"	.align	8			\n"
   23.67 -"stack:					\n"
   23.68 -"	.skip	0x4000			\n"
   23.69 -"stack_top:				\n"
   23.70 -);
   23.71 -
   23.72 -void *
   23.73 -memcpy(void *dest, const void *src, unsigned n)
   23.74 -{
   23.75 -	int t0, t1, t2;
   23.76 -
   23.77 -	__asm__ __volatile__(
   23.78 -		"cld\n"
   23.79 -		"rep; movsl\n"
   23.80 -		"testb $2,%b4\n"
   23.81 -		"je 1f\n"
   23.82 -		"movsw\n"
   23.83 -		"1: testb $1,%b4\n"
   23.84 -		"je 2f\n"
   23.85 -		"movsb\n"
   23.86 -		"2:"
   23.87 -		: "=&c" (t0), "=&D" (t1), "=&S" (t2)
   23.88 -		: "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
   23.89 -		: "memory"
   23.90 -	);
   23.91 -	return dest;
   23.92 -}
   23.93 -
   23.94 -int
   23.95 -puts(const char *s)
   23.96 -{
   23.97 -	while (*s)
   23.98 -		outb(0xE9, *s++);
   23.99 -	return 0;
  23.100 -}
  23.101 -
  23.102 -int
  23.103 -cirrus_check(void)
  23.104 -{
  23.105 -	outw(0x3C4, 0x9206);
  23.106 -	return inb(0x3C5) == 0x12;
  23.107 -}
  23.108 -
  23.109 -int
  23.110 -main(void)
  23.111 -{
  23.112 -	puts("VMXAssist Loader\n");
  23.113 -	puts("Loading ROMBIOS ...\n");
  23.114 -	memcpy((void *)0xF0000, rombios, sizeof(rombios));
  23.115 -	if (cirrus_check()) {
  23.116 -		puts("Loading Cirrus VGABIOS ...\n");
  23.117 -		memcpy((void *)0xC0000,
  23.118 -			vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
  23.119 -	} else {
  23.120 -		puts("Loading Standard VGABIOS ...\n");
  23.121 -		memcpy((void *)0xC0000,
  23.122 -			vgabios_stdvga, sizeof(vgabios_stdvga));
  23.123 -	}
  23.124 -
  23.125 -	if (get_acpi_enabled() != 0) {
  23.126 -		puts("Loading ACPI ...\n");
  23.127 -		acpi_madt_update((unsigned char*)acpi);
  23.128 -		if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
  23.129 -			/* make sure acpi table does not overlap rombios
  23.130 -			 * currently acpi less than 8K will be OK.
  23.131 -			 */
  23.132 -			memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
  23.133 -		}
  23.134 -	}
  23.135 -
  23.136 -	puts("Loading VMXAssist ...\n");
  23.137 -	memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
  23.138 -
  23.139 -	puts("Go ...\n");
  23.140 -	asm volatile ( "jmp *%%eax" : : "a" (TEXTADDR), "d" (0) );
  23.141 -
  23.142 -	return 0;
  23.143 -}
    24.1 --- a/tools/ioemu/exec-all.h	Mon Jan 30 18:51:35 2006 +0100
    24.2 +++ b/tools/ioemu/exec-all.h	Tue Jan 31 11:49:51 2006 +0100
    24.3 @@ -584,5 +584,5 @@ static inline target_ulong get_phys_addr
    24.4  
    24.5  //#define DEBUG_UNUSED_IOPORT
    24.6  //#define DEBUG_IOPORT
    24.7 -#define TARGET_VMX
    24.8 +#define TARGET_HVM
    24.9  
    25.1 --- a/tools/ioemu/hw/i8254.c	Mon Jan 30 18:51:35 2006 +0100
    25.2 +++ b/tools/ioemu/hw/i8254.c	Tue Jan 31 11:49:51 2006 +0100
    25.3 @@ -50,7 +50,7 @@ typedef struct PITChannelState {
    25.4      int64_t next_transition_time;
    25.5      QEMUTimer *irq_timer;
    25.6      int irq;
    25.7 -    int vmx_channel; /* Is this accelerated by VMX ? */
    25.8 +    int hvm_channel; /* Is this accelerated by HVM ? */
    25.9  } PITChannelState;
   25.10  
   25.11  struct PITState {
   25.12 @@ -61,8 +61,8 @@ static PITState pit_state;
   25.13  
   25.14  static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
   25.15  
   25.16 -/* currently operate which channel for vmx use */
   25.17 -int vmx_channel = -1;
   25.18 +/* currently operate which channel for hvm use */
   25.19 +int hvm_channel = -1;
   25.20  extern FILE *logfile;
   25.21  static int pit_get_count(PITChannelState *s)
   25.22  {
   25.23 @@ -215,7 +215,7 @@ int pit_get_gate(PITState *pit, int chan
   25.24      return s->gate;
   25.25  }
   25.26  
   25.27 -void pit_reset_vmx_vectors()
   25.28 +void pit_reset_hvm_vectors()
   25.29  {
   25.30      extern shared_iopage_t *shared_page;
   25.31      ioreq_t *req; 
   25.32 @@ -225,18 +225,18 @@ void pit_reset_vmx_vectors()
   25.33      irq = 0;
   25.34  
   25.35      for(i = 0; i < 3; i++) {
   25.36 -        if (pit_state.channels[i].vmx_channel)
   25.37 +        if (pit_state.channels[i].hvm_channel)
   25.38               break;
   25.39      }
   25.40      
   25.41      if (i == 3)
   25.42          return;
   25.43  
   25.44 -    /* Assumes just one VMX accelerated channel */
   25.45 -    vmx_channel = i;
   25.46 -    s = &pit_state.channels[vmx_channel];
   25.47 +    /* Assumes just one HVM accelerated channel */
   25.48 +    hvm_channel = i;
   25.49 +    s = &pit_state.channels[hvm_channel];
   25.50      fprintf(logfile,
   25.51 -    	"VMX_PIT:guest init pit channel %d!\n", vmx_channel);
   25.52 +    	"HVM_PIT:guest init pit channel %d!\n", hvm_channel);
   25.53      req = &shared_page->vcpu_iodata[0].vp_ioreq;
   25.54  
   25.55      req->state = STATE_IORESP_HOOK;
   25.56 @@ -247,9 +247,9 @@ void pit_reset_vmx_vectors()
   25.57       */
   25.58      req->u.data = s->count;
   25.59      req->u.data |= (irq << 16);
   25.60 -    req->u.data |= (vmx_channel << 24);
   25.61 +    req->u.data |= (hvm_channel << 24);
   25.62      req->u.data |= ((s->rw_mode) << 26);
   25.63 -    fprintf(logfile, "VMX_PIT:pass info 0x%llx to HV!\n", req->u.data);
   25.64 +    fprintf(logfile, "HVM_PIT:pass info 0x%llx to HV!\n", req->u.data);
   25.65  }
   25.66  
   25.67  static inline void pit_load_count(PITChannelState *s, int val)
   25.68 @@ -261,9 +261,9 @@ static inline void pit_load_count(PITCha
   25.69  
   25.70      /* guest init this pit channel for periodic mode. we do not update related
   25.71       * timer so the channel never send intr from device model*/
   25.72 -    if (vmx_channel != -1 && s->mode == 2) {
   25.73 -        pit_reset_vmx_vectors();
   25.74 -        vmx_channel = -1;
   25.75 +    if (hvm_channel != -1 && s->mode == 2) {
   25.76 +        pit_reset_hvm_vectors();
   25.77 +        hvm_channel = -1;
   25.78      }
   25.79  
   25.80  /*    pit_irq_timer_update(s, s->count_load_time);*/
   25.81 @@ -323,8 +323,8 @@ static void pit_ioport_write(void *opaqu
   25.82          }
   25.83      } else {
   25.84          s = &pit->channels[addr];
   25.85 -        s->vmx_channel = 1;
   25.86 -        vmx_channel = addr;
   25.87 +        s->hvm_channel = 1;
   25.88 +        hvm_channel = addr;
   25.89          switch(s->write_state) {
   25.90          default:
   25.91          case RW_STATE_LSB:
    26.1 --- a/tools/ioemu/hw/i8259.c	Mon Jan 30 18:51:35 2006 +0100
    26.2 +++ b/tools/ioemu/hw/i8259.c	Tue Jan 31 11:49:51 2006 +0100
    26.3 @@ -31,7 +31,7 @@
    26.4  //#define DEBUG_IRQ_LATENCY
    26.5  //#define DEBUG_IRQ_COUNT
    26.6  
    26.7 -extern void pit_reset_vmx_vectors();
    26.8 +extern void pit_reset_hvm_vectors();
    26.9  
   26.10  typedef struct PicState {
   26.11      uint8_t last_irr; /* edge detection */
   26.12 @@ -368,7 +368,7 @@ static void pic_ioport_write(void *opaqu
   26.13          case 1:
   26.14              s->irq_base = val & 0xf8;
   26.15              s->init_state = 2;
   26.16 -            pit_reset_vmx_vectors();
   26.17 +            pit_reset_hvm_vectors();
   26.18              break;
   26.19          case 2:
   26.20              if (s->init4) {
    27.1 --- a/tools/ioemu/monitor.c	Mon Jan 30 18:51:35 2006 +0100
    27.2 +++ b/tools/ioemu/monitor.c	Tue Jan 31 11:49:51 2006 +0100
    27.3 @@ -225,10 +225,10 @@ static void do_info_history (void)
    27.4      }
    27.5  }
    27.6  
    27.7 -extern void destroy_vmx_domain(void);
    27.8 +extern void destroy_hvm_domain(void);
    27.9  static void do_quit(void)
   27.10  {
   27.11 -    destroy_vmx_domain();
   27.12 +    destroy_hvm_domain();
   27.13      exit(0);
   27.14  }
   27.15  
   27.16 @@ -506,8 +506,8 @@ static term_cmd_t info_cmds[] = {
   27.17        "", "show i8259 (PIC) state", },
   27.18      { "pci", "", pci_info,
   27.19        "", "show PCI info", },
   27.20 -    { "vmxiopage", "", sp_info,
   27.21 -      "", "show VMX device model shared page info", },
   27.22 +    { "hvmiopage", "", sp_info,
   27.23 +      "", "show HVM device model shared page info", },
   27.24      { NULL, NULL, },
   27.25  };
   27.26  
   27.27 @@ -700,7 +700,7 @@ static void monitor_handle_command(const
   27.28                  args[nb_args++] = (void *)has_option;
   27.29              }
   27.30              break;
   27.31 -        /* TODO: add more commands we need here to support vmx device model */
   27.32 +        /* TODO: add more commands we need here to support hvm device model */
   27.33          case '/':
   27.34          case 'i':
   27.35          default:
   27.36 @@ -772,14 +772,14 @@ static void monitor_handle_command1(void
   27.37  
   27.38  static void monitor_start_input(void)
   27.39  {
   27.40 -    readline_start("(VTXen) ", 0, monitor_handle_command1, NULL);
   27.41 +    readline_start("(HVMXen) ", 0, monitor_handle_command1, NULL);
   27.42  }
   27.43  
   27.44  void monitor_init(CharDriverState *hd, int show_banner)
   27.45  {
   27.46      monitor_hd = hd;
   27.47      if (show_banner) {
   27.48 -        term_printf("VMX device model. type 'q' to exit\n");
   27.49 +        term_printf("HVM device model. type 'q' to exit\n");
   27.50      }
   27.51      qemu_chr_add_read_handler(hd, term_can_read, term_read, NULL);
   27.52      monitor_start_input();
    28.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Mon Jan 30 18:51:35 2006 +0100
    28.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Tue Jan 31 11:49:51 2006 +0100
    28.3 @@ -20,7 +20,9 @@
    28.4  
    28.5  /*
    28.6   * Main cpu loop for handling I/O requests coming from a virtual machine
    28.7 + *
    28.8   * Copyright  2004, Intel Corporation.
    28.9 + * Copyright  2005, International Business Machines Corporation.
   28.10   *
   28.11   * This program is free software; you can redistribute it and/or modify it
   28.12   * under the terms and conditions of the GNU Lesser General Public License,
   28.13 @@ -394,7 +396,7 @@ void cpu_handle_ioreq(CPUState *env)
   28.14  int xc_handle;
   28.15  
   28.16  void
   28.17 -destroy_vmx_domain(void)
   28.18 +destroy_hvm_domain(void)
   28.19  {
   28.20      extern FILE* logfile;
   28.21      char destroy_cmd[32];
   28.22 @@ -467,11 +469,11 @@ int main_loop(void)
   28.23              (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
   28.24          }
   28.25      }
   28.26 -    destroy_vmx_domain();
   28.27 +    destroy_hvm_domain();
   28.28      return 0;
   28.29  }
   28.30  
   28.31 -static void qemu_vmx_reset(void *unused)
   28.32 +static void qemu_hvm_reset(void *unused)
   28.33  {
   28.34      char cmd[64];
   28.35  
   28.36 @@ -489,7 +491,7 @@ CPUState * cpu_init()
   28.37      int rc;
   28.38  
   28.39      cpu_exec_init();
   28.40 -    qemu_register_reset(qemu_vmx_reset, NULL);
   28.41 +    qemu_register_reset(qemu_hvm_reset, NULL);
   28.42      env = malloc(sizeof(CPUX86State));
   28.43      if (!env)
   28.44          return NULL;
    29.1 --- a/tools/ioemu/vl.c	Mon Jan 30 18:51:35 2006 +0100
    29.2 +++ b/tools/ioemu/vl.c	Tue Jan 31 11:49:51 2006 +0100
    29.3 @@ -125,7 +125,7 @@ static char network_script[1024];
    29.4  int pit_min_timer_count = 0;
    29.5  int nb_nics;
    29.6  char bridge[16];
    29.7 -char domain_name[1024] = { 'V', 'T', 'X', 'E', 'N', '-'};
    29.8 +char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
    29.9  NetDriverState nd_table[MAX_NICS];
   29.10  QEMUTimer *gui_timer;
   29.11  QEMUTimer *polling_timer;
   29.12 @@ -826,8 +826,8 @@ static void init_timers(void)
   29.13      {
   29.14          /* get times() syscall frequency */
   29.15          timer_freq = sysconf(_SC_CLK_TCK);
   29.16 -
   29.17 -#ifndef TARGET_VMX
   29.18 +      
   29.19 +#ifndef TARGET_HVM
   29.20          /* timer signal */
   29.21          sigfillset(&act.sa_mask);
   29.22          act.sa_flags = 0;
   29.23 @@ -869,7 +869,7 @@ static void init_timers(void)
   29.24              pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
   29.25                                     PIT_FREQ) / 1000000;
   29.26          }
   29.27 -#endif /* TARGET_VMX */
   29.28 +#endif /* TARGET_HVM */
   29.29      }
   29.30  #endif
   29.31  }
    30.1 --- a/tools/libxc/Makefile	Mon Jan 30 18:51:35 2006 +0100
    30.2 +++ b/tools/libxc/Makefile	Tue Jan 31 11:49:51 2006 +0100
    30.3 @@ -45,7 +45,7 @@ else
    30.4  BUILD_SRCS += xc_load_aout9.c
    30.5  BUILD_SRCS += xc_linux_restore.c
    30.6  BUILD_SRCS += xc_linux_save.c
    30.7 -BUILD_SRCS += xc_vmx_build.c
    30.8 +BUILD_SRCS += xc_hvm_build.c
    30.9  endif
   30.10  
   30.11  CFLAGS   += -Wall
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/libxc/xc_hvm_build.c	Tue Jan 31 11:49:51 2006 +0100
    31.3 @@ -0,0 +1,849 @@
    31.4 +/******************************************************************************
    31.5 + * xc_hvm_build.c
    31.6 + */
    31.7 +
    31.8 +#include <stddef.h>
    31.9 +#include "xg_private.h"
   31.10 +#define ELFSIZE 32
   31.11 +#include "xc_elf.h"
   31.12 +#include <stdlib.h>
   31.13 +#include <unistd.h>
   31.14 +#include <zlib.h>
   31.15 +#include <xen/hvm/hvm_info_table.h>
   31.16 +#include <xen/hvm/ioreq.h>
   31.17 +
   31.18 +#define HVM_LOADER_ENTR_ADDR  0x00100000
   31.19 +
   31.20 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
   31.21 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   31.22 +#ifdef __x86_64__
   31.23 +#define L3_PROT (_PAGE_PRESENT)
   31.24 +#endif
   31.25 +
   31.26 +#define E820MAX	128
   31.27 +
   31.28 +#define E820_RAM          1
   31.29 +#define E820_RESERVED     2
   31.30 +#define E820_ACPI         3
   31.31 +#define E820_NVS          4
   31.32 +#define E820_IO          16
   31.33 +#define E820_SHARED_PAGE 17
   31.34 +#define E820_XENSTORE    18
   31.35 +
   31.36 +#define E820_MAP_PAGE       0x00090000
   31.37 +#define E820_MAP_NR_OFFSET  0x000001E8
   31.38 +#define E820_MAP_OFFSET     0x000002D0
   31.39 +
   31.40 +struct e820entry {
   31.41 +    uint64_t addr;
   31.42 +    uint64_t size;
   31.43 +    uint32_t type;
   31.44 +} __attribute__((packed));
   31.45 +
   31.46 +#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   31.47 +#define round_pgdown(_p)  ((_p)&PAGE_MASK)
   31.48 +
   31.49 +static int
   31.50 +parseelfimage(
   31.51 +    char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
   31.52 +static int
   31.53 +loadelfimage(
   31.54 +    char *elfbase, int xch, uint32_t dom, unsigned long *parray,
   31.55 +    struct domain_setup_info *dsi);
   31.56 +
   31.57 +static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
   31.58 +{
   31.59 +    struct e820entry *e820entry =
   31.60 +        (struct e820entry *)(((unsigned char *)e820_page) + E820_MAP_OFFSET);
   31.61 +    unsigned char nr_map = 0;
   31.62 +
   31.63 +    /* XXX: Doesn't work for > 4GB yet */
   31.64 +    e820entry[nr_map].addr = 0x0;
   31.65 +    e820entry[nr_map].size = 0x9F800;
   31.66 +    e820entry[nr_map].type = E820_RAM;
   31.67 +    nr_map++;
   31.68 +
   31.69 +    e820entry[nr_map].addr = 0x9F800;
   31.70 +    e820entry[nr_map].size = 0x800;
   31.71 +    e820entry[nr_map].type = E820_RESERVED;
   31.72 +    nr_map++;
   31.73 +
   31.74 +    e820entry[nr_map].addr = 0xA0000;
   31.75 +    e820entry[nr_map].size = 0x20000;
   31.76 +    e820entry[nr_map].type = E820_IO;
   31.77 +    nr_map++;
   31.78 +
   31.79 +    e820entry[nr_map].addr = 0xF0000;
   31.80 +    e820entry[nr_map].size = 0x10000;
   31.81 +    e820entry[nr_map].type = E820_RESERVED;
   31.82 +    nr_map++;
   31.83 +
   31.84 +#define STATIC_PAGES    2       /* for ioreq_t and store_mfn */
   31.85 +    /* Most of the ram goes here */
   31.86 +    e820entry[nr_map].addr = 0x100000;
   31.87 +    e820entry[nr_map].size = mem_size - 0x100000 - STATIC_PAGES*PAGE_SIZE;
   31.88 +    e820entry[nr_map].type = E820_RAM;
   31.89 +    nr_map++;
   31.90 +
   31.91 +    /* Statically allocated special pages */
   31.92 +
   31.93 +    /* Shared ioreq_t page */
   31.94 +    e820entry[nr_map].addr = mem_size - PAGE_SIZE;
   31.95 +    e820entry[nr_map].size = PAGE_SIZE;
   31.96 +    e820entry[nr_map].type = E820_SHARED_PAGE;
   31.97 +    nr_map++;
   31.98 +
   31.99 +    /* For xenstore */
  31.100 +    e820entry[nr_map].addr = mem_size - 2*PAGE_SIZE;
  31.101 +    e820entry[nr_map].size = PAGE_SIZE;
  31.102 +    e820entry[nr_map].type = E820_XENSTORE;
  31.103 +    nr_map++;
  31.104 +
  31.105 +    e820entry[nr_map].addr = mem_size;
  31.106 +    e820entry[nr_map].size = 0x3 * PAGE_SIZE;
  31.107 +    e820entry[nr_map].type = E820_NVS;
  31.108 +    nr_map++;
  31.109 +
  31.110 +    e820entry[nr_map].addr = mem_size + 0x3 * PAGE_SIZE;
  31.111 +    e820entry[nr_map].size = 0xA * PAGE_SIZE;
  31.112 +    e820entry[nr_map].type = E820_ACPI;
  31.113 +    nr_map++;
  31.114 +
  31.115 +    e820entry[nr_map].addr = 0xFEC00000;
  31.116 +    e820entry[nr_map].size = 0x1400000;
  31.117 +    e820entry[nr_map].type = E820_IO;
  31.118 +    nr_map++;
  31.119 +
  31.120 +    return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
  31.121 +}
  31.122 +
  31.123 +static void
  31.124 +set_hvm_info_checksum(struct hvm_info_table *t)
  31.125 +{
  31.126 +    uint8_t *ptr = (uint8_t *)t, sum = 0;
  31.127 +    unsigned int i;
  31.128 +
  31.129 +    t->checksum = 0;
  31.130 +
  31.131 +    for (i = 0; i < t->length; i++)
  31.132 +        sum += *ptr++;
  31.133 +
  31.134 +    t->checksum = -sum;
  31.135 +}
  31.136 +
  31.137 +/*
  31.138 + * Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
  31.139 + * hvmloader will use this info to set BIOS accordingly
  31.140 + */
  31.141 +static int set_hvm_info(int xc_handle, uint32_t dom,
  31.142 +                        unsigned long *pfn_list, unsigned int vcpus,
  31.143 +                        unsigned int acpi, unsigned int apic)
  31.144 +{
  31.145 +    char *va_map;
  31.146 +    struct hvm_info_table *va_hvm;
  31.147 +
  31.148 +
  31.149 +    va_map = xc_map_foreign_range(
  31.150 +        xc_handle,
  31.151 +        dom,
  31.152 +        PAGE_SIZE,
  31.153 +        PROT_READ|PROT_WRITE,
  31.154 +        pfn_list[HVM_INFO_PFN]);
  31.155 +    
  31.156 +    if ( va_map == NULL )
  31.157 +        return -1;
  31.158 +
  31.159 +    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
  31.160 +    memset(va_hvm, 0, sizeof(*va_hvm));
  31.161 +    strncpy(va_hvm->signature, "HVM INFO", 8);
  31.162 +    va_hvm->length       = sizeof(struct hvm_info_table);
  31.163 +    va_hvm->acpi_enabled = acpi;
  31.164 +    va_hvm->apic_enabled = apic;
  31.165 +    va_hvm->nr_vcpus     = vcpus;
  31.166 +
  31.167 +    set_hvm_info_checksum(va_hvm);
  31.168 +
  31.169 +    munmap(va_map, PAGE_SIZE);
  31.170 +
  31.171 +    return 0;
  31.172 +}
  31.173 +
  31.174 +#ifdef __i386__
  31.175 +static int zap_mmio_range(int xc_handle, uint32_t dom,
  31.176 +                          l2_pgentry_32_t *vl2tab,
  31.177 +                          unsigned long mmio_range_start,
  31.178 +                          unsigned long mmio_range_size)
  31.179 +{
  31.180 +    unsigned long mmio_addr;
  31.181 +    unsigned long mmio_range_end = mmio_range_start + mmio_range_size;
  31.182 +    unsigned long vl2e;
  31.183 +    l1_pgentry_32_t *vl1tab;
  31.184 +
  31.185 +    mmio_addr = mmio_range_start & PAGE_MASK;
  31.186 +    for (; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE) {
  31.187 +        vl2e = vl2tab[l2_table_offset(mmio_addr)];
  31.188 +        if (vl2e == 0)
  31.189 +            continue;
  31.190 +        vl1tab = xc_map_foreign_range(
  31.191 +            xc_handle, dom, PAGE_SIZE,
  31.192 +            PROT_READ|PROT_WRITE, vl2e >> PAGE_SHIFT);
  31.193 +        if ( vl1tab == 0 )
  31.194 +        {
  31.195 +            PERROR("Failed zap MMIO range");
  31.196 +            return -1;
  31.197 +        }
  31.198 +        vl1tab[l1_table_offset(mmio_addr)] = 0;
  31.199 +        munmap(vl1tab, PAGE_SIZE);
  31.200 +    }
  31.201 +    return 0;
  31.202 +}
  31.203 +
  31.204 +static int zap_mmio_ranges(int xc_handle, uint32_t dom, unsigned long l2tab,
  31.205 +                           unsigned char e820_map_nr, unsigned char *e820map)
  31.206 +{
  31.207 +    unsigned int i;
  31.208 +    struct e820entry *e820entry = (struct e820entry *)e820map;
  31.209 +
  31.210 +    l2_pgentry_32_t *vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.211 +                                                   PROT_READ|PROT_WRITE,
  31.212 +                                                   l2tab >> PAGE_SHIFT);
  31.213 +    if ( vl2tab == 0 )
  31.214 +        return -1;
  31.215 +
  31.216 +    for ( i = 0; i < e820_map_nr; i++ )
  31.217 +    {
  31.218 +        if ( (e820entry[i].type == E820_IO) &&
  31.219 +             (zap_mmio_range(xc_handle, dom, vl2tab,
  31.220 +                             e820entry[i].addr, e820entry[i].size) == -1))
  31.221 +            return -1;
  31.222 +    }
  31.223 +
  31.224 +    munmap(vl2tab, PAGE_SIZE);
  31.225 +    return 0;
  31.226 +}
  31.227 +#else
  31.228 +static int zap_mmio_range(int xc_handle, uint32_t dom,
  31.229 +                          l3_pgentry_t *vl3tab,
  31.230 +                          unsigned long mmio_range_start,
  31.231 +                          unsigned long mmio_range_size)
  31.232 +{
  31.233 +    unsigned long mmio_addr;
  31.234 +    unsigned long mmio_range_end = mmio_range_start + mmio_range_size;
  31.235 +    unsigned long vl2e = 0;
  31.236 +    unsigned long vl3e;
  31.237 +    l1_pgentry_t *vl1tab;
  31.238 +    l2_pgentry_t *vl2tab;
  31.239 +
  31.240 +    mmio_addr = mmio_range_start & PAGE_MASK;
  31.241 +    for ( ; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE )
  31.242 +    {
  31.243 +        vl3e = vl3tab[l3_table_offset(mmio_addr)];
  31.244 +        if ( vl3e == 0 )
  31.245 +            continue;
  31.246 +
  31.247 +        vl2tab = xc_map_foreign_range(
  31.248 +            xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl3e>>PAGE_SHIFT);
  31.249 +        if ( vl2tab == NULL )
  31.250 +        {
  31.251 +            PERROR("Failed zap MMIO range");
  31.252 +            return -1;
  31.253 +        }
  31.254 +
  31.255 +        vl2e = vl2tab[l2_table_offset(mmio_addr)];
  31.256 +        if ( vl2e == 0 )
  31.257 +        {
  31.258 +            munmap(vl2tab, PAGE_SIZE);
  31.259 +            continue;
  31.260 +        }
  31.261 +
  31.262 +        vl1tab = xc_map_foreign_range(
  31.263 +            xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl2e>>PAGE_SHIFT);
  31.264 +        if ( vl1tab == NULL )
  31.265 +        {
  31.266 +            PERROR("Failed zap MMIO range");
  31.267 +            munmap(vl2tab, PAGE_SIZE);
  31.268 +            return -1;
  31.269 +        }
  31.270 +
  31.271 +        vl1tab[l1_table_offset(mmio_addr)] = 0;
  31.272 +        munmap(vl2tab, PAGE_SIZE);
  31.273 +        munmap(vl1tab, PAGE_SIZE);
  31.274 +    }
  31.275 +    return 0;
  31.276 +}
  31.277 +
  31.278 +static int zap_mmio_ranges(int xc_handle, uint32_t dom, unsigned long l3tab,
  31.279 +                           unsigned char e820_map_nr, unsigned char *e820map)
  31.280 +{
  31.281 +    unsigned int i;
  31.282 +    struct e820entry *e820entry = (struct e820entry *)e820map;
  31.283 +
  31.284 +    l3_pgentry_t *vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.285 +                                                PROT_READ|PROT_WRITE,
  31.286 +                                                l3tab >> PAGE_SHIFT);
  31.287 +    if (vl3tab == 0)
  31.288 +        return -1;
  31.289 +    for ( i = 0; i < e820_map_nr; i++ ) {
  31.290 +        if ( (e820entry[i].type == E820_IO) &&
  31.291 +             (zap_mmio_range(xc_handle, dom, vl3tab,
  31.292 +                             e820entry[i].addr, e820entry[i].size) == -1) )
  31.293 +            return -1;
  31.294 +    }
  31.295 +    munmap(vl3tab, PAGE_SIZE);
  31.296 +    return 0;
  31.297 +}
  31.298 +
  31.299 +#endif
  31.300 +
  31.301 +static int setup_guest(int xc_handle,
  31.302 +                       uint32_t dom, int memsize,
  31.303 +                       char *image, unsigned long image_size,
  31.304 +                       unsigned long nr_pages,
  31.305 +                       vcpu_guest_context_t *ctxt,
  31.306 +                       unsigned long shared_info_frame,
  31.307 +                       unsigned int control_evtchn,
  31.308 +                       unsigned int vcpus,
  31.309 +		       unsigned int acpi,
  31.310 +                       unsigned int apic,
  31.311 +                       unsigned int store_evtchn,
  31.312 +                       unsigned long *store_mfn)
  31.313 +{
  31.314 +    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
  31.315 +    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
  31.316 +    unsigned long *page_array = NULL;
  31.317 +#ifdef __x86_64__
  31.318 +    l3_pgentry_t *vl3tab=NULL;
  31.319 +    unsigned long l3tab;
  31.320 +#endif
  31.321 +    unsigned long l2tab = 0;
  31.322 +    unsigned long l1tab = 0;
  31.323 +    unsigned long count, i;
  31.324 +    shared_info_t *shared_info;
  31.325 +    void *e820_page;
  31.326 +    unsigned char e820_map_nr;
  31.327 +    xc_mmu_t *mmu = NULL;
  31.328 +    int rc;
  31.329 +
  31.330 +    unsigned long nr_pt_pages;
  31.331 +    unsigned long ppt_alloc;
  31.332 +
  31.333 +    struct domain_setup_info dsi;
  31.334 +    unsigned long vpt_start;
  31.335 +    unsigned long vpt_end;
  31.336 +    unsigned long v_end;
  31.337 +
  31.338 +    unsigned long shared_page_frame = 0;
  31.339 +    shared_iopage_t *sp;
  31.340 +
  31.341 +    memset(&dsi, 0, sizeof(struct domain_setup_info));
  31.342 +
  31.343 +    if ( (rc = parseelfimage(image, image_size, &dsi)) != 0 )
  31.344 +        goto error_out;
  31.345 +
  31.346 +    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
  31.347 +    {
  31.348 +        PERROR("Guest OS must load to a page boundary.\n");
  31.349 +        goto error_out;
  31.350 +    }
  31.351 +
  31.352 +    /* memsize is in megabytes */
  31.353 +    v_end              = (unsigned long)memsize << 20;
  31.354 +
  31.355 +#ifdef __i386__
  31.356 +    nr_pt_pages = 1 + ((memsize + 3) >> 2);
  31.357 +#else
  31.358 +    nr_pt_pages = 5 + ((memsize + 1) >> 1);
  31.359 +#endif
  31.360 +    vpt_start   = v_end;
  31.361 +    vpt_end     = vpt_start + (nr_pt_pages * PAGE_SIZE);
  31.362 +
  31.363 +    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
  31.364 +           " Loaded HVM loader: %08lx->%08lx\n"
  31.365 +           " Page tables:   %08lx->%08lx\n"
  31.366 +           " TOTAL:         %08lx->%08lx\n",
  31.367 +           dsi.v_kernstart, dsi.v_kernend,
  31.368 +           vpt_start, vpt_end,
  31.369 +           dsi.v_start, v_end);
  31.370 +    printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
  31.371 +
  31.372 +    if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
  31.373 +    {
  31.374 +        ERROR("Initial guest OS requires too much space\n"
  31.375 +               "(%luMB is greater than %luMB limit)\n",
  31.376 +               (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
  31.377 +        goto error_out;
  31.378 +    }
  31.379 +
  31.380 +    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
  31.381 +    {
  31.382 +        PERROR("Could not allocate memory");
  31.383 +        goto error_out;
  31.384 +    }
  31.385 +
  31.386 +    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
  31.387 +    {
  31.388 +        PERROR("Could not get the page frame list");
  31.389 +        goto error_out;
  31.390 +    }
  31.391 +
  31.392 +    loadelfimage(image, xc_handle, dom, page_array, &dsi);
  31.393 +
  31.394 +    if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
  31.395 +        goto error_out;
  31.396 +
  31.397 +    /* First allocate page for page dir or pdpt */
  31.398 +    ppt_alloc = vpt_start >> PAGE_SHIFT;
  31.399 +    if ( page_array[ppt_alloc] > 0xfffff )
  31.400 +    {
  31.401 +        unsigned long nmfn;
  31.402 +        nmfn = xc_make_page_below_4G( xc_handle, dom, page_array[ppt_alloc] );
  31.403 +        if ( nmfn == 0 )
  31.404 +        {
  31.405 +            fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
  31.406 +            goto error_out;
  31.407 +        }
  31.408 +        page_array[ppt_alloc] = nmfn;
  31.409 +    }
  31.410 +
  31.411 +#ifdef __i386__
  31.412 +    l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  31.413 +    ctxt->ctrlreg[3] = l2tab;
  31.414 +
  31.415 +    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.416 +                                        PROT_READ|PROT_WRITE,
  31.417 +                                        l2tab >> PAGE_SHIFT)) == NULL )
  31.418 +        goto error_out;
  31.419 +    memset(vl2tab, 0, PAGE_SIZE);
  31.420 +    vl2e = &vl2tab[l2_table_offset(0)];
  31.421 +    for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
  31.422 +    {
  31.423 +        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
  31.424 +        {
  31.425 +            l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  31.426 +            if ( vl1tab != NULL )
  31.427 +                munmap(vl1tab, PAGE_SIZE);
  31.428 +            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.429 +                                                PROT_READ|PROT_WRITE,
  31.430 +                                                l1tab >> PAGE_SHIFT)) == NULL )
  31.431 +            {
  31.432 +                munmap(vl2tab, PAGE_SIZE);
  31.433 +                goto error_out;
  31.434 +            }
  31.435 +            memset(vl1tab, 0, PAGE_SIZE);
  31.436 +            vl1e = &vl1tab[l1_table_offset(count << PAGE_SHIFT)];
  31.437 +            *vl2e++ = l1tab | L2_PROT;
  31.438 +        }
  31.439 +
  31.440 +        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
  31.441 +        vl1e++;
  31.442 +    }
  31.443 +    munmap(vl1tab, PAGE_SIZE);
  31.444 +    munmap(vl2tab, PAGE_SIZE);
  31.445 +#else
  31.446 +    l3tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  31.447 +    ctxt->ctrlreg[3] = l3tab;
  31.448 +
  31.449 +    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.450 +                                        PROT_READ|PROT_WRITE,
  31.451 +                                        l3tab >> PAGE_SHIFT)) == NULL )
  31.452 +        goto error_out;
  31.453 +    memset(vl3tab, 0, PAGE_SIZE);
  31.454 +
  31.455 +    /* Fill in every PDPT entry. */
  31.456 +    for ( i = 0; i < L3_PAGETABLE_ENTRIES_PAE; i++ )
  31.457 +    {
  31.458 +        l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  31.459 +        if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.460 +                                            PROT_READ|PROT_WRITE,
  31.461 +                                            l2tab >> PAGE_SHIFT)) == NULL )
  31.462 +            goto error_out;
  31.463 +        memset(vl2tab, 0, PAGE_SIZE);
  31.464 +        munmap(vl2tab, PAGE_SIZE);
  31.465 +        vl2tab = NULL;
  31.466 +        vl3tab[i] = l2tab | L3_PROT;
  31.467 +    }
  31.468 +
  31.469 +    for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
  31.470 +    {
  31.471 +        if ( !(count & ((1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)) - 1)) )
  31.472 +        {
  31.473 +            l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
  31.474 +                    & PAGE_MASK;
  31.475 +
  31.476 +            if (vl2tab != NULL)
  31.477 +                munmap(vl2tab, PAGE_SIZE);
  31.478 +
  31.479 +            if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.480 +                                                PROT_READ|PROT_WRITE,
  31.481 +                                                l2tab >> PAGE_SHIFT)) == NULL )
  31.482 +                goto error_out;
  31.483 +
  31.484 +            vl2e = &vl2tab[l2_table_offset(count << PAGE_SHIFT)];
  31.485 +        }
  31.486 +        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
  31.487 +        {
  31.488 +            l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  31.489 +            if ( vl1tab != NULL )
  31.490 +                munmap(vl1tab, PAGE_SIZE);
  31.491 +            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  31.492 +                                                PROT_READ|PROT_WRITE,
  31.493 +                                                l1tab >> PAGE_SHIFT)) == NULL )
  31.494 +            {
  31.495 +                munmap(vl2tab, PAGE_SIZE);
  31.496 +                goto error_out;
  31.497 +            }
  31.498 +            memset(vl1tab, 0, PAGE_SIZE);
  31.499 +            vl1e = &vl1tab[l1_table_offset(count << PAGE_SHIFT)];
  31.500 +            *vl2e++ = l1tab | L2_PROT;
  31.501 +        }
  31.502 +
  31.503 +        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
  31.504 +        vl1e++;
  31.505 +    }
  31.506 +
  31.507 +    munmap(vl1tab, PAGE_SIZE);
  31.508 +    munmap(vl2tab, PAGE_SIZE);
  31.509 +    munmap(vl3tab, PAGE_SIZE);
  31.510 +#endif
  31.511 +    /* Write the machine->phys table entries. */
  31.512 +    for ( count = 0; count < nr_pages; count++ )
  31.513 +    {
  31.514 +        if ( xc_add_mmu_update(xc_handle, mmu,
  31.515 +                               (page_array[count] << PAGE_SHIFT) |
  31.516 +                               MMU_MACHPHYS_UPDATE, count) )
  31.517 +            goto error_out;
  31.518 +    }
  31.519 +
  31.520 +    if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi, apic) ) {
  31.521 +        fprintf(stderr, "Couldn't set hvm info for HVM guest.\n");
  31.522 +        goto error_out;
  31.523 +    }
  31.524 +
  31.525 +    if ( (e820_page = xc_map_foreign_range(
  31.526 +         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  31.527 +         page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0 )
  31.528 +        goto error_out;
  31.529 +    memset(e820_page, 0, PAGE_SIZE);
  31.530 +    e820_map_nr = build_e820map(e820_page, v_end);
  31.531 +#if defined (__i386__)
  31.532 +    if (zap_mmio_ranges(xc_handle, dom, l2tab, e820_map_nr,
  31.533 +                        ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
  31.534 +#else
  31.535 +    if (zap_mmio_ranges(xc_handle, dom, l3tab, e820_map_nr,
  31.536 +                        ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
  31.537 +#endif
  31.538 +        goto error_out;
  31.539 +    munmap(e820_page, PAGE_SIZE);
  31.540 +
  31.541 +    /* shared_info page starts its life empty. */
  31.542 +    if ( (shared_info = xc_map_foreign_range(
  31.543 +         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  31.544 +         shared_info_frame)) == 0 )
  31.545 +        goto error_out;
  31.546 +    memset(shared_info, 0, sizeof(shared_info_t));
  31.547 +    /* Mask all upcalls... */
  31.548 +    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
  31.549 +        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
  31.550 +    munmap(shared_info, PAGE_SIZE);
  31.551 +
  31.552 +    /* Populate the event channel port in the shared page */
  31.553 +    shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1];
  31.554 +    if ( (sp = (shared_iopage_t *) xc_map_foreign_range(
  31.555 +         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  31.556 +         shared_page_frame)) == 0 )
  31.557 +        goto error_out;
  31.558 +    memset(sp, 0, PAGE_SIZE);
  31.559 +    sp->sp_global.eport = control_evtchn;
  31.560 +    munmap(sp, PAGE_SIZE);
  31.561 +
  31.562 +    *store_mfn = page_array[(v_end >> PAGE_SHIFT) - 2];
  31.563 +    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
  31.564 +        goto error_out;
  31.565 +
  31.566 +    /* Send the page update requests down to the hypervisor. */
  31.567 +    if ( xc_finish_mmu_updates(xc_handle, mmu) )
  31.568 +        goto error_out;
  31.569 +
  31.570 +    free(mmu);
  31.571 +    free(page_array);
  31.572 +
  31.573 +    /*
  31.574 +     * Initial register values:
  31.575 +     */
  31.576 +    ctxt->user_regs.ds = 0;
  31.577 +    ctxt->user_regs.es = 0;
  31.578 +    ctxt->user_regs.fs = 0;
  31.579 +    ctxt->user_regs.gs = 0;
  31.580 +    ctxt->user_regs.ss = 0;
  31.581 +    ctxt->user_regs.cs = 0;
  31.582 +    ctxt->user_regs.eip = dsi.v_kernentry;
  31.583 +    ctxt->user_regs.edx = 0;
  31.584 +    ctxt->user_regs.eax = 0;
  31.585 +    ctxt->user_regs.esp = 0;
  31.586 +    ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */
  31.587 +    ctxt->user_regs.ecx = 0;
  31.588 +    ctxt->user_regs.esi = 0;
  31.589 +    ctxt->user_regs.edi = 0;
  31.590 +    ctxt->user_regs.ebp = 0;
  31.591 +
  31.592 +    ctxt->user_regs.eflags = 0;
  31.593 +
  31.594 +    return 0;
  31.595 +
  31.596 + error_out:
  31.597 +    free(mmu);
  31.598 +    free(page_array);
  31.599 +    return -1;
  31.600 +}
  31.601 +
  31.602 +int xc_hvm_build(int xc_handle,
  31.603 +                 uint32_t domid,
  31.604 +                 int memsize,
  31.605 +                 const char *image_name,
  31.606 +                 unsigned int control_evtchn,
  31.607 +                 unsigned int vcpus,
  31.608 +		 unsigned int acpi,
  31.609 +                 unsigned int apic,
  31.610 +                 unsigned int store_evtchn,
  31.611 +                 unsigned long *store_mfn)
  31.612 +{
  31.613 +    dom0_op_t launch_op, op;
  31.614 +    int rc, i;
  31.615 +    vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
  31.616 +    unsigned long nr_pages;
  31.617 +    char         *image = NULL;
  31.618 +    unsigned long image_size;
  31.619 +    xen_capabilities_info_t xen_caps;
  31.620 +
  31.621 +    if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
  31.622 +    {
  31.623 +        PERROR("Failed to get xen version info");
  31.624 +        goto error_out;
  31.625 +    }
  31.626 +
  31.627 +    if ( !strstr(xen_caps, "hvm") )
  31.628 +    {
  31.629 +	PERROR("CPU doesn't support HVM extensions or "
  31.630 +	       "the extensions are not enabled");
  31.631 +        goto error_out;
  31.632 +    }
  31.633 +
  31.634 +    if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
  31.635 +    {
  31.636 +        PERROR("Could not find total pages for domain");
  31.637 +        goto error_out;
  31.638 +    }
  31.639 +
  31.640 +    if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
  31.641 +        goto error_out;
  31.642 +
  31.643 +    if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
  31.644 +    {
  31.645 +        PERROR("%s: ctxt mlock failed", __func__);
  31.646 +        return 1;
  31.647 +    }
  31.648 +
  31.649 +    op.cmd = DOM0_GETDOMAININFO;
  31.650 +    op.u.getdomaininfo.domain = (domid_t)domid;
  31.651 +    if ( (xc_dom0_op(xc_handle, &op) < 0) ||
  31.652 +         ((uint16_t)op.u.getdomaininfo.domain != domid) )
  31.653 +    {
  31.654 +        PERROR("Could not get info on domain");
  31.655 +        goto error_out;
  31.656 +    }
  31.657 +
  31.658 +    memset(ctxt, 0, sizeof(*ctxt));
  31.659 +
  31.660 +    ctxt->flags = VGCF_HVM_GUEST;
  31.661 +    if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
  31.662 +                     ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
  31.663 +                     vcpus, acpi, apic, store_evtchn, store_mfn) < 0)
  31.664 +    {
  31.665 +        ERROR("Error constructing guest OS");
  31.666 +        goto error_out;
  31.667 +    }
  31.668 +
  31.669 +    free(image);
  31.670 +
  31.671 +    /* FPU is set up to default initial state. */
  31.672 +    memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
  31.673 +
  31.674 +    /* Virtual IDT is empty at start-of-day. */
  31.675 +    for ( i = 0; i < 256; i++ )
  31.676 +    {
  31.677 +        ctxt->trap_ctxt[i].vector = i;
  31.678 +        ctxt->trap_ctxt[i].cs     = FLAT_KERNEL_CS;
  31.679 +    }
  31.680 +
  31.681 +    /* No LDT. */
  31.682 +    ctxt->ldt_ents = 0;
  31.683 +
  31.684 +    /* Use the default Xen-provided GDT. */
  31.685 +    ctxt->gdt_ents = 0;
  31.686 +
  31.687 +    /* No debugging. */
  31.688 +    memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
  31.689 +
  31.690 +    /* No callback handlers. */
  31.691 +#if defined(__i386__)
  31.692 +    ctxt->event_callback_cs     = FLAT_KERNEL_CS;
  31.693 +    ctxt->event_callback_eip    = 0;
  31.694 +    ctxt->failsafe_callback_cs  = FLAT_KERNEL_CS;
  31.695 +    ctxt->failsafe_callback_eip = 0;
  31.696 +#elif defined(__x86_64__)
  31.697 +    ctxt->event_callback_eip    = 0;
  31.698 +    ctxt->failsafe_callback_eip = 0;
  31.699 +    ctxt->syscall_callback_eip  = 0;
  31.700 +#endif
  31.701 +
  31.702 +    memset( &launch_op, 0, sizeof(launch_op) );
  31.703 +
  31.704 +    launch_op.u.setvcpucontext.domain = (domid_t)domid;
  31.705 +    launch_op.u.setvcpucontext.vcpu   = 0;
  31.706 +    launch_op.u.setvcpucontext.ctxt   = ctxt;
  31.707 +
  31.708 +    launch_op.cmd = DOM0_SETVCPUCONTEXT;
  31.709 +    rc = xc_dom0_op(xc_handle, &launch_op);
  31.710 +
  31.711 +    return rc;
  31.712 +
  31.713 + error_out:
  31.714 +    free(image);
  31.715 +    return -1;
  31.716 +}
  31.717 +
  31.718 +static inline int is_loadable_phdr(Elf32_Phdr *phdr)
  31.719 +{
  31.720 +    return ((phdr->p_type == PT_LOAD) &&
  31.721 +            ((phdr->p_flags & (PF_W|PF_X)) != 0));
  31.722 +}
  31.723 +
  31.724 +static int parseelfimage(char *elfbase,
  31.725 +                         unsigned long elfsize,
  31.726 +                         struct domain_setup_info *dsi)
  31.727 +{
  31.728 +    Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
  31.729 +    Elf32_Phdr *phdr;
  31.730 +    Elf32_Shdr *shdr;
  31.731 +    unsigned long kernstart = ~0UL, kernend=0UL;
  31.732 +    char *shstrtab;
  31.733 +    int h;
  31.734 +
  31.735 +    if ( !IS_ELF(*ehdr) )
  31.736 +    {
  31.737 +        ERROR("Kernel image does not have an ELF header.");
  31.738 +        return -EINVAL;
  31.739 +    }
  31.740 +
  31.741 +    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
  31.742 +    {
  31.743 +        ERROR("ELF program headers extend beyond end of image.");
  31.744 +        return -EINVAL;
  31.745 +    }
  31.746 +
  31.747 +    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
  31.748 +    {
  31.749 +        ERROR("ELF section headers extend beyond end of image.");
  31.750 +        return -EINVAL;
  31.751 +    }
  31.752 +
  31.753 +    /* Find the section-header strings table. */
  31.754 +    if ( ehdr->e_shstrndx == SHN_UNDEF )
  31.755 +    {
  31.756 +        ERROR("ELF image has no section-header strings table (shstrtab).");
  31.757 +        return -EINVAL;
  31.758 +    }
  31.759 +    shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
  31.760 +                          (ehdr->e_shstrndx*ehdr->e_shentsize));
  31.761 +    shstrtab = elfbase + shdr->sh_offset;
  31.762 +
  31.763 +    for ( h = 0; h < ehdr->e_phnum; h++ )
  31.764 +    {
  31.765 +        phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
  31.766 +        if ( !is_loadable_phdr(phdr) )
  31.767 +            continue;
  31.768 +        if ( phdr->p_paddr < kernstart )
  31.769 +            kernstart = phdr->p_paddr;
  31.770 +        if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
  31.771 +            kernend = phdr->p_paddr + phdr->p_memsz;
  31.772 +    }
  31.773 +
  31.774 +    if ( (kernstart > kernend) ||
  31.775 +         (ehdr->e_entry < kernstart) ||
  31.776 +         (ehdr->e_entry > kernend) )
  31.777 +    {
  31.778 +        ERROR("Malformed ELF image.");
  31.779 +        return -EINVAL;
  31.780 +    }
  31.781 +
  31.782 +    dsi->v_start = 0x00000000;
  31.783 +
  31.784 +    dsi->v_kernstart = kernstart;
  31.785 +    dsi->v_kernend   = kernend;
  31.786 +    dsi->v_kernentry = HVM_LOADER_ENTR_ADDR;
  31.787 +
  31.788 +    dsi->v_end       = dsi->v_kernend;
  31.789 +
  31.790 +    return 0;
  31.791 +}
  31.792 +
  31.793 +static int
  31.794 +loadelfimage(
  31.795 +    char *elfbase, int xch, uint32_t dom, unsigned long *parray,
  31.796 +    struct domain_setup_info *dsi)
  31.797 +{
  31.798 +    Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
  31.799 +    Elf32_Phdr *phdr;
  31.800 +    int h;
  31.801 +
  31.802 +    char         *va;
  31.803 +    unsigned long pa, done, chunksz;
  31.804 +
  31.805 +    for ( h = 0; h < ehdr->e_phnum; h++ )
  31.806 +    {
  31.807 +        phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
  31.808 +        if ( !is_loadable_phdr(phdr) )
  31.809 +            continue;
  31.810 +
  31.811 +        for ( done = 0; done < phdr->p_filesz; done += chunksz )
  31.812 +        {
  31.813 +            pa = (phdr->p_paddr + done) - dsi->v_start;
  31.814 +            if ((va = xc_map_foreign_range(
  31.815 +                xch, dom, PAGE_SIZE, PROT_WRITE,
  31.816 +                parray[pa >> PAGE_SHIFT])) == 0)
  31.817 +                return -1;
  31.818 +            chunksz = phdr->p_filesz - done;
  31.819 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  31.820 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  31.821 +            memcpy(va + (pa & (PAGE_SIZE-1)),
  31.822 +                   elfbase + phdr->p_offset + done, chunksz);
  31.823 +            munmap(va, PAGE_SIZE);
  31.824 +        }
  31.825 +
  31.826 +        for ( ; done < phdr->p_memsz; done += chunksz )
  31.827 +        {
  31.828 +            pa = (phdr->p_paddr + done) - dsi->v_start;
  31.829 +            if ((va = xc_map_foreign_range(
  31.830 +                xch, dom, PAGE_SIZE, PROT_WRITE,
  31.831 +                parray[pa >> PAGE_SHIFT])) == 0)
  31.832 +                return -1;
  31.833 +            chunksz = phdr->p_memsz - done;
  31.834 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  31.835 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  31.836 +            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
  31.837 +            munmap(va, PAGE_SIZE);
  31.838 +        }
  31.839 +    }
  31.840 +
  31.841 +    return 0;
  31.842 +}
  31.843 +
  31.844 +/*
  31.845 + * Local variables:
  31.846 + * mode: C
  31.847 + * c-set-style: "BSD"
  31.848 + * c-basic-offset: 4
  31.849 + * tab-width: 4
  31.850 + * indent-tabs-mode: nil
  31.851 + * End:
  31.852 + */
    32.1 --- a/tools/libxc/xc_ia64_stubs.c	Mon Jan 30 18:51:35 2006 +0100
    32.2 +++ b/tools/libxc/xc_ia64_stubs.c	Tue Jan 31 11:49:51 2006 +0100
    32.3 @@ -621,7 +621,7 @@ static int setup_guest(  int xc_handle,
    32.4      return -1;
    32.5  }
    32.6  
    32.7 -int xc_vmx_build(int xc_handle,
    32.8 +int xc_hvm_build(int xc_handle,
    32.9                   uint32_t domid,
   32.10                   int memsize,
   32.11                   const char *image_name,
    33.1 --- a/tools/libxc/xc_linux_build.c	Mon Jan 30 18:51:35 2006 +0100
    33.2 +++ b/tools/libxc/xc_linux_build.c	Tue Jan 31 11:49:51 2006 +0100
    33.3 @@ -815,7 +815,7 @@ static int setup_guest(int xc_handle,
    33.4          start_info->mod_len      = initrd_len;
    33.5      }
    33.6      if ( cmdline != NULL )
    33.7 -    {
    33.8 +    { 
    33.9          strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
   33.10          start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
   33.11      }
    34.1 --- a/tools/libxc/xc_ptrace.c	Mon Jan 30 18:51:35 2006 +0100
    34.2 +++ b/tools/libxc/xc_ptrace.c	Tue Jan 31 11:49:51 2006 +0100
    34.3 @@ -240,7 +240,7 @@ map_domain_va(
    34.4      }
    34.5      if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
    34.6          goto error_out;
    34.7 -    if ( (ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]) )
    34.8 +    if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
    34.9          pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
   34.10      if ( pde != pde_phys[cpu] )
   34.11      {
   34.12 @@ -255,7 +255,7 @@ map_domain_va(
   34.13      }
   34.14      if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
   34.15          goto error_out;
   34.16 -    if ( (ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]) )
   34.17 +    if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
   34.18          page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
   34.19      if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
   34.20      {
    35.1 --- a/tools/libxc/xc_ptrace_core.c	Mon Jan 30 18:51:35 2006 +0100
    35.2 +++ b/tools/libxc/xc_ptrace_core.c	Tue Jan 31 11:49:51 2006 +0100
    35.3 @@ -126,7 +126,7 @@ map_domain_va(unsigned long domfd, int c
    35.4      } 
    35.5      if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */
    35.6          goto error_out;
    35.7 -    if (ctxt[cpu].flags & VGCF_VMX_GUEST)
    35.8 +    if (ctxt[cpu].flags & VGCF_HVM_GUEST)
    35.9          pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
   35.10      if (pde != pde_phys[cpu]) 
   35.11      {
   35.12 @@ -142,7 +142,7 @@ map_domain_va(unsigned long domfd, int c
   35.13      }
   35.14      if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */
   35.15          goto error_out;
   35.16 -    if (ctxt[cpu].flags & VGCF_VMX_GUEST)
   35.17 +    if (ctxt[cpu].flags & VGCF_HVM_GUEST)
   35.18          page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
   35.19      if (page != page_phys[cpu]) 
   35.20      {
    36.1 --- a/tools/libxc/xc_vmx_build.c	Mon Jan 30 18:51:35 2006 +0100
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,848 +0,0 @@
    36.4 -/******************************************************************************
    36.5 - * xc_vmx_build.c
    36.6 - */
    36.7 -
    36.8 -#include <stddef.h>
    36.9 -#include "xg_private.h"
   36.10 -#define ELFSIZE 32
   36.11 -#include "xc_elf.h"
   36.12 -#include <stdlib.h>
   36.13 -#include <unistd.h>
   36.14 -#include <zlib.h>
   36.15 -#include <xen/hvm/hvm_info_table.h>
   36.16 -#include <xen/hvm/ioreq.h>
   36.17 -
   36.18 -#define VMX_LOADER_ENTR_ADDR  0x00100000
   36.19 -
   36.20 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
   36.21 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   36.22 -#ifdef __x86_64__
   36.23 -#define L3_PROT (_PAGE_PRESENT)
   36.24 -#endif
   36.25 -
   36.26 -#define E820MAX	128
   36.27 -
   36.28 -#define E820_RAM          1
   36.29 -#define E820_RESERVED     2
   36.30 -#define E820_ACPI         3
   36.31 -#define E820_NVS          4
   36.32 -#define E820_IO          16
   36.33 -#define E820_SHARED_PAGE 17
   36.34 -#define E820_XENSTORE    18
   36.35 -
   36.36 -#define E820_MAP_PAGE       0x00090000
   36.37 -#define E820_MAP_NR_OFFSET  0x000001E8
   36.38 -#define E820_MAP_OFFSET     0x000002D0
   36.39 -
   36.40 -struct e820entry {
   36.41 -    uint64_t addr;
   36.42 -    uint64_t size;
   36.43 -    uint32_t type;
   36.44 -} __attribute__((packed));
   36.45 -
   36.46 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   36.47 -#define round_pgdown(_p)  ((_p)&PAGE_MASK)
   36.48 -
   36.49 -static int
   36.50 -parseelfimage(
   36.51 -    char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
   36.52 -static int
   36.53 -loadelfimage(
   36.54 -    char *elfbase, int xch, uint32_t dom, unsigned long *parray,
   36.55 -    struct domain_setup_info *dsi);
   36.56 -
   36.57 -static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
   36.58 -{
   36.59 -    struct e820entry *e820entry =
   36.60 -        (struct e820entry *)(((unsigned char *)e820_page) + E820_MAP_OFFSET);
   36.61 -    unsigned char nr_map = 0;
   36.62 -
   36.63 -    /* XXX: Doesn't work for > 4GB yet */
   36.64 -    e820entry[nr_map].addr = 0x0;
   36.65 -    e820entry[nr_map].size = 0x9F800;
   36.66 -    e820entry[nr_map].type = E820_RAM;
   36.67 -    nr_map++;
   36.68 -
   36.69 -    e820entry[nr_map].addr = 0x9F800;
   36.70 -    e820entry[nr_map].size = 0x800;
   36.71 -    e820entry[nr_map].type = E820_RESERVED;
   36.72 -    nr_map++;
   36.73 -
   36.74 -    e820entry[nr_map].addr = 0xA0000;
   36.75 -    e820entry[nr_map].size = 0x20000;
   36.76 -    e820entry[nr_map].type = E820_IO;
   36.77 -    nr_map++;
   36.78 -
   36.79 -    e820entry[nr_map].addr = 0xF0000;
   36.80 -    e820entry[nr_map].size = 0x10000;
   36.81 -    e820entry[nr_map].type = E820_RESERVED;
   36.82 -    nr_map++;
   36.83 -
   36.84 -#define STATIC_PAGES    2       /* for ioreq_t and store_mfn */
   36.85 -    /* Most of the ram goes here */
   36.86 -    e820entry[nr_map].addr = 0x100000;
   36.87 -    e820entry[nr_map].size = mem_size - 0x100000 - STATIC_PAGES*PAGE_SIZE;
   36.88 -    e820entry[nr_map].type = E820_RAM;
   36.89 -    nr_map++;
   36.90 -
   36.91 -    /* Statically allocated special pages */
   36.92 -
   36.93 -    /* Shared ioreq_t page */
   36.94 -    e820entry[nr_map].addr = mem_size - PAGE_SIZE;
   36.95 -    e820entry[nr_map].size = PAGE_SIZE;
   36.96 -    e820entry[nr_map].type = E820_SHARED_PAGE;
   36.97 -    nr_map++;
   36.98 -
   36.99 -    /* For xenstore */
  36.100 -    e820entry[nr_map].addr = mem_size - 2*PAGE_SIZE;
  36.101 -    e820entry[nr_map].size = PAGE_SIZE;
  36.102 -    e820entry[nr_map].type = E820_XENSTORE;
  36.103 -    nr_map++;
  36.104 -
  36.105 -    e820entry[nr_map].addr = mem_size;
  36.106 -    e820entry[nr_map].size = 0x3 * PAGE_SIZE;
  36.107 -    e820entry[nr_map].type = E820_NVS;
  36.108 -    nr_map++;
  36.109 -
  36.110 -    e820entry[nr_map].addr = mem_size + 0x3 * PAGE_SIZE;
  36.111 -    e820entry[nr_map].size = 0xA * PAGE_SIZE;
  36.112 -    e820entry[nr_map].type = E820_ACPI;
  36.113 -    nr_map++;
  36.114 -
  36.115 -    e820entry[nr_map].addr = 0xFEC00000;
  36.116 -    e820entry[nr_map].size = 0x1400000;
  36.117 -    e820entry[nr_map].type = E820_IO;
  36.118 -    nr_map++;
  36.119 -
  36.120 -    return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
  36.121 -}
  36.122 -
  36.123 -static void
  36.124 -set_hvm_info_checksum(struct hvm_info_table *t)
  36.125 -{
  36.126 -    uint8_t *ptr = (uint8_t *)t, sum = 0;
  36.127 -    unsigned int i;
  36.128 -
  36.129 -    t->checksum = 0;
  36.130 -
  36.131 -    for (i = 0; i < t->length; i++)
  36.132 -        sum += *ptr++;
  36.133 -
  36.134 -    t->checksum = -sum;
  36.135 -}
  36.136 -
  36.137 -/*
  36.138 - * Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
  36.139 - * vmxloader will use this info to set BIOS accordingly
  36.140 - */
  36.141 -static int set_hvm_info(int xc_handle, uint32_t dom,
  36.142 -                        unsigned long *pfn_list, unsigned int vcpus,
  36.143 -                        unsigned int acpi, unsigned int apic)
  36.144 -{
  36.145 -    char *va_map;
  36.146 -    struct hvm_info_table *va_hvm;
  36.147 -
  36.148 -    va_map = xc_map_foreign_range(
  36.149 -        xc_handle,
  36.150 -        dom,
  36.151 -        PAGE_SIZE,
  36.152 -        PROT_READ|PROT_WRITE,
  36.153 -        pfn_list[HVM_INFO_PFN]);
  36.154 -    
  36.155 -    if ( va_map == NULL )
  36.156 -        return -1;
  36.157 -
  36.158 -    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
  36.159 -    memset(va_hvm, 0, sizeof(*va_hvm));
  36.160 -    strncpy(va_hvm->signature, "HVM INFO", 8);
  36.161 -    va_hvm->length       = sizeof(struct hvm_info_table);
  36.162 -    va_hvm->acpi_enabled = acpi;
  36.163 -    va_hvm->apic_enabled = apic;
  36.164 -    va_hvm->nr_vcpus     = vcpus;
  36.165 -
  36.166 -    set_hvm_info_checksum(va_hvm);
  36.167 -
  36.168 -    munmap(va_map, PAGE_SIZE);
  36.169 -
  36.170 -    return 0;
  36.171 -}
  36.172 -
  36.173 -#ifdef __i386__
  36.174 -static int zap_mmio_range(int xc_handle, uint32_t dom,
  36.175 -                          l2_pgentry_32_t *vl2tab,
  36.176 -                          unsigned long mmio_range_start,
  36.177 -                          unsigned long mmio_range_size)
  36.178 -{
  36.179 -    unsigned long mmio_addr;
  36.180 -    unsigned long mmio_range_end = mmio_range_start + mmio_range_size;
  36.181 -    unsigned long vl2e;
  36.182 -    l1_pgentry_32_t *vl1tab;
  36.183 -
  36.184 -    mmio_addr = mmio_range_start & PAGE_MASK;
  36.185 -    for (; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE) {
  36.186 -        vl2e = vl2tab[l2_table_offset(mmio_addr)];
  36.187 -        if (vl2e == 0)
  36.188 -            continue;
  36.189 -        vl1tab = xc_map_foreign_range(
  36.190 -            xc_handle, dom, PAGE_SIZE,
  36.191 -            PROT_READ|PROT_WRITE, vl2e >> PAGE_SHIFT);
  36.192 -        if ( vl1tab == 0 )
  36.193 -        {
  36.194 -            PERROR("Failed zap MMIO range");
  36.195 -            return -1;
  36.196 -        }
  36.197 -        vl1tab[l1_table_offset(mmio_addr)] = 0;
  36.198 -        munmap(vl1tab, PAGE_SIZE);
  36.199 -    }
  36.200 -    return 0;
  36.201 -}
  36.202 -
  36.203 -static int zap_mmio_ranges(int xc_handle, uint32_t dom, unsigned long l2tab,
  36.204 -                           unsigned char e820_map_nr, unsigned char *e820map)
  36.205 -{
  36.206 -    unsigned int i;
  36.207 -    struct e820entry *e820entry = (struct e820entry *)e820map;
  36.208 -
  36.209 -    l2_pgentry_32_t *vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.210 -                                                   PROT_READ|PROT_WRITE,
  36.211 -                                                   l2tab >> PAGE_SHIFT);
  36.212 -    if ( vl2tab == 0 )
  36.213 -        return -1;
  36.214 -
  36.215 -    for ( i = 0; i < e820_map_nr; i++ )
  36.216 -    {
  36.217 -        if ( (e820entry[i].type == E820_IO) &&
  36.218 -             (zap_mmio_range(xc_handle, dom, vl2tab,
  36.219 -                             e820entry[i].addr, e820entry[i].size) == -1))
  36.220 -            return -1;
  36.221 -    }
  36.222 -
  36.223 -    munmap(vl2tab, PAGE_SIZE);
  36.224 -    return 0;
  36.225 -}
  36.226 -#else
  36.227 -static int zap_mmio_range(int xc_handle, uint32_t dom,
  36.228 -                          l3_pgentry_t *vl3tab,
  36.229 -                          unsigned long mmio_range_start,
  36.230 -                          unsigned long mmio_range_size)
  36.231 -{
  36.232 -    unsigned long mmio_addr;
  36.233 -    unsigned long mmio_range_end = mmio_range_start + mmio_range_size;
  36.234 -    unsigned long vl2e = 0;
  36.235 -    unsigned long vl3e;
  36.236 -    l1_pgentry_t *vl1tab;
  36.237 -    l2_pgentry_t *vl2tab;
  36.238 -
  36.239 -    mmio_addr = mmio_range_start & PAGE_MASK;
  36.240 -    for ( ; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE )
  36.241 -    {
  36.242 -        vl3e = vl3tab[l3_table_offset(mmio_addr)];
  36.243 -        if ( vl3e == 0 )
  36.244 -            continue;
  36.245 -
  36.246 -        vl2tab = xc_map_foreign_range(
  36.247 -            xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl3e>>PAGE_SHIFT);
  36.248 -        if ( vl2tab == NULL )
  36.249 -        {
  36.250 -            PERROR("Failed zap MMIO range");
  36.251 -            return -1;
  36.252 -        }
  36.253 -
  36.254 -        vl2e = vl2tab[l2_table_offset(mmio_addr)];
  36.255 -        if ( vl2e == 0 )
  36.256 -        {
  36.257 -            munmap(vl2tab, PAGE_SIZE);
  36.258 -            continue;
  36.259 -        }
  36.260 -
  36.261 -        vl1tab = xc_map_foreign_range(
  36.262 -            xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl2e>>PAGE_SHIFT);
  36.263 -        if ( vl1tab == NULL )
  36.264 -        {
  36.265 -            PERROR("Failed zap MMIO range");
  36.266 -            munmap(vl2tab, PAGE_SIZE);
  36.267 -            return -1;
  36.268 -        }
  36.269 -
  36.270 -        vl1tab[l1_table_offset(mmio_addr)] = 0;
  36.271 -        munmap(vl2tab, PAGE_SIZE);
  36.272 -        munmap(vl1tab, PAGE_SIZE);
  36.273 -    }
  36.274 -    return 0;
  36.275 -}
  36.276 -
  36.277 -static int zap_mmio_ranges(int xc_handle, uint32_t dom, unsigned long l3tab,
  36.278 -                           unsigned char e820_map_nr, unsigned char *e820map)
  36.279 -{
  36.280 -    unsigned int i;
  36.281 -    struct e820entry *e820entry = (struct e820entry *)e820map;
  36.282 -
  36.283 -    l3_pgentry_t *vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.284 -                                                PROT_READ|PROT_WRITE,
  36.285 -                                                l3tab >> PAGE_SHIFT);
  36.286 -    if (vl3tab == 0)
  36.287 -        return -1;
  36.288 -    for ( i = 0; i < e820_map_nr; i++ ) {
  36.289 -        if ( (e820entry[i].type == E820_IO) &&
  36.290 -             (zap_mmio_range(xc_handle, dom, vl3tab,
  36.291 -                             e820entry[i].addr, e820entry[i].size) == -1) )
  36.292 -            return -1;
  36.293 -    }
  36.294 -    munmap(vl3tab, PAGE_SIZE);
  36.295 -    return 0;
  36.296 -}
  36.297 -
  36.298 -#endif
  36.299 -
  36.300 -static int setup_guest(int xc_handle,
  36.301 -                       uint32_t dom, int memsize,
  36.302 -                       char *image, unsigned long image_size,
  36.303 -                       unsigned long nr_pages,
  36.304 -                       vcpu_guest_context_t *ctxt,
  36.305 -                       unsigned long shared_info_frame,
  36.306 -                       unsigned int control_evtchn,
  36.307 -                       unsigned int vcpus,
  36.308 -                       unsigned int acpi,
  36.309 -                       unsigned int apic,
  36.310 -                       unsigned int store_evtchn,
  36.311 -                       unsigned long *store_mfn)
  36.312 -{
  36.313 -    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
  36.314 -    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
  36.315 -    unsigned long *page_array = NULL;
  36.316 -#ifdef __x86_64__
  36.317 -    l3_pgentry_t *vl3tab=NULL;
  36.318 -    unsigned long l3tab;
  36.319 -#endif
  36.320 -    unsigned long l2tab = 0;
  36.321 -    unsigned long l1tab = 0;
  36.322 -    unsigned long count, i;
  36.323 -    shared_info_t *shared_info;
  36.324 -    void *e820_page;
  36.325 -    unsigned char e820_map_nr;
  36.326 -    xc_mmu_t *mmu = NULL;
  36.327 -    int rc;
  36.328 -
  36.329 -    unsigned long nr_pt_pages;
  36.330 -    unsigned long ppt_alloc;
  36.331 -
  36.332 -    struct domain_setup_info dsi;
  36.333 -    unsigned long vpt_start;
  36.334 -    unsigned long vpt_end;
  36.335 -    unsigned long v_end;
  36.336 -
  36.337 -    unsigned long shared_page_frame = 0;
  36.338 -    shared_iopage_t *sp;
  36.339 -
  36.340 -    memset(&dsi, 0, sizeof(struct domain_setup_info));
  36.341 -
  36.342 -    if ( (rc = parseelfimage(image, image_size, &dsi)) != 0 )
  36.343 -        goto error_out;
  36.344 -
  36.345 -    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
  36.346 -    {
  36.347 -        PERROR("Guest OS must load to a page boundary.\n");
  36.348 -        goto error_out;
  36.349 -    }
  36.350 -
  36.351 -    /* memsize is in megabytes */
  36.352 -    v_end              = (unsigned long)memsize << 20;
  36.353 -
  36.354 -#ifdef __i386__
  36.355 -    nr_pt_pages = 1 + ((memsize + 3) >> 2);
  36.356 -#else
  36.357 -    nr_pt_pages = 5 + ((memsize + 1) >> 1);
  36.358 -#endif
  36.359 -    vpt_start   = v_end;
  36.360 -    vpt_end     = vpt_start + (nr_pt_pages * PAGE_SIZE);
  36.361 -
  36.362 -    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
  36.363 -           " Loaded VMX loader: %08lx->%08lx\n"
  36.364 -           " Page tables:   %08lx->%08lx\n"
  36.365 -           " TOTAL:         %08lx->%08lx\n",
  36.366 -           dsi.v_kernstart, dsi.v_kernend,
  36.367 -           vpt_start, vpt_end,
  36.368 -           dsi.v_start, v_end);
  36.369 -    printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
  36.370 -
  36.371 -    if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
  36.372 -    {
  36.373 -        ERROR("Initial guest OS requires too much space\n"
  36.374 -               "(%luMB is greater than %luMB limit)\n",
  36.375 -               (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
  36.376 -        goto error_out;
  36.377 -    }
  36.378 -
  36.379 -    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
  36.380 -    {
  36.381 -        PERROR("Could not allocate memory");
  36.382 -        goto error_out;
  36.383 -    }
  36.384 -
  36.385 -    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
  36.386 -    {
  36.387 -        PERROR("Could not get the page frame list");
  36.388 -        goto error_out;
  36.389 -    }
  36.390 -
  36.391 -    loadelfimage(image, xc_handle, dom, page_array, &dsi);
  36.392 -
  36.393 -    if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
  36.394 -        goto error_out;
  36.395 -
  36.396 -    /* First allocate page for page dir or pdpt */
  36.397 -    ppt_alloc = vpt_start >> PAGE_SHIFT;
  36.398 -    if ( page_array[ppt_alloc] > 0xfffff )
  36.399 -    {
  36.400 -        unsigned long nmfn;
  36.401 -        nmfn = xc_make_page_below_4G( xc_handle, dom, page_array[ppt_alloc] );
  36.402 -        if ( nmfn == 0 )
  36.403 -        {
  36.404 -            fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
  36.405 -            goto error_out;
  36.406 -        }
  36.407 -        page_array[ppt_alloc] = nmfn;
  36.408 -    }
  36.409 -
  36.410 -#ifdef __i386__
  36.411 -    l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  36.412 -    ctxt->ctrlreg[3] = l2tab;
  36.413 -
  36.414 -    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.415 -                                        PROT_READ|PROT_WRITE,
  36.416 -                                        l2tab >> PAGE_SHIFT)) == NULL )
  36.417 -        goto error_out;
  36.418 -    memset(vl2tab, 0, PAGE_SIZE);
  36.419 -    vl2e = &vl2tab[l2_table_offset(0)];
  36.420 -    for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
  36.421 -    {
  36.422 -        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
  36.423 -        {
  36.424 -            l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  36.425 -            if ( vl1tab != NULL )
  36.426 -                munmap(vl1tab, PAGE_SIZE);
  36.427 -            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.428 -                                                PROT_READ|PROT_WRITE,
  36.429 -                                                l1tab >> PAGE_SHIFT)) == NULL )
  36.430 -            {
  36.431 -                munmap(vl2tab, PAGE_SIZE);
  36.432 -                goto error_out;
  36.433 -            }
  36.434 -            memset(vl1tab, 0, PAGE_SIZE);
  36.435 -            vl1e = &vl1tab[l1_table_offset(count << PAGE_SHIFT)];
  36.436 -            *vl2e++ = l1tab | L2_PROT;
  36.437 -        }
  36.438 -
  36.439 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
  36.440 -        vl1e++;
  36.441 -    }
  36.442 -    munmap(vl1tab, PAGE_SIZE);
  36.443 -    munmap(vl2tab, PAGE_SIZE);
  36.444 -#else
  36.445 -    l3tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  36.446 -    ctxt->ctrlreg[3] = l3tab;
  36.447 -
  36.448 -    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.449 -                                        PROT_READ|PROT_WRITE,
  36.450 -                                        l3tab >> PAGE_SHIFT)) == NULL )
  36.451 -        goto error_out;
  36.452 -    memset(vl3tab, 0, PAGE_SIZE);
  36.453 -
  36.454 -    /* Fill in every PDPT entry. */
  36.455 -    for ( i = 0; i < L3_PAGETABLE_ENTRIES_PAE; i++ )
  36.456 -    {
  36.457 -        l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  36.458 -        if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.459 -                                            PROT_READ|PROT_WRITE,
  36.460 -                                            l2tab >> PAGE_SHIFT)) == NULL )
  36.461 -            goto error_out;
  36.462 -        memset(vl2tab, 0, PAGE_SIZE);
  36.463 -        munmap(vl2tab, PAGE_SIZE);
  36.464 -        vl2tab = NULL;
  36.465 -        vl3tab[i] = l2tab | L3_PROT;
  36.466 -    }
  36.467 -
  36.468 -    for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
  36.469 -    {
  36.470 -        if ( !(count & ((1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)) - 1)) )
  36.471 -        {
  36.472 -            l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
  36.473 -                    & PAGE_MASK;
  36.474 -
  36.475 -            if (vl2tab != NULL)
  36.476 -                munmap(vl2tab, PAGE_SIZE);
  36.477 -
  36.478 -            if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.479 -                                                PROT_READ|PROT_WRITE,
  36.480 -                                                l2tab >> PAGE_SHIFT)) == NULL )
  36.481 -                goto error_out;
  36.482 -
  36.483 -            vl2e = &vl2tab[l2_table_offset(count << PAGE_SHIFT)];
  36.484 -        }
  36.485 -        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
  36.486 -        {
  36.487 -            l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  36.488 -            if ( vl1tab != NULL )
  36.489 -                munmap(vl1tab, PAGE_SIZE);
  36.490 -            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  36.491 -                                                PROT_READ|PROT_WRITE,
  36.492 -                                                l1tab >> PAGE_SHIFT)) == NULL )
  36.493 -            {
  36.494 -                munmap(vl2tab, PAGE_SIZE);
  36.495 -                goto error_out;
  36.496 -            }
  36.497 -            memset(vl1tab, 0, PAGE_SIZE);
  36.498 -            vl1e = &vl1tab[l1_table_offset(count << PAGE_SHIFT)];
  36.499 -            *vl2e++ = l1tab | L2_PROT;
  36.500 -        }
  36.501 -
  36.502 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
  36.503 -        vl1e++;
  36.504 -    }
  36.505 -
  36.506 -    munmap(vl1tab, PAGE_SIZE);
  36.507 -    munmap(vl2tab, PAGE_SIZE);
  36.508 -    munmap(vl3tab, PAGE_SIZE);
  36.509 -#endif
  36.510 -    /* Write the machine->phys table entries. */
  36.511 -    for ( count = 0; count < nr_pages; count++ )
  36.512 -    {
  36.513 -        if ( xc_add_mmu_update(xc_handle, mmu,
  36.514 -                               (page_array[count] << PAGE_SHIFT) |
  36.515 -                               MMU_MACHPHYS_UPDATE, count) )
  36.516 -            goto error_out;
  36.517 -    }
  36.518 -
  36.519 -    if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi, apic) ) {
  36.520 -        fprintf(stderr, "Couldn't set hvm info for VMX guest.\n");
  36.521 -        goto error_out;
  36.522 -    }
  36.523 -
  36.524 -    if ( (e820_page = xc_map_foreign_range(
  36.525 -         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  36.526 -         page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0 )
  36.527 -        goto error_out;
  36.528 -    memset(e820_page, 0, PAGE_SIZE);
  36.529 -    e820_map_nr = build_e820map(e820_page, v_end);
  36.530 -#if defined (__i386__)
  36.531 -    if (zap_mmio_ranges(xc_handle, dom, l2tab, e820_map_nr,
  36.532 -                        ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
  36.533 -#else
  36.534 -    if (zap_mmio_ranges(xc_handle, dom, l3tab, e820_map_nr,
  36.535 -                        ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
  36.536 -#endif
  36.537 -        goto error_out;
  36.538 -    munmap(e820_page, PAGE_SIZE);
  36.539 -
  36.540 -    /* shared_info page starts its life empty. */
  36.541 -    if ( (shared_info = xc_map_foreign_range(
  36.542 -         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  36.543 -         shared_info_frame)) == 0 )
  36.544 -        goto error_out;
  36.545 -    memset(shared_info, 0, sizeof(shared_info_t));
  36.546 -    /* Mask all upcalls... */
  36.547 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
  36.548 -        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
  36.549 -    munmap(shared_info, PAGE_SIZE);
  36.550 -
  36.551 -    /* Populate the event channel port in the shared page */
  36.552 -    shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1];
  36.553 -    if ( (sp = (shared_iopage_t *) xc_map_foreign_range(
  36.554 -         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  36.555 -         shared_page_frame)) == 0 )
  36.556 -        goto error_out;
  36.557 -    memset(sp, 0, PAGE_SIZE);
  36.558 -    sp->sp_global.eport = control_evtchn;
  36.559 -    munmap(sp, PAGE_SIZE);
  36.560 -
  36.561 -    *store_mfn = page_array[(v_end >> PAGE_SHIFT) - 2];
  36.562 -    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
  36.563 -        goto error_out;
  36.564 -
  36.565 -    /* Send the page update requests down to the hypervisor. */
  36.566 -    if ( xc_finish_mmu_updates(xc_handle, mmu) )
  36.567 -        goto error_out;
  36.568 -
  36.569 -    free(mmu);
  36.570 -    free(page_array);
  36.571 -
  36.572 -    /*
  36.573 -     * Initial register values:
  36.574 -     */
  36.575 -    ctxt->user_regs.ds = 0;
  36.576 -    ctxt->user_regs.es = 0;
  36.577 -    ctxt->user_regs.fs = 0;
  36.578 -    ctxt->user_regs.gs = 0;
  36.579 -    ctxt->user_regs.ss = 0;
  36.580 -    ctxt->user_regs.cs = 0;
  36.581 -    ctxt->user_regs.eip = dsi.v_kernentry;
  36.582 -    ctxt->user_regs.edx = 0;
  36.583 -    ctxt->user_regs.eax = 0;
  36.584 -    ctxt->user_regs.esp = 0;
  36.585 -    ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */
  36.586 -    ctxt->user_regs.ecx = 0;
  36.587 -    ctxt->user_regs.esi = 0;
  36.588 -    ctxt->user_regs.edi = 0;
  36.589 -    ctxt->user_regs.ebp = 0;
  36.590 -
  36.591 -    ctxt->user_regs.eflags = 0;
  36.592 -
  36.593 -    return 0;
  36.594 -
  36.595 - error_out:
  36.596 -    free(mmu);
  36.597 -    free(page_array);
  36.598 -    return -1;
  36.599 -}
  36.600 -
  36.601 -int xc_vmx_build(int xc_handle,
  36.602 -                 uint32_t domid,
  36.603 -                 int memsize,
  36.604 -                 const char *image_name,
  36.605 -                 unsigned int control_evtchn,
  36.606 -                 unsigned int vcpus,
  36.607 -                 unsigned int acpi,
  36.608 -                 unsigned int apic,
  36.609 -                 unsigned int store_evtchn,
  36.610 -                 unsigned long *store_mfn)
  36.611 -{
  36.612 -    dom0_op_t launch_op, op;
  36.613 -    int rc, i;
  36.614 -    vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
  36.615 -    unsigned long nr_pages;
  36.616 -    char         *image = NULL;
  36.617 -    unsigned long image_size;
  36.618 -    xen_capabilities_info_t xen_caps;
  36.619 -
  36.620 -    if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
  36.621 -    {
  36.622 -        PERROR("Failed to get xen version info");
  36.623 -        goto error_out;
  36.624 -    }
  36.625 -
  36.626 -    if ( !strstr(xen_caps, "hvm") )
  36.627 -    {
  36.628 -        PERROR("CPU doesn't support VMX Extensions or "
  36.629 -               "CPU VMX Extensions are not turned on");
  36.630 -        goto error_out;
  36.631 -    }
  36.632 -
  36.633 -    if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
  36.634 -    {
  36.635 -        PERROR("Could not find total pages for domain");
  36.636 -        goto error_out;
  36.637 -    }
  36.638 -
  36.639 -    if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
  36.640 -        goto error_out;
  36.641 -
  36.642 -    if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
  36.643 -    {
  36.644 -        PERROR("%s: ctxt mlock failed", __func__);
  36.645 -        return 1;
  36.646 -    }
  36.647 -
  36.648 -    op.cmd = DOM0_GETDOMAININFO;
  36.649 -    op.u.getdomaininfo.domain = (domid_t)domid;
  36.650 -    if ( (xc_dom0_op(xc_handle, &op) < 0) ||
  36.651 -         ((uint16_t)op.u.getdomaininfo.domain != domid) )
  36.652 -    {
  36.653 -        PERROR("Could not get info on domain");
  36.654 -        goto error_out;
  36.655 -    }
  36.656 -
  36.657 -    memset(ctxt, 0, sizeof(*ctxt));
  36.658 -
  36.659 -    if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
  36.660 -                     ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
  36.661 -                     vcpus, acpi, apic, store_evtchn, store_mfn) < 0)
  36.662 -    {
  36.663 -        ERROR("Error constructing guest OS");
  36.664 -        goto error_out;
  36.665 -    }
  36.666 -
  36.667 -    free(image);
  36.668 -
  36.669 -    ctxt->flags = VGCF_VMX_GUEST;
  36.670 -    /* FPU is set up to default initial state. */
  36.671 -    memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
  36.672 -
  36.673 -    /* Virtual IDT is empty at start-of-day. */
  36.674 -    for ( i = 0; i < 256; i++ )
  36.675 -    {
  36.676 -        ctxt->trap_ctxt[i].vector = i;
  36.677 -        ctxt->trap_ctxt[i].cs     = FLAT_KERNEL_CS;
  36.678 -    }
  36.679 -
  36.680 -    /* No LDT. */
  36.681 -    ctxt->ldt_ents = 0;
  36.682 -
  36.683 -    /* Use the default Xen-provided GDT. */
  36.684 -    ctxt->gdt_ents = 0;
  36.685 -
  36.686 -    /* No debugging. */
  36.687 -    memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
  36.688 -
  36.689 -    /* No callback handlers. */
  36.690 -#if defined(__i386__)
  36.691 -    ctxt->event_callback_cs     = FLAT_KERNEL_CS;
  36.692 -    ctxt->event_callback_eip    = 0;
  36.693 -    ctxt->failsafe_callback_cs  = FLAT_KERNEL_CS;
  36.694 -    ctxt->failsafe_callback_eip = 0;
  36.695 -#elif defined(__x86_64__)
  36.696 -    ctxt->event_callback_eip    = 0;
  36.697 -    ctxt->failsafe_callback_eip = 0;
  36.698 -    ctxt->syscall_callback_eip  = 0;
  36.699 -#endif
  36.700 -
  36.701 -    memset( &launch_op, 0, sizeof(launch_op) );
  36.702 -
  36.703 -    launch_op.u.setvcpucontext.domain = (domid_t)domid;
  36.704 -    launch_op.u.setvcpucontext.vcpu   = 0;
  36.705 -    launch_op.u.setvcpucontext.ctxt   = ctxt;
  36.706 -
  36.707 -    launch_op.cmd = DOM0_SETVCPUCONTEXT;
  36.708 -    rc = xc_dom0_op(xc_handle, &launch_op);
  36.709 -
  36.710 -    return rc;
  36.711 -
  36.712 - error_out:
  36.713 -    free(image);
  36.714 -    return -1;
  36.715 -}
  36.716 -
  36.717 -static inline int is_loadable_phdr(Elf32_Phdr *phdr)
  36.718 -{
  36.719 -    return ((phdr->p_type == PT_LOAD) &&
  36.720 -            ((phdr->p_flags & (PF_W|PF_X)) != 0));
  36.721 -}
  36.722 -
  36.723 -static int parseelfimage(char *elfbase,
  36.724 -                         unsigned long elfsize,
  36.725 -                         struct domain_setup_info *dsi)
  36.726 -{
  36.727 -    Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
  36.728 -    Elf32_Phdr *phdr;
  36.729 -    Elf32_Shdr *shdr;
  36.730 -    unsigned long kernstart = ~0UL, kernend=0UL;
  36.731 -    char *shstrtab;
  36.732 -    int h;
  36.733 -
  36.734 -    if ( !IS_ELF(*ehdr) )
  36.735 -    {
  36.736 -        ERROR("Kernel image does not have an ELF header.");
  36.737 -        return -EINVAL;
  36.738 -    }
  36.739 -
  36.740 -    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
  36.741 -    {
  36.742 -        ERROR("ELF program headers extend beyond end of image.");
  36.743 -        return -EINVAL;
  36.744 -    }
  36.745 -
  36.746 -    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
  36.747 -    {
  36.748 -        ERROR("ELF section headers extend beyond end of image.");
  36.749 -        return -EINVAL;
  36.750 -    }
  36.751 -
  36.752 -    /* Find the section-header strings table. */
  36.753 -    if ( ehdr->e_shstrndx == SHN_UNDEF )
  36.754 -    {
  36.755 -        ERROR("ELF image has no section-header strings table (shstrtab).");
  36.756 -        return -EINVAL;
  36.757 -    }
  36.758 -    shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
  36.759 -                          (ehdr->e_shstrndx*ehdr->e_shentsize));
  36.760 -    shstrtab = elfbase + shdr->sh_offset;
  36.761 -
  36.762 -    for ( h = 0; h < ehdr->e_phnum; h++ )
  36.763 -    {
  36.764 -        phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
  36.765 -        if ( !is_loadable_phdr(phdr) )
  36.766 -            continue;
  36.767 -        if ( phdr->p_paddr < kernstart )
  36.768 -            kernstart = phdr->p_paddr;
  36.769 -        if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
  36.770 -            kernend = phdr->p_paddr + phdr->p_memsz;
  36.771 -    }
  36.772 -
  36.773 -    if ( (kernstart > kernend) ||
  36.774 -         (ehdr->e_entry < kernstart) ||
  36.775 -         (ehdr->e_entry > kernend) )
  36.776 -    {
  36.777 -        ERROR("Malformed ELF image.");
  36.778 -        return -EINVAL;
  36.779 -    }
  36.780 -
  36.781 -    dsi->v_start = 0x00000000;
  36.782 -
  36.783 -    dsi->v_kernstart = kernstart;
  36.784 -    dsi->v_kernend   = kernend;
  36.785 -    dsi->v_kernentry = VMX_LOADER_ENTR_ADDR;
  36.786 -
  36.787 -    dsi->v_end       = dsi->v_kernend;
  36.788 -
  36.789 -    return 0;
  36.790 -}
  36.791 -
  36.792 -static int
  36.793 -loadelfimage(
  36.794 -    char *elfbase, int xch, uint32_t dom, unsigned long *parray,
  36.795 -    struct domain_setup_info *dsi)
  36.796 -{
  36.797 -    Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
  36.798 -    Elf32_Phdr *phdr;
  36.799 -    int h;
  36.800 -
  36.801 -    char         *va;
  36.802 -    unsigned long pa, done, chunksz;
  36.803 -
  36.804 -    for ( h = 0; h < ehdr->e_phnum; h++ )
  36.805 -    {
  36.806 -        phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
  36.807 -        if ( !is_loadable_phdr(phdr) )
  36.808 -            continue;
  36.809 -
  36.810 -        for ( done = 0; done < phdr->p_filesz; done += chunksz )
  36.811 -        {
  36.812 -            pa = (phdr->p_paddr + done) - dsi->v_start;
  36.813 -            if ((va = xc_map_foreign_range(
  36.814 -                xch, dom, PAGE_SIZE, PROT_WRITE,
  36.815 -                parray[pa >> PAGE_SHIFT])) == 0)
  36.816 -                return -1;
  36.817 -            chunksz = phdr->p_filesz - done;
  36.818 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  36.819 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  36.820 -            memcpy(va + (pa & (PAGE_SIZE-1)),
  36.821 -                   elfbase + phdr->p_offset + done, chunksz);
  36.822 -            munmap(va, PAGE_SIZE);
  36.823 -        }
  36.824 -
  36.825 -        for ( ; done < phdr->p_memsz; done += chunksz )
  36.826 -        {
  36.827 -            pa = (phdr->p_paddr + done) - dsi->v_start;
  36.828 -            if ((va = xc_map_foreign_range(
  36.829 -                xch, dom, PAGE_SIZE, PROT_WRITE,
  36.830 -                parray[pa >> PAGE_SHIFT])) == 0)
  36.831 -                return -1;
  36.832 -            chunksz = phdr->p_memsz - done;
  36.833 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  36.834 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  36.835 -            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
  36.836 -            munmap(va, PAGE_SIZE);
  36.837 -        }
  36.838 -    }
  36.839 -
  36.840 -    return 0;
  36.841 -}
  36.842 -
  36.843 -/*
  36.844 - * Local variables:
  36.845 - * mode: C
  36.846 - * c-set-style: "BSD"
  36.847 - * c-basic-offset: 4
  36.848 - * tab-width: 4
  36.849 - * indent-tabs-mode: nil
  36.850 - * End:
  36.851 - */
    37.1 --- a/tools/libxc/xenguest.h	Mon Jan 30 18:51:35 2006 +0100
    37.2 +++ b/tools/libxc/xenguest.h	Tue Jan 31 11:49:51 2006 +0100
    37.3 @@ -53,7 +53,7 @@ int xc_linux_build(int xc_handle,
    37.4                     unsigned int console_evtchn,
    37.5                     unsigned long *console_mfn);
    37.6  
    37.7 -int xc_vmx_build(int xc_handle,
    37.8 +int xc_hvm_build(int xc_handle,
    37.9                   uint32_t domid,
   37.10                   int memsize,
   37.11                   const char *image_name,
    38.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Mon Jan 30 18:51:35 2006 +0100
    38.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue Jan 31 11:49:51 2006 +0100
    38.3 @@ -355,7 +355,7 @@ static PyObject *pyxc_linux_build(XcObje
    38.4  			 "console_mfn", console_mfn);
    38.5  }
    38.6  
    38.7 -static PyObject *pyxc_vmx_build(XcObject *self,
    38.8 +static PyObject *pyxc_hvm_build(XcObject *self,
    38.9                                  PyObject *args,
   38.10                                  PyObject *kwds)
   38.11  {
   38.12 @@ -369,16 +369,15 @@ static PyObject *pyxc_vmx_build(XcObject
   38.13      unsigned long store_mfn = 0;
   38.14  
   38.15      static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
   38.16 -                                "memsize", "image", "vcpus", "acpi", "apic",
   38.17 -                                NULL };
   38.18 -
   38.19 +				"memsize", "image", "vcpus", "acpi", "apic",
   38.20 +				NULL };
   38.21      if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list,
   38.22                                        &dom, &control_evtchn, &store_evtchn,
   38.23 -                                      &memsize, &image, &vcpus, &acpi, &apic) )
   38.24 +				      &memsize, &image, &vcpus, &acpi, &apic) )
   38.25          return NULL;
   38.26  
   38.27 -    if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
   38.28 -                      vcpus, acpi, apic, store_evtchn, &store_mfn) != 0 )
   38.29 +    if ( xc_hvm_build(self->xc_handle, dom, memsize, image, control_evtchn,
   38.30 +		      vcpus, acpi, apic, store_evtchn, &store_mfn) != 0 )
   38.31          return PyErr_SetFromErrno(xc_error);
   38.32  
   38.33      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
   38.34 @@ -965,12 +964,12 @@ static PyMethodDef pyxc_methods[] = {
   38.35        " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
   38.36        "Returns: [int] 0 on success; -1 on error.\n" },
   38.37  
   38.38 -    { "vmx_build", 
   38.39 -      (PyCFunction)pyxc_vmx_build, 
   38.40 +    { "hvm_build", 
   38.41 +      (PyCFunction)pyxc_hvm_build, 
   38.42        METH_VARARGS | METH_KEYWORDS, "\n"
   38.43 -      "Build a new VMX guest OS.\n"
   38.44 +      "Build a new HVM guest OS.\n"
   38.45        " dom     [int]:      Identifier of domain to build into.\n"
   38.46 -      " image   [str]:      Name of VMX loader image file.\n"
   38.47 +      " image   [str]:      Name of HVM loader image file.\n"
   38.48        " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
   38.49        "Returns: [int] 0 on success; -1 on error.\n" },
   38.50  
    39.1 --- a/tools/python/xen/xend/image.py	Mon Jan 30 18:51:35 2006 +0100
    39.2 +++ b/tools/python/xen/xend/image.py	Tue Jan 31 11:49:51 2006 +0100
    39.3 @@ -143,7 +143,7 @@ class ImageHandler:
    39.4  
    39.5      def getDomainMemory(self, mem):
    39.6          """@return The memory required, in KiB, by the domain to store the
    39.7 -        given amount, also in KiB.  This is normally just mem, but VMX domains
    39.8 +        given amount, also in KiB.  This is normally just mem, but HVM domains
    39.9          have overheads to account for."""
   39.10          return mem
   39.11  
   39.12 @@ -183,21 +183,21 @@ class LinuxImageHandler(ImageHandler):
   39.13                                cmdline        = self.cmdline,
   39.14                                ramdisk        = self.ramdisk)
   39.15  
   39.16 -class VmxImageHandler(ImageHandler):
   39.17 +class HVMImageHandler(ImageHandler):
   39.18  
   39.19 -    ostype = "vmx"
   39.20 +    ostype = "hvm"
   39.21  
   39.22      def configure(self, imageConfig, deviceConfig):
   39.23          ImageHandler.configure(self, imageConfig, deviceConfig)
   39.24  
   39.25          info = xc.xeninfo()
   39.26 -        if not 'hvm' in info['xen_caps']:
   39.27 -            raise VmError("vmx: not an Intel VT platform, we stop creating!")
   39.28 +	if not 'hvm' in info['xen_caps']:
   39.29 +	    raise VmError("Not an HVM capable platform, we stop creating!")
   39.30  
   39.31          self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
   39.32          self.device_model = sxp.child_value(imageConfig, 'device_model')
   39.33          if not self.device_model:
   39.34 -            raise VmError("vmx: missing device model")
   39.35 +            raise VmError("hvm: missing device model")
   39.36          self.display = sxp.child_value(imageConfig, 'display')
   39.37          self.xauthority = sxp.child_value(imageConfig, 'xauthority')
   39.38  
   39.39 @@ -217,7 +217,7 @@ class VmxImageHandler(ImageHandler):
   39.40          # Create an event channel
   39.41          self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
   39.42                                                        remote_dom=0)
   39.43 -        log.info("VMX device model port: %d", self.device_channel)
   39.44 +        log.info("HVM device model port: %d", self.device_channel)
   39.45  
   39.46          store_evtchn = self.vm.getStorePort()
   39.47  
   39.48 @@ -232,7 +232,7 @@ class VmxImageHandler(ImageHandler):
   39.49  
   39.50          self.register_shutdown_watch()
   39.51  
   39.52 -        return xc.vmx_build(dom            = self.vm.getDomid(),
   39.53 +        return xc.hvm_build(dom            = self.vm.getDomid(),
   39.54                              image          = self.kernel,
   39.55                              control_evtchn = self.device_channel,
   39.56                              store_evtchn   = store_evtchn,
   39.57 @@ -283,7 +283,7 @@ class VmxImageHandler(ImageHandler):
   39.58                      continue;
   39.59                  vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
   39.60                  if vbddev not in vbddev_list:
   39.61 -                    raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
   39.62 +                    raise VmError("hvm: for qemu vbd type=file&dev=hda~hdd")
   39.63                  ret.append("-%s" % vbddev)
   39.64                  ret.append("%s" % vbdparam)
   39.65              if name == 'vif':
   39.66 @@ -405,8 +405,8 @@ class VmxImageHandler(ImageHandler):
   39.67      def register_shutdown_watch(self):
   39.68          """ add xen store watch on control/shutdown """
   39.69          self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \
   39.70 -                                    self.vmx_shutdown)
   39.71 -        log.debug("vmx shutdown watch registered")
   39.72 +                                    self.hvm_shutdown)
   39.73 +        log.debug("hvm shutdown watch registered")
   39.74  
   39.75      def unregister_shutdown_watch(self):
   39.76          """Remove the watch on the control/shutdown, if any. Nothrow
   39.77 @@ -416,11 +416,11 @@ class VmxImageHandler(ImageHandler):
   39.78              if self.shutdownWatch:
   39.79                  self.shutdownWatch.unwatch()
   39.80          except:
   39.81 -            log.exception("Unwatching vmx shutdown watch failed.")
   39.82 +            log.exception("Unwatching hvm shutdown watch failed.")
   39.83          self.shutdownWatch = None
   39.84 -        log.debug("vmx shutdown watch unregistered")
   39.85 +        log.debug("hvm shutdown watch unregistered")
   39.86  
   39.87 -    def vmx_shutdown(self, _):
   39.88 +    def hvm_shutdown(self, _):
   39.89          """ watch call back on node control/shutdown,
   39.90              if node changed, this function will be called
   39.91          """
   39.92 @@ -429,7 +429,7 @@ class VmxImageHandler(ImageHandler):
   39.93          vm = xd.domain_lookup( self.vm.getDomid() )
   39.94  
   39.95          reason = vm.readDom('control/shutdown')
   39.96 -        log.debug("vmx_shutdown fired, shutdown reason=%s", reason)
   39.97 +        log.debug("hvm_shutdown fired, shutdown reason=%s", reason)
   39.98          for x in shutdown_reasons.keys():
   39.99              if shutdown_reasons[x] == reason:
  39.100                  vm.info['shutdown'] = 1
  39.101 @@ -444,7 +444,7 @@ image type.
  39.102  imageHandlerClasses = {}
  39.103  
  39.104  
  39.105 -for h in LinuxImageHandler, VmxImageHandler:
  39.106 +for h in LinuxImageHandler, HVMImageHandler:
  39.107      imageHandlerClasses[h.ostype] = h
  39.108  
  39.109  
    40.1 --- a/tools/python/xen/xm/create.py	Mon Jan 30 18:51:35 2006 +0100
    40.2 +++ b/tools/python/xen/xm/create.py	Tue Jan 31 11:49:51 2006 +0100
    40.3 @@ -162,11 +162,11 @@ gopts.var('cpus', val='CPUS',
    40.4  
    40.5  gopts.var('acpi', val='ACPI',
    40.6            fn=set_int, default=0,
    40.7 -          use="Disable or enable ACPI of VMX domain.")
    40.8 +          use="Disable or enable ACPI of HVM domain.")
    40.9  
   40.10  gopts.var('apic', val='APIC',
   40.11            fn=set_int, default=0,
   40.12 -          use="Disable or enable APIC of VMX domain.")
   40.13 +          use="Disable or enable APIC of HVM domain.")
   40.14  
   40.15  gopts.var('vcpus', val='VCPUS',
   40.16            fn=set_int, default=1,
   40.17 @@ -441,8 +441,8 @@ def configure_image(vals):
   40.18      if vals.extra:
   40.19          config_image.append(['args', vals.extra])
   40.20  
   40.21 -    if vals.builder == 'vmx':
   40.22 -        configure_vmx(config_image, vals)
   40.23 +    if vals.builder == 'hvm':
   40.24 +        configure_hvm(config_image, vals)
   40.25          
   40.26      return config_image
   40.27      
   40.28 @@ -536,8 +536,8 @@ def configure_vifs(config_devs, vals):
   40.29          config_devs.append(['device', config_vif])
   40.30  
   40.31  
   40.32 -def configure_vmx(config_image, vals):
   40.33 -    """Create the config for VMX devices.
   40.34 +def configure_hvm(config_image, vals):
   40.35 +    """Create the config for HVM devices.
   40.36      """
   40.37      args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
   40.38               'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
    41.1 --- a/tools/python/xen/xm/tests/test_create.py	Mon Jan 30 18:51:35 2006 +0100
    41.2 +++ b/tools/python/xen/xm/tests/test_create.py	Tue Jan 31 11:49:51 2006 +0100
    41.3 @@ -141,15 +141,15 @@ cpu_weight = 0.75
    41.4                   })
    41.5              
    41.6  
    41.7 -    def testVMXConfigFile(self):
    41.8 +    def testHVMConfigFile(self):
    41.9          (fd, fname) = tempfile.mkstemp()
   41.10          try:
   41.11              os.write(fd,
   41.12                       '''
   41.13 -kernel = "/usr/lib/xen/boot/vmxloader"
   41.14 -builder='vmx'
   41.15 +kernel = "/usr/lib/xen/boot/hvmloader"
   41.16 +builder='hvm'
   41.17  memory = 128
   41.18 -name = "ExampleVMXDomain"
   41.19 +name = "ExampleHVMDomain"
   41.20  vcpus=1
   41.21  vif = [ 'type=ioemu, bridge=xenbr0' ]
   41.22  disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
   41.23 @@ -163,10 +163,10 @@ ne2000=0
   41.24              os.close(fd)
   41.25  
   41.26          self.t('-f %s display=fakedisplay' % fname,
   41.27 -               { 'kernel'      : '/usr/lib/xen/boot/vmxloader',
   41.28 -                 'builder'     : 'vmx',
   41.29 +               { 'kernel'      : '/usr/lib/xen/boot/hvmloader',
   41.30 +                 'builder'     : 'hvm',
   41.31                   'memory'      : 128,
   41.32 -                 'name'        : 'ExampleVMXDomain',
   41.33 +                 'name'        : 'ExampleHVMDomain',
   41.34                   'vcpus'       : 1,
   41.35                   'nics'        : -1,
   41.36                   'vif'         : ['type=ioemu, bridge=xenbr0'],
    42.1 --- a/tools/xm-test/README	Mon Jan 30 18:51:35 2006 +0100
    42.2 +++ b/tools/xm-test/README	Tue Jan 31 11:49:51 2006 +0100
    42.3 @@ -60,26 +60,26 @@ BUILDING with HVM Support
    42.4  =========================
    42.5  
    42.6  If you'd like to build and run this with hardware virtual machine assist
    42.7 -(HVM) support to test fully virtualized disk images on VMX hardware, 
    42.8 -please add the --enable-vmx-support option to configure:
    42.9 +(HVM) support to test fully virtualized disk images on VMX/SVM hardware, 
   42.10 +please add the --enable-hvm-support option to configure:
   42.11  
   42.12    # ./autogen
   42.13 -  # ./configure --enable-vmx-support
   42.14 +  # ./configure --enable-hvm-support
   42.15    # make
   42.16  
   42.17  The ramdisk/bin/create_disk_image script, which builds the full virt
   42.18  disk.img, requires Lilo 22.7+ to be installed on the system. Lilo is 
   42.19  used to install the bootloader on the disk.img.
   42.20  
   42.21 -If HVM / VMX support is enabled, the ramdisk/bin/create_disk_image script
   42.22 +If HVM support is enabled, the ramdisk/bin/create_disk_image script
   42.23  will be run to create a full virt disk.img in the ramdisk directory. The
   42.24  script, by default, will look in /boot for the first non-Xen kernel it
   42.25  runs across. If you'd like to set xm-test to use a specific kernel,
   42.26  rather than the first one it finds in /boot, you can configure it in
   42.27 -with the "--with-vmx-kernel=KERNEL" option:
   42.28 -
   42.29 +with the "--with-hvm-kernel=KERNEL" option:
   42.30 + 
   42.31  # ./autogen
   42.32 -# ./configure --enable-vmx-support --with-vmx-kernel=KERNEL
   42.33 +# ./configure --enable-hvm-support --with-hvm-kernel=KERNEL
   42.34  # make
   42.35  
   42.36  Otherwise, you can always rerun the create script using the -k option
   42.37 @@ -92,14 +92,14 @@ used. If you'd like to specify a differe
   42.38  want to tell the script that the driver is built into the kernel, please
   42.39  use the "--with-driver-dir=DRVDIR" configure option. If built into
   42.40  the kernel, please use the key word "builtin" with the option:
   42.41 -
   42.42 + 
   42.43  # ./autogen
   42.44 -# ./configure --enable-vmx-support --with-driver-dir=builtin
   42.45 +# ./configure --enable-hvm-support --with-driver-dir=builtin
   42.46  - or -
   42.47 -# ./configure --enable-vmx-support --with-driver-dir=/driver/directory
   42.48 +# ./configure --enable-hvm-support --with-driver-dir=/driver/directory
   42.49  # make
   42.50 -
   42.51 -Xm-test will look for disk.img in the ramdisk directory when run by 
   42.52 + 
   42.53 +Xm-test will look for disk.img in the ramdisk directory when run by
   42.54  default.
   42.55  
   42.56  
    43.1 --- a/tools/xm-test/configure.ac	Mon Jan 30 18:51:35 2006 +0100
    43.2 +++ b/tools/xm-test/configure.ac	Tue Jan 31 11:49:51 2006 +0100
    43.3 @@ -15,18 +15,18 @@ TESTLIB=../../lib
    43.4  RD_PATH=../../ramdisk
    43.5  TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB:/usr/lib/python RD_PATH=$RD_PATH"
    43.6  
    43.7 -AC_ARG_ENABLE(vmx-support,
    43.8 -	[[  --enable-vmx-support           enable hardware virtual machine assist]],
    43.9 +AC_ARG_ENABLE(hvm-support,
   43.10 +	[[  --enable-hvm-support           enable hardware virtual machine assist]],
   43.11  	[
   43.12 -		ENABLE_VMX=True
   43.13 +		ENABLE_HVM=True
   43.14  	],[
   43.15 -		ENABLE_VMX=False
   43.16 +		ENABLE_HVM=False
   43.17  	])
   43.18  
   43.19 -if test "x$ENABLE_VMX" = "xTrue"; then
   43.20 +if test "x$ENABLE_HVM" = "xTrue"; then
   43.21  	if test "$LILO" = "no"; then 
   43.22  		AC_MSG_ERROR([lilo not found
   43.23 -lilo version 22.7 or greater must be installed for testing with vmx enabled.])
   43.24 +lilo version 22.7 or greater must be installed for testing with hvm enabled.])
   43.25  	else
   43.26  		pass=`$LILO -V | sed -e "s/LILO version //" | awk -F "." '{if ($1 >=22 && $2 >= 7) print "true"; else print "false"}'`
   43.27  		if test "$pass" != "true"; then
   43.28 @@ -35,16 +35,16 @@ lilo version 22.7 or greater must be ins
   43.29  	fi
   43.30  fi
   43.31  
   43.32 -AM_CONDITIONAL(VMX, test x$ENABLE_VMX = xTrue)
   43.33 -AC_SUBST(ENABLE_VMX)
   43.34 +AM_CONDITIONAL(HVM, test x$ENABLE_HVM = xTrue)
   43.35 +AC_SUBST(ENABLE_HVM)
   43.36  
   43.37 -AC_ARG_WITH(vmx-kernel,
   43.38 -	[[  --with-vmx-kernel=kernel       Use this kernel for vmx disk.img testing]],
   43.39 -	VMXKERNEL=$withval,
   43.40 -	VMXKERNEL="no")
   43.41 +AC_ARG_WITH(hvm-kernel,
   43.42 +      [[  --with-hvm-kernel=kernel       Use this kernel for hvm disk.img testing]],
   43.43 +      HVMKERNEL=$withval,
   43.44 +      HVMKERNEL="no")
   43.45  
   43.46 -dnl substitute @VMXKERNEL@ in all Makefiles
   43.47 -AC_SUBST(VMXKERNEL)
   43.48 +dnl substitute @HVMKERNEL@ in all Makefiles
   43.49 +AC_SUBST(HVMKERNEL)
   43.50  
   43.51  AC_ARG_WITH(driver-dir,
   43.52  	[[  --with-driver-dir=drvdir       Look in this directory for the pcnet32 driver for the vmx disk.img. drvdir can equal key word "builtin" if driver is built into the kernel]],
    44.1 --- a/tools/xm-test/lib/XmTestLib/XenDomain.py	Mon Jan 30 18:51:35 2006 +0100
    44.2 +++ b/tools/xm-test/lib/XmTestLib/XenDomain.py	Tue Jan 31 11:49:51 2006 +0100
    44.3 @@ -70,14 +70,14 @@ ParavirtDefaults = {"memory"       : 64,
    44.4                      "root"         : "/dev/ram0",
    44.5                      "ramdisk"      : getRdPath() + "/initrd.img"
    44.6                      }
    44.7 -VmxDefaults =      {"memory"       : 64,
    44.8 +HVMDefaults =      {"memory"       : 64,
    44.9                      "vcpus"        : 1,
   44.10                      "acpi"         : 0,
   44.11                      "apic"         : 0,
   44.12                      "disk"         : ["file:%s/disk.img,ioemu:%s,w" %
   44.13                                     (getRdPath(), BLOCK_ROOT_DEV)],
   44.14 -                    "kernel"       : "/usr/lib/xen/boot/vmxloader",
   44.15 -                    "builder"      : "vmx",
   44.16 +                    "kernel"       : "/usr/lib/xen/boot/hvmloader",
   44.17 +                    "builder"      : "hvm",
   44.18                      "sdl"          : 0,
   44.19                      "vnc"          : 0,
   44.20                      "vncviewer"    : 0,
   44.21 @@ -86,8 +86,8 @@ VmxDefaults =      {"memory"       : 64,
   44.22                      "device_model" : getDeviceModel()
   44.23                      }
   44.24  
   44.25 -if ENABLE_VMX_SUPPORT:
   44.26 -    configDefaults = VmxDefaults
   44.27 +if ENABLE_HVM_SUPPORT:
   44.28 +    configDefaults = HVMDefaults
   44.29  else:
   44.30      configDefaults = ParavirtDefaults
   44.31  
   44.32 @@ -247,7 +247,7 @@ class XmTestDomain(XenDomain):
   44.33  
   44.34      def start(self):
   44.35          XenDomain.start(self)
   44.36 -        if ENABLE_VMX_SUPPORT:
   44.37 +        if ENABLE_HVM_SUPPORT:
   44.38              waitForBoot()
   44.39  
   44.40      def startNow(self):
   44.41 @@ -271,7 +271,7 @@ if __name__ == "__main__":
   44.42  
   44.43      print str(c)
   44.44  
   44.45 -    
   44.46 +
   44.47  
   44.48  #    c.write("/tmp/foo.conf")
   44.49  
    45.1 --- a/tools/xm-test/lib/XmTestLib/config.py.in	Mon Jan 30 18:51:35 2006 +0100
    45.2 +++ b/tools/xm-test/lib/XmTestLib/config.py.in	Tue Jan 31 11:49:51 2006 +0100
    45.3 @@ -1,4 +1,4 @@
    45.4  #!/usr/bin/python
    45.5  
    45.6 -ENABLE_VMX_SUPPORT = @ENABLE_VMX@
    45.7 +ENABLE_HVM_SUPPORT = @ENABLE_HVM@
    45.8  
    46.1 --- a/tools/xm-test/ramdisk/Makefile.am	Mon Jan 30 18:51:35 2006 +0100
    46.2 +++ b/tools/xm-test/ramdisk/Makefile.am	Tue Jan 31 11:49:51 2006 +0100
    46.3 @@ -9,12 +9,12 @@ BR_IMG = $(BR_SRC)/rootfs.i386.ext2
    46.4  
    46.5  BR_ROOT = build_i386/root
    46.6  
    46.7 -VMX_SCRIPT = bin/create_disk_image
    46.8 +HVM_SCRIPT = bin/create_disk_image
    46.9  
   46.10  XMTEST_MAJ_VER = $(shell echo @PACKAGE_VERSION@ | perl -pe 's/(\d+)\.(\d+)\.\d+/\1.\2/')
   46.11  XMTEST_VER_IMG = initrd-$(XMTEST_MAJ_VER).img
   46.12  
   46.13 -if VMX
   46.14 +if HVM
   46.15  all: initrd.img disk.img
   46.16  else
   46.17  all: initrd.img
   46.18 @@ -44,16 +44,16 @@ initrd.img: $(XMTEST_VER_IMG)
   46.19  	ln -sf $(XMTEST_VER_IMG) initrd.img
   46.20  
   46.21  disk.img: $(XMTEST_VER_IMG)
   46.22 -	chmod a+x $(VMX_SCRIPT)
   46.23 -	@if test ! "$(VMXKERNEL)" = "no" -a ! "$(DRVDIR)" = "no"; then \
   46.24 -		$(VMX_SCRIPT) -r $(XMTEST_VER_IMG) -k $(VMXKERNEL) \
   46.25 +	chmod a+x $(HVM_SCRIPT)
   46.26 +	@if test ! "$(HVMKERNEL)" = "no" -a ! "$(DRVDIR)" = "no"; then \
   46.27 +		$(HVM_SCRIPT) -r $(XMTEST_VER_IMG) -k $(HVMKERNEL) \
   46.28  			-d $(DRVDIR); \
   46.29 -	elif test "$(VMXKERNEL)" = "no" -a ! "$(DRVDIR)" = "no"; then \
   46.30 -		$(VMX_SCRIPT) -r $(XMTEST_VER_IMG) -d $(DRVDIR); \
   46.31 -	elif test ! "$(VMXKERNEL)" = "no" -a "$(DRVDIR)" = "no"; then \
   46.32 -		$(VMX_SCRIPT) -r $(XMTEST_VER_IMG) -k $(VMXKERNEL); \
   46.33 +	elif test "$(HVMKERNEL)" = "no" -a ! "$(DRVDIR)" = "no"; then \
   46.34 +		$(HVM_SCRIPT) -r $(XMTEST_VER_IMG) -d $(DRVDIR); \
   46.35 +	elif test ! "$(HVMKERNEL)" = "no" -a "$(DRVDIR)" = "no"; then \
   46.36 +		$(HVM_SCRIPT) -r $(XMTEST_VER_IMG) -k $(HVMKERNEL); \
   46.37  	else \
   46.38 -		$(VMX_SCRIPT) -r $(XMTEST_VER_IMG); \
   46.39 +		$(HVM_SCRIPT) -r $(XMTEST_VER_IMG); \
   46.40  	fi
   46.41  
   46.42  existing:
    47.1 --- a/tools/xm-test/ramdisk/bin/create_disk_image	Mon Jan 30 18:51:35 2006 +0100
    47.2 +++ b/tools/xm-test/ramdisk/bin/create_disk_image	Tue Jan 31 11:49:51 2006 +0100
    47.3 @@ -46,7 +46,7 @@ function die()
    47.4  function usage()
    47.5  {
    47.6  	cat << EOU
    47.7 -Command creates a vmx guest disk image for xm-test. 
    47.8 +Command creates a hvm guest disk image for xm-test. 
    47.9  
   47.10  Usage: $0 [OPTIONS]
   47.11  
    48.1 --- a/tools/xm-test/tests/block-create/01_block_attach_device_pos.py	Mon Jan 30 18:51:35 2006 +0100
    48.2 +++ b/tools/xm-test/tests/block-create/01_block_attach_device_pos.py	Tue Jan 31 11:49:51 2006 +0100
    48.3 @@ -9,8 +9,8 @@ import time
    48.4  
    48.5  from XmTestLib import *
    48.6  
    48.7 -if ENABLE_VMX_SUPPORT:
    48.8 -    SKIP("Block-attach not supported for VMX domains")
    48.9 +if ENABLE_HVM_SUPPORT:
   48.10 +    SKIP("Block-attach not supported for HVM domains")
   48.11  
   48.12  # Create a domain (default XmTestDomain, with our ramdisk)
   48.13  domain = XmTestDomain()
    49.1 --- a/tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py	Mon Jan 30 18:51:35 2006 +0100
    49.2 +++ b/tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py	Tue Jan 31 11:49:51 2006 +0100
    49.3 @@ -9,8 +9,8 @@ import time
    49.4  
    49.5  from XmTestLib import *
    49.6  
    49.7 -if ENABLE_VMX_SUPPORT:
    49.8 -    SKIP("Block-attach not supported for VMX domains")
    49.9 +if ENABLE_HVM_SUPPORT:
   49.10 +    SKIP("Block-attach not supported for HVM domains")
   49.11  
   49.12  # Create a domain (default XmTestDomain, with our ramdisk)
   49.13  domain = XmTestDomain()
    50.1 --- a/tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py	Mon Jan 30 18:51:35 2006 +0100
    50.2 +++ b/tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py	Tue Jan 31 11:49:51 2006 +0100
    50.3 @@ -9,8 +9,8 @@ import time
    50.4  
    50.5  from XmTestLib import *
    50.6  
    50.7 -if ENABLE_VMX_SUPPORT:
    50.8 -    SKIP("Block-attach not supported for VMX domains")
    50.9 +if ENABLE_HVM_SUPPORT:
   50.10 +    SKIP("Block-attach not supported for HVM domains")
   50.11  
   50.12  # Create a domain (default XmTestDomain, with our ramdisk)
   50.13  domain = XmTestDomain()
    51.1 --- a/tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py	Mon Jan 30 18:51:35 2006 +0100
    51.2 +++ b/tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py	Tue Jan 31 11:49:51 2006 +0100
    51.3 @@ -9,8 +9,8 @@ import time
    51.4  
    51.5  from XmTestLib import *
    51.6  
    51.7 -if ENABLE_VMX_SUPPORT:
    51.8 -    SKIP("Block-attach not supported for VMX domains")
    51.9 +if ENABLE_HVM_SUPPORT:
   51.10 +    SKIP("Block-attach not supported for HVM domains")
   51.11  
   51.12  # Create a domain (default XmTestDomain, with our ramdisk)
   51.13  domain = XmTestDomain()
    52.1 --- a/tools/xm-test/tests/block-create/06_block_attach_baddomain_neg.py	Mon Jan 30 18:51:35 2006 +0100
    52.2 +++ b/tools/xm-test/tests/block-create/06_block_attach_baddomain_neg.py	Tue Jan 31 11:49:51 2006 +0100
    52.3 @@ -5,8 +5,8 @@
    52.4  
    52.5  from XmTestLib import *
    52.6  
    52.7 -if ENABLE_VMX_SUPPORT:
    52.8 -    SKIP("Block-attach not supported for VMX domains")
    52.9 +if ENABLE_HVM_SUPPORT:
   52.10 +    SKIP("Block-attach not supported for HVM domains")
   52.11  
   52.12  status, output = traceCommand("xm block-attach NOT-EXIST phy:ram1 sdb1 w")
   52.13  
    53.1 --- a/tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py	Mon Jan 30 18:51:35 2006 +0100
    53.2 +++ b/tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py	Tue Jan 31 11:49:51 2006 +0100
    53.3 @@ -9,8 +9,8 @@ import time
    53.4  
    53.5  from XmTestLib import *
    53.6  
    53.7 -if ENABLE_VMX_SUPPORT:
    53.8 -    SKIP("Block-attach not supported for VMX domains")
    53.9 +if ENABLE_HVM_SUPPORT:
   53.10 +    SKIP("Block-attach not supported for HVM domains")
   53.11  
   53.12  # Create a domain (default XmTestDomain, with our ramdisk)
   53.13  domain = XmTestDomain()
    54.1 --- a/tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py	Mon Jan 30 18:51:35 2006 +0100
    54.2 +++ b/tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py	Tue Jan 31 11:49:51 2006 +0100
    54.3 @@ -9,8 +9,8 @@ import time
    54.4  
    54.5  from XmTestLib import *
    54.6  
    54.7 -if ENABLE_VMX_SUPPORT:
    54.8 -    SKIP("Block-attach not supported for VMX domains")
    54.9 +if ENABLE_HVM_SUPPORT:
   54.10 +    SKIP("Block-attach not supported for HVM domains")
   54.11  
   54.12  # Create a domain (default XmTestDomain, with our ramdisk)
   54.13  domain = XmTestDomain()
    55.1 --- a/tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py	Mon Jan 30 18:51:35 2006 +0100
    55.2 +++ b/tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py	Tue Jan 31 11:49:51 2006 +0100
    55.3 @@ -9,8 +9,8 @@ import time
    55.4  
    55.5  from XmTestLib import *
    55.6  
    55.7 -if ENABLE_VMX_SUPPORT:
    55.8 -    SKIP("Block-attach not supported for VMX domains")
    55.9 +if ENABLE_HVM_SUPPORT:
   55.10 +    SKIP("Block-attach not supported for HVM domains")
   55.11  
   55.12  # Create a domain (default XmTestDomain, with our ramdisk)
   55.13  domain = XmTestDomain()
    56.1 --- a/tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py	Mon Jan 30 18:51:35 2006 +0100
    56.2 +++ b/tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py	Tue Jan 31 11:49:51 2006 +0100
    56.3 @@ -46,8 +46,8 @@ def dettach(devname):
    56.4  
    56.5      return 0, None
    56.6  	
    56.7 -if ENABLE_VMX_SUPPORT:
    56.8 -    SKIP("Block-attach not supported for VMX domains")
    56.9 +if ENABLE_HVM_SUPPORT:
   56.10 +    SKIP("Block-attach not supported for HVM domains")
   56.11  
   56.12  # Create a domain (default XmTestDomain, with our ramdisk)
   56.13  domain = XmTestDomain()
    57.1 --- a/tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py	Mon Jan 30 18:51:35 2006 +0100
    57.2 +++ b/tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py	Tue Jan 31 11:49:51 2006 +0100
    57.3 @@ -5,8 +5,8 @@
    57.4  
    57.5  from XmTestLib import *
    57.6  
    57.7 -if ENABLE_VMX_SUPPORT:
    57.8 -    SKIP("Block-attach not supported for VMX domains")
    57.9 +if ENABLE_HVM_SUPPORT:
   57.10 +    SKIP("Block-attach not supported for HVM domains")
   57.11  
   57.12  # Mount /dev/ram0
   57.13  
    58.1 --- a/tools/xm-test/tests/block-create/12_block_attach_shared_domU.py	Mon Jan 30 18:51:35 2006 +0100
    58.2 +++ b/tools/xm-test/tests/block-create/12_block_attach_shared_domU.py	Tue Jan 31 11:49:51 2006 +0100
    58.3 @@ -5,8 +5,8 @@
    58.4  
    58.5  from XmTestLib import *
    58.6  
    58.7 -if ENABLE_VMX_SUPPORT:
    58.8 -    SKIP("Block-attach not supported for VMX domains")
    58.9 +if ENABLE_HVM_SUPPORT:
   58.10 +    SKIP("Block-attach not supported for HVM domains")
   58.11  
   58.12  config = {"disk":"phy:/dev/ram0,hda1,w"}
   58.13  
    59.1 --- a/tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py	Mon Jan 30 18:51:35 2006 +0100
    59.2 +++ b/tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py	Tue Jan 31 11:49:51 2006 +0100
    59.3 @@ -5,8 +5,8 @@
    59.4  
    59.5  from XmTestLib import *
    59.6  
    59.7 -if ENABLE_VMX_SUPPORT:
    59.8 -    SKIP("Block-detach not supported for VMX domains")
    59.9 +if ENABLE_HVM_SUPPORT:
   59.10 +    SKIP("Block-detach not supported for HVM domains")
   59.11  
   59.12  config = {"disk":"phy:/dev/ram0,hda1,w"}
   59.13  domain = XmTestDomain(extraConfig=config)
    60.1 --- a/tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py	Mon Jan 30 18:51:35 2006 +0100
    60.2 +++ b/tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py	Tue Jan 31 11:49:51 2006 +0100
    60.3 @@ -5,8 +5,8 @@
    60.4  
    60.5  from XmTestLib import *
    60.6  
    60.7 -if ENABLE_VMX_SUPPORT:
    60.8 -    SKIP("Block-detach not supported for VMX domains")
    60.9 +if ENABLE_HVM_SUPPORT:
   60.10 +    SKIP("Block-detach not supported for HVM domains")
   60.11  
   60.12  domain = XmTestDomain()
   60.13  
    61.1 --- a/tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py	Mon Jan 30 18:51:35 2006 +0100
    61.2 +++ b/tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py	Tue Jan 31 11:49:51 2006 +0100
    61.3 @@ -7,8 +7,8 @@
    61.4  
    61.5  from XmTestLib import *
    61.6  
    61.7 -if ENABLE_VMX_SUPPORT:
    61.8 -    SKIP("Block-detach not supported for VMX domains")
    61.9 +if ENABLE_HVM_SUPPORT:
   61.10 +    SKIP("Block-detach not supported for HVM domains")
   61.11  
   61.12  domain = XmTestDomain()
   61.13                                                                                                         
    62.1 --- a/tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py	Mon Jan 30 18:51:35 2006 +0100
    62.2 +++ b/tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py	Tue Jan 31 11:49:51 2006 +0100
    62.3 @@ -5,8 +5,8 @@
    62.4  
    62.5  from XmTestLib import *
    62.6  
    62.7 -if ENABLE_VMX_SUPPORT:
    62.8 -    SKIP("Block-detach not supported for VMX domains")
    62.9 +if ENABLE_HVM_SUPPORT:
   62.10 +    SKIP("Block-detach not supported for HVM domains")
   62.11  
   62.12  config = {"disk":"phy:/dev/ram0,hda1,w"}
   62.13  domain = XmTestDomain(extraConfig=config)
    63.1 --- a/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py	Mon Jan 30 18:51:35 2006 +0100
    63.2 +++ b/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py	Tue Jan 31 11:49:51 2006 +0100
    63.3 @@ -26,8 +26,8 @@ def checkXmLongList(domain):
    63.4      else:
    63.5          return False
    63.6  
    63.7 -if ENABLE_VMX_SUPPORT:
    63.8 -    SKIP("Block-detach not supported for VMX domains")
    63.9 +if ENABLE_HVM_SUPPORT:
   63.10 +    SKIP("Block-detach not supported for HVM domains")
   63.11  
   63.12  domain = XmTestDomain()
   63.13  
    64.1 --- a/tools/xm-test/tests/block-list/01_block-list_pos.py	Mon Jan 30 18:51:35 2006 +0100
    64.2 +++ b/tools/xm-test/tests/block-list/01_block-list_pos.py	Tue Jan 31 11:49:51 2006 +0100
    64.3 @@ -8,8 +8,8 @@
    64.4  
    64.5  from XmTestLib import *
    64.6  
    64.7 -if ENABLE_VMX_SUPPORT:
    64.8 -    SKIP("Block-list not supported for VMX domains")
    64.9 +if ENABLE_HVM_SUPPORT:
   64.10 +    SKIP("Block-list not supported for HVM domains")
   64.11  
   64.12  config = {"disk":"phy:/dev/ram0,hda1,w"}
   64.13  domain = XmTestDomain(extraConfig=config)
    65.1 --- a/tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py	Mon Jan 30 18:51:35 2006 +0100
    65.2 +++ b/tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py	Tue Jan 31 11:49:51 2006 +0100
    65.3 @@ -8,8 +8,8 @@
    65.4  
    65.5  from XmTestLib import *
    65.6  
    65.7 -if ENABLE_VMX_SUPPORT:
    65.8 -    SKIP("Block-list not supported for VMX domains")
    65.9 +if ENABLE_HVM_SUPPORT:
   65.10 +    SKIP("Block-list not supported for HVM domains")
   65.11  
   65.12  domain = XmTestDomain()
   65.13                                                                                                
    66.1 --- a/tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py	Mon Jan 30 18:51:35 2006 +0100
    66.2 +++ b/tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py	Tue Jan 31 11:49:51 2006 +0100
    66.3 @@ -8,8 +8,8 @@
    66.4  
    66.5  from XmTestLib import *
    66.6  
    66.7 -if ENABLE_VMX_SUPPORT:
    66.8 -    SKIP("Block-list not supported for VMX domains")
    66.9 +if ENABLE_HVM_SUPPORT:
   66.10 +    SKIP("Block-list not supported for HVM domains")
   66.11  
   66.12  config = {"disk":"phy:/dev/ram0,hda1,w"}
   66.13  domain = XmTestDomain(extraConfig=config)
    67.1 --- a/tools/xm-test/tests/block-list/04_block-list_nodb_pos.py	Mon Jan 30 18:51:35 2006 +0100
    67.2 +++ b/tools/xm-test/tests/block-list/04_block-list_nodb_pos.py	Tue Jan 31 11:49:51 2006 +0100
    67.3 @@ -8,8 +8,8 @@
    67.4  
    67.5  from XmTestLib import *
    67.6  
    67.7 -if ENABLE_VMX_SUPPORT:
    67.8 -    SKIP("Block-list not supported for VMX domains")
    67.9 +if ENABLE_HVM_SUPPORT:
   67.10 +    SKIP("Block-list not supported for HVM domains")
   67.11  
   67.12  domain = XmTestDomain()
   67.13  
    68.1 --- a/tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py	Mon Jan 30 18:51:35 2006 +0100
    68.2 +++ b/tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py	Tue Jan 31 11:49:51 2006 +0100
    68.3 @@ -5,8 +5,8 @@
    68.4  
    68.5  from XmTestLib import *
    68.6  
    68.7 -if ENABLE_VMX_SUPPORT:
    68.8 -    SKIP("Block-list not supported for VMX domains")
    68.9 +if ENABLE_HVM_SUPPORT:
   68.10 +    SKIP("Block-list not supported for HVM domains")
   68.11  
   68.12  domain = XmTestDomain()
   68.13  
    69.1 --- a/tools/xm-test/tests/create/14_create_blockroot_pos.py	Mon Jan 30 18:51:35 2006 +0100
    69.2 +++ b/tools/xm-test/tests/create/14_create_blockroot_pos.py	Tue Jan 31 11:49:51 2006 +0100
    69.3 @@ -17,7 +17,7 @@ rdpath = getRdPath()
    69.4  # if verbose:
    69.5  #     print "Using %s" % output
    69.6  
    69.7 -if ENABLE_VMX_SUPPORT:
    69.8 +if ENABLE_HVM_SUPPORT:
    69.9      domain = XmTestDomain(name="14_create_blockroot")
   69.10  else:
   69.11      config = {"memory" : "64",
    70.1 --- a/tools/xm-test/tests/memmax/01_memmax_badparm_neg.py	Mon Jan 30 18:51:35 2006 +0100
    70.2 +++ b/tools/xm-test/tests/memmax/01_memmax_badparm_neg.py	Tue Jan 31 11:49:51 2006 +0100
    70.3 @@ -8,8 +8,8 @@ import re
    70.4  
    70.5  from XmTestLib import *
    70.6  
    70.7 -if ENABLE_VMX_SUPPORT:
    70.8 -    SKIP("Mem-max not supported for VMX domains")
    70.9 +if ENABLE_HVM_SUPPORT:
   70.10 +    SKIP("Mem-max not supported for HVM domains")
   70.11  
   70.12  status, output = traceCommand("xm mem-max")
   70.13  eyecatcher = "Error:"
    71.1 --- a/tools/xm-test/tests/memset/01_memset_basic_pos.py	Mon Jan 30 18:51:35 2006 +0100
    71.2 +++ b/tools/xm-test/tests/memset/01_memset_basic_pos.py	Tue Jan 31 11:49:51 2006 +0100
    71.3 @@ -20,8 +20,8 @@ import re
    71.4  import time 
    71.5  from XmTestLib import * 
    71.6  
    71.7 -if ENABLE_VMX_SUPPORT:
    71.8 -    SKIP("Mem-set not supported for VMX domains")
    71.9 +if ENABLE_HVM_SUPPORT:
   71.10 +    SKIP("Mem-set not supported for HVM domains")
   71.11  
   71.12  # Create a domain (default XmTestDomain, with our ramdisk)
   71.13  domain = XmTestDomain() 
    72.1 --- a/tools/xm-test/tests/memset/02_memset_badparm_neg.py	Mon Jan 30 18:51:35 2006 +0100
    72.2 +++ b/tools/xm-test/tests/memset/02_memset_badparm_neg.py	Tue Jan 31 11:49:51 2006 +0100
    72.3 @@ -18,8 +18,8 @@ import re
    72.4  
    72.5  from XmTestLib import * 
    72.6  
    72.7 -if ENABLE_VMX_SUPPORT:
    72.8 -    SKIP("Mem-set not supported for VMX domains")
    72.9 +if ENABLE_HVM_SUPPORT:
   72.10 +    SKIP("Mem-set not supported for HVM domains")
   72.11  
   72.12  # destroy no parm input - negative test
   72.13  status, output = traceCommand("xm mem-set")
    73.1 --- a/tools/xm-test/tests/memset/03_memset_random_pos.py	Mon Jan 30 18:51:35 2006 +0100
    73.2 +++ b/tools/xm-test/tests/memset/03_memset_random_pos.py	Tue Jan 31 11:49:51 2006 +0100
    73.3 @@ -8,8 +8,8 @@ import re
    73.4  
    73.5  from XmTestLib import *
    73.6  
    73.7 -if ENABLE_VMX_SUPPORT:
    73.8 -    SKIP("Mem-set not supported for VMX domains")
    73.9 +if ENABLE_HVM_SUPPORT:
   73.10 +    SKIP("Mem-set not supported for HVM domains")
   73.11  
   73.12  domain = XmTestDomain()
   73.13  
    74.1 --- a/tools/xm-test/tests/memset/04_memset_smallmem_pos.py	Mon Jan 30 18:51:35 2006 +0100
    74.2 +++ b/tools/xm-test/tests/memset/04_memset_smallmem_pos.py	Tue Jan 31 11:49:51 2006 +0100
    74.3 @@ -5,8 +5,8 @@
    74.4  
    74.5  from XmTestLib import *
    74.6  
    74.7 -if ENABLE_VMX_SUPPORT:
    74.8 -    SKIP("Mem-set not supported for VMX domains")
    74.9 +if ENABLE_HVM_SUPPORT:
   74.10 +    SKIP("Mem-set not supported for HVM domains")
   74.11  
   74.12  domain = XmTestDomain()
   74.13  
    75.1 --- a/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py	Mon Jan 30 18:51:35 2006 +0100
    75.2 +++ b/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py	Tue Jan 31 11:49:51 2006 +0100
    75.3 @@ -17,8 +17,8 @@ import commands
    75.4  
    75.5  from XmTestLib import *
    75.6  
    75.7 -if ENABLE_VMX_SUPPORT:
    75.8 -    SKIP("Migrate currently not supported for VMX domains")
    75.9 +if ENABLE_HVM_SUPPORT:
   75.10 +    SKIP("Migrate currently not supported for HVM domains")
   75.11  
   75.12  # Create a domain (default XmTestDomain, with our ramdisk)
   75.13  domain = XmTestDomain()
    76.1 --- a/tools/xm-test/tests/network-attach/01_network_attach_pos.py	Mon Jan 30 18:51:35 2006 +0100
    76.2 +++ b/tools/xm-test/tests/network-attach/01_network_attach_pos.py	Tue Jan 31 11:49:51 2006 +0100
    76.3 @@ -8,8 +8,8 @@ import sys
    76.4  from XmTestLib import *
    76.5  from network_utils import *
    76.6  
    76.7 -if ENABLE_VMX_SUPPORT:
    76.8 -    SKIP("Network-attach not supported for VMX domains")
    76.9 +if ENABLE_HVM_SUPPORT:
   76.10 +    SKIP("Network-attach not supported for HVM domains")
   76.11  
   76.12  # Create a domain (default XmTestDomain, with our ramdisk)
   76.13  domain = XmTestDomain()
    77.1 --- a/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py	Mon Jan 30 18:51:35 2006 +0100
    77.2 +++ b/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py	Tue Jan 31 11:49:51 2006 +0100
    77.3 @@ -10,8 +10,8 @@ import time
    77.4  from XmTestLib import *
    77.5  from network_utils import *
    77.6  
    77.7 -if ENABLE_VMX_SUPPORT:
    77.8 -    SKIP("Network-attach not supported for VMX domains")
    77.9 +if ENABLE_HVM_SUPPORT:
   77.10 +    SKIP("Network-attach not supported for HVM domains")
   77.11  
   77.12  # Create a domain (default XmTestDomain, with our ramdisk)
   77.13  domain = XmTestDomain()
    78.1 --- a/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py	Mon Jan 30 18:51:35 2006 +0100
    78.2 +++ b/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py	Tue Jan 31 11:49:51 2006 +0100
    78.3 @@ -10,8 +10,8 @@ import time
    78.4  from XmTestLib import *
    78.5  from network_utils import *
    78.6  
    78.7 -if ENABLE_VMX_SUPPORT:
    78.8 -    SKIP("Network-attach not supported for VMX domains")
    78.9 +if ENABLE_HVM_SUPPORT:
   78.10 +    SKIP("Network-attach not supported for HVM domains")
   78.11  
   78.12  # Create a domain (default XmTestDomain, with our ramdisk)
   78.13  domain = XmTestDomain()
    79.1 --- a/tools/xm-test/tests/restore/01_restore_basic_pos.py	Mon Jan 30 18:51:35 2006 +0100
    79.2 +++ b/tools/xm-test/tests/restore/01_restore_basic_pos.py	Tue Jan 31 11:49:51 2006 +0100
    79.3 @@ -12,8 +12,8 @@ import time
    79.4  
    79.5  from XmTestLib import *
    79.6  
    79.7 -if ENABLE_VMX_SUPPORT:
    79.8 -    SKIP("Restore currently not supported for VMX domains")
    79.9 +if ENABLE_HVM_SUPPORT:
   79.10 +    SKIP("Restore currently not supported for HVM domains")
   79.11  
   79.12  domain = XmTestDomain()
   79.13  
    80.1 --- a/tools/xm-test/tests/restore/02_restore_badparm_neg.py	Mon Jan 30 18:51:35 2006 +0100
    80.2 +++ b/tools/xm-test/tests/restore/02_restore_badparm_neg.py	Tue Jan 31 11:49:51 2006 +0100
    80.3 @@ -12,8 +12,8 @@ import re
    80.4  
    80.5  from XmTestLib import *
    80.6  
    80.7 -if ENABLE_VMX_SUPPORT:
    80.8 -    SKIP("Restore currently not supported for VMX domains")
    80.9 +if ENABLE_HVM_SUPPORT:
   80.10 +    SKIP("Restore currently not supported for HVM domains")
   80.11  
   80.12  status, output = traceCommand("xm restore -x")
   80.13  eyecatcher1 = "Error:"
    81.1 --- a/tools/xm-test/tests/restore/03_restore_badfilename_neg.py	Mon Jan 30 18:51:35 2006 +0100
    81.2 +++ b/tools/xm-test/tests/restore/03_restore_badfilename_neg.py	Tue Jan 31 11:49:51 2006 +0100
    81.3 @@ -12,8 +12,8 @@ import re
    81.4  
    81.5  from XmTestLib import *
    81.6  
    81.7 -if ENABLE_VMX_SUPPORT:
    81.8 -    SKIP("Restore currently not supported for VMX domains")
    81.9 +if ENABLE_HVM_SUPPORT:
   81.10 +    SKIP("Restore currently not supported for HVM domains")
   81.11  
   81.12  status, output = traceCommand("xm restore /tmp/NON_EXIST")
   81.13  eyecatcher1 = "Error:"
    82.1 --- a/tools/xm-test/tests/restore/04_restore_withdevices_pos.py	Mon Jan 30 18:51:35 2006 +0100
    82.2 +++ b/tools/xm-test/tests/restore/04_restore_withdevices_pos.py	Tue Jan 31 11:49:51 2006 +0100
    82.3 @@ -7,8 +7,8 @@ from XmTestLib import *
    82.4  
    82.5  import re
    82.6  
    82.7 -if ENABLE_VMX_SUPPORT:
    82.8 -    SKIP("Restore currently not supported for VMX domains")
    82.9 +if ENABLE_HVM_SUPPORT:
   82.10 +    SKIP("Restore currently not supported for HVM domains")
   82.11  
   82.12  config = {"disk": ["phy:/dev/ram0,hda1,w", "phy:/dev/ram1,hdb2,w"],
   82.13            "vif":  ['', '']}
    83.1 --- a/tools/xm-test/tests/save/01_save_basic_pos.py	Mon Jan 30 18:51:35 2006 +0100
    83.2 +++ b/tools/xm-test/tests/save/01_save_basic_pos.py	Tue Jan 31 11:49:51 2006 +0100
    83.3 @@ -7,8 +7,8 @@ import time
    83.4  
    83.5  from XmTestLib import *
    83.6  
    83.7 -if ENABLE_VMX_SUPPORT:
    83.8 -    SKIP("Save currently not supported for VMX domains")
    83.9 +if ENABLE_HVM_SUPPORT:
   83.10 +    SKIP("Save currently not supported for HVM domains")
   83.11  
   83.12  domain = XmTestDomain()
   83.13  
    84.1 --- a/tools/xm-test/tests/save/02_save_badparm_neg.py	Mon Jan 30 18:51:35 2006 +0100
    84.2 +++ b/tools/xm-test/tests/save/02_save_badparm_neg.py	Tue Jan 31 11:49:51 2006 +0100
    84.3 @@ -12,8 +12,8 @@ import re
    84.4  
    84.5  from XmTestLib import *
    84.6  
    84.7 -if ENABLE_VMX_SUPPORT:
    84.8 -    SKIP("Save currently not supported for VMX domains")
    84.9 +if ENABLE_HVM_SUPPORT:
   84.10 +    SKIP("Save currently not supported for HVM domains")
   84.11  
   84.12  status, output = traceCommand("xm save -x")
   84.13  eyecatcher1 = "Error:"
    85.1 --- a/tools/xm-test/tests/save/03_save_bogusfile_neg.py	Mon Jan 30 18:51:35 2006 +0100
    85.2 +++ b/tools/xm-test/tests/save/03_save_bogusfile_neg.py	Tue Jan 31 11:49:51 2006 +0100
    85.3 @@ -10,8 +10,8 @@ import time
    85.4  
    85.5  from XmTestLib import *
    85.6  
    85.7 -if ENABLE_VMX_SUPPORT:
    85.8 -    SKIP("Save currently not supported for VMX domains")
    85.9 +if ENABLE_HVM_SUPPORT:
   85.10 +    SKIP("Save currently not supported for HVM domains")
   85.11  
   85.12  domain = XmTestDomain()
   85.13  
    86.1 --- a/tools/xm-test/tests/sysrq/01_sysrq_basic_neg.py	Mon Jan 30 18:51:35 2006 +0100
    86.2 +++ b/tools/xm-test/tests/sysrq/01_sysrq_basic_neg.py	Tue Jan 31 11:49:51 2006 +0100
    86.3 @@ -9,8 +9,8 @@ import re
    86.4  
    86.5  from XmTestLib import *
    86.6  
    86.7 -if ENABLE_VMX_SUPPORT:
    86.8 -    SKIP("Sysrq not supported for VMX domains")
    86.9 +if ENABLE_HVM_SUPPORT:
   86.10 +    SKIP("Sysrq not supported for HVM domains")
   86.11  
   86.12  status, output = traceCommand("xm sysrq does_not_exist s");
   86.13  
    87.1 --- a/tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py	Mon Jan 30 18:51:35 2006 +0100
    87.2 +++ b/tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py	Tue Jan 31 11:49:51 2006 +0100
    87.3 @@ -9,8 +9,8 @@ import time
    87.4  
    87.5  from XmTestLib import *
    87.6  
    87.7 -if ENABLE_VMX_SUPPORT:
    87.8 -    SKIP("Sysrq not supported for VMX domains")
    87.9 +if ENABLE_HVM_SUPPORT:
   87.10 +    SKIP("Sysrq not supported for HVM domains")
   87.11  
   87.12  # Create a domain (default XmTestDomain, with our ramdisk)
   87.13  domain = XmTestDomain()
    88.1 --- a/tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py	Mon Jan 30 18:51:35 2006 +0100
    88.2 +++ b/tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py	Tue Jan 31 11:49:51 2006 +0100
    88.3 @@ -7,8 +7,8 @@ from XmTestLib import *
    88.4  
    88.5  import time
    88.6  
    88.7 -if ENABLE_VMX_SUPPORT:
    88.8 -    SKIP("Sysrq not supported for VMX domains")
    88.9 +if ENABLE_HVM_SUPPORT:
   88.10 +    SKIP("Sysrq not supported for HVM domains")
   88.11  
   88.12  domain = XmTestDomain()
   88.13  
    89.1 --- a/xen/Rules.mk	Mon Jan 30 18:51:35 2006 +0100
    89.2 +++ b/xen/Rules.mk	Tue Jan 31 11:49:51 2006 +0100
    89.3 @@ -53,6 +53,9 @@ else
    89.4  CFLAGS += -g -DVERBOSE
    89.5  endif
    89.6  
    89.7 +# There is no real reason to compile without it
    89.8 +CFLAGS += -g
    89.9 +
   89.10  ifeq ($(crash_debug),y)
   89.11  CFLAGS += -g -DCRASH_DEBUG
   89.12  endif
    90.1 --- a/xen/arch/ia64/Makefile	Mon Jan 30 18:51:35 2006 +0100
    90.2 +++ b/xen/arch/ia64/Makefile	Tue Jan 31 11:49:51 2006 +0100
    90.3 @@ -15,7 +15,7 @@ OBJS = xensetup.o setup.o time.o irq.o p
    90.4  OBJS += vmx_init.o vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o\
    90.5  	vmx_phy_mode.o vmx_utility.o vmx_interrupt.o vmx_entry.o vmmu.o \
    90.6  	vtlb.o mmio.o vlsapic.o vmx_hypercall.o mm.o vmx_support.o \
    90.7 -	pal_emul.o vmx_irq_ia64.o vmx_vioapic.o
    90.8 +	pal_emul.o vmx_irq_ia64.o hvm_vioapic.o
    90.9  
   90.10  # lib files from xen/arch/ia64/linux/ (linux/arch/ia64/lib)
   90.11  OBJS +=	bitop.o clear_page.o flush.o copy_page_mck.o			\
   90.12 @@ -94,13 +94,19 @@ asm-xsi-offsets.s: asm-xsi-offsets.c
   90.13  	 || ln -s $(BASEDIR)/include/xen $(BASEDIR)/include/linux
   90.14  	[ -e $(BASEDIR)/include/asm-ia64/xen ] \
   90.15  	 || ln -s $(BASEDIR)/include/asm-ia64/linux $(BASEDIR)/include/asm-ia64/xen
   90.16 -# Link to DM file in Xen for ia64/vti
   90.17 -	[ -e $(BASEDIR)/include/asm-ia64/vmx_vpic.h ] \
   90.18 -	 || ln -s ../../include/asm-x86/vmx_vpic.h $(BASEDIR)/include/asm-ia64/vmx_vpic.h
   90.19 -	[ -e $(BASEDIR)/include/asm-ia64/vmx_vioapic.h ] \
   90.20 -	 || ln -s ../../include/asm-x86/vmx_vioapic.h $(BASEDIR)/include/asm-ia64/vmx_vioapic.h
   90.21 -	[ -e $(BASEDIR)/arch/ia64/vmx/vmx_vioapic.c ] \
   90.22 -	 || ln -s ../../../arch/x86/dm/vmx_vioapic.c $(BASEDIR)/arch/ia64/vmx/vmx_vioapic.c
   90.23 +# Link to HVM files in Xen for ia64/vti
   90.24 +	[ -e $(BASEDIR)/include/asm-ia64/hvm ] \
   90.25 +	 || mkdir $(BASEDIR)/include/asm-ia64/hvm
   90.26 +	[ -e $(BASEDIR)/include/asm-ia64/hvm/support.h ] \
   90.27 +	 || ln -s ../../../include/asm-x86/hvm/support.h $(BASEDIR)/include/asm-ia64/hvm/support.h
   90.28 +	[ -e $(BASEDIR)/include/asm-ia64/hvm/io.h ] \
   90.29 +	 || ln -s ../../../include/asm-x86/hvm/io.h $(BASEDIR)/include/asm-ia64/hvm/io.h
   90.30 +	[ -e $(BASEDIR)/include/asm-ia64/hvm/vpic.h ] \
   90.31 +	 || ln -s ../../../include/asm-x86/hvm/vpic.h $(BASEDIR)/include/asm-ia64/hvm/vpic.h
   90.32 +	[ -e $(BASEDIR)/include/asm-ia64/hvm/vioapic.h ] \
   90.33 +	 || ln -s ../../../include/asm-x86/hvm/vioapic.h $(BASEDIR)/include/asm-ia64/hvm/vioapic.h
   90.34 +	[ -e $(BASEDIR)/arch/ia64/vmx/hvm_vioapic.c ] \
   90.35 +	 || ln -s ../../../arch/x86/hvm/vioapic.c $(BASEDIR)/arch/ia64/vmx/hvm_vioapic.c
   90.36  # Solve circular reference on asm-offsets.h
   90.37  	[ -f $(BASEDIR)/include/asm-ia64/asm-offsets.h ] \
   90.38  	 || echo "#define IA64_TASK_SIZE 0" > $(BASEDIR)/include/asm-ia64/asm-offsets.h
   90.39 @@ -136,6 +142,8 @@ xen.lds.s: xen/xen.lds.S
   90.40  clean:
   90.41  	rm -f *.o *~ core  xen.lds.s $(BASEDIR)/include/asm-ia64/.offsets.h.stamp asm-offsets.s map.out
   90.42  	rm -f asm-xsi-offsets.s $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h
   90.43 +	rm -f $(BASEDIR)/arch/ia64/vmx/hvm_*.c
   90.44 +	rm -rf $(BASEDIR)/include/asm-ia64/hvm
   90.45  	rm -f linux/lib/*.o
   90.46  
   90.47  .PHONY: default clean
    91.1 --- a/xen/arch/ia64/vmx/mmio.c	Mon Jan 30 18:51:35 2006 +0100
    91.2 +++ b/xen/arch/ia64/vmx/mmio.c	Tue Jan 31 11:49:51 2006 +0100
    91.3 @@ -207,7 +207,7 @@ static void legacy_io_access(VCPU *vcpu,
    91.4  extern struct vmx_mmio_handler vioapic_mmio_handler;
    91.5  static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir)
    91.6  {
    91.7 -    struct virutal_platform_def *v_plat;
    91.8 +    struct virtual_platform_def *v_plat;
    91.9      //mmio_type_t iot;
   91.10      unsigned long iot;
   91.11      struct vmx_mmio_handler *vioapic_handler = &vioapic_mmio_handler;
    92.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Mon Jan 30 18:51:35 2006 +0100
    92.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Tue Jan 31 11:49:51 2006 +0100
    92.3 @@ -38,7 +38,7 @@
    92.4  #include <asm/vmx_pal_vsa.h>
    92.5  #include <asm/kregs.h>
    92.6  #include <asm/vmx_platform.h>
    92.7 -#include <asm/vmx_vioapic.h>
    92.8 +#include <asm/hvm/vioapic.h>
    92.9  
   92.10  //u64  fire_itc;
   92.11  //u64  fire_itc2;
   92.12 @@ -278,7 +278,7 @@ void vmx_virq_line_assist(struct vcpu *v
   92.13  	do {
   92.14  	    irqs = *(volatile uint16_t*)virq_line;
   92.15  	} while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs);
   92.16 -	vmx_vioapic_do_irqs(v->domain, irqs);
   92.17 +	hvm_vioapic_do_irqs(v->domain, irqs);
   92.18      }
   92.19  
   92.20      virq_line = &spg->pic_clear_irr;
   92.21 @@ -286,7 +286,7 @@ void vmx_virq_line_assist(struct vcpu *v
   92.22  	do {
   92.23  	    irqs = *(volatile uint16_t*)virq_line;
   92.24  	} while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs);
   92.25 -	vmx_vioapic_do_irqs_clear(v->domain, irqs);
   92.26 +	hvm_vioapic_do_irqs_clear(v->domain, irqs);
   92.27      }
   92.28  }
   92.29  
   92.30 @@ -300,7 +300,7 @@ void vmx_virq_line_init(struct domain *d
   92.31      spg->pic_clear_irr = 0;
   92.32  }
   92.33  
   92.34 -int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint16_t dest)
   92.35 +int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint16_t dest)
   92.36  {
   92.37      return (VLAPIC_ID(s->lapic_info[number]) == dest);
   92.38  }
   92.39 @@ -311,14 +311,14 @@ struct vlapic* apic_round_robin(struct d
   92.40  				uint32_t bitmap)
   92.41  {
   92.42      uint8_t bit;
   92.43 -    vmx_vioapic_t *s;
   92.44 +    hvm_vioapic_t *s;
   92.45      
   92.46      if (!bitmap) {
   92.47  	printk("<apic_round_robin> no bit on bitmap\n");
   92.48  	return NULL;
   92.49      }
   92.50  
   92.51 -    s = &d->arch.vmx_platform.vmx_vioapic;
   92.52 +    s = &d->arch.vmx_platform.vioapic;
   92.53      for (bit = 0; bit < s->lapic_count; bit++) {
   92.54  	if (bitmap & (1 << bit))
   92.55  	    return s->lapic_info[bit];
   92.56 @@ -351,7 +351,7 @@ void vlsapic_reset(VCPU *vcpu)
   92.57  
   92.58  #ifdef V_IOSAPIC_READY
   92.59      vcpu->arch.arch_vmx.vlapic.vcpu = vcpu;
   92.60 -    vmx_vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu);
   92.61 +    hvm_vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu);
   92.62  #endif
   92.63      DPRINTK("VLSAPIC inservice base=%lp\n", &VLSAPIC_INSVC(vcpu,0) );
   92.64  }
    93.1 --- a/xen/arch/ia64/vmx/vmx_init.c	Mon Jan 30 18:51:35 2006 +0100
    93.2 +++ b/xen/arch/ia64/vmx/vmx_init.c	Tue Jan 31 11:49:51 2006 +0100
    93.3 @@ -48,7 +48,7 @@
    93.4  #include <asm/vmx.h>
    93.5  #include <xen/mm.h>
    93.6  #include <public/arch-ia64.h>
    93.7 -#include <asm/vmx_vioapic.h>
    93.8 +#include <asm/hvm/vioapic.h>
    93.9  
   93.10  /* Global flag to identify whether Intel vmx feature is on */
   93.11  u32 vmx_enabled = 0;
   93.12 @@ -394,7 +394,7 @@ void vmx_setup_platform(struct domain *d
   93.13  	vmx_virq_line_init(d);
   93.14  
   93.15  	/* Initialize iosapic model within hypervisor */
   93.16 -	vmx_vioapic_init(d);
   93.17 +	hvm_vioapic_init(d);
   93.18  }
   93.19  
   93.20  
    94.1 --- a/xen/arch/ia64/vmx/vmx_vcpu.c	Mon Jan 30 18:51:35 2006 +0100
    94.2 +++ b/xen/arch/ia64/vmx/vmx_vcpu.c	Tue Jan 31 11:49:51 2006 +0100
    94.3 @@ -198,7 +198,7 @@ vmx_vcpu_get_vtlb(VCPU *vcpu)
    94.4  }
    94.5  
    94.6  
    94.7 -struct virutal_platform_def *
    94.8 +struct virtual_platform_def *
    94.9  vmx_vcpu_get_plat(VCPU *vcpu)
   94.10  {
   94.11      return &(vcpu->domain->arch.vmx_platform);
    95.1 --- a/xen/arch/x86/Makefile	Mon Jan 30 18:51:35 2006 +0100
    95.2 +++ b/xen/arch/x86/Makefile	Tue Jan 31 11:49:51 2006 +0100
    95.3 @@ -4,10 +4,14 @@ include $(BASEDIR)/Rules.mk
    95.4  OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S))
    95.5  OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c))
    95.6  OBJS += $(patsubst %.c,%.o,$(wildcard acpi/*.c))
    95.7 -OBJS += $(patsubst %.c,%.o,$(wildcard dm/*.c))
    95.8  OBJS += $(patsubst %.c,%.o,$(wildcard mtrr/*.c))
    95.9  OBJS += $(patsubst %.c,%.o,$(wildcard genapic/*.c))
   95.10  OBJS += $(patsubst %.c,%.o,$(wildcard cpu/*.c))
   95.11 +OBJS += $(patsubst %.c,%.o,$(wildcard hvm/*.c))
   95.12 +OBJS += $(patsubst %.c,%.o,$(wildcard hvm/vmx/*.c))
   95.13 +OBJS += $(patsubst %.S,%.o,$(wildcard hvm/vmx/$(TARGET_SUBARCH)/*.S))
   95.14 +OBJS += $(patsubst %.c,%.o,$(wildcard hvm/svm/*.c))
   95.15 +OBJS += $(patsubst %.S,%.o,$(wildcard hvm/svm/$(TARGET_SUBARCH)/*.S))
   95.16  
   95.17  ifeq ($(TARGET_SUBARCH),x86_64) 
   95.18  OBJS := $(subst cpu/centaur.o,,$(OBJS))
   95.19 @@ -74,9 +78,15 @@ clean:
   95.20  	rm -f x86_64/*.o x86_64/*~ x86_64/core
   95.21  	rm -f mtrr/*.o mtrr/*~ mtrr/core
   95.22  	rm -f acpi/*.o acpi/*~ acpi/core
   95.23 -	rm -f dm/*.o dm/*~ dm/core
   95.24  	rm -f genapic/*.o genapic/*~ genapic/core
   95.25  	rm -f cpu/*.o cpu/*~ cpu/core
   95.26 +	rm -f hvm/*.o hvm/*~ hvm/core
   95.27 +	rm -f hvm/vmx/*.o hvm/vmx/*~ hvm/vmx/core
   95.28 +	rm -f hvm/vmx/x86_32/*.o hvm/vmx/x86_32/*~ hvm/vmx/x86_32/core
   95.29 +	rm -f hvm/vmx/x86_64/*.o hvm/vmx/x86_64/*~ hvm/vmx/x86_64/core
   95.30 +	rm -f hvm/svm/*.o hvm/svm/*~ hvm/svm/core
   95.31 +	rm -f hvm/svm/x86_32/*.o hvm/svm/x86_32/*~ hvm/svm/x86_32/core
   95.32 +	rm -f hvm/svm/x86_64/*.o hvm/svm/x86_64/*~ hvm/svm/x86_64/core
   95.33  	rm -f xen.lds
   95.34  
   95.35  .PHONY: default clean
    96.1 --- a/xen/arch/x86/cpu/amd.c	Mon Jan 30 18:51:35 2006 +0100
    96.2 +++ b/xen/arch/x86/cpu/amd.c	Tue Jan 31 11:49:51 2006 +0100
    96.3 @@ -3,12 +3,20 @@
    96.4  #include <xen/bitops.h>
    96.5  #include <xen/mm.h>
    96.6  #include <xen/smp.h>
    96.7 +#include <xen/sched.h>
    96.8  #include <asm/io.h>
    96.9  #include <asm/msr.h>
   96.10  #include <asm/processor.h>
   96.11 +#include <asm/hvm/vcpu.h>
   96.12 +#include <asm/hvm/support.h>
   96.13 +
   96.14  
   96.15  #include "cpu.h"
   96.16  
   96.17 +
   96.18 +#define		AMD_C1_CLOCK_RAMP			0x80000084
   96.19 +#define		AMD_ADVPM_TSC_INVARIANT		0x80000007
   96.20 +
   96.21  /*
   96.22   * amd_flush_filter={on,off}. Forcibly Enable or disable the TLB flush
   96.23   * filter on AMD 64-bit processors.
   96.24 @@ -41,6 +49,99 @@ custom_param("amd_flush_filter", flush_f
   96.25  extern void vide(void);
   96.26  __asm__(".text\n.align 4\nvide: ret");
   96.27  
   96.28 +
   96.29 +/*
   96.30 + *	Check if C1-Clock ramping enabled in  PMM7.CpuLowPwrEnh
   96.31 + *	On 8th-Generation cores only. Assume BIOS has setup
   96.32 + *	all Northbridges equivalently.
   96.33 + */
   96.34 +
   96.35 +static int c1_ramp_8gen(void) 
   96.36 +{
   96.37 +	u32 l;
   96.38 +
   96.39 +	/*	Read dev=0x18, function = 3, offset=0x87  */
   96.40 +	l = AMD_C1_CLOCK_RAMP;
   96.41 +	/*	fill in dev (18) + function (3) */
   96.42 +	/*	direct cfc/cf8 should be safe here */
   96.43 +	l += (((0x18) << 3) + 0x3) << 8; 
   96.44 +	outl(l, 0xcf8);
   96.45 +	return (1 & (inl(0xcfc) >> 24));
   96.46 +}
   96.47 +
   96.48 +/*
   96.49 + * returns TRUE if ok to use TSC
   96.50 + */
   96.51 +
   96.52 +static int use_amd_tsc(struct cpuinfo_x86 *c) 
   96.53 +{ 
   96.54 +	if (c->x86 < 0xf) {
   96.55 +		/*
   96.56 +		 *	TSC drift doesn't exist on 7th Gen or less
   96.57 +		 *	However, OS still needs to consider effects
   96.58 +		 *	of P-state changes on TSC
   96.59 +		*/
   96.60 +		return 1;
   96.61 +	} else if ( cpuid_edx(AMD_ADVPM_TSC_INVARIANT) & 0x100 ) {
   96.62 +		/*
   96.63 +		 *	CPUID.AdvPowerMgmtInfo.TscInvariant
   96.64 +		 *	EDX bit 8, 8000_0007
   96.65 +		 *	Invariant TSC on 8th Gen or newer, use it
   96.66 +		 *	(assume all cores have invariant TSC)
   96.67 +		*/
   96.68 +		return 1;
   96.69 +	} else if ((mp_get_num_processors() == 1) && (c->x86_num_cores == 1)) {
   96.70 +		/*
   96.71 +		 *	OK to use TSC on uni-processor-uni-core
   96.72 +		 *	However, OS still needs to consider effects
   96.73 +		 *	of P-state changes on TSC
   96.74 +		*/
   96.75 +		return 1;
   96.76 +	} else if ( (mp_get_num_processors() == 1) && (c->x86 == 0x0f) 
   96.77 +				&& !c1_ramp_8gen()) {
   96.78 +		/*
   96.79 +		 *	Use TSC on 8th Gen uni-proc with C1_ramp off 
   96.80 +		 *	However, OS still needs to consider effects
   96.81 +		 *	of P-state changes on TSC
   96.82 +		*/
   96.83 +		return 1;
   96.84 +	} else { 
   96.85 +		return 0;
   96.86 +	}
   96.87 +}
   96.88 +
   96.89 +/*
   96.90 + *	Disable C1-Clock ramping if enabled in PMM7.CpuLowPwrEnh
   96.91 + *	On 8th-Generation cores only. Assume BIOS has setup
   96.92 + *	all Northbridges equivalently.
   96.93 + */
   96.94 +
   96.95 +static void amd_disable_c1_ramping(void) 
   96.96 +{
   96.97 +	u32 l, h;
   96.98 +	int i;
   96.99 +
  96.100 +	for (i=0; i < NR_CPUS;i++) {
  96.101 +		/* Read from the Northbridge for Node x. until we get invalid data */
  96.102 +		/* fill in dev (18 + cpu#) + function (3) */
  96.103 +		l = AMD_C1_CLOCK_RAMP + ((((0x18 + i) << 3) + 0x3) << 8);
  96.104 +		/*	direct cfc/cf8 should be safe here */
  96.105 +		outl(l, 0xcf8);
  96.106 +		h = inl(0xcfc);
  96.107 +		if (h != 0xFFFFFFFF) {
  96.108 +			h &= 0xFCFFFFFF; /* clears pmm7[1:0]  */
  96.109 +			outl(l, 0xcf8);
  96.110 +			outl(h, 0xcfc);
  96.111 +			printk ("AMD: Disabling C1 Clock Ramping Node #%x\n",i);
  96.112 +		}
  96.113 +		else {
  96.114 +			i = NR_CPUS;
  96.115 +		}
  96.116 +			
  96.117 +	}
  96.118 +	return;
  96.119 +}
  96.120 +
  96.121  static void __init init_amd(struct cpuinfo_x86 *c)
  96.122  {
  96.123  	u32 l, h;
  96.124 @@ -246,6 +347,18 @@ static void __init init_amd(struct cpuin
  96.125  		       cpu, c->x86_num_cores, cpu_core_id[cpu]);
  96.126  	}
  96.127  #endif
  96.128 +	/*
  96.129 +	 * Prevent TSC drift in non single-processor, single-core platforms
  96.130 +	 */
  96.131 +	if ( !use_amd_tsc(c) && (c->x86 == 0x0f) && c1_ramp_8gen() && 
  96.132 +			(smp_processor_id() == 0)) {
  96.133 +		/* Disable c1 Clock Ramping on all cores */
  96.134 +		amd_disable_c1_ramping();
  96.135 +	}
  96.136 +
  96.137 +#ifdef CONFIG_SVM
  96.138 +	start_svm();
  96.139 +#endif
  96.140  }
  96.141  
  96.142  static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
    97.1 --- a/xen/arch/x86/cpu/intel.c	Mon Jan 30 18:51:35 2006 +0100
    97.2 +++ b/xen/arch/x86/cpu/intel.c	Tue Jan 31 11:49:51 2006 +0100
    97.3 @@ -10,7 +10,9 @@
    97.4  #include <asm/mpspec.h>
    97.5  #include <asm/apic.h>
    97.6  #include <mach_apic.h>
    97.7 -#include <asm/vmx_vmcs.h>
    97.8 +#include <asm/hvm/vpit.h>
    97.9 +#include <asm/hvm/vcpu.h>
   97.10 +#include <asm/hvm/support.h>
   97.11  
   97.12  #include "cpu.h"
   97.13  
    98.1 --- a/xen/arch/x86/dm/i8259.c	Mon Jan 30 18:51:35 2006 +0100
    98.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.3 @@ -1,550 +0,0 @@
    98.4 -/*
    98.5 - * QEMU 8259 interrupt controller emulation
    98.6 - * 
    98.7 - * Copyright (c) 2003-2004 Fabrice Bellard
    98.8 - * Copyright (c) 2005 Intel Corperation
    98.9 - * 
   98.10 - * Permission is hereby granted, free of charge, to any person obtaining a copy
   98.11 - * of this software and associated documentation files (the "Software"), to deal
   98.12 - * in the Software without restriction, including without limitation the rights
   98.13 - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   98.14 - * copies of the Software, and to permit persons to whom the Software is
   98.15 - * furnished to do so, subject to the following conditions:
   98.16 - *
   98.17 - * The above copyright notice and this permission notice shall be included in
   98.18 - * all copies or substantial portions of the Software.
   98.19 - *
   98.20 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   98.21 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   98.22 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   98.23 - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   98.24 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   98.25 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   98.26 - * THE SOFTWARE.
   98.27 - */
   98.28 -#include <xen/config.h>
   98.29 -#include <xen/types.h>
   98.30 -#include <xen/mm.h>
   98.31 -#include <xen/xmalloc.h>
   98.32 -#include <xen/lib.h>
   98.33 -#include <xen/errno.h>
   98.34 -#include <xen/sched.h>
   98.35 -#include <public/hvm/ioreq.h>
   98.36 -#include <asm/vmx.h>
   98.37 -#include <asm/vmx_vpic.h>
   98.38 -#include <asm/current.h>
   98.39 -#include <asm/vmx_vioapic.h>
   98.40 -#include <asm/vmx_vlapic.h>
   98.41 -
   98.42 -/* set irq level. If an edge is detected, then the IRR is set to 1 */
   98.43 -static inline void pic_set_irq1(PicState *s, int irq, int level)
   98.44 -{
   98.45 -    int mask;
   98.46 -    mask = 1 << irq;
   98.47 -    if (s->elcr & mask) {
   98.48 -        /* level triggered */
   98.49 -        if (level) {
   98.50 -            s->irr |= mask;
   98.51 -            s->last_irr |= mask;
   98.52 -        } else {
   98.53 -            s->irr &= ~mask;
   98.54 -            s->last_irr &= ~mask;
   98.55 -        }
   98.56 -    } else {
   98.57 -        /* edge triggered */
   98.58 -        if (level) {
   98.59 -            if ((s->last_irr & mask) == 0) {
   98.60 -                s->irr |= mask;
   98.61 -	    }
   98.62 -            s->last_irr |= mask;
   98.63 -        } else {
   98.64 -            s->last_irr &= ~mask;
   98.65 -        }
   98.66 -    }
   98.67 -}
   98.68 -
   98.69 -/* return the highest priority found in mask (highest = smallest
   98.70 -   number). Return 8 if no irq */
   98.71 -static inline int get_priority(PicState *s, int mask)
   98.72 -{
   98.73 -    int priority;
   98.74 -    if (mask == 0)
   98.75 -        return 8;
   98.76 -    priority = 0;
   98.77 -    while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
   98.78 -        priority++;
   98.79 -    return priority;
   98.80 -}
   98.81 -
   98.82 -/* return the pic wanted interrupt. return -1 if none */
   98.83 -static int pic_get_irq(PicState *s)
   98.84 -{
   98.85 -    int mask, cur_priority, priority;
   98.86 -
   98.87 -    mask = s->irr & ~s->imr;
   98.88 -    priority = get_priority(s, mask);
   98.89 -    if (priority == 8)
   98.90 -        return -1;
   98.91 -    /* compute current priority. If special fully nested mode on the
   98.92 -       master, the IRQ coming from the slave is not taken into account
   98.93 -       for the priority computation. */
   98.94 -    mask = s->isr;
   98.95 -    if (s->special_fully_nested_mode && s == &s->pics_state->pics[0])
   98.96 -        mask &= ~(1 << 2);
   98.97 -    cur_priority = get_priority(s, mask);
   98.98 -    if (priority < cur_priority) {
   98.99 -        /* higher priority found: an irq should be generated */
  98.100 -        return (priority + s->priority_add) & 7;
  98.101 -    } else {
  98.102 -        return -1;
  98.103 -    }
  98.104 -}
  98.105 -
  98.106 -/* raise irq to CPU if necessary. must be called every time the active
  98.107 -   irq may change */
  98.108 -/* XXX: should not export it, but it is needed for an APIC kludge */
  98.109 -void pic_update_irq(struct vmx_virpic *s)
  98.110 -{
  98.111 -    int irq2, irq;
  98.112 -
  98.113 -    /* first look at slave pic */
  98.114 -    irq2 = pic_get_irq(&s->pics[1]);
  98.115 -    if (irq2 >= 0) {
  98.116 -        /* if irq request by slave pic, signal master PIC */
  98.117 -        pic_set_irq1(&s->pics[0], 2, 1);
  98.118 -        pic_set_irq1(&s->pics[0], 2, 0);
  98.119 -    }
  98.120 -    /* look at requested irq */
  98.121 -    irq = pic_get_irq(&s->pics[0]);
  98.122 -    if (irq >= 0) {
  98.123 -        s->irq_request(s->irq_request_opaque, 1);
  98.124 -    }
  98.125 -}
  98.126 -
  98.127 -void pic_set_irq_new(void *opaque, int irq, int level)
  98.128 -{
  98.129 -    struct vmx_virpic *s = opaque;
  98.130 -
  98.131 -    vmx_vioapic_set_irq(current->domain, irq, level);
  98.132 -    pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
  98.133 -    /* used for IOAPIC irqs */
  98.134 -    if (s->alt_irq_func)
  98.135 -        s->alt_irq_func(s->alt_irq_opaque, irq, level);
  98.136 -    pic_update_irq(s);
  98.137 -}
  98.138 -
  98.139 -void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs)
  98.140 -{
  98.141 -    s->pics[1].irr |= (uint8_t)(irqs >> 8);
  98.142 -    s->pics[0].irr |= (uint8_t) irqs;
  98.143 -    vmx_vioapic_do_irqs(current->domain, irqs);
  98.144 -    pic_update_irq(s);
  98.145 -}
  98.146 -
  98.147 -void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs)
  98.148 -{
  98.149 -    s->pics[1].irr &= ~(uint8_t)(irqs >> 8);
  98.150 -    s->pics[0].irr &= ~(uint8_t) irqs;
  98.151 -    vmx_vioapic_do_irqs_clear(current->domain, irqs);
  98.152 -    pic_update_irq(s);
  98.153 -}
  98.154 -
  98.155 -/* obsolete function */
  98.156 -void pic_set_irq(struct vmx_virpic *isa_pic, int irq, int level)
  98.157 -{
  98.158 -    pic_set_irq_new(isa_pic, irq, level);
  98.159 -}
  98.160 -
  98.161 -/* acknowledge interrupt 'irq' */
  98.162 -static inline void pic_intack(PicState *s, int irq)
  98.163 -{
  98.164 -    if (s->auto_eoi) {
  98.165 -        if (s->rotate_on_auto_eoi)
  98.166 -            s->priority_add = (irq + 1) & 7;
  98.167 -    } else {
  98.168 -        s->isr |= (1 << irq);
  98.169 -    }
  98.170 -    /* We don't clear a level sensitive interrupt here */
  98.171 -    if (!(s->elcr & (1 << irq)))
  98.172 -        s->irr &= ~(1 << irq);
  98.173 -}
  98.174 -
  98.175 -int pic_read_irq(struct vmx_virpic *s)
  98.176 -{
  98.177 -    int irq, irq2, intno;
  98.178 -
  98.179 -    irq = pic_get_irq(&s->pics[0]);
  98.180 -    if (irq >= 0) {
  98.181 -        pic_intack(&s->pics[0], irq);
  98.182 -        if (irq == 2) {
  98.183 -            irq2 = pic_get_irq(&s->pics[1]);
  98.184 -            if (irq2 >= 0) {
  98.185 -                pic_intack(&s->pics[1], irq2);
  98.186 -            } else {
  98.187 -                /* spurious IRQ on slave controller */
  98.188 -                irq2 = 7;
  98.189 -            }
  98.190 -            intno = s->pics[1].irq_base + irq2;
  98.191 -            irq = irq2 + 8;
  98.192 -        } else {
  98.193 -            intno = s->pics[0].irq_base + irq;
  98.194 -        }
  98.195 -    } else {
  98.196 -        /* spurious IRQ on host controller */
  98.197 -        printk("spurious IRQ irq got=%d\n",irq);
  98.198 -        irq = 7;
  98.199 -        intno = s->pics[0].irq_base + irq;
  98.200 -    }
  98.201 -    pic_update_irq(s);
  98.202 -        
  98.203 -    return intno;
  98.204 -}
  98.205 -
  98.206 -static void update_shared_irr(struct vmx_virpic *s, PicState *c)
  98.207 -{
  98.208 -    uint8_t *pl, *pe;
  98.209 -
  98.210 -    get_sp(current->domain)->sp_global.pic_elcr = 
  98.211 -		s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
  98.212 -    pl =(uint8_t*)&get_sp(current->domain)->sp_global.pic_last_irr;
  98.213 -    pe =(uint8_t*)&get_sp(current->domain)->sp_global.pic_elcr;
  98.214 -    if ( c == &s->pics[0] ) {
  98.215 -         *pl = c->last_irr;
  98.216 -         *pe = c->elcr;
  98.217 -    }
  98.218 -    else {
  98.219 -         *(pl+1) = c->last_irr;
  98.220 -         *(pe+1) = c->elcr;
  98.221 -    }
  98.222 -}
  98.223 -
  98.224 -static void pic_reset(void *opaque)
  98.225 -{
  98.226 -    PicState *s = opaque;
  98.227 -
  98.228 -    s->last_irr = 0;
  98.229 -    s->irr = 0;
  98.230 -    s->imr = 0;
  98.231 -    s->isr = 0;
  98.232 -    s->priority_add = 0;
  98.233 -    s->irq_base = 0;
  98.234 -    s->read_reg_select = 0;
  98.235 -    s->poll = 0;
  98.236 -    s->special_mask = 0;
  98.237 -    s->init_state = 0;
  98.238 -    s->auto_eoi = 0;
  98.239 -    s->rotate_on_auto_eoi = 0;
  98.240 -    s->special_fully_nested_mode = 0;
  98.241 -    s->init4 = 0;
  98.242 -    s->elcr = 0;
  98.243 -}
  98.244 -
  98.245 -static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  98.246 -{
  98.247 -    PicState *s = opaque;
  98.248 -    int priority, cmd, irq;
  98.249 -
  98.250 -    addr &= 1;
  98.251 -    if (addr == 0) {
  98.252 -        if (val & 0x10) {
  98.253 -            /* init */
  98.254 -            pic_reset(s);
  98.255 -            update_shared_irr(s->pics_state, s);
  98.256 -            /* deassert a pending interrupt */
  98.257 -            s->pics_state->irq_request(s->pics_state->irq_request_opaque, 0);
  98.258 -            s->init_state = 1;
  98.259 -            s->init4 = val & 1;
  98.260 -            if (val & 0x02)
  98.261 -                hw_error("single mode not supported");
  98.262 -            if (val & 0x08)
  98.263 -                hw_error("level sensitive irq not supported");
  98.264 -        } else if (val & 0x08) {
  98.265 -            if (val & 0x04)
  98.266 -                s->poll = 1;
  98.267 -            if (val & 0x02)
  98.268 -                s->read_reg_select = val & 1;
  98.269 -            if (val & 0x40)
  98.270 -                s->special_mask = (val >> 5) & 1;
  98.271 -        } else {
  98.272 -            cmd = val >> 5;
  98.273 -            switch(cmd) {
  98.274 -            case 0:
  98.275 -            case 4:
  98.276 -                s->rotate_on_auto_eoi = cmd >> 2;
  98.277 -                break;
  98.278 -            case 1: /* end of interrupt */
  98.279 -            case 5:
  98.280 -                priority = get_priority(s, s->isr);
  98.281 -                if (priority != 8) {
  98.282 -                    irq = (priority + s->priority_add) & 7;
  98.283 -                    s->isr &= ~(1 << irq);
  98.284 -                    if (cmd == 5)
  98.285 -                        s->priority_add = (irq + 1) & 7;
  98.286 -                    pic_update_irq(s->pics_state);
  98.287 -                }
  98.288 -                break;
  98.289 -            case 3:
  98.290 -                irq = val & 7;
  98.291 -                s->isr &= ~(1 << irq);
  98.292 -                pic_update_irq(s->pics_state);
  98.293 -                break;
  98.294 -            case 6:
  98.295 -                s->priority_add = (val + 1) & 7;
  98.296 -                pic_update_irq(s->pics_state);
  98.297 -                break;
  98.298 -            case 7:
  98.299 -                irq = val & 7;
  98.300 -                s->isr &= ~(1 << irq);
  98.301 -                s->priority_add = (irq + 1) & 7;
  98.302 -                pic_update_irq(s->pics_state);
  98.303 -                break;
  98.304 -            default:
  98.305 -                /* no operation */
  98.306 -                break;
  98.307 -            }
  98.308 -        }
  98.309 -    } else {
  98.310 -        switch(s->init_state) {
  98.311 -        case 0:
  98.312 -            /* normal mode */
  98.313 -            s->imr = val;
  98.314 -            pic_update_irq(s->pics_state);
  98.315 -            break;
  98.316 -        case 1:
  98.317 -            s->irq_base = val & 0xf8;
  98.318 -            s->init_state = 2;
  98.319 -            break;
  98.320 -        case 2:
  98.321 -            if (s->init4) {
  98.322 -                s->init_state = 3;
  98.323 -            } else {
  98.324 -                s->init_state = 0;
  98.325 -            }
  98.326 -            break;
  98.327 -        case 3:
  98.328 -            s->special_fully_nested_mode = (val >> 4) & 1;
  98.329 -            s->auto_eoi = (val >> 1) & 1;
  98.330 -            s->init_state = 0;
  98.331 -            break;
  98.332 -        }
  98.333 -    }
  98.334 -}
  98.335 -
  98.336 -static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
  98.337 -{
  98.338 -    int ret;
  98.339 -
  98.340 -    ret = pic_get_irq(s);
  98.341 -    if (ret >= 0) {
  98.342 -        if (addr1 >> 7) {
  98.343 -            s->pics_state->pics[0].isr &= ~(1 << 2);
  98.344 -            s->pics_state->pics[0].irr &= ~(1 << 2);
  98.345 -        }
  98.346 -        s->irr &= ~(1 << ret);
  98.347 -        s->isr &= ~(1 << ret);
  98.348 -        if (addr1 >> 7 || ret != 2)
  98.349 -            pic_update_irq(s->pics_state);
  98.350 -    } else {
  98.351 -        ret = 0x07;
  98.352 -        pic_update_irq(s->pics_state);
  98.353 -    }
  98.354 -
  98.355 -    return ret;
  98.356 -}
  98.357 -
  98.358 -static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
  98.359 -{
  98.360 -    PicState *s = opaque;
  98.361 -    unsigned int addr;
  98.362 -    int ret;
  98.363 -
  98.364 -    addr = addr1;
  98.365 -    addr &= 1;
  98.366 -    if (s->poll) {
  98.367 -        ret = pic_poll_read(s, addr1);
  98.368 -        s->poll = 0;
  98.369 -    } else {
  98.370 -        if (addr == 0) {
  98.371 -            if (s->read_reg_select)
  98.372 -                ret = s->isr;
  98.373 -            else
  98.374 -                ret = s->irr;
  98.375 -        } else {
  98.376 -            ret = s->imr;
  98.377 -        }
  98.378 -    }
  98.379 -    return ret;
  98.380 -}
  98.381 -
  98.382 -/* memory mapped interrupt status */
  98.383 -/* XXX: may be the same than pic_read_irq() */
  98.384 -uint32_t pic_intack_read(struct vmx_virpic *s)
  98.385 -{
  98.386 -    int ret;
  98.387 -
  98.388 -    ret = pic_poll_read(&s->pics[0], 0x00);
  98.389 -    if (ret == 2)
  98.390 -        ret = pic_poll_read(&s->pics[1], 0x80) + 8;
  98.391 -    /* Prepare for ISR read */
  98.392 -    s->pics[0].read_reg_select = 1;
  98.393 -    
  98.394 -    return ret;
  98.395 -}
  98.396 -
  98.397 -static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  98.398 -{
  98.399 -    PicState *s = opaque;
  98.400 -    s->elcr = val & s->elcr_mask;
  98.401 -}
  98.402 -
  98.403 -static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1)
  98.404 -{
  98.405 -    PicState *s = opaque;
  98.406 -    return s->elcr;
  98.407 -}
  98.408 -
  98.409 -/* XXX: add generic master/slave system */
  98.410 -static void pic_init1(int io_addr, int elcr_addr, PicState *s)
  98.411 -{
  98.412 -    pic_reset(s);
  98.413 -}
  98.414 -
  98.415 -void pic_init(struct vmx_virpic *s, void (*irq_request)(), 
  98.416 -              void *irq_request_opaque)
  98.417 -{
  98.418 -    memset(s, 0, sizeof(*s));
  98.419 -    pic_init1(0x20, 0x4d0, &s->pics[0]);
  98.420 -    pic_init1(0xa0, 0x4d1, &s->pics[1]);
  98.421 -    s->pics[0].elcr_mask = 0xf8;
  98.422 -    s->pics[1].elcr_mask = 0xde;
  98.423 -    s->irq_request = irq_request;
  98.424 -    s->irq_request_opaque = irq_request_opaque;
  98.425 -    s->pics[0].pics_state = s;
  98.426 -    s->pics[1].pics_state = s;
  98.427 -    return; 
  98.428 -}
  98.429 -
  98.430 -void pic_set_alt_irq_func(struct vmx_virpic *s, void (*alt_irq_func)(),
  98.431 -                          void *alt_irq_opaque)
  98.432 -{
  98.433 -    s->alt_irq_func = alt_irq_func;
  98.434 -    s->alt_irq_opaque = alt_irq_opaque;
  98.435 -}
  98.436 -
  98.437 -static int intercept_pic_io(ioreq_t *p)
  98.438 -{
  98.439 -    struct vmx_virpic  *pic;
  98.440 -    struct vcpu *v = current;
  98.441 -    uint32_t data;
  98.442 -    
  98.443 -    if ( p->size != 1 || p->count != 1) {
  98.444 -        printk("PIC_IO wrong access size %d!\n", (int)p->size);
  98.445 -        return 1;
  98.446 -    }
  98.447 -    pic = &v->domain->arch.vmx_platform.vmx_pic;
  98.448 -    if ( p->dir == 0 ) {
  98.449 -        if(p->pdata_valid) 
  98.450 -            vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_IN);
  98.451 -        else
  98.452 -            data = p->u.data;
  98.453 -        pic_ioport_write((void*)&pic->pics[p->addr>>7],
  98.454 -                (uint32_t) p->addr, (uint32_t) (data & 0xff));
  98.455 -    }
  98.456 -    else {
  98.457 -        data = pic_ioport_read(
  98.458 -            (void*)&pic->pics[p->addr>>7], (uint32_t) p->addr);
  98.459 -        if(p->pdata_valid) 
  98.460 -            vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_OUT);
  98.461 -        else 
  98.462 -            p->u.data = (u64)data;
  98.463 -    }
  98.464 -    return 1;
  98.465 -}
  98.466 -
  98.467 -static int intercept_elcr_io(ioreq_t *p)
  98.468 -{
  98.469 -    struct vmx_virpic  *s;
  98.470 -    struct vcpu *v = current;
  98.471 -    uint32_t data;
  98.472 -    
  98.473 -    if ( p->size != 1 || p->count != 1 ) {
  98.474 -        printk("PIC_IO wrong access size %d!\n", (int)p->size);
  98.475 -        return 1;
  98.476 -    }
  98.477 -
  98.478 -    s = &v->domain->arch.vmx_platform.vmx_pic;
  98.479 -    if ( p->dir == 0 ) {
  98.480 -        if(p->pdata_valid) 
  98.481 -            vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_IN);
  98.482 -        else
  98.483 -            data = p->u.data;
  98.484 -        elcr_ioport_write((void*)&s->pics[p->addr&1],
  98.485 -                (uint32_t) p->addr, (uint32_t)( data & 0xff));
  98.486 -    	get_sp(current->domain)->sp_global.pic_elcr = 
  98.487 -            s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
  98.488 -    }
  98.489 -    else {
  98.490 -        data = (u64) elcr_ioport_read(
  98.491 -                (void*)&s->pics[p->addr&1], (uint32_t) p->addr);
  98.492 -        if(p->pdata_valid) 
  98.493 -            vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_OUT);
  98.494 -        else 
  98.495 -            p->u.data = (u64)data;
  98.496 -
  98.497 -    }
  98.498 -    return 1;
  98.499 -}
  98.500 -void register_pic_io_hook (void)
  98.501 -{
  98.502 -    register_portio_handler(0x20, 2, intercept_pic_io); 
  98.503 -    register_portio_handler(0x4d0, 1, intercept_elcr_io); 
  98.504 -    register_portio_handler(0xa0, 2, intercept_pic_io); 
  98.505 -    register_portio_handler(0x4d1, 1, intercept_elcr_io); 
  98.506 -}
  98.507 -
  98.508 -
  98.509 -/* IRQ handling */
  98.510 -int cpu_get_pic_interrupt(struct vcpu *v, int *type)
  98.511 -{
  98.512 -    int intno;
  98.513 -    struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic;
  98.514 -    struct vmx_platform *plat = &v->domain->arch.vmx_platform;
  98.515 -
  98.516 -    if ( !vlapic_accept_pic_intr(v) )
  98.517 -        return -1;
  98.518 -
  98.519 -    if ( !plat->interrupt_request )
  98.520 -        return -1;
  98.521 -
  98.522 -    plat->interrupt_request = 0;
  98.523 -    /* read the irq from the PIC */
  98.524 -    intno = pic_read_irq(s);
  98.525 -    *type = VLAPIC_DELIV_MODE_EXT;
  98.526 -    return intno;
  98.527 -}
  98.528 -
  98.529 -int is_pit_irq(struct vcpu *v, int irq, int type)
  98.530 -{
  98.531 -    int pit_vec;
  98.532 -
  98.533 -    if (type == VLAPIC_DELIV_MODE_EXT)
  98.534 -        pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base;
  98.535 -    else
  98.536 -        pit_vec =
  98.537 -          v->domain->arch.vmx_platform.vmx_vioapic.redirtbl[0].RedirForm.vector;
  98.538 -
  98.539 -    return (irq == pit_vec);
  98.540 -}
  98.541 -
  98.542 -int is_irq_enabled(struct vcpu *v, int irq)
  98.543 -{
  98.544 -    struct vmx_virpic *vpic=&v->domain->arch.vmx_platform.vmx_pic;
  98.545 -        
  98.546 -    if ( irq & 8 ) {
  98.547 -        return !( (1 << (irq&7)) & vpic->pics[1].imr);
  98.548 -    }
  98.549 -    else {
  98.550 -        return !( (1 << irq) & vpic->pics[0].imr);
  98.551 -    }
  98.552 -}
  98.553 -
    99.1 --- a/xen/arch/x86/dm/vmx_vioapic.c	Mon Jan 30 18:51:35 2006 +0100
    99.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.3 @@ -1,621 +0,0 @@
    99.4 -/*
    99.5 -*  Copyright (C) 2001  MandrakeSoft S.A.
    99.6 -*
    99.7 -*    MandrakeSoft S.A.
    99.8 -*    43, rue d'Aboukir
    99.9 -*    75002 Paris - France
   99.10 -*    http://www.linux-mandrake.com/
   99.11 -*    http://www.mandrakesoft.com/
   99.12 -*
   99.13 -*  This library is free software; you can redistribute it and/or
   99.14 -*  modify it under the terms of the GNU Lesser General Public
   99.15 -*  License as published by the Free Software Foundation; either
   99.16 -*  version 2 of the License, or (at your option) any later version.
   99.17 -*
   99.18 -*  This library is distributed in the hope that it will be useful,
   99.19 -*  but WITHOUT ANY WARRANTY; without even the implied warranty of
   99.20 -*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   99.21 -*  Lesser General Public License for more details.
   99.22 -*
   99.23 -*  You should have received a copy of the GNU Lesser General Public
   99.24 -*  License along with this library; if not, write to the Free Software
   99.25 -*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   99.26 -*/
   99.27 -
   99.28 -/*
   99.29 -*  Yunhong Jiang <yunhong.jiang@intel.com>
   99.30 -*  Ported to xen by using virtual IRQ line.
   99.31 -*/
   99.32 -
   99.33 -#include <asm/vmx_vioapic.h>
   99.34 -#include <asm/vmx_platform.h>
   99.35 -
   99.36 -#include <xen/config.h>
   99.37 -#include <xen/types.h>
   99.38 -#include <xen/mm.h>
   99.39 -#include <xen/xmalloc.h>
   99.40 -#include <xen/lib.h>
   99.41 -#include <xen/errno.h>
   99.42 -#include <xen/sched.h>
   99.43 -#include <public/hvm/ioreq.h>
   99.44 -#include <asm/vmx.h>
   99.45 -#include <asm/vmx_vpic.h>
   99.46 -#include <asm/current.h>
   99.47 -
   99.48 -static void ioapic_enable(vmx_vioapic_t *s, uint8_t enable)
   99.49 -{
   99.50 -    if (enable)
   99.51 -        s->flags |= IOAPIC_ENABLE_FLAG;
   99.52 -    else
   99.53 -        s->flags &= ~IOAPIC_ENABLE_FLAG;
   99.54 -}
   99.55 -
   99.56 -static void ioapic_dump_redir(vmx_vioapic_t *s, uint8_t entry)
   99.57 -{
   99.58 -    RedirStatus redir = s->redirtbl[entry];
   99.59 -
   99.60 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_dump_redir "
   99.61 -      "entry %x vector %x deliver_mod %x destmode %x delivestatus %x "
   99.62 -      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
   99.63 -      entry, redir.RedirForm.vector, redir.RedirForm.deliver_mode,
   99.64 -      redir.RedirForm.destmode, redir.RedirForm.delivestatus,
   99.65 -      redir.RedirForm.polarity, redir.RedirForm.remoteirr,
   99.66 -      redir.RedirForm.trigmod, redir.RedirForm.mask,
   99.67 -      redir.RedirForm.dest_id);
   99.68 -}
   99.69 -
   99.70 -#ifdef VMX_DOMAIN_SAVE_RESTORE
   99.71 -void ioapic_save(QEMUFile* f, void* opaque)
   99.72 -{
   99.73 -    printk("no implementation for ioapic_save\n");
   99.74 -}
   99.75 -
   99.76 -int ioapic_load(QEMUFile* f, void* opaque, int version_id)
   99.77 -{
   99.78 -    printk("no implementation for ioapic_load\n");
   99.79 -    return 0;
   99.80 -}
   99.81 -#endif
   99.82 -
   99.83 -static unsigned long vmx_vioapic_read_indirect(struct vmx_vioapic *s,
   99.84 -                                              unsigned long addr,
   99.85 -                                              unsigned long length)
   99.86 -{
   99.87 -    unsigned long result = 0;
   99.88 -
   99.89 -    ASSERT(s);
   99.90 -
   99.91 -    switch (s->ioregsel) {
   99.92 -    case IOAPIC_REG_VERSION:
   99.93 -        result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)
   99.94 -                  | (IOAPIC_VERSION_ID & 0x0f));
   99.95 -        break;
   99.96 -
   99.97 -#ifndef __ia64__
   99.98 -    case IOAPIC_REG_APIC_ID:
   99.99 -        result = ((s->id & 0xf) << 24);
  99.100 -        break;
  99.101 -
  99.102 -    case IOAPIC_REG_ARB_ID:
  99.103 -        /* XXX how arb_id used on p4? */
  99.104 -        result = ((s->id & 0xf) << 24);
  99.105 -        break;
  99.106 -#endif
  99.107 -
  99.108 -    default:
  99.109 -        {
  99.110 -            uint32_t redir_index = 0;
  99.111 -            uint64_t redir_content = 0;
  99.112 -
  99.113 -            redir_index = (s->ioregsel - 0x10) >> 1;
  99.114 -
  99.115 -            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
  99.116 -                redir_content = s->redirtbl[redir_index].value;
  99.117 -
  99.118 -                result = (s->ioregsel & 0x1)?
  99.119 -                           (redir_content >> 32) & 0xffffffff :
  99.120 -                           redir_content & 0xffffffff;
  99.121 -            } else {
  99.122 -                printk("upic_mem_readl:undefined ioregsel %x\n",
  99.123 -                        s->ioregsel);
  99.124 -                domain_crash_synchronous();
  99.125 -            }
  99.126 -            break;
  99.127 -        }
  99.128 -    } /* switch */
  99.129 -
  99.130 -    return result;
  99.131 -}
  99.132 -
  99.133 -static unsigned long vmx_vioapic_read(struct vcpu *v,
  99.134 -                                     unsigned long addr,
  99.135 -                                     unsigned long length)
  99.136 -{
  99.137 -    struct vmx_vioapic *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  99.138 -    uint32_t    result = 0;
  99.139 -
  99.140 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_read addr %lx\n", addr);
  99.141 -
  99.142 -    ASSERT(s);
  99.143 -
  99.144 -    addr &= 0xff;
  99.145 -
  99.146 -    switch (addr) {
  99.147 -    case IOAPIC_REG_SELECT:
  99.148 -        result = s->ioregsel;
  99.149 -        break;
  99.150 -
  99.151 -    case IOAPIC_REG_WINDOW:
  99.152 -        result = vmx_vioapic_read_indirect(s, addr, length);
  99.153 -        break;
  99.154 -
  99.155 -    default:
  99.156 -          break;
  99.157 -    }
  99.158 -
  99.159 -    return result;
  99.160 -}
  99.161 -
  99.162 -static void vmx_vioapic_update_imr(struct vmx_vioapic *s, int index)
  99.163 -{
  99.164 -   if (s->redirtbl[index].RedirForm.mask)
  99.165 -       set_bit(index, &s->imr);
  99.166 -   else
  99.167 -       clear_bit(index, &s->imr);
  99.168 -}
  99.169 -
  99.170 -static void vmx_vioapic_write_indirect(struct vmx_vioapic *s,
  99.171 -                                      unsigned long addr,
  99.172 -                                      unsigned long length,
  99.173 -                                      unsigned long val)
  99.174 -{
  99.175 -    switch (s->ioregsel) {
  99.176 -    case IOAPIC_REG_VERSION:
  99.177 -        printk("vmx_vioapic_write_indirect: version register read only\n");
  99.178 -        break;
  99.179 -
  99.180 -#ifndef __ia64__
  99.181 -    case IOAPIC_REG_APIC_ID:
  99.182 -        s->id = (val >> 24) & 0xf;
  99.183 -        break;
  99.184 -
  99.185 -    case IOAPIC_REG_ARB_ID:
  99.186 -        s->arb_id = val;
  99.187 -        break;
  99.188 -#endif
  99.189 -
  99.190 -    default:
  99.191 -        {
  99.192 -            uint32_t redir_index = 0;
  99.193 -
  99.194 -            VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_write_indirect "
  99.195 -              "change redir index %x val %lx\n",
  99.196 -              redir_index, val);
  99.197 -
  99.198 -            redir_index = (s->ioregsel - 0x10) >> 1;
  99.199 -
  99.200 -            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
  99.201 -                uint64_t redir_content;
  99.202 -
  99.203 -                redir_content = s->redirtbl[redir_index].value;
  99.204 -
  99.205 -                if (s->ioregsel & 0x1)
  99.206 -                    redir_content = (((uint64_t)val & 0xffffffff) << 32) |
  99.207 -                                    (redir_content & 0xffffffff);
  99.208 -                else
  99.209 -                    redir_content = ((redir_content >> 32) << 32) |
  99.210 -                                    (val & 0xffffffff);
  99.211 -                s->redirtbl[redir_index].value = redir_content;
  99.212 -                vmx_vioapic_update_imr(s, redir_index);
  99.213 -            } else  {
  99.214 -                printk("vmx_vioapic_write_indirect "
  99.215 -                  "error register %x\n", s->ioregsel);
  99.216 -            }
  99.217 -            break;
  99.218 -        }
  99.219 -    } /* switch */
  99.220 -}
  99.221 -
  99.222 -static void vmx_vioapic_write(struct vcpu *v,
  99.223 -                             unsigned long addr,
  99.224 -                             unsigned long length,
  99.225 -                             unsigned long val)
  99.226 -{
  99.227 -    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  99.228 -
  99.229 -    ASSERT(s);
  99.230 -
  99.231 -    addr &= 0xff;
  99.232 -
  99.233 -    switch (addr) {
  99.234 -    case IOAPIC_REG_SELECT:
  99.235 -        s->ioregsel = val;
  99.236 -        break;
  99.237 -
  99.238 -    case IOAPIC_REG_WINDOW:
  99.239 -        vmx_vioapic_write_indirect(s, addr, length, val);
  99.240 -        break;
  99.241 -
  99.242 -#ifdef __ia64__
  99.243 -    case IOAPIC_REG_EOI:
  99.244 -        ioapic_update_EOI(v->domain, val);
  99.245 -        break;
  99.246 -#endif
  99.247 -
  99.248 -    default:
  99.249 -        break;
  99.250 -    }
  99.251 -}
  99.252 -
  99.253 -static int vmx_vioapic_range(struct vcpu *v, unsigned long addr)
  99.254 -{
  99.255 -    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  99.256 -
  99.257 -    if ((s->flags & IOAPIC_ENABLE_FLAG) &&
  99.258 -        (addr >= s->base_address &&
  99.259 -        (addr <= s->base_address + IOAPIC_MEM_LENGTH)))
  99.260 -        return 1;
  99.261 -    else
  99.262 -        return 0;
  99.263 -}
  99.264 -
  99.265 -struct vmx_mmio_handler vioapic_mmio_handler = {
  99.266 -    .check_handler = vmx_vioapic_range,
  99.267 -    .read_handler = vmx_vioapic_read,
  99.268 -    .write_handler = vmx_vioapic_write
  99.269 -};
  99.270 -
  99.271 -static void vmx_vioapic_reset(vmx_vioapic_t *s)
  99.272 -{
  99.273 -    int i;
  99.274 -
  99.275 -    memset(s, 0, sizeof(vmx_vioapic_t));
  99.276 -
  99.277 -    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
  99.278 -        s->redirtbl[i].RedirForm.mask = 0x1;
  99.279 -        vmx_vioapic_update_imr(s, i);
  99.280 -    }
  99.281 -}
  99.282 -
  99.283 -static void ioapic_update_config(vmx_vioapic_t *s,
  99.284 -                                 unsigned long address,
  99.285 -                                 uint8_t enable)
  99.286 -{
  99.287 -    ASSERT(s);
  99.288 -
  99.289 -    ioapic_enable(s, enable);
  99.290 -
  99.291 -    if (address != s->base_address)
  99.292 -        s->base_address = address;
  99.293 -}
  99.294 -
  99.295 -static int ioapic_inj_irq(vmx_vioapic_t *s,
  99.296 -                          struct vlapic * target,
  99.297 -                          uint8_t vector,
  99.298 -                          uint8_t trig_mode,
  99.299 -                          uint8_t delivery_mode)
  99.300 -{
  99.301 -    int result = 0;
  99.302 -
  99.303 -    ASSERT(s && target);
  99.304 -
  99.305 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq "
  99.306 -      "irq %d trig %d delive mode %d\n",
  99.307 -      vector, trig_mode, delivery_mode);
  99.308 -
  99.309 -    switch (delivery_mode) {
  99.310 -    case VLAPIC_DELIV_MODE_FIXED:
  99.311 -    case VLAPIC_DELIV_MODE_LPRI:
  99.312 -        if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1))
  99.313 -            printk("<ioapic_inj_irq> level interrupt happen before cleard\n");
  99.314 -        result = 1;
  99.315 -        break;
  99.316 -    default:
  99.317 -        printk("<ioapic_inj_irq> error delivery mode %d\n",
  99.318 -                delivery_mode);
  99.319 -        break;
  99.320 -   }
  99.321 -
  99.322 -   return result;
  99.323 -}
  99.324 -
  99.325 -#ifndef __ia64__
  99.326 -static int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t dest)
  99.327 -{
  99.328 -    int result = 0;
  99.329 -
  99.330 -    ASSERT(s && s->lapic_info[number]);
  99.331 -
  99.332 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr "
  99.333 -      "number %i dest %x\n",
  99.334 -      number, dest);
  99.335 -
  99.336 -    switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) {
  99.337 -    case 0xf:
  99.338 -        result =
  99.339 -          (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0;
  99.340 -        break;
  99.341 -    case 0x0:
  99.342 -        /* Should we support flat cluster mode ?*/
  99.343 -        if ( ((s->lapic_info[number]->logical_dest >> 28)
  99.344 -               == ((dest >> 0x4) & 0xf)) &&
  99.345 -             (((s->lapic_info[number]->logical_dest >> 24) & 0xf)
  99.346 -               & (dest  & 0xf)) )
  99.347 -            result = 1;
  99.348 -        break;
  99.349 -    default:
  99.350 -        printk("error DFR value for %x local apic\n", number);
  99.351 -        break;
  99.352 -    }
  99.353 -
  99.354 -    return result;
  99.355 -}
  99.356 -#else
  99.357 -extern int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t dest);
  99.358 -#endif
  99.359 -
  99.360 -static uint32_t ioapic_get_delivery_bitmask(vmx_vioapic_t *s,
  99.361 -                                            uint16_t dest,
  99.362 -                                            uint8_t dest_mode,
  99.363 -                                            uint8_t vector,
  99.364 -                                            uint8_t delivery_mode)
  99.365 -{
  99.366 -    uint32_t mask = 0;
  99.367 -    int i;
  99.368 -
  99.369 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
  99.370 -      "dest %d dest_mode %d "
  99.371 -      "vector %d del_mode %d, lapic_count %d\n",
  99.372 -      dest, dest_mode, vector, delivery_mode, s->lapic_count);
  99.373 -
  99.374 -    ASSERT(s);
  99.375 -
  99.376 -    if (dest_mode == 0) { /* Physical mode */
  99.377 -        for (i = 0; i < s->lapic_count; i++) {
  99.378 -            if (VLAPIC_ID(s->lapic_info[i]) == dest) {
  99.379 -                mask = 1 << i;
  99.380 -                break;
  99.381 -            }
  99.382 -        }
  99.383 -    } else {
  99.384 -        /* logical destination. call match_logical_addr for each APIC. */
  99.385 -        if (dest != 0) {
  99.386 -            for (i=0; i< s->lapic_count; i++) {
  99.387 -                if ( s->lapic_info[i] &&
  99.388 -                     ioapic_match_logical_addr(s, i, dest) ) {
  99.389 -                    mask |= (1<<i);
  99.390 -                }
  99.391 -            }
  99.392 -        }
  99.393 -    }
  99.394 -
  99.395 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
  99.396 -      "mask %x\n", mask);
  99.397 -
  99.398 -    return mask;
  99.399 -}
  99.400 -
  99.401 -static void ioapic_deliver(vmx_vioapic_t *s, int irqno)
  99.402 -{
  99.403 -    uint16_t dest = s->redirtbl[irqno].RedirForm.dest_id;
  99.404 -    uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode;
  99.405 -    uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode;
  99.406 -    uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
  99.407 -    uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
  99.408 -    uint32_t deliver_bitmask;
  99.409 -
  99.410 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "IOAPIC deliver: "
  99.411 -      "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
  99.412 -      dest, dest_mode, delivery_mode, vector, trig_mode);
  99.413 -
  99.414 -    deliver_bitmask =
  99.415 -      ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
  99.416 -
  99.417 -    if (!deliver_bitmask) {
  99.418 -        VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
  99.419 -          "no target on destination\n");
  99.420 -
  99.421 -        return;
  99.422 -    }
  99.423 -
  99.424 -    switch (delivery_mode) {
  99.425 -    case VLAPIC_DELIV_MODE_LPRI:
  99.426 -    {
  99.427 -        struct vlapic* target;
  99.428 -
  99.429 -        target = apic_round_robin(
  99.430 -                s->domain, dest_mode, vector, deliver_bitmask);
  99.431 -        if (target)
  99.432 -            ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
  99.433 -        else{
  99.434 -            VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
  99.435 -              "null round robin mask %x vector %x delivery_mode %x\n",
  99.436 -              deliver_bitmask, vector, deliver_bitmask);
  99.437 -        }
  99.438 -        break;
  99.439 -    }
  99.440 -
  99.441 -    case VLAPIC_DELIV_MODE_FIXED:
  99.442 -    case VLAPIC_DELIV_MODE_EXT:
  99.443 -    {
  99.444 -        uint8_t bit;
  99.445 -        for (bit = 0; bit < s->lapic_count; bit++) {
  99.446 -            if (deliver_bitmask & (1 << bit)) {
  99.447 -                if (s->lapic_info[bit]) {
  99.448 -                    ioapic_inj_irq(s, s->lapic_info[bit],
  99.449 -                                vector, trig_mode, delivery_mode);
  99.450 -                }
  99.451 -            }
  99.452 -        }
  99.453 -        break;
  99.454 -    }
  99.455 -
  99.456 -    case VLAPIC_DELIV_MODE_SMI:
  99.457 -    case VLAPIC_DELIV_MODE_NMI:
  99.458 -    case VLAPIC_DELIV_MODE_INIT:
  99.459 -    case VLAPIC_DELIV_MODE_STARTUP:
  99.460 -    default:
  99.461 -        printk("Not support delivey mode %d\n", delivery_mode);
  99.462 -        break;
  99.463 -    }
  99.464 -}
  99.465 -
  99.466 -static int ioapic_get_highest_irq(vmx_vioapic_t *s)
  99.467 -{
  99.468 -    uint32_t irqs;
  99.469 -
  99.470 -    ASSERT(s);
  99.471 -
  99.472 -    irqs = s->irr & ~s->isr & ~s->imr;
  99.473 -    return __fls(irqs);
  99.474 -}
  99.475 -
  99.476 -
  99.477 -static void service_ioapic(vmx_vioapic_t *s)
  99.478 -{
  99.479 -    int irqno;
  99.480 -
  99.481 -    while ((irqno = ioapic_get_highest_irq(s)) != -1) {
  99.482 -
  99.483 -        VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic "
  99.484 -          "highest irqno %x\n", irqno);
  99.485 -
  99.486 -        if (!test_bit(irqno, &s->imr)) {
  99.487 -            ioapic_deliver(s, irqno);
  99.488 -        }
  99.489 -
  99.490 -        if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
  99.491 -            s->isr |= (1 << irqno);
  99.492 -        }
  99.493 -
  99.494 -        s->irr &= ~(1 << irqno);
  99.495 -    }
  99.496 -}
  99.497 -
  99.498 -void vmx_vioapic_do_irqs(struct domain *d, uint16_t irqs)
  99.499 -{
  99.500 -    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  99.501 -
  99.502 -    if (!vmx_apic_support(d))
  99.503 -        return;
  99.504 -
  99.505 -    s->irr |= irqs & ~s->imr;
  99.506 -    service_ioapic(s);
  99.507 -}
  99.508 -
  99.509 -void vmx_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs)
  99.510 -{
  99.511 -    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  99.512 -
  99.513 -    if (!vmx_apic_support(d))
  99.514 -        return;
  99.515 -
  99.516 -    s->irr &= ~irqs;
  99.517 -    service_ioapic(s);
  99.518 -}
  99.519 -
  99.520 -void vmx_vioapic_set_irq(struct domain *d, int irq, int level)
  99.521 -{
  99.522 -    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  99.523 -
  99.524 -    if (!vmx_apic_support(d))
  99.525 -        return ;
  99.526 -
  99.527 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq "
  99.528 -      "irq %x level %x\n", irq, level);
  99.529 -
  99.530 -    if (irq < 0 || irq >= IOAPIC_NUM_PINS) {
  99.531 -        printk("ioapic_set_irq irq %x is illegal\n", irq);
  99.532 -        domain_crash_synchronous();
  99.533 -    }
  99.534 -
  99.535 -    if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
  99.536 -        return;
  99.537 -
  99.538 -    ioapic_dump_redir(s, irq);
  99.539 -
  99.540 -    if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
  99.541 -        uint32_t bit = 1 << irq;
  99.542 -        if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
  99.543 -            if (level)
  99.544 -                s->irr |= bit;
  99.545 -            else
  99.546 -                s->irr &= ~bit;
  99.547 -        } else {
  99.548 -            if (level)
  99.549 -                /* XXX No irr clear for edge interrupt */
  99.550 -                s->irr |= bit;
  99.551 -        }
  99.552 -    }
  99.553 -
  99.554 -    service_ioapic(s);
  99.555 -}
  99.556 -
  99.557 -/* XXX If level interrupt, use vector->irq table for performance */
  99.558 -static int get_redir_num(vmx_vioapic_t *s, int vector)
  99.559 -{
  99.560 -    int i = 0;
  99.561 -
  99.562 -    ASSERT(s);
  99.563 -
  99.564 -    for(i = 0; i < IOAPIC_NUM_PINS - 1; i++) {
  99.565 -        if (s->redirtbl[i].RedirForm.vector == vector)
  99.566 -            return i;
  99.567 -    }
  99.568 -
  99.569 -    return -1;
  99.570 -}
  99.571 -
  99.572 -void ioapic_update_EOI(struct domain *d, int vector)
  99.573 -{
  99.574 -    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  99.575 -    int redir_num;
  99.576 -
  99.577 -    if ((redir_num = get_redir_num(s, vector)) == -1) {
  99.578 -        printk("Can't find redir item for %d EOI \n", vector);
  99.579 -        return;
  99.580 -    }
  99.581 -
  99.582 -    if (!test_and_clear_bit(redir_num, &s->isr)) {
  99.583 -        printk("redir %d not set for %d  EOI\n", redir_num, vector);
  99.584 -        return;
  99.585 -    }
  99.586 -}
  99.587 -
  99.588 -int vmx_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v)
  99.589 -{
  99.590 -    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  99.591 -
  99.592 -    if (v->vcpu_id != s->lapic_count) {
  99.593 -        printk("vmx_vioapic_add_lapic "
  99.594 -           "cpu_id not match vcpu_id %x lapic_count %x\n",
  99.595 -           v->vcpu_id, s->lapic_count);
  99.596 -        domain_crash_synchronous();
  99.597 -    }
  99.598 -
  99.599 -    /* update count later for race condition on interrupt */
  99.600 -    s->lapic_info[s->lapic_count] = vlapic;
  99.601 -    s->lapic_count ++;
  99.602 -
  99.603 -    return s->lapic_count;
  99.604 -}
  99.605 -
  99.606 -vmx_vioapic_t * vmx_vioapic_init(struct domain *d)
  99.607 -{
  99.608 -    int i = 0;
  99.609 -    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  99.610 -
  99.611 -    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_init\n");
  99.612 -
  99.613 -    vmx_vioapic_reset(s);
  99.614 -
  99.615 -    s->domain = d;
  99.616 -
  99.617 -    for (i = 0; i < MAX_LAPIC_NUM; i++)
  99.618 -        s->lapic_info[i] = NULL;
  99.619 -
  99.620 -    /* Remove after GFW ready */
  99.621 -    ioapic_update_config(s, IOAPIC_DEFAULT_BASE_ADDRESS, 1);
  99.622 -
  99.623 -    return s;
  99.624 -}
   100.1 --- a/xen/arch/x86/dom0_ops.c	Mon Jan 30 18:51:35 2006 +0100
   100.2 +++ b/xen/arch/x86/dom0_ops.c	Tue Jan 31 11:49:51 2006 +0100
   100.3 @@ -20,6 +20,8 @@
   100.4  #include <xen/iocap.h>
   100.5  #include <asm/shadow.h>
   100.6  #include <asm/irq.h>
   100.7 +#include <asm/hvm/hvm.h>
   100.8 +#include <asm/hvm/support.h>
   100.9  #include <asm/processor.h>
  100.10  #include <public/sched_ctl.h>
  100.11  
  100.12 @@ -448,15 +450,12 @@ long arch_do_dom0_op(struct dom0_op *op,
  100.13  void arch_getdomaininfo_ctxt(
  100.14      struct vcpu *v, struct vcpu_guest_context *c)
  100.15  {
  100.16 -    extern void save_vmx_cpu_user_regs(struct cpu_user_regs *);
  100.17 -
  100.18      memcpy(c, &v->arch.guest_context, sizeof(*c));
  100.19  
  100.20 -    if ( VMX_DOMAIN(v) )
  100.21 +    if ( HVM_DOMAIN(v) )
  100.22      {
  100.23 -        save_vmx_cpu_user_regs(&c->user_regs);
  100.24 -        __vmread(CR0_READ_SHADOW, &c->ctrlreg[0]);
  100.25 -        __vmread(CR4_READ_SHADOW, &c->ctrlreg[4]);
  100.26 +	hvm_store_cpu_guest_regs(v, &c->user_regs);
  100.27 +	hvm_store_cpu_guest_ctrl_regs(v, c->ctrlreg);
  100.28      }
  100.29      else
  100.30      {
  100.31 @@ -470,8 +469,8 @@ void arch_getdomaininfo_ctxt(
  100.32          c->flags |= VGCF_I387_VALID;
  100.33      if ( KERNEL_MODE(v, &v->arch.guest_context.user_regs) )
  100.34          c->flags |= VGCF_IN_KERNEL;
  100.35 -    if (VMX_DOMAIN(v))
  100.36 -        c->flags |= VGCF_VMX_GUEST;
  100.37 +    if ( HVM_DOMAIN(v) )
  100.38 +        c->flags |= VGCF_HVM_GUEST;
  100.39  
  100.40      c->ctrlreg[3] = pagetable_get_paddr(v->arch.guest_table);
  100.41  
   101.1 --- a/xen/arch/x86/domain.c	Mon Jan 30 18:51:35 2006 +0100
   101.2 +++ b/xen/arch/x86/domain.c	Tue Jan 31 11:49:51 2006 +0100
   101.3 @@ -35,7 +35,8 @@
   101.4  #include <asm/shadow.h>
   101.5  #include <xen/console.h>
   101.6  #include <xen/elf.h>
   101.7 -#include <asm/vmx.h>
   101.8 +#include <asm/hvm/hvm.h>
   101.9 +#include <asm/hvm/support.h>
  101.10  #include <asm/msr.h>
  101.11  #include <xen/kernel.h>
  101.12  #include <xen/multicall.h>
  101.13 @@ -153,8 +154,7 @@ void machine_restart(char * __unused)
  101.14       */
  101.15      smp_send_stop();
  101.16      disable_IO_APIC();
  101.17 -
  101.18 -    stop_vmx();
  101.19 +    hvm_disable();
  101.20  
  101.21      /* Rebooting needs to touch the page at absolute address 0. */
  101.22      *((unsigned short *)__va(0x472)) = reboot_mode;
  101.23 @@ -354,26 +354,26 @@ int arch_set_info_guest(
  101.24       * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically.
  101.25       * If SS RPL or DPL differs from CS RPL then we'll #GP.
  101.26       */
  101.27 -    if ( !(c->flags & VGCF_VMX_GUEST) )
  101.28 +    if ( !(c->flags & VGCF_HVM_GUEST) )
  101.29      {
  101.30          if ( ((c->user_regs.cs & 3) == 0) ||
  101.31               ((c->user_regs.ss & 3) == 0) )
  101.32              return -EINVAL;
  101.33      }
  101.34      else if ( !hvm_enabled )
  101.35 -        return -EINVAL;
  101.36 +      return -EINVAL;
  101.37  
  101.38      clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
  101.39      if ( c->flags & VGCF_I387_VALID )
  101.40          set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
  101.41  
  101.42      v->arch.flags &= ~TF_kernel_mode;
  101.43 -    if ( (c->flags & VGCF_IN_KERNEL) || (c->flags & VGCF_VMX_GUEST) )
  101.44 +    if ( (c->flags & VGCF_IN_KERNEL) || (c->flags & VGCF_HVM_GUEST) )
  101.45          v->arch.flags |= TF_kernel_mode;
  101.46  
  101.47      memcpy(&v->arch.guest_context, c, sizeof(*c));
  101.48  
  101.49 -    if ( !(c->flags & VGCF_VMX_GUEST) )
  101.50 +    if ( !(c->flags & VGCF_HVM_GUEST) )
  101.51      {
  101.52          /* IOPL privileges are virtualised. */
  101.53          v->arch.iopl = (v->arch.guest_context.user_regs.eflags >> 12) & 3;
  101.54 @@ -384,9 +384,7 @@ int arch_set_info_guest(
  101.55      }
  101.56      else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  101.57      {
  101.58 -        return modify_vmcs(
  101.59 -            &v->arch.arch_vmx,
  101.60 -            &v->arch.guest_context.user_regs);
  101.61 +	hvm_modify_guest_state(v);
  101.62      }
  101.63  
  101.64      if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  101.65 @@ -418,7 +416,7 @@ int arch_set_info_guest(
  101.66              return -EINVAL;
  101.67          }
  101.68      }
  101.69 -    else if ( !(c->flags & VGCF_VMX_GUEST) )
  101.70 +    else if ( !(c->flags & VGCF_HVM_GUEST) )
  101.71      {
  101.72          if ( !get_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT), d,
  101.73                                  PGT_base_page_table) )
  101.74 @@ -428,14 +426,17 @@ int arch_set_info_guest(
  101.75          }
  101.76      }
  101.77  
  101.78 -    if ( c->flags & VGCF_VMX_GUEST )
  101.79 +    if ( c->flags & VGCF_HVM_GUEST )
  101.80      {
  101.81 -        /* VMX uses the initially provided page tables as the P2M map. */
  101.82 +        /* HVM uses the initially provided page tables as the P2M map. */
  101.83          if ( !pagetable_get_paddr(d->arch.phys_table) )
  101.84              d->arch.phys_table = v->arch.guest_table;
  101.85          v->arch.guest_table = mk_pagetable(0);
  101.86  
  101.87 -        vmx_final_setup_guest(v);
  101.88 +	if (!hvm_initialize_guest_resources(v))
  101.89 +            return -EINVAL;
  101.90 +	   
  101.91 +	hvm_switch_on = 1;
  101.92      }
  101.93  
  101.94      update_pagetables(v);
  101.95 @@ -611,8 +612,8 @@ static void save_segments(struct vcpu *v
  101.96      struct cpu_user_regs      *regs = &ctxt->user_regs;
  101.97      unsigned int dirty_segment_mask = 0;
  101.98  
  101.99 -    if ( VMX_DOMAIN(v) )
 101.100 -        rdmsrl(MSR_SHADOW_GS_BASE, v->arch.arch_vmx.msr_content.shadow_gs);
 101.101 +    if ( HVM_DOMAIN(v) )
 101.102 +	hvm_save_segments(v);
 101.103  
 101.104      __asm__ __volatile__ ( "mov %%ds,%0" : "=m" (regs->ds) );
 101.105      __asm__ __volatile__ ( "mov %%es,%0" : "=m" (regs->es) );
 101.106 @@ -704,7 +705,7 @@ static void __context_switch(void)
 101.107              loaddebug(&n->arch.guest_context, 7);
 101.108          }
 101.109  
 101.110 -        if ( !VMX_DOMAIN(n) )
 101.111 +        if ( !HVM_DOMAIN(n) )
 101.112          {
 101.113              set_int80_direct_trap(n);
 101.114              switch_kernel_stack(n, cpu);
 101.115 @@ -764,15 +765,16 @@ void context_switch(struct vcpu *prev, s
 101.116          /* Re-enable interrupts before restoring state which may fault. */
 101.117          local_irq_enable();
 101.118  
 101.119 -        if ( VMX_DOMAIN(next) )
 101.120 +        if ( HVM_DOMAIN(next) )
 101.121          {
 101.122 -            vmx_restore_msrs(next);
 101.123 +            hvm_restore_msrs(next);
 101.124          }
 101.125          else
 101.126          {
 101.127              load_LDT(next);
 101.128              load_segments(next);
 101.129 -            vmx_load_msrs(next);
 101.130 +	    if ( HVM_DOMAIN(next) )
 101.131 +                hvm_load_msrs(next);
 101.132          }
 101.133      }
 101.134  
 101.135 @@ -962,7 +964,8 @@ void domain_relinquish_resources(struct 
 101.136              v->arch.guest_table_user = mk_pagetable(0);
 101.137          }
 101.138  
 101.139 -        vmx_relinquish_resources(v);
 101.140 +	if ( HVM_DOMAIN(v) )
 101.141 +            hvm_relinquish_guest_resources(v);
 101.142      }
 101.143  
 101.144      shadow_mode_disable(d);
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/xen/arch/x86/hvm/hvm.c	Tue Jan 31 11:49:51 2006 +0100
   102.3 @@ -0,0 +1,308 @@
   102.4 +/*
   102.5 + * hvm.c: Common hardware virtual machine abstractions.
   102.6 + *
   102.7 + * Copyright (c) 2004, Intel Corporation.
   102.8 + * Copyright (c) 2005, International Business Machines Corporation.
   102.9 + *
  102.10 + * This program is free software; you can redistribute it and/or modify it
  102.11 + * under the terms and conditions of the GNU General Public License,
  102.12 + * version 2, as published by the Free Software Foundation.
  102.13 + *
  102.14 + * This program is distributed in the hope it will be useful, but WITHOUT
  102.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  102.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  102.17 + * more details.
  102.18 + *
  102.19 + * You should have received a copy of the GNU General Public License along with
  102.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  102.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
  102.22 + */
  102.23 +
  102.24 +#include <xen/config.h>
  102.25 +#include <xen/init.h>
  102.26 +#include <xen/lib.h>
  102.27 +#include <xen/trace.h>
  102.28 +#include <xen/sched.h>
  102.29 +#include <xen/irq.h>
  102.30 +#include <xen/softirq.h>
  102.31 +#include <xen/domain_page.h>
  102.32 +#include <asm/current.h>
  102.33 +#include <asm/io.h>
  102.34 +#include <asm/shadow.h>
  102.35 +#include <asm/regs.h>
  102.36 +#include <asm/cpufeature.h>
  102.37 +#include <asm/processor.h>
  102.38 +#include <asm/types.h>
  102.39 +#include <asm/msr.h>
  102.40 +#include <asm/spinlock.h>
  102.41 +#include <asm/hvm/hvm.h>
  102.42 +#include <asm/hvm/support.h>
  102.43 +#include <asm/shadow.h>
  102.44 +#if CONFIG_PAGING_LEVELS >= 3
  102.45 +#include <asm/shadow_64.h>
  102.46 +#endif
  102.47 +#include <public/sched.h>
  102.48 +#include <public/hvm/ioreq.h>
  102.49 +#include <public/hvm/hvm_info_table.h>
  102.50 +
  102.51 +int hvm_enabled = 0;
  102.52 +int hvm_switch_on = 0;
  102.53 +
  102.54 +unsigned int opt_hvm_debug_level = 0;
  102.55 +integer_param("hvm_debug", opt_hvm_debug_level);
  102.56 +
  102.57 +struct hvm_function_table hvm_funcs;
  102.58 +
  102.59 +static void hvm_map_io_shared_page(struct domain *d)
  102.60 +{
  102.61 +    int i;
  102.62 +    unsigned char e820_map_nr;
  102.63 +    struct e820entry *e820entry;
  102.64 +    unsigned char *p;
  102.65 +    unsigned long mpfn;
  102.66 +    unsigned long gpfn = 0;
  102.67 +
  102.68 +    local_flush_tlb_pge();
  102.69 +
  102.70 +    mpfn = get_mfn_from_pfn(E820_MAP_PAGE >> PAGE_SHIFT);
  102.71 +    if (mpfn == INVALID_MFN) {
  102.72 +        printk("Can not find E820 memory map page for HVM domain.\n");
  102.73 +        domain_crash_synchronous();
  102.74 +    }
  102.75 +
  102.76 +    p = map_domain_page(mpfn);
  102.77 +    if (p == NULL) {
  102.78 +        printk("Can not map E820 memory map page for HVM domain.\n");
  102.79 +        domain_crash_synchronous();
  102.80 +    }
  102.81 +
  102.82 +    e820_map_nr = *(p + E820_MAP_NR_OFFSET);
  102.83 +    e820entry = (struct e820entry *)(p + E820_MAP_OFFSET);
  102.84 +
  102.85 +    for ( i = 0; i < e820_map_nr; i++ )
  102.86 +    {
  102.87 +        if (e820entry[i].type == E820_SHARED_PAGE)
  102.88 +        {
  102.89 +            gpfn = (e820entry[i].addr >> PAGE_SHIFT);
  102.90 +            break;
  102.91 +        }
  102.92 +    }
  102.93 +
  102.94 +    if ( gpfn == 0 ) {
  102.95 +        printk("Can not get io request shared page"
  102.96 +               " from E820 memory map for HVM domain.\n");
  102.97 +        unmap_domain_page(p);
  102.98 +        domain_crash_synchronous();
  102.99 +    }
 102.100 +    unmap_domain_page(p);
 102.101 +
 102.102 +    /* Initialise shared page */
 102.103 +    mpfn = get_mfn_from_pfn(gpfn);
 102.104 +    if (mpfn == INVALID_MFN) {
 102.105 +        printk("Can not find io request shared page for HVM domain.\n");
 102.106 +        domain_crash_synchronous();
 102.107 +    }
 102.108 +
 102.109 +    p = map_domain_page_global(mpfn);
 102.110 +    if (p == NULL) {
 102.111 +        printk("Can not map io request shared page for HVM domain.\n");
 102.112 +        domain_crash_synchronous();
 102.113 +    }
 102.114 +    d->arch.hvm_domain.shared_page_va = (unsigned long)p;
 102.115 +
 102.116 +    HVM_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(d));
 102.117 +
 102.118 +    clear_bit(iopacket_port(d),
 102.119 +              &d->shared_info->evtchn_mask[0]);
 102.120 +}
 102.121 +
 102.122 +static int validate_hvm_info(struct hvm_info_table *t)
 102.123 +{
 102.124 +    char signature[] = "HVM INFO";
 102.125 +    uint8_t *ptr = (uint8_t *)t;
 102.126 +    uint8_t sum = 0;
 102.127 +    int i;
 102.128 +
 102.129 +    /* strncmp(t->signature, "HVM INFO", 8) */
 102.130 +    for ( i = 0; i < 8; i++ ) {
 102.131 +        if ( signature[i] != t->signature[i] ) {
 102.132 +            printk("Bad hvm info signature\n");
 102.133 +            return 0;
 102.134 +        }
 102.135 +    }
 102.136 +
 102.137 +    for ( i = 0; i < t->length; i++ )
 102.138 +        sum += ptr[i];
 102.139 +
 102.140 +    return (sum == 0);
 102.141 +}
 102.142 +
 102.143 +static void hvm_get_info(struct domain *d)
 102.144 +{
 102.145 +    unsigned char *p;
 102.146 +    unsigned long mpfn;
 102.147 +    struct hvm_info_table *t;
 102.148 +
 102.149 +    mpfn = get_mfn_from_pfn(HVM_INFO_PFN);
 102.150 +    if ( mpfn == INVALID_MFN ) {
 102.151 +        printk("Can not get info page mfn for HVM domain.\n");
 102.152 +        domain_crash_synchronous();
 102.153 +    }
 102.154 +
 102.155 +    p = map_domain_page(mpfn);
 102.156 +    if ( p == NULL ) {
 102.157 +        printk("Can not map info page for HVM domain.\n");
 102.158 +        domain_crash_synchronous();
 102.159 +    }
 102.160 +
 102.161 +    t = (struct hvm_info_table *)(p + HVM_INFO_OFFSET);
 102.162 +
 102.163 +    if ( validate_hvm_info(t) ) {
 102.164 +        d->arch.hvm_domain.nr_vcpus = t->nr_vcpus;
 102.165 +        d->arch.hvm_domain.apic_enabled = t->apic_enabled;
 102.166 +    } else {
 102.167 +        printk("Bad hvm info table\n");
 102.168 +        d->arch.hvm_domain.nr_vcpus = 1;
 102.169 +        d->arch.hvm_domain.apic_enabled = 0;
 102.170 +    }
 102.171 +
 102.172 +    unmap_domain_page(p);
 102.173 +}
 102.174 +
 102.175 +void hvm_setup_platform(struct domain* d)
 102.176 +{
 102.177 +    struct hvm_domain *platform;
 102.178 +
 102.179 +    if (!(HVM_DOMAIN(current) && (current->vcpu_id == 0)))
 102.180 +        return;
 102.181 +
 102.182 +    hvm_map_io_shared_page(d);
 102.183 +    hvm_get_info(d);
 102.184 +
 102.185 +    platform = &d->arch.hvm_domain;
 102.186 +    pic_init(&platform->vpic, pic_irq_request, &platform->interrupt_request);
 102.187 +    register_pic_io_hook();
 102.188 +
 102.189 +    if ( hvm_apic_support(d) ) {
 102.190 +        spin_lock_init(&d->arch.hvm_domain.round_robin_lock);
 102.191 +        hvm_vioapic_init(d);
 102.192 +    }
 102.193 +}
 102.194 +
 102.195 +void pic_irq_request(int *interrupt_request, int level)
 102.196 +{
 102.197 +    if (level)
 102.198 +        *interrupt_request = 1;
 102.199 +    else
 102.200 +        *interrupt_request = 0;
 102.201 +}
 102.202 +
 102.203 +void hvm_pic_assist(struct vcpu *v)
 102.204 +{
 102.205 +    global_iodata_t *spg;
 102.206 +    u16   *virq_line, irqs;
 102.207 +    struct hvm_virpic *pic = &v->domain->arch.hvm_domain.vpic;
 102.208 +    
 102.209 +    spg = &get_sp(v->domain)->sp_global;
 102.210 +    virq_line  = &spg->pic_clear_irr;
 102.211 +    if ( *virq_line ) {
 102.212 +        do {
 102.213 +            irqs = *(volatile u16*)virq_line;
 102.214 +        } while ( (u16)cmpxchg(virq_line,irqs, 0) != irqs );
 102.215 +        do_pic_irqs_clear(pic, irqs);
 102.216 +    }
 102.217 +    virq_line  = &spg->pic_irr;
 102.218 +    if ( *virq_line ) {
 102.219 +        do {
 102.220 +            irqs = *(volatile u16*)virq_line;
 102.221 +        } while ( (u16)cmpxchg(virq_line,irqs, 0) != irqs );
 102.222 +        do_pic_irqs(pic, irqs);
 102.223 +    }
 102.224 +}
 102.225 +
 102.226 +int cpu_get_interrupt(struct vcpu *v, int *type)
 102.227 +{
 102.228 +    int intno;
 102.229 +    struct hvm_virpic *s = &v->domain->arch.hvm_domain.vpic;
 102.230 +
 102.231 +    if ( (intno = cpu_get_apic_interrupt(v, type)) != -1 ) {
 102.232 +        /* set irq request if a PIC irq is still pending */
 102.233 +        /* XXX: improve that */
 102.234 +        pic_update_irq(s);
 102.235 +        return intno;
 102.236 +    }
 102.237 +    /* read the irq from the PIC */
 102.238 +    if ( (intno = cpu_get_pic_interrupt(v, type)) != -1 )
 102.239 +        return intno;
 102.240 +
 102.241 +    return -1;
 102.242 +}
 102.243 +
 102.244 +/*
 102.245 + * Copy from/to guest virtual.
 102.246 + */
 102.247 +int
 102.248 +hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
 102.249 +{
 102.250 +    unsigned long gpa, mfn;
 102.251 +    char *addr;
 102.252 +    int count;
 102.253 +
 102.254 +    while (size > 0) {
 102.255 +        count = PAGE_SIZE - (vaddr & ~PAGE_MASK);
 102.256 +        if (count > size)
 102.257 +            count = size;
 102.258 +
 102.259 +        if (hvm_paging_enabled(current)) {
 102.260 +            gpa = gva_to_gpa(vaddr);
 102.261 +            mfn = get_mfn_from_pfn(gpa >> PAGE_SHIFT);
 102.262 +        } else
 102.263 +            mfn = get_mfn_from_pfn(vaddr >> PAGE_SHIFT);
 102.264 +        if (mfn == INVALID_MFN)
 102.265 +            return 0;
 102.266 +
 102.267 +        addr = (char *)map_domain_page(mfn) + (vaddr & ~PAGE_MASK);
 102.268 +
 102.269 +        if (dir == HVM_COPY_IN)
 102.270 +            memcpy(buf, addr, count);
 102.271 +        else
 102.272 +            memcpy(addr, buf, count);
 102.273 +
 102.274 +        unmap_domain_page(addr);
 102.275 +
 102.276 +        vaddr += count;
 102.277 +        buf += count;
 102.278 +        size -= count;
 102.279 +    }
 102.280 +
 102.281 +    return 1;
 102.282 +}
 102.283 +
 102.284 +/*
 102.285 + * HVM specific printbuf. Mostly used for hvmloader chit-chat.
 102.286 + */
 102.287 +void hvm_print_line(struct vcpu *v, const char c)
 102.288 +{
 102.289 +    int *index = &v->domain->arch.hvm_domain.pbuf_index;
 102.290 +    char *pbuf = v->domain->arch.hvm_domain.pbuf;
 102.291 +
 102.292 +    if (*index == HVM_PBUF_SIZE-2 || c == '\n') {
 102.293 +        if (*index == HVM_PBUF_SIZE-2)
 102.294 +	    pbuf[(*index)++] = c;
 102.295 +        pbuf[*index] = '\0';
 102.296 +        printk("(GUEST: %u) %s\n", v->domain->domain_id, pbuf);
 102.297 +	*index = 0;
 102.298 +    } else
 102.299 +	pbuf[(*index)++] = c;
 102.300 +}
 102.301 +
 102.302 +/*
 102.303 + * Local variables:
 102.304 + * mode: C
 102.305 + * c-set-style: "BSD"
 102.306 + * c-basic-offset: 4
 102.307 + * tab-width: 4
 102.308 + * indent-tabs-mode: nil
 102.309 + * End:
 102.310 + */
 102.311 +
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/xen/arch/x86/hvm/i8259.c	Tue Jan 31 11:49:51 2006 +0100
   103.3 @@ -0,0 +1,548 @@
   103.4 +/*
   103.5 + * QEMU 8259 interrupt controller emulation
   103.6 + * 
   103.7 + * Copyright (c) 2003-2004 Fabrice Bellard
   103.8 + * Copyright (c) 2005 Intel Corperation
   103.9 + * 
  103.10 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  103.11 + * of this software and associated documentation files (the "Software"), to deal
  103.12 + * in the Software without restriction, including without limitation the rights
  103.13 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  103.14 + * copies of the Software, and to permit persons to whom the Software is
  103.15 + * furnished to do so, subject to the following conditions:
  103.16 + *
  103.17 + * The above copyright notice and this permission notice shall be included in
  103.18 + * all copies or substantial portions of the Software.
  103.19 + *
  103.20 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  103.21 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  103.22 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  103.23 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  103.24 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  103.25 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  103.26 + * THE SOFTWARE.
  103.27 + */
  103.28 +#include <xen/config.h>
  103.29 +#include <xen/types.h>
  103.30 +#include <xen/mm.h>
  103.31 +#include <xen/xmalloc.h>
  103.32 +#include <xen/lib.h>
  103.33 +#include <xen/errno.h>
  103.34 +#include <xen/sched.h>
  103.35 +#include <asm/hvm/hvm.h>
  103.36 +#include <asm/hvm/io.h>
  103.37 +#include <asm/hvm/support.h>
  103.38 +#include <asm/current.h>
  103.39 +
  103.40 +/* set irq level. If an edge is detected, then the IRR is set to 1 */
  103.41 +static inline void pic_set_irq1(PicState *s, int irq, int level)
  103.42 +{
  103.43 +    int mask;
  103.44 +    mask = 1 << irq;
  103.45 +    if (s->elcr & mask) {
  103.46 +        /* level triggered */
  103.47 +        if (level) {
  103.48 +            s->irr |= mask;
  103.49 +            s->last_irr |= mask;
  103.50 +        } else {
  103.51 +            s->irr &= ~mask;
  103.52 +            s->last_irr &= ~mask;
  103.53 +        }
  103.54 +    } else {
  103.55 +        /* edge triggered */
  103.56 +        if (level) {
  103.57 +            if ((s->last_irr & mask) == 0) {
  103.58 +                s->irr |= mask;
  103.59 +	    }
  103.60 +            s->last_irr |= mask;
  103.61 +        } else {
  103.62 +            s->last_irr &= ~mask;
  103.63 +        }
  103.64 +    }
  103.65 +}
  103.66 +
  103.67 +/* return the highest priority found in mask (highest = smallest
  103.68 +   number). Return 8 if no irq */
  103.69 +static inline int get_priority(PicState *s, int mask)
  103.70 +{
  103.71 +    int priority;
  103.72 +    if (mask == 0)
  103.73 +        return 8;
  103.74 +    priority = 0;
  103.75 +    while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
  103.76 +        priority++;
  103.77 +    return priority;
  103.78 +}
  103.79 +
  103.80 +/* return the pic wanted interrupt. return -1 if none */
  103.81 +static int pic_get_irq(PicState *s)
  103.82 +{
  103.83 +    int mask, cur_priority, priority;
  103.84 +
  103.85 +    mask = s->irr & ~s->imr;
  103.86 +    priority = get_priority(s, mask);
  103.87 +    if (priority == 8)
  103.88 +        return -1;
  103.89 +    /* compute current priority. If special fully nested mode on the
  103.90 +       master, the IRQ coming from the slave is not taken into account
  103.91 +       for the priority computation. */
  103.92 +    mask = s->isr;
  103.93 +    if (s->special_fully_nested_mode && s == &s->pics_state->pics[0])
  103.94 +        mask &= ~(1 << 2);
  103.95 +    cur_priority = get_priority(s, mask);
  103.96 +    if (priority < cur_priority) {
  103.97 +        /* higher priority found: an irq should be generated */
  103.98 +        return (priority + s->priority_add) & 7;
  103.99 +    } else {
 103.100 +        return -1;
 103.101 +    }
 103.102 +}
 103.103 +
 103.104 +/* raise irq to CPU if necessary. must be called every time the active
 103.105 +   irq may change */
 103.106 +/* XXX: should not export it, but it is needed for an APIC kludge */
 103.107 +void pic_update_irq(struct hvm_virpic *s)
 103.108 +{
 103.109 +    int irq2, irq;
 103.110 +
 103.111 +    /* first look at slave pic */
 103.112 +    irq2 = pic_get_irq(&s->pics[1]);
 103.113 +    if (irq2 >= 0) {
 103.114 +        /* if irq request by slave pic, signal master PIC */
 103.115 +        pic_set_irq1(&s->pics[0], 2, 1);
 103.116 +        pic_set_irq1(&s->pics[0], 2, 0);
 103.117 +    }
 103.118 +    /* look at requested irq */
 103.119 +    irq = pic_get_irq(&s->pics[0]);
 103.120 +    if (irq >= 0) {
 103.121 +        s->irq_request(s->irq_request_opaque, 1);
 103.122 +    }
 103.123 +}
 103.124 +
 103.125 +void pic_set_irq_new(void *opaque, int irq, int level)
 103.126 +{
 103.127 +    struct hvm_virpic *s = opaque;
 103.128 +
 103.129 +    hvm_vioapic_set_irq(current->domain, irq, level);
 103.130 +    pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
 103.131 +    /* used for IOAPIC irqs */
 103.132 +    if (s->alt_irq_func)
 103.133 +        s->alt_irq_func(s->alt_irq_opaque, irq, level);
 103.134 +    pic_update_irq(s);
 103.135 +}
 103.136 +
 103.137 +void do_pic_irqs (struct hvm_virpic *s, uint16_t irqs)
 103.138 +{
 103.139 +    s->pics[1].irr |= (uint8_t)(irqs >> 8);
 103.140 +    s->pics[0].irr |= (uint8_t) irqs;
 103.141 +    hvm_vioapic_do_irqs(current->domain, irqs);
 103.142 +    pic_update_irq(s);
 103.143 +}
 103.144 +
 103.145 +void do_pic_irqs_clear (struct hvm_virpic *s, uint16_t irqs)
 103.146 +{
 103.147 +    s->pics[1].irr &= ~(uint8_t)(irqs >> 8);
 103.148 +    s->pics[0].irr &= ~(uint8_t) irqs;
 103.149 +    hvm_vioapic_do_irqs_clear(current->domain, irqs);
 103.150 +    pic_update_irq(s);
 103.151 +}
 103.152 +
 103.153 +/* obsolete function */
 103.154 +void pic_set_irq(struct hvm_virpic *isa_pic, int irq, int level)
 103.155 +{
 103.156 +    pic_set_irq_new(isa_pic, irq, level);
 103.157 +}
 103.158 +
 103.159 +/* acknowledge interrupt 'irq' */
 103.160 +static inline void pic_intack(PicState *s, int irq)
 103.161 +{
 103.162 +    if (s->auto_eoi) {
 103.163 +        if (s->rotate_on_auto_eoi)
 103.164 +            s->priority_add = (irq + 1) & 7;
 103.165 +    } else {
 103.166 +        s->isr |= (1 << irq);
 103.167 +    }
 103.168 +    /* We don't clear a level sensitive interrupt here */
 103.169 +    if (!(s->elcr & (1 << irq)))
 103.170 +        s->irr &= ~(1 << irq);
 103.171 +}
 103.172 +
 103.173 +int pic_read_irq(struct hvm_virpic *s)
 103.174 +{
 103.175 +    int irq, irq2, intno;
 103.176 +
 103.177 +    irq = pic_get_irq(&s->pics[0]);
 103.178 +    if (irq >= 0) {
 103.179 +        pic_intack(&s->pics[0], irq);
 103.180 +        if (irq == 2) {
 103.181 +            irq2 = pic_get_irq(&s->pics[1]);
 103.182 +            if (irq2 >= 0) {
 103.183 +                pic_intack(&s->pics[1], irq2);
 103.184 +            } else {
 103.185 +                /* spurious IRQ on slave controller */
 103.186 +                irq2 = 7;
 103.187 +            }
 103.188 +            intno = s->pics[1].irq_base + irq2;
 103.189 +            irq = irq2 + 8;
 103.190 +        } else {
 103.191 +            intno = s->pics[0].irq_base + irq;
 103.192 +        }
 103.193 +    } else {
 103.194 +        /* spurious IRQ on host controller */
 103.195 +        printk("spurious IRQ irq got=%d\n",irq);
 103.196 +        irq = 7;
 103.197 +        intno = s->pics[0].irq_base + irq;
 103.198 +    }
 103.199 +    pic_update_irq(s);
 103.200 +        
 103.201 +    return intno;
 103.202 +}
 103.203 +
 103.204 +static void update_shared_irr(struct hvm_virpic *s, PicState *c)
 103.205 +{
 103.206 +    uint8_t *pl, *pe;
 103.207 +
 103.208 +    get_sp(current->domain)->sp_global.pic_elcr = 
 103.209 +		s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
 103.210 +    pl =(uint8_t*)&get_sp(current->domain)->sp_global.pic_last_irr;
 103.211 +    pe =(uint8_t*)&get_sp(current->domain)->sp_global.pic_elcr;
 103.212 +    if ( c == &s->pics[0] ) {
 103.213 +         *pl = c->last_irr;
 103.214 +         *pe = c->elcr;
 103.215 +    }
 103.216 +    else {
 103.217 +         *(pl+1) = c->last_irr;
 103.218 +         *(pe+1) = c->elcr;
 103.219 +    }
 103.220 +}
 103.221 +
 103.222 +static void pic_reset(void *opaque)
 103.223 +{
 103.224 +    PicState *s = opaque;
 103.225 +
 103.226 +    s->last_irr = 0;
 103.227 +    s->irr = 0;
 103.228 +    s->imr = 0;
 103.229 +    s->isr = 0;
 103.230 +    s->priority_add = 0;
 103.231 +    s->irq_base = 0;
 103.232 +    s->read_reg_select = 0;
 103.233 +    s->poll = 0;
 103.234 +    s->special_mask = 0;
 103.235 +    s->init_state = 0;
 103.236 +    s->auto_eoi = 0;
 103.237 +    s->rotate_on_auto_eoi = 0;
 103.238 +    s->special_fully_nested_mode = 0;
 103.239 +    s->init4 = 0;
 103.240 +    s->elcr = 0;
 103.241 +}
 103.242 +
 103.243 +static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 103.244 +{
 103.245 +    PicState *s = opaque;
 103.246 +    int priority, cmd, irq;
 103.247 +
 103.248 +    addr &= 1;
 103.249 +    if (addr == 0) {
 103.250 +        if (val & 0x10) {
 103.251 +            /* init */
 103.252 +            pic_reset(s);
 103.253 +            update_shared_irr(s->pics_state, s);
 103.254 +            /* deassert a pending interrupt */
 103.255 +            s->pics_state->irq_request(s->pics_state->irq_request_opaque, 0);
 103.256 +            s->init_state = 1;
 103.257 +            s->init4 = val & 1;
 103.258 +            if (val & 0x02)
 103.259 +                hw_error("single mode not supported");
 103.260 +            if (val & 0x08)
 103.261 +                hw_error("level sensitive irq not supported");
 103.262 +        } else if (val & 0x08) {
 103.263 +            if (val & 0x04)
 103.264 +                s->poll = 1;
 103.265 +            if (val & 0x02)
 103.266 +                s->read_reg_select = val & 1;
 103.267 +            if (val & 0x40)
 103.268 +                s->special_mask = (val >> 5) & 1;
 103.269 +        } else {
 103.270 +            cmd = val >> 5;
 103.271 +            switch(cmd) {
 103.272 +            case 0:
 103.273 +            case 4:
 103.274 +                s->rotate_on_auto_eoi = cmd >> 2;
 103.275 +                break;
 103.276 +            case 1: /* end of interrupt */
 103.277 +            case 5:
 103.278 +                priority = get_priority(s, s->isr);
 103.279 +                if (priority != 8) {
 103.280 +                    irq = (priority + s->priority_add) & 7;
 103.281 +                    s->isr &= ~(1 << irq);
 103.282 +                    if (cmd == 5)
 103.283 +                        s->priority_add = (irq + 1) & 7;
 103.284 +                    pic_update_irq(s->pics_state);
 103.285 +                }
 103.286 +                break;
 103.287 +            case 3:
 103.288 +                irq = val & 7;
 103.289 +                s->isr &= ~(1 << irq);
 103.290 +                pic_update_irq(s->pics_state);
 103.291 +                break;
 103.292 +            case 6:
 103.293 +                s->priority_add = (val + 1) & 7;
 103.294 +                pic_update_irq(s->pics_state);
 103.295 +                break;
 103.296 +            case 7:
 103.297 +                irq = val & 7;
 103.298 +                s->isr &= ~(1 << irq);
 103.299 +                s->priority_add = (irq + 1) & 7;
 103.300 +                pic_update_irq(s->pics_state);
 103.301 +                break;
 103.302 +            default:
 103.303 +                /* no operation */
 103.304 +                break;
 103.305 +            }
 103.306 +        }
 103.307 +    } else {
 103.308 +        switch(s->init_state) {
 103.309 +        case 0:
 103.310 +            /* normal mode */
 103.311 +            s->imr = val;
 103.312 +            pic_update_irq(s->pics_state);
 103.313 +            break;
 103.314 +        case 1:
 103.315 +            s->irq_base = val & 0xf8;
 103.316 +            s->init_state = 2;
 103.317 +            break;
 103.318 +        case 2:
 103.319 +            if (s->init4) {
 103.320 +                s->init_state = 3;
 103.321 +            } else {
 103.322 +                s->init_state = 0;
 103.323 +            }
 103.324 +            break;
 103.325 +        case 3:
 103.326 +            s->special_fully_nested_mode = (val >> 4) & 1;
 103.327 +            s->auto_eoi = (val >> 1) & 1;
 103.328 +            s->init_state = 0;
 103.329 +            break;
 103.330 +        }
 103.331 +    }
 103.332 +}
 103.333 +
 103.334 +static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
 103.335 +{
 103.336 +    int ret;
 103.337 +
 103.338 +    ret = pic_get_irq(s);
 103.339 +    if (ret >= 0) {
 103.340 +        if (addr1 >> 7) {
 103.341 +            s->pics_state->pics[0].isr &= ~(1 << 2);
 103.342 +            s->pics_state->pics[0].irr &= ~(1 << 2);
 103.343 +        }
 103.344 +        s->irr &= ~(1 << ret);
 103.345 +        s->isr &= ~(1 << ret);
 103.346 +        if (addr1 >> 7 || ret != 2)
 103.347 +            pic_update_irq(s->pics_state);
 103.348 +    } else {
 103.349 +        ret = 0x07;
 103.350 +        pic_update_irq(s->pics_state);
 103.351 +    }
 103.352 +
 103.353 +    return ret;
 103.354 +}
 103.355 +
 103.356 +static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
 103.357 +{
 103.358 +    PicState *s = opaque;
 103.359 +    unsigned int addr;
 103.360 +    int ret;
 103.361 +
 103.362 +    addr = addr1;
 103.363 +    addr &= 1;
 103.364 +    if (s->poll) {
 103.365 +        ret = pic_poll_read(s, addr1);
 103.366 +        s->poll = 0;
 103.367 +    } else {
 103.368 +        if (addr == 0) {
 103.369 +            if (s->read_reg_select)
 103.370 +                ret = s->isr;
 103.371 +            else
 103.372 +                ret = s->irr;
 103.373 +        } else {
 103.374 +            ret = s->imr;
 103.375 +        }
 103.376 +    }
 103.377 +    return ret;
 103.378 +}
 103.379 +
 103.380 +/* memory mapped interrupt status */
 103.381 +/* XXX: may be the same than pic_read_irq() */
 103.382 +uint32_t pic_intack_read(struct hvm_virpic *s)
 103.383 +{
 103.384 +    int ret;
 103.385 +
 103.386 +    ret = pic_poll_read(&s->pics[0], 0x00);
 103.387 +    if (ret == 2)
 103.388 +        ret = pic_poll_read(&s->pics[1], 0x80) + 8;
 103.389 +    /* Prepare for ISR read */
 103.390 +    s->pics[0].read_reg_select = 1;
 103.391 +    
 103.392 +    return ret;
 103.393 +}
 103.394 +
 103.395 +static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 103.396 +{
 103.397 +    PicState *s = opaque;
 103.398 +    s->elcr = val & s->elcr_mask;
 103.399 +}
 103.400 +
 103.401 +static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1)
 103.402 +{
 103.403 +    PicState *s = opaque;
 103.404 +    return s->elcr;
 103.405 +}
 103.406 +
 103.407 +/* XXX: add generic master/slave system */
 103.408 +static void pic_init1(int io_addr, int elcr_addr, PicState *s)
 103.409 +{
 103.410 +    pic_reset(s);
 103.411 +}
 103.412 +
 103.413 +void pic_init(struct hvm_virpic *s, void (*irq_request)(), 
 103.414 +              void *irq_request_opaque)
 103.415 +{
 103.416 +    memset(s, 0, sizeof(*s));
 103.417 +    pic_init1(0x20, 0x4d0, &s->pics[0]);
 103.418 +    pic_init1(0xa0, 0x4d1, &s->pics[1]);
 103.419 +    s->pics[0].elcr_mask = 0xf8;
 103.420 +    s->pics[1].elcr_mask = 0xde;
 103.421 +    s->irq_request = irq_request;
 103.422 +    s->irq_request_opaque = irq_request_opaque;
 103.423 +    s->pics[0].pics_state = s;
 103.424 +    s->pics[1].pics_state = s;
 103.425 +    return; 
 103.426 +}
 103.427 +
 103.428 +void pic_set_alt_irq_func(struct hvm_virpic *s, void (*alt_irq_func)(),
 103.429 +                          void *alt_irq_opaque)
 103.430 +{
 103.431 +    s->alt_irq_func = alt_irq_func;
 103.432 +    s->alt_irq_opaque = alt_irq_opaque;
 103.433 +}
 103.434 +
 103.435 +static int intercept_pic_io(ioreq_t *p)
 103.436 +{
 103.437 +    struct hvm_virpic  *pic;
 103.438 +    struct vcpu *v = current;
 103.439 +    uint32_t data;
 103.440 +    
 103.441 +    if ( p->size != 1 || p->count != 1) {
 103.442 +        printk("PIC_IO wrong access size %d!\n", (int)p->size);
 103.443 +        return 1;
 103.444 +    }
 103.445 +    pic = &v->domain->arch.hvm_domain.vpic;
 103.446 +    if ( p->dir == 0 ) {
 103.447 +        if(p->pdata_valid) 
 103.448 +            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
 103.449 +        else
 103.450 +            data = p->u.data;
 103.451 +        pic_ioport_write((void*)&pic->pics[p->addr>>7],
 103.452 +                (uint32_t) p->addr, (uint32_t) (data & 0xff));
 103.453 +    }
 103.454 +    else {
 103.455 +        data = pic_ioport_read(
 103.456 +            (void*)&pic->pics[p->addr>>7], (uint32_t) p->addr);
 103.457 +        if(p->pdata_valid) 
 103.458 +            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
 103.459 +        else 
 103.460 +            p->u.data = (u64)data;
 103.461 +    }
 103.462 +    return 1;
 103.463 +}
 103.464 +
 103.465 +static int intercept_elcr_io(ioreq_t *p)
 103.466 +{
 103.467 +    struct hvm_virpic  *s;
 103.468 +    struct vcpu *v = current;
 103.469 +    uint32_t data;
 103.470 +    
 103.471 +    if ( p->size != 1 || p->count != 1 ) {
 103.472 +        printk("PIC_IO wrong access size %d!\n", (int)p->size);
 103.473 +        return 1;
 103.474 +    }
 103.475 +
 103.476 +    s = &v->domain->arch.hvm_domain.vpic;
 103.477 +    if ( p->dir == 0 ) {
 103.478 +        if(p->pdata_valid) 
 103.479 +            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
 103.480 +        else
 103.481 +            data = p->u.data;
 103.482 +        elcr_ioport_write((void*)&s->pics[p->addr&1],
 103.483 +                (uint32_t) p->addr, (uint32_t)( data & 0xff));
 103.484 +    	get_sp(current->domain)->sp_global.pic_elcr = 
 103.485 +            s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
 103.486 +    }
 103.487 +    else {
 103.488 +        data = (u64) elcr_ioport_read(
 103.489 +                (void*)&s->pics[p->addr&1], (uint32_t) p->addr);
 103.490 +        if(p->pdata_valid) 
 103.491 +            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
 103.492 +        else 
 103.493 +            p->u.data = (u64)data;
 103.494 +
 103.495 +    }
 103.496 +    return 1;
 103.497 +}
 103.498 +void register_pic_io_hook (void)
 103.499 +{
 103.500 +    register_portio_handler(0x20, 2, intercept_pic_io); 
 103.501 +    register_portio_handler(0x4d0, 1, intercept_elcr_io); 
 103.502 +    register_portio_handler(0xa0, 2, intercept_pic_io); 
 103.503 +    register_portio_handler(0x4d1, 1, intercept_elcr_io); 
 103.504 +}
 103.505 +
 103.506 +
 103.507 +/* IRQ handling */
 103.508 +int cpu_get_pic_interrupt(struct vcpu *v, int *type)
 103.509 +{
 103.510 +    int intno;
 103.511 +    struct hvm_virpic *s = &v->domain->arch.hvm_domain.vpic;
 103.512 +    struct hvm_domain *plat = &v->domain->arch.hvm_domain;
 103.513 +
 103.514 +    if ( !vlapic_accept_pic_intr(v) )
 103.515 +        return -1;
 103.516 +
 103.517 +    if ( !plat->interrupt_request )
 103.518 +        return -1;
 103.519 +
 103.520 +    plat->interrupt_request = 0;
 103.521 +    /* read the irq from the PIC */
 103.522 +    intno = pic_read_irq(s);
 103.523 +    *type = VLAPIC_DELIV_MODE_EXT;
 103.524 +    return intno;
 103.525 +}
 103.526 +
 103.527 +int is_pit_irq(struct vcpu *v, int irq, int type)
 103.528 +{
 103.529 +    int pit_vec;
 103.530 +
 103.531 +    if (type == VLAPIC_DELIV_MODE_EXT)
 103.532 +        pit_vec = v->domain->arch.hvm_domain.vpic.pics[0].irq_base;
 103.533 +    else
 103.534 +        pit_vec =
 103.535 +          v->domain->arch.hvm_domain.vioapic.redirtbl[0].RedirForm.vector;
 103.536 +
 103.537 +    return (irq == pit_vec);
 103.538 +}
 103.539 +
 103.540 +int is_irq_enabled(struct vcpu *v, int irq)
 103.541 +{
 103.542 +    struct hvm_virpic *vpic=&v->domain->arch.hvm_domain.vpic;
 103.543 +        
 103.544 +    if ( irq & 8 ) {
 103.545 +        return !( (1 << (irq&7)) & vpic->pics[1].imr);
 103.546 +    }
 103.547 +    else {
 103.548 +        return !( (1 << irq) & vpic->pics[0].imr);
 103.549 +    }
 103.550 +}
 103.551 +
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/xen/arch/x86/hvm/intercept.c	Tue Jan 31 11:49:51 2006 +0100
   104.3 @@ -0,0 +1,457 @@
   104.4 +/*
   104.5 + * intercept.c: Handle performance critical I/O packets in hypervisor space
   104.6 + *
   104.7 + * Copyright (c) 2004, Intel Corporation.
   104.8 + *
   104.9 + * This program is free software; you can redistribute it and/or modify it
  104.10 + * under the terms and conditions of the GNU General Public License,
  104.11 + * version 2, as published by the Free Software Foundation.
  104.12 + *
  104.13 + * This program is distributed in the hope it will be useful, but WITHOUT
  104.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  104.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  104.16 + * more details.
  104.17 + *
  104.18 + * You should have received a copy of the GNU General Public License along with
  104.19 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  104.20 + * Place - Suite 330, Boston, MA 02111-1307 USA.
  104.21 + */
  104.22 +
  104.23 +#include <xen/config.h>
  104.24 +#include <xen/types.h>
  104.25 +#include <xen/sched.h>
  104.26 +#include <asm/regs.h>
  104.27 +#include <asm/hvm/hvm.h>
  104.28 +#include <asm/hvm/support.h>
  104.29 +#include <asm/hvm/domain.h>
  104.30 +#include <xen/lib.h>
  104.31 +#include <xen/sched.h>
  104.32 +#include <asm/current.h>
  104.33 +#include <io_ports.h>
  104.34 +#include <xen/event.h>
  104.35 +
  104.36 +
  104.37 +extern struct hvm_mmio_handler vlapic_mmio_handler;
  104.38 +extern struct hvm_mmio_handler vioapic_mmio_handler;
  104.39 +
  104.40 +#define HVM_MMIO_HANDLER_NR 2
  104.41 +
  104.42 +struct hvm_mmio_handler *hvm_mmio_handlers[HVM_MMIO_HANDLER_NR] =
  104.43 +{
  104.44 +    &vlapic_mmio_handler,
  104.45 +    &vioapic_mmio_handler
  104.46 +};
  104.47 +
  104.48 +static inline void hvm_mmio_access(struct vcpu *v,
  104.49 +                                   ioreq_t *p,
  104.50 +                                   hvm_mmio_read_t read_handler,
  104.51 +                                   hvm_mmio_write_t write_handler)
  104.52 +{
  104.53 +    ioreq_t *req;
  104.54 +    vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id);
  104.55 +    unsigned int tmp1, tmp2;
  104.56 +    unsigned long data;
  104.57 +
  104.58 +    if (vio == NULL) {
  104.59 +        printk("vlapic_access: bad shared page\n");
  104.60 +        domain_crash_synchronous();
  104.61 +    }
  104.62 +
  104.63 +    req = &vio->vp_ioreq;
  104.64 +
  104.65 +    switch (req->type) {
  104.66 +    case IOREQ_TYPE_COPY:
  104.67 +    {
  104.68 +        int sign = (req->df) ? -1 : 1, i;
  104.69 +
  104.70 +        if (!req->pdata_valid) {
  104.71 +            if (req->dir == IOREQ_READ){
  104.72 +                req->u.data = read_handler(v, req->addr, req->size);
  104.73 +            } else {                 /* req->dir != IOREQ_READ */
  104.74 +                write_handler(v, req->addr, req->size, req->u.data);
  104.75 +            }
  104.76 +        } else {                     /* !req->pdata_valid */
  104.77 +            if (req->dir == IOREQ_READ) {
  104.78 +                for (i = 0; i < req->count; i++) {
  104.79 +                    data = read_handler(v,
  104.80 +                      req->addr + (sign * i * req->size),
  104.81 +                      req->size);
  104.82 +                    hvm_copy(&data,
  104.83 +                      (unsigned long)p->u.pdata + (sign * i * req->size),
  104.84 +                      p->size,
  104.85 +                      HVM_COPY_OUT);
  104.86 +                }
  104.87 +            } else {                  /* !req->dir == IOREQ_READ */
  104.88 +                for (i = 0; i < req->count; i++) {
  104.89 +                    hvm_copy(&data,
  104.90 +                      (unsigned long)p->u.pdata + (sign * i * req->size),
  104.91 +                      p->size,
  104.92 +                      HVM_COPY_IN);
  104.93 +                    write_handler(v,
  104.94 +                      req->addr + (sign * i * req->size),
  104.95 +                      req->size, data);
  104.96 +                }
  104.97 +            }
  104.98 +        }
  104.99 +        break;
 104.100 +    }
 104.101 +
 104.102 +    case IOREQ_TYPE_AND:
 104.103 +        tmp1 = read_handler(v, req->addr, req->size);
 104.104 +        if (req->dir == IOREQ_WRITE) {
 104.105 +            tmp2 = tmp1 & (unsigned long) req->u.data;
 104.106 +            write_handler(v, req->addr, req->size, tmp2);
 104.107 +        }
 104.108 +        req->u.data = tmp1;
 104.109 +        break;
 104.110 +
 104.111 +    case IOREQ_TYPE_OR:
 104.112 +        tmp1 = read_handler(v, req->addr, req->size);
 104.113 +        if (req->dir == IOREQ_WRITE) {
 104.114 +            tmp2 = tmp1 | (unsigned long) req->u.data;
 104.115 +            write_handler(v, req->addr, req->size, tmp2);
 104.116 +        }
 104.117 +        req->u.data = tmp1;
 104.118 +        break;
 104.119 +
 104.120 +    case IOREQ_TYPE_XOR:
 104.121 +        tmp1 = read_handler(v, req->addr, req->size);
 104.122 +        if (req->dir == IOREQ_WRITE) {
 104.123 +            tmp2 = tmp1 ^ (unsigned long) req->u.data;
 104.124 +            write_handler(v, req->addr, req->size, tmp2);
 104.125 +        }
 104.126 +        req->u.data = tmp1;
 104.127 +        break;
 104.128 +
 104.129 +    default:
 104.130 +        printk("error ioreq type for local APIC %x\n", req->type);
 104.131 +        domain_crash_synchronous();
 104.132 +        break;
 104.133 +    }
 104.134 +}
 104.135 +
 104.136 +int hvm_mmio_intercept(ioreq_t *p)
 104.137 +{
 104.138 +    struct vcpu *v = current;
 104.139 +    int i;
 104.140 +
 104.141 +    /* XXX currently only APIC use intercept */
 104.142 +    if ( !hvm_apic_support(v->domain) )
 104.143 +        return 0;
 104.144 +
 104.145 +    for ( i = 0; i < HVM_MMIO_HANDLER_NR; i++ ) {
 104.146 +        if ( hvm_mmio_handlers[i]->check_handler(v, p->addr) ) {
 104.147 +            hvm_mmio_access(v, p,
 104.148 +                            hvm_mmio_handlers[i]->read_handler,
 104.149 +	                    hvm_mmio_handlers[i]->write_handler);
 104.150 +            return 1;
 104.151 +        }
 104.152 +    }
 104.153 +    return 0;
 104.154 +}
 104.155 +
 104.156 +/*
 104.157 + * Check if the request is handled inside xen
 104.158 + * return value: 0 --not handled; 1 --handled
 104.159 + */
 104.160 +int hvm_io_intercept(ioreq_t *p, int type)
 104.161 +{
 104.162 +    struct vcpu *v = current;
 104.163 +    struct hvm_io_handler *handler =
 104.164 +                           &(v->domain->arch.hvm_domain.io_handler);
 104.165 +    int i;
 104.166 +    unsigned long addr, size;
 104.167 +
 104.168 +    for (i = 0; i < handler->num_slot; i++) {
 104.169 +        if( type != handler->hdl_list[i].type)
 104.170 +            continue;
 104.171 +        addr = handler->hdl_list[i].addr;
 104.172 +        size = handler->hdl_list[i].size;
 104.173 +        if (p->addr >= addr &&
 104.174 +            p->addr <  addr + size)
 104.175 +            return handler->hdl_list[i].action(p);
 104.176 +    }
 104.177 +    return 0;
 104.178 +}
 104.179 +
 104.180 +int register_io_handler(unsigned long addr, unsigned long size,
 104.181 +                        intercept_action_t action, int type)
 104.182 +{
 104.183 +    struct vcpu *v = current;
 104.184 +    struct hvm_io_handler *handler =
 104.185 +                             &(v->domain->arch.hvm_domain.io_handler);
 104.186 +    int num = handler->num_slot;
 104.187 +
 104.188 +    if (num >= MAX_IO_HANDLER) {
 104.189 +        printk("no extra space, register io interceptor failed!\n");
 104.190 +        domain_crash_synchronous();
 104.191 +    }
 104.192 +
 104.193 +    handler->hdl_list[num].addr = addr;
 104.194 +    handler->hdl_list[num].size = size;
 104.195 +    handler->hdl_list[num].action = action;
 104.196 +    handler->hdl_list[num].type = type;
 104.197 +    handler->num_slot++;
 104.198 +
 104.199 +    return 1;
 104.200 +}
 104.201 +
 104.202 +static void pit_cal_count(struct hvm_virpit *vpit)
 104.203 +{
 104.204 +    u64 nsec_delta = (unsigned int)((NOW() - vpit->inject_point));
 104.205 +
 104.206 +    if (nsec_delta > vpit->period)
 104.207 +        HVM_DBG_LOG(DBG_LEVEL_1,
 104.208 +	            "HVM_PIT: long time has passed from last injection!");
 104.209 +
 104.210 +    if(vpit->init_val == 0)
 104.211 +    {
 104.212 +        printk("PIT init value == 0!\n");
 104.213 +        domain_crash_synchronous();
 104.214 +    }
 104.215 +
 104.216 +    vpit->count = vpit->init_val
 104.217 +                  - ((nsec_delta * PIT_FREQ / 1000000000ULL) % vpit->init_val);
 104.218 +}
 104.219 +
 104.220 +static void pit_latch_io(struct hvm_virpit *vpit)
 104.221 +{
 104.222 +    pit_cal_count(vpit);
 104.223 +
 104.224 +    switch(vpit->read_state) {
 104.225 +    case MSByte:
 104.226 +        vpit->count_MSB_latched=1;
 104.227 +        break;
 104.228 +    case LSByte:
 104.229 +        vpit->count_LSB_latched=1;
 104.230 +        break;
 104.231 +    case LSByte_multiple:
 104.232 +        vpit->count_LSB_latched=1;
 104.233 +        vpit->count_MSB_latched=1;
 104.234 +        break;
 104.235 +    case MSByte_multiple:
 104.236 +        HVM_DBG_LOG(DBG_LEVEL_1,
 104.237 +	            "HVM_PIT: latch PIT counter before MSB_multiple!");
 104.238 +        vpit->read_state=LSByte_multiple;
 104.239 +        vpit->count_LSB_latched=1;
 104.240 +        vpit->count_MSB_latched=1;
 104.241 +        break;
 104.242 +    default:
 104.243 +        domain_crash_synchronous();
 104.244 +    }
 104.245 +}
 104.246 +
 104.247 +static int pit_read_io(struct hvm_virpit *vpit)
 104.248 +{
 104.249 +    if(vpit->count_LSB_latched) {
 104.250 +        /* Read Least Significant Byte */
 104.251 +        if(vpit->read_state==LSByte_multiple) {
 104.252 +            vpit->read_state=MSByte_multiple;
 104.253 +        }
 104.254 +        vpit->count_LSB_latched=0;
 104.255 +        return (vpit->count & 0xFF);
 104.256 +    } else if(vpit->count_MSB_latched) {
 104.257 +        /* Read Most Significant Byte */
 104.258 +        if(vpit->read_state==MSByte_multiple) {
 104.259 +            vpit->read_state=LSByte_multiple;
 104.260 +        }
 104.261 +        vpit->count_MSB_latched=0;
 104.262 +        return ((vpit->count>>8) & 0xFF);
 104.263 +    } else {
 104.264 +        /* Unlatched Count Read */
 104.265 +        HVM_DBG_LOG(DBG_LEVEL_1, "HVM_PIT: unlatched read");
 104.266 +        pit_cal_count(vpit);
 104.267 +        if(!(vpit->read_state & 0x1)) {
 104.268 +            /* Read Least Significant Byte */
 104.269 +            if(vpit->read_state==LSByte_multiple) {
 104.270 +                vpit->read_state=MSByte_multiple;
 104.271 +            }
 104.272 +            return (vpit->count & 0xFF);
 104.273 +        } else {
 104.274 +            /* Read Most Significant Byte */
 104.275 +            if(vpit->read_state==MSByte_multiple) {
 104.276 +                vpit->read_state=LSByte_multiple;
 104.277 +            }
 104.278 +            return ((vpit->count>>8) & 0xFF);
 104.279 +        }
 104.280 +    }
 104.281 +}
 104.282 +
 104.283 +/* hvm_io_assist light-weight version, specific to PIT DM */ 
 104.284 +static void resume_pit_io(ioreq_t *p)
 104.285 +{
 104.286 +    struct cpu_user_regs *regs = guest_cpu_user_regs();
 104.287 +    unsigned long old_eax = regs->eax;
 104.288 +    p->state = STATE_INVALID;
 104.289 +
 104.290 +    switch(p->size) {
 104.291 +    case 1:
 104.292 +        regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
 104.293 +        break;
 104.294 +    case 2:
 104.295 +        regs->eax = (old_eax & 0xffff0000) | (p->u.data & 0xffff);
 104.296 +        break;
 104.297 +    case 4:
 104.298 +        regs->eax = (p->u.data & 0xffffffff);
 104.299 +        break;
 104.300 +    default:
 104.301 +        BUG();
 104.302 +    }
 104.303 +}
 104.304 +
 104.305 +/* the intercept action for PIT DM retval:0--not handled; 1--handled */
 104.306 +int intercept_pit_io(ioreq_t *p)
 104.307 +{
 104.308 +    struct vcpu *v = current;
 104.309 +    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
 104.310 +
 104.311 +    if (p->size != 1 ||
 104.312 +        p->pdata_valid ||
 104.313 +        p->type != IOREQ_TYPE_PIO)
 104.314 +        return 0;
 104.315 +    
 104.316 +    if (p->addr == PIT_MODE &&
 104.317 +        p->dir == 0 &&    /* write */
 104.318 +        ((p->u.data >> 4) & 0x3) == 0 && /* latch command */
 104.319 +        ((p->u.data >> 6) & 0x3) == (vpit->channel)) {/* right channel */
 104.320 +        pit_latch_io(vpit);
 104.321 +        return 1;
 104.322 +    }
 104.323 +
 104.324 +    if (p->addr == (PIT_CH0 + vpit->channel) &&
 104.325 +        p->dir == 1) { /* read */
 104.326 +        p->u.data = pit_read_io(vpit);
 104.327 +        resume_pit_io(p);
 104.328 +        return 1;
 104.329 +    }
 104.330 +
 104.331 +    return 0;
 104.332 +}
 104.333 +
 104.334 +/* hooks function for the HLT instruction emulation wakeup */
 104.335 +void hlt_timer_fn(void *data)
 104.336 +{
 104.337 +    struct vcpu *v = data;
 104.338 +    
 104.339 +    evtchn_set_pending(v, iopacket_port(v->domain));
 104.340 +}
 104.341 +
 104.342 +static __inline__ void missed_ticks(struct hvm_virpit*vpit)
 104.343 +{
 104.344 +    int        missed_ticks;
 104.345 +
 104.346 +    missed_ticks = (NOW() - vpit->scheduled)/(s_time_t) vpit->period;
 104.347 +    if ( missed_ticks > 0 ) {
 104.348 +        vpit->pending_intr_nr += missed_ticks;
 104.349 +        vpit->scheduled += missed_ticks * vpit->period;
 104.350 +    }
 104.351 +}
 104.352 +
 104.353 +/* hooks function for the PIT when the guest is active */
 104.354 +static void pit_timer_fn(void *data)
 104.355 +{
 104.356 +    struct vcpu *v = data;
 104.357 +    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
 104.358 +
 104.359 +    /* pick up missed timer tick */
 104.360 +    missed_ticks(vpit);
 104.361 +
 104.362 +    vpit->pending_intr_nr++;
 104.363 +    if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
 104.364 +        vpit->scheduled += vpit->period;
 104.365 +        set_timer(&vpit->pit_timer, vpit->scheduled);
 104.366 +    }
 104.367 +}
 104.368 +
 104.369 +void pickup_deactive_ticks(struct hvm_virpit *vpit)
 104.370 +{
 104.371 +
 104.372 +    if ( !active_timer(&(vpit->pit_timer)) ) {
 104.373 +        /* pick up missed timer tick */
 104.374 +        missed_ticks(vpit);
 104.375 +    
 104.376 +        vpit->scheduled += vpit->period;
 104.377 +        set_timer(&vpit->pit_timer, vpit->scheduled);
 104.378 +    }
 104.379 +}
 104.380 +
 104.381 +/* Only some PIT operations such as load init counter need a hypervisor hook.
 104.382 + * leave all other operations in user space DM
 104.383 + */
 104.384 +void hvm_hooks_assist(struct vcpu *v)
 104.385 +{
 104.386 +    vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id);
 104.387 +    ioreq_t *p = &vio->vp_ioreq;
 104.388 +    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
 104.389 +    int rw_mode, reinit = 0;
 104.390 +
 104.391 +    /* load init count*/
 104.392 +    if (p->state == STATE_IORESP_HOOK) {
 104.393 +        /* set up actimer, handle re-init */
 104.394 +        if ( active_timer(&(vpit->pit_timer)) ) {
 104.395 +            HVM_DBG_LOG(DBG_LEVEL_1, "HVM_PIT: guest reset PIT with channel %lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) );
 104.396 +            stop_timer(&(vpit->pit_timer));
 104.397 +            reinit = 1;
 104.398 + 
 104.399 +        }
 104.400 +        else {
 104.401 +            init_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
 104.402 +        }
 104.403 +
 104.404 +        /* init count for this channel */
 104.405 +        vpit->init_val = (p->u.data & 0xFFFF) ;
 104.406 +        /* frequency(ns) of pit */
 104.407 +        vpit->period = DIV_ROUND(((vpit->init_val) * 1000000000ULL), PIT_FREQ);
 104.408 +        HVM_DBG_LOG(DBG_LEVEL_1,"HVM_PIT: guest set init pit freq:%u ns, initval:0x%x\n", vpit->period, vpit->init_val);
 104.409 +        if (vpit->period < 900000) { /* < 0.9 ms */
 104.410 +            printk("HVM_PIT: guest programmed too small an init_val: %x\n",
 104.411 +                   vpit->init_val);
 104.412 +            vpit->period = 1000000;
 104.413 +        }
 104.414 +         vpit->period_cycles = (u64)vpit->period * cpu_khz / 1000000L;
 104.415 +         printk("HVM_PIT: guest freq in cycles=%lld\n",(long long)vpit->period_cycles);
 104.416 +
 104.417 +        vpit->channel = ((p->u.data >> 24) & 0x3);
 104.418 +        vpit->first_injected = 0;
 104.419 +
 104.420 +        vpit->count_LSB_latched = 0;
 104.421 +        vpit->count_MSB_latched = 0;
 104.422 +
 104.423 +        rw_mode = ((p->u.data >> 26) & 0x3);
 104.424 +        switch(rw_mode) {
 104.425 +        case 0x1:
 104.426 +            vpit->read_state=LSByte;
 104.427 +            break;
 104.428 +        case 0x2:
 104.429 +            vpit->read_state=MSByte;
 104.430 +            break;
 104.431 +        case 0x3:
 104.432 +            vpit->read_state=LSByte_multiple;
 104.433 +            break;
 104.434 +        default:
 104.435 +            printk("HVM_PIT:wrong PIT rw_mode!\n");
 104.436 +            break;
 104.437 +        }
 104.438 +
 104.439 +        vpit->scheduled = NOW() + vpit->period;
 104.440 +        set_timer(&vpit->pit_timer, vpit->scheduled);
 104.441 +
 104.442 +        /*restore the state*/
 104.443 +        p->state = STATE_IORESP_READY;
 104.444 +
 104.445 +        /* register handler to intercept the PIT io when vm_exit */
 104.446 +        if (!reinit) {
 104.447 +            register_portio_handler(0x40, 4, intercept_pit_io); 
 104.448 +        }
 104.449 +    }
 104.450 +}
 104.451 +
 104.452 +/*
 104.453 + * Local variables:
 104.454 + * mode: C
 104.455 + * c-set-style: "BSD"
 104.456 + * c-basic-offset: 4
 104.457 + * tab-width: 4
 104.458 + * indent-tabs-mode: nil
 104.459 + * End:
 104.460 + */
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/xen/arch/x86/hvm/io.c	Tue Jan 31 11:49:51 2006 +0100
   105.3 @@ -0,0 +1,759 @@
   105.4 +/*
   105.5 + * io.c: Handling I/O and interrupts.
   105.6 + *
   105.7 + * Copyright (c) 2004, Intel Corporation.
   105.8 + * Copyright (c) 2005, International Business Machines Corporation.
   105.9 + *
  105.10 + * This program is free software; you can redistribute it and/or modify it
  105.11 + * under the terms and conditions of the GNU General Public License,
  105.12 + * version 2, as published by the Free Software Foundation.
  105.13 + *
  105.14 + * This program is distributed in the hope it will be useful, but WITHOUT
  105.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  105.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  105.17 + * more details.
  105.18 + *
  105.19 + * You should have received a copy of the GNU General Public License along with
  105.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  105.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
  105.22 + */
  105.23 +
  105.24 +#include <xen/config.h>
  105.25 +#include <xen/init.h>
  105.26 +#include <xen/mm.h>
  105.27 +#include <xen/lib.h>
  105.28 +#include <xen/errno.h>
  105.29 +#include <xen/trace.h>
  105.30 +#include <xen/event.h>
  105.31 +
  105.32 +#include <xen/hypercall.h>
  105.33 +#include <asm/current.h>
  105.34 +#include <asm/cpufeature.h>
  105.35 +#include <asm/processor.h>
  105.36 +#include <asm/msr.h>
  105.37 +#include <asm/apic.h>
  105.38 +#include <asm/shadow.h>
  105.39 +#include <asm/hvm/hvm.h>
  105.40 +#include <asm/hvm/support.h>
  105.41 +#include <asm/hvm/vpit.h>
  105.42 +#include <asm/hvm/vpic.h>
  105.43 +#include <asm/hvm/vlapic.h>
  105.44 +
  105.45 +#include <public/sched.h>
  105.46 +#include <public/hvm/ioreq.h>
  105.47 +
  105.48 +#if defined (__i386__)
  105.49 +static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *regs, long value)
  105.50 +{
  105.51 +    switch (size) {
  105.52 +    case BYTE:
  105.53 +        switch (index) {
  105.54 +        case 0:
  105.55 +            regs->eax &= 0xFFFFFF00;
  105.56 +            regs->eax |= (value & 0xFF);
  105.57 +            break;
  105.58 +        case 1:
  105.59 +            regs->ecx &= 0xFFFFFF00;
  105.60 +            regs->ecx |= (value & 0xFF);
  105.61 +            break;
  105.62 +        case 2:
  105.63 +            regs->edx &= 0xFFFFFF00;
  105.64 +            regs->edx |= (value & 0xFF);
  105.65 +            break;
  105.66 +        case 3:
  105.67 +            regs->ebx &= 0xFFFFFF00;
  105.68 +            regs->ebx |= (value & 0xFF);
  105.69 +            break;
  105.70 +        case 4:
  105.71 +            regs->eax &= 0xFFFF00FF;
  105.72 +            regs->eax |= ((value & 0xFF) << 8);
  105.73 +            break;
  105.74 +        case 5:
  105.75 +            regs->ecx &= 0xFFFF00FF;
  105.76 +            regs->ecx |= ((value & 0xFF) << 8);
  105.77 +            break;
  105.78 +        case 6:
  105.79 +            regs->edx &= 0xFFFF00FF;
  105.80 +            regs->edx |= ((value & 0xFF) << 8);
  105.81 +            break;
  105.82 +        case 7:
  105.83 +            regs->ebx &= 0xFFFF00FF;
  105.84 +            regs->ebx |= ((value & 0xFF) << 8);
  105.85 +            break;
  105.86 +        default:
  105.87 +            printk("Error: size:%x, index:%x are invalid!\n", size, index);
  105.88 +            domain_crash_synchronous();
  105.89 +            break;
  105.90 +        }
  105.91 +        break;
  105.92 +    case WORD:
  105.93 +        switch (index) {
  105.94 +        case 0:
  105.95 +            regs->eax &= 0xFFFF0000;
  105.96 +            regs->eax |= (value & 0xFFFF);
  105.97 +            break;
  105.98 +        case 1:
  105.99 +            regs->ecx &= 0xFFFF0000;
 105.100 +            regs->ecx |= (value & 0xFFFF);
 105.101 +            break;
 105.102 +        case 2:
 105.103 +            regs->edx &= 0xFFFF0000;
 105.104 +            regs->edx |= (value & 0xFFFF);
 105.105 +            break;
 105.106 +        case 3:
 105.107 +            regs->ebx &= 0xFFFF0000;
 105.108 +            regs->ebx |= (value & 0xFFFF);
 105.109 +            break;
 105.110 +        case 4:
 105.111 +            regs->esp &= 0xFFFF0000;
 105.112 +            regs->esp |= (value & 0xFFFF);
 105.113 +            break;
 105.114 +        case 5:
 105.115 +            regs->ebp &= 0xFFFF0000;
 105.116 +            regs->ebp |= (value & 0xFFFF);
 105.117 +            break;
 105.118 +        case 6:
 105.119 +            regs->esi &= 0xFFFF0000;
 105.120 +            regs->esi |= (value & 0xFFFF);
 105.121 +            break;
 105.122 +        case 7:
 105.123 +            regs->edi &= 0xFFFF0000;
 105.124 +            regs->edi |= (value & 0xFFFF);
 105.125 +            break;
 105.126 +        default:
 105.127 +            printk("Error: size:%x, index:%x are invalid!\n", size, index);
 105.128 +            domain_crash_synchronous();
 105.129 +            break;
 105.130 +        }
 105.131 +        break;
 105.132 +    case LONG:
 105.133 +        switch (index) {
 105.134 +        case 0:
 105.135 +            regs->eax = value;
 105.136 +            break;
 105.137 +        case 1:
 105.138 +            regs->ecx = value;
 105.139 +            break;
 105.140 +        case 2:
 105.141 +            regs->edx = value;
 105.142 +            break;
 105.143 +        case 3:
 105.144 +            regs->ebx = value;
 105.145 +            break;
 105.146 +        case 4:
 105.147 +            regs->esp = value;
 105.148 +            break;
 105.149 +        case 5:
 105.150 +            regs->ebp = value;
 105.151 +            break;
 105.152 +        case 6:
 105.153 +            regs->esi = value;
 105.154 +            break;
 105.155 +        case 7:
 105.156 +            regs->edi = value;
 105.157 +            break;
 105.158 +        default:
 105.159 +            printk("Error: size:%x, index:%x are invalid!\n", size, index);
 105.160 +            domain_crash_synchronous();
 105.161 +            break;
 105.162 +        }
 105.163 +        break;
 105.164 +    default:
 105.165 +        printk("Error: size:%x, index:%x are invalid!\n", size, index);
 105.166 +        domain_crash_synchronous();
 105.167 +        break;
 105.168 +    }
 105.169 +}
 105.170 +#else
 105.171 +static inline void __set_reg_value(unsigned long *reg, int size, long value)
 105.172 +{
 105.173 +    switch (size) {
 105.174 +    case BYTE_64:
 105.175 +        *reg &= ~0xFF;
 105.176 +        *reg |= (value & 0xFF);
 105.177 +        break;
 105.178 +    case WORD:
 105.179 +        *reg &= ~0xFFFF;
 105.180 +        *reg |= (value & 0xFFFF);
 105.181 +        break;
 105.182 +    case LONG:
 105.183 +        *reg &= ~0xFFFFFFFF;
 105.184 +        *reg |= (value & 0xFFFFFFFF);
 105.185 +        break;
 105.186 +    case QUAD:
 105.187 +        *reg = value;
 105.188 +        break;
 105.189 +    default:
 105.190 +        printk("Error: <__set_reg_value>: size:%x is invalid\n", size);
 105.191 +        domain_crash_synchronous();
 105.192 +    }
 105.193 +}
 105.194 +
 105.195 +static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *regs, long value)
 105.196 +{
 105.197 +    if (size == BYTE) {
 105.198 +        switch (index) {
 105.199 +        case 0:
 105.200 +            regs->rax &= ~0xFF;
 105.201 +            regs->rax |= (value & 0xFF);
 105.202 +            break;
 105.203 +        case 1:
 105.204 +            regs->rcx &= ~0xFF;
 105.205 +            regs->rcx |= (value & 0xFF);
 105.206 +            break;
 105.207 +        case 2:
 105.208 +            regs->rdx &= ~0xFF;
 105.209 +            regs->rdx |= (value & 0xFF);
 105.210 +            break;
 105.211 +        case 3:
 105.212 +            regs->rbx &= ~0xFF;
 105.213 +            regs->rbx |= (value & 0xFF);
 105.214 +            break;
 105.215 +        case 4:
 105.216 +            regs->rax &= 0xFFFFFFFFFFFF00FF;
 105.217 +            regs->rax |= ((value & 0xFF) << 8);
 105.218 +            break;
 105.219 +        case 5:
 105.220 +            regs->rcx &= 0xFFFFFFFFFFFF00FF;
 105.221 +            regs->rcx |= ((value & 0xFF) << 8);
 105.222 +            break;
 105.223 +        case 6:
 105.224 +            regs->rdx &= 0xFFFFFFFFFFFF00FF;
 105.225 +            regs->rdx |= ((value & 0xFF) << 8);
 105.226 +            break;
 105.227 +        case 7:
 105.228 +            regs->rbx &= 0xFFFFFFFFFFFF00FF;
 105.229 +            regs->rbx |= ((value & 0xFF) << 8);
 105.230 +            break;
 105.231 +        default:
 105.232 +            printk("Error: size:%x, index:%x are invalid!\n", size, index);
 105.233 +            domain_crash_synchronous();
 105.234 +            break;
 105.235 +        }
 105.236 +        return;
 105.237 +    }
 105.238 +
 105.239 +    switch (index) {
 105.240 +    case 0:
 105.241 +        __set_reg_value(&regs->rax, size, value);
 105.242 +        break;
 105.243 +    case 1:
 105.244 +        __set_reg_value(&regs->rcx, size, value);
 105.245 +        break;
 105.246 +    case 2:
 105.247 +        __set_reg_value(&regs->rdx, size, value);
 105.248 +        break;
 105.249 +    case 3:
 105.250 +        __set_reg_value(&regs->rbx, size, value);
 105.251 +        break;
 105.252 +    case 4:
 105.253 +        __set_reg_value(&regs->rsp, size, value);
 105.254 +        break;
 105.255 +    case 5:
 105.256 +        __set_reg_value(&regs->rbp, size, value);
 105.257 +        break;
 105.258 +    case 6:
 105.259 +        __set_reg_value(&regs->rsi, size, value);
 105.260 +        break;
 105.261 +    case 7:
 105.262 +        __set_reg_value(&regs->rdi, size, value);
 105.263 +        break;
 105.264 +    case 8:
 105.265 +        __set_reg_value(&regs->r8, size, value);
 105.266 +        break;
 105.267 +    case 9:
 105.268 +        __set_reg_value(&regs->r9, size, value);
 105.269 +        break;
 105.270 +    case 10:
 105.271 +        __set_reg_value(&regs->r10, size, value);
 105.272 +        break;
 105.273 +    case 11:
 105.274 +        __set_reg_value(&regs->r11, size, value);
 105.275 +        break;
 105.276 +    case 12:
 105.277 +        __set_reg_value(&regs->r12, size, value);
 105.278 +        break;
 105.279 +    case 13:
 105.280 +        __set_reg_value(&regs->r13, size, value);
 105.281 +        break;
 105.282 +    case 14:
 105.283 +        __set_reg_value(&regs->r14, size, value);
 105.284 +        break;
 105.285 +    case 15:
 105.286 +        __set_reg_value(&regs->r15, size, value);
 105.287 +        break;
 105.288 +    default:
 105.289 +        printk("Error: <set_reg_value> Invalid index\n");
 105.290 +        domain_crash_synchronous();
 105.291 +    }
 105.292 +    return;
 105.293 +}
 105.294 +#endif
 105.295 +
 105.296 +extern long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs);
 105.297 +
 105.298 +static inline void set_eflags_CF(int size, unsigned long v1,
 105.299 +                                 unsigned long v2, struct cpu_user_regs *regs)
 105.300 +{
 105.301 +    unsigned long mask = (1 << (8 * size)) - 1;
 105.302 +
 105.303 +    if ((v1 & mask) > (v2 & mask))
 105.304 +        regs->eflags |= X86_EFLAGS_CF;
 105.305 +    else
 105.306 +        regs->eflags &= ~X86_EFLAGS_CF;
 105.307 +}
 105.308 +
 105.309 +static inline void set_eflags_OF(int size, unsigned long v1,
 105.310 +                                 unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
 105.311 +{
 105.312 +    if ((v3 ^ v2) & (v3 ^ v1) & (1 << ((8 * size) - 1)))
 105.313 +        regs->eflags |= X86_EFLAGS_OF;
 105.314 +}
 105.315 +
 105.316 +static inline void set_eflags_AF(int size, unsigned long v1,
 105.317 +                                 unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
 105.318 +{
 105.319 +    if ((v1 ^ v2 ^ v3) & 0x10)
 105.320 +        regs->eflags |= X86_EFLAGS_AF;
 105.321 +}
 105.322 +
 105.323 +static inline void set_eflags_ZF(int size, unsigned long v1,
 105.324 +                                 struct cpu_user_regs *regs)
 105.325 +{
 105.326 +    unsigned long mask = (1 << (8 * size)) - 1;
 105.327 +
 105.328 +    if ((v1 & mask) == 0)
 105.329 +        regs->eflags |= X86_EFLAGS_ZF;
 105.330 +}
 105.331 +
 105.332 +static inline void set_eflags_SF(int size, unsigned long v1,
 105.333 +                                 struct cpu_user_regs *regs)
 105.334 +{
 105.335 +    if (v1 & (1 << ((8 * size) - 1)))
 105.336 +        regs->eflags |= X86_EFLAGS_SF;
 105.337 +}
 105.338 +
 105.339 +static char parity_table[256] = {
 105.340 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
 105.341 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.342 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.343 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
 105.344 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.345 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
 105.346 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
 105.347 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.348 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.349 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
 105.350 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
 105.351 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.352 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
 105.353 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.354 +    0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
 105.355 +    1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
 105.356 +};
 105.357 +
 105.358 +static inline void set_eflags_PF(int size, unsigned long v1,
 105.359 +                                 struct cpu_user_regs *regs)
 105.360 +{
 105.361 +    if (parity_table[v1 & 0xFF])
 105.362 +        regs->eflags |= X86_EFLAGS_PF;
 105.363 +}
 105.364 +
 105.365 +static void hvm_pio_assist(struct cpu_user_regs *regs, ioreq_t *p,
 105.366 +                           struct mmio_op *mmio_opp)
 105.367 +{
 105.368 +    unsigned long old_eax;
 105.369 +    int sign = p->df ? -1 : 1;
 105.370 +
 105.371 +    if (p->dir == IOREQ_WRITE) {
 105.372 +        if (p->pdata_valid) {
 105.373 +            regs->esi += sign * p->count * p->size;
 105.374 +            if (mmio_opp->flags & REPZ)
 105.375 +                regs->ecx -= p->count;
 105.376 +        }
 105.377 +    } else {
 105.378 +        if (mmio_opp->flags & OVERLAP) {
 105.379 +            unsigned long addr;
 105.380 +
 105.381 +            regs->edi += sign * p->count * p->size;
 105.382 +            if (mmio_opp->flags & REPZ)
 105.383 +                regs->ecx -= p->count;
 105.384 +
 105.385 +            addr = regs->edi;
 105.386 +            if (sign > 0)
 105.387 +                addr -= p->size;
 105.388 +            hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
 105.389 +        } else if (p->pdata_valid) {
 105.390 +            regs->edi += sign * p->count * p->size;
 105.391 +            if (mmio_opp->flags & REPZ)
 105.392 +                regs->ecx -= p->count;
 105.393 +        } else {
 105.394 +            old_eax = regs->eax;
 105.395 +            switch (p->size) {
 105.396 +            case 1:
 105.397 +                regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
 105.398 +                break;
 105.399 +            case 2:
 105.400 +                regs->eax = (old_eax & 0xffff0000) | (p->u.data & 0xffff);
 105.401 +                break;
 105.402 +            case 4:
 105.403 +                regs->eax = (p->u.data & 0xffffffff);
 105.404 +                break;
 105.405 +            default:
 105.406 +                printk("Error: %s unknown port size\n", __FUNCTION__);
 105.407 +                domain_crash_synchronous();
 105.408 +            }
 105.409 +        }
 105.410 +    }
 105.411 +}
 105.412 +
 105.413 +static void hvm_mmio_assist(struct vcpu *v, struct cpu_user_regs *regs,
 105.414 +                            ioreq_t *p, struct mmio_op *mmio_opp)
 105.415 +{
 105.416 +    int sign = p->df ? -1 : 1;
 105.417 +    int size = -1, index = -1;
 105.418 +    unsigned long value = 0, diff = 0;
 105.419 +    unsigned long src, dst;
 105.420 +
 105.421 +    src = mmio_opp->operand[0];
 105.422 +    dst = mmio_opp->operand[1];
 105.423 +    size = operand_size(src);
 105.424 +
 105.425 +    switch (mmio_opp->instr) {
 105.426 +    case INSTR_MOV:
 105.427 +        if (dst & REGISTER) {
 105.428 +            index = operand_index(dst);
 105.429 +            set_reg_value(size, index, 0, regs, p->u.data);
 105.430 +        }
 105.431 +        break;
 105.432 +
 105.433 +    case INSTR_MOVZX:
 105.434 +        if (dst & REGISTER) {
 105.435 +            switch (size) {
 105.436 +            case BYTE:
 105.437 +                p->u.data &= 0xFFULL;
 105.438 +                break;
 105.439 +
 105.440 +            case WORD:
 105.441 +                p->u.data &= 0xFFFFULL;
 105.442 +                break;
 105.443 +
 105.444 +            case LONG:
 105.445 +                p->u.data &= 0xFFFFFFFFULL;
 105.446 +                break;
 105.447 +
 105.448 +            default:
 105.449 +                printk("Impossible source operand size of movzx instr: %d\n", size);
 105.450 +                domain_crash_synchronous();
 105.451 +            }
 105.452 +            index = operand_index(dst);
 105.453 +            set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
 105.454 +        }
 105.455 +        break;
 105.456 +
 105.457 +    case INSTR_MOVSX:
 105.458 +        if (dst & REGISTER) {
 105.459 +            switch (size) {
 105.460 +            case BYTE:
 105.461 +                p->u.data &= 0xFFULL;
 105.462 +                if ( p->u.data & 0x80ULL )
 105.463 +                    p->u.data |= 0xFFFFFFFFFFFFFF00ULL;
 105.464 +                break;
 105.465 +
 105.466 +            case WORD:
 105.467 +                p->u.data &= 0xFFFFULL;
 105.468 +                if ( p->u.data & 0x8000ULL )
 105.469 +                    p->u.data |= 0xFFFFFFFFFFFF0000ULL;
 105.470 +                break;
 105.471 +
 105.472 +            case LONG:
 105.473 +                p->u.data &= 0xFFFFFFFFULL;
 105.474 +                if ( p->u.data & 0x80000000ULL )
 105.475 +                    p->u.data |= 0xFFFFFFFF00000000ULL;
 105.476 +                break;
 105.477 +
 105.478 +            default:
 105.479 +                printk("Impossible source operand size of movsx instr: %d\n", size);
 105.480 +                domain_crash_synchronous();
 105.481 +            }
 105.482 +            index = operand_index(dst);
 105.483 +            set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
 105.484 +        }
 105.485 +        break;
 105.486 +
 105.487 +    case INSTR_MOVS:
 105.488 +        sign = p->df ? -1 : 1;
 105.489 +        regs->esi += sign * p->count * p->size;
 105.490 +        regs->edi += sign * p->count * p->size;
 105.491 +
 105.492 +        if ((mmio_opp->flags & OVERLAP) && p->dir == IOREQ_READ) {
 105.493 +            unsigned long addr = regs->edi;
 105.494 +
 105.495 +            if (sign > 0)
 105.496 +                addr -= p->size;
 105.497 +            hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
 105.498 +        }
 105.499 +
 105.500 +        if (mmio_opp->flags & REPZ)
 105.501 +            regs->ecx -= p->count;
 105.502 +        break;
 105.503 +
 105.504 +    case INSTR_STOS:
 105.505 +        sign = p->df ? -1 : 1;
 105.506 +        regs->edi += sign * p->count * p->size;
 105.507 +        if (mmio_opp->flags & REPZ)
 105.508 +            regs->ecx -= p->count;
 105.509 +        break;
 105.510 +
 105.511 +    case INSTR_AND:
 105.512 +        if (src & REGISTER) {
 105.513 +            index = operand_index(src);
 105.514 +            value = get_reg_value(size, index, 0, regs);
 105.515 +            diff = (unsigned long) p->u.data & value;
 105.516 +        } else if (src & IMMEDIATE) {
 105.517 +            value = mmio_opp->immediate;
 105.518 +            diff = (unsigned long) p->u.data & value;
 105.519 +        } else if (src & MEMORY) {
 105.520 +            index = operand_index(dst);
 105.521 +            value = get_reg_value(size, index, 0, regs);
 105.522 +            diff = (unsigned long) p->u.data & value;
 105.523 +            set_reg_value(size, index, 0, regs, diff);
 105.524 +        }
 105.525 +
 105.526 +        /*
 105.527 +         * The OF and CF flags are cleared; the SF, ZF, and PF
 105.528 +         * flags are set according to the result. The state of
 105.529 +         * the AF flag is undefined.
 105.530 +         */
 105.531 +        regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
 105.532 +                          X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
 105.533 +        set_eflags_ZF(size, diff, regs);
 105.534 +        set_eflags_SF(size, diff, regs);
 105.535 +        set_eflags_PF(size, diff, regs);
 105.536 +        break;
 105.537 +
 105.538 +    case INSTR_OR:
 105.539 +        if (src & REGISTER) {
 105.540 +            index = operand_index(src);
 105.541 +            value = get_reg_value(size, index, 0, regs);
 105.542 +            diff = (unsigned long) p->u.data | value;
 105.543 +        } else if (src & IMMEDIATE) {
 105.544 +            value = mmio_opp->immediate;
 105.545 +            diff = (unsigned long) p->u.data | value;
 105.546 +        } else if (src & MEMORY) {
 105.547 +            index = operand_index(dst);
 105.548 +            value = get_reg_value(size, index, 0, regs);
 105.549 +            diff = (unsigned long) p->u.data | value;
 105.550 +            set_reg_value(size, index, 0, regs, diff);
 105.551 +        }
 105.552 +
 105.553 +        /*
 105.554 +         * The OF and CF flags are cleared; the SF, ZF, and PF
 105.555 +         * flags are set according to the result. The state of
 105.556 +         * the AF flag is undefined.
 105.557 +         */
 105.558 +        regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
 105.559 +                          X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
 105.560 +        set_eflags_ZF(size, diff, regs);
 105.561 +        set_eflags_SF(size, diff, regs);
 105.562 +        set_eflags_PF(size, diff, regs);
 105.563 +        break;
 105.564 +
 105.565 +    case INSTR_XOR:
 105.566 +        if (src & REGISTER) {
 105.567 +            index = operand_index(src);
 105.568 +            value = get_reg_value(size, index, 0, regs);
 105.569 +            diff = (unsigned long) p->u.data ^ value;
 105.570 +        } else if (src & IMMEDIATE) {
 105.571 +            value = mmio_opp->immediate;
 105.572 +            diff = (unsigned long) p->u.data ^ value;
 105.573 +        } else if (src & MEMORY) {
 105.574 +            index = operand_index(dst);
 105.575 +            value = get_reg_value(size, index, 0, regs);
 105.576 +            diff = (unsigned long) p->u.data ^ value;
 105.577 +            set_reg_value(size, index, 0, regs, diff);
 105.578 +        }
 105.579 +
 105.580 +        /*
 105.581 +         * The OF and CF flags are cleared; the SF, ZF, and PF
 105.582 +         * flags are set according to the result. The state of
 105.583 +         * the AF flag is undefined.
 105.584 +         */
 105.585 +        regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
 105.586 +                          X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
 105.587 +        set_eflags_ZF(size, diff, regs);
 105.588 +        set_eflags_SF(size, diff, regs);
 105.589 +        set_eflags_PF(size, diff, regs);
 105.590 +        break;
 105.591 +
 105.592 +    case INSTR_CMP:
 105.593 +        if (src & REGISTER) {
 105.594 +            index = operand_index(src);
 105.595 +            value = get_reg_value(size, index, 0, regs);
 105.596 +            diff = (unsigned long) p->u.data - value;
 105.597 +        } else if (src & IMMEDIATE) {
 105.598 +            value = mmio_opp->immediate;
 105.599 +            diff = (unsigned long) p->u.data - value;
 105.600 +        } else if (src & MEMORY) {
 105.601 +            index = operand_index(dst);
 105.602 +            value = get_reg_value(size, index, 0, regs);
 105.603 +            diff = value - (unsigned long) p->u.data;
 105.604 +        }
 105.605 +
 105.606 +        /*
 105.607 +         * The CF, OF, SF, ZF, AF, and PF flags are set according
 105.608 +         * to the result
 105.609 +         */
 105.610 +        regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|X86_EFLAGS_AF|
 105.611 +                          X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
 105.612 +        set_eflags_CF(size, value, (unsigned long) p->u.data, regs);
 105.613 +        set_eflags_OF(size, diff, value, (unsigned long) p->u.data, regs);
 105.614 +        set_eflags_AF(size, diff, value, (unsigned long) p->u.data, regs);
 105.615 +        set_eflags_ZF(size, diff, regs);
 105.616 +        set_eflags_SF(size, diff, regs);
 105.617 +        set_eflags_PF(size, diff, regs);
 105.618 +        break;
 105.619 +
 105.620 +    case INSTR_TEST:
 105.621 +        if (src & REGISTER) {
 105.622 +            index = operand_index(src);
 105.623 +            value = get_reg_value(size, index, 0, regs);
 105.624 +        } else if (src & IMMEDIATE) {
 105.625 +            value = mmio_opp->immediate;
 105.626 +        } else if (src & MEMORY) {
 105.627 +            index = operand_index(dst);
 105.628 +            value = get_reg_value(size, index, 0, regs);
 105.629 +        }
 105.630 +        diff = (unsigned long) p->u.data & value;
 105.631 +
 105.632 +        /*
 105.633 +         * Sets the SF, ZF, and PF status flags. CF and OF are set to 0
 105.634 +         */
 105.635 +        regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
 105.636 +                          X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
 105.637 +        set_eflags_ZF(size, diff, regs);
 105.638 +        set_eflags_SF(size, diff, regs);
 105.639 +        set_eflags_PF(size, diff, regs);
 105.640 +        break;
 105.641 +
 105.642 +    case INSTR_BT:
 105.643 +        index = operand_index(src);
 105.644 +        value = get_reg_value(size, index, 0, regs);
 105.645 +
 105.646 +        if (p->u.data & (1 << (value & ((1 << 5) - 1))))
 105.647 +            regs->eflags |= X86_EFLAGS_CF;
 105.648 +        else
 105.649 +            regs->eflags &= ~X86_EFLAGS_CF;
 105.650 +
 105.651 +        break;
 105.652 +    }
 105.653 +
 105.654 +    hvm_load_cpu_guest_regs(v, regs);
 105.655 +}
 105.656 +
 105.657 +void hvm_io_assist(struct vcpu *v)
 105.658 +{
 105.659 +    vcpu_iodata_t *vio;
 105.660 +    ioreq_t *p;
 105.661 +    struct cpu_user_regs *regs = guest_cpu_user_regs();
 105.662 +    struct mmio_op *mmio_opp;
 105.663 +    struct cpu_user_regs *inst_decoder_regs;
 105.664 +
 105.665 +    mmio_opp = &v->arch.hvm_vcpu.mmio_op;
 105.666 +    inst_decoder_regs = mmio_opp->inst_decoder_regs;
 105.667 +
 105.668 +    vio = get_vio(v->domain, v->vcpu_id);
 105.669 +
 105.670 +    if (vio == 0) {
 105.671 +        HVM_DBG_LOG(DBG_LEVEL_1,
 105.672 +                    "bad shared page: %lx", (unsigned long) vio);
 105.673 +        printf("bad shared page: %lx\n", (unsigned long) vio);
 105.674 +        domain_crash_synchronous();
 105.675 +    }
 105.676 +
 105.677 +    p = &vio->vp_ioreq;
 105.678 +    if (p->state == STATE_IORESP_HOOK)
 105.679 +        hvm_hooks_assist(v);
 105.680 +
 105.681 +    /* clear IO wait HVM flag */
 105.682 +    if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) {
 105.683 +        if (p->state == STATE_IORESP_READY) {
 105.684 +            p->state = STATE_INVALID;
 105.685 +            clear_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
 105.686 +
 105.687 +            if (p->type == IOREQ_TYPE_PIO)
 105.688 +                hvm_pio_assist(regs, p, mmio_opp);
 105.689 +            else
 105.690 +                hvm_mmio_assist(v, regs, p, mmio_opp);
 105.691 +        }
 105.692 +        /* else an interrupt send event raced us */
 105.693 +    }
 105.694 +}
 105.695 +
 105.696 +int hvm_clear_pending_io_event(struct vcpu *v)
 105.697 +{
 105.698 +    struct domain *d = v->domain;
 105.699 +    int port = iopacket_port(d);
 105.700 +
 105.701 +    /* evtchn_pending_sel bit is shared by other event channels. */
 105.702 +    if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG])
 105.703 +        clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
 105.704 +
 105.705 +    /* Note: HVM domains may need upcalls as well. */
 105.706 +    if (!v->vcpu_info->evtchn_pending_sel)
 105.707 +        clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
 105.708 +
 105.709 +    /* Clear the pending bit for port. */
 105.710 +    return test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]);
 105.711 +}
 105.712 +
 105.713 +/*
 105.714 + * Because we've cleared the pending events first, we need to guarantee that
 105.715 + * all events to be handled by xen for HVM domains are taken care of here.
 105.716 + *
 105.717 + * interrupts are guaranteed to be checked before resuming guest.
 105.718 + * HVM upcalls have been already arranged for if necessary.
 105.719 + */
 105.720 +void hvm_check_events(struct vcpu *v)
 105.721 +{
 105.722 +    /*
 105.723 +     * Clear the event *before* checking for work. This should
 105.724 +     * avoid the set-and-check races
 105.725 +     */
 105.726 +    if (hvm_clear_pending_io_event(current))
 105.727 +        hvm_io_assist(v);
 105.728 +}
 105.729 +
 105.730 +/*
 105.731 + * On exit from hvm_wait_io, we're guaranteed to have a I/O response
 105.732 + * from the device model.
 105.733 + */
 105.734 +void hvm_wait_io(void)
 105.735 +{
 105.736 +    int port = iopacket_port(current->domain);
 105.737 +
 105.738 +    do {
 105.739 +        if (!test_bit(port, &current->domain->shared_info->evtchn_pending[0]))
 105.740 +	    do_sched_op(SCHEDOP_block, 0);
 105.741 +
 105.742 +        hvm_check_events(current);
 105.743 +        if (!test_bit(ARCH_HVM_IO_WAIT, &current->arch.hvm_vcpu.ioflags))
 105.744 +            break;
 105.745 +        /*
 105.746 +	 * Events other than IOPACKET_PORT might have woken us up.
 105.747 +	 * In that case, safely go back to sleep.
 105.748 +	 */
 105.749 +        clear_bit(port/BITS_PER_LONG, &current->vcpu_info->evtchn_pending_sel);
 105.750 +        clear_bit(0, &current->vcpu_info->evtchn_upcall_pending);
 105.751 +    } while(1);
 105.752 +}
 105.753 +
 105.754 +/*
 105.755 + * Local variables:
 105.756 + * mode: C
 105.757 + * c-set-style: "BSD"
 105.758 + * c-basic-offset: 4
 105.759 + * tab-width: 4
 105.760 + * indent-tabs-mode: nil
 105.761 + * End:
 105.762 + */
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/xen/arch/x86/hvm/platform.c	Tue Jan 31 11:49:51 2006 +0100
   106.3 @@ -0,0 +1,951 @@
   106.4 +/*
   106.5 + * platform.c: handling x86 platform related MMIO instructions
   106.6 + *
   106.7 + * Copyright (c) 2004, Intel Corporation.
   106.8 + * Copyright (c) 2005, International Business Machines Corporation.
   106.9 + *
  106.10 + * This program is free software; you can redistribute it and/or modify it
  106.11 + * under the terms and conditions of the GNU General Public License,
  106.12 + * version 2, as published by the Free Software Foundation.
  106.13 + *
  106.14 + * This program is distributed in the hope it will be useful, but WITHOUT
  106.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  106.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  106.17 + * more details.
  106.18 + *
  106.19 + * You should have received a copy of the GNU General Public License along with
  106.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  106.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
  106.22 + */
  106.23 +
  106.24 +#include <xen/config.h>
  106.25 +#include <xen/types.h>
  106.26 +#include <xen/mm.h>
  106.27 +#include <asm/shadow.h>
  106.28 +#include <xen/domain_page.h>
  106.29 +#include <asm/page.h>
  106.30 +#include <xen/event.h>
  106.31 +#include <xen/trace.h>
  106.32 +#include <xen/sched.h>
  106.33 +#include <asm/regs.h>
  106.34 +#include <asm/hvm/hvm.h>
  106.35 +#include <asm/hvm/support.h>
  106.36 +#include <public/hvm/ioreq.h>
  106.37 +
  106.38 +#include <xen/lib.h>
  106.39 +#include <xen/sched.h>
  106.40 +#include <asm/current.h>
  106.41 +#if CONFIG_PAGING_LEVELS >= 3
  106.42 +#include <asm/shadow_64.h>
  106.43 +#endif
  106.44 +
  106.45 +#define DECODE_success  1
  106.46 +#define DECODE_failure  0
  106.47 +
  106.48 +extern long evtchn_send(int lport);
  106.49 +
  106.50 +#if defined (__x86_64__)
  106.51 +static inline long __get_reg_value(unsigned long reg, int size)
  106.52 +{
  106.53 +    switch(size) {
  106.54 +    case BYTE_64:
  106.55 +        return (char)(reg & 0xFF);
  106.56 +    case WORD:
  106.57 +        return (short)(reg & 0xFFFF);
  106.58 +    case LONG:
  106.59 +        return (int)(reg & 0xFFFFFFFF);
  106.60 +    case QUAD:
  106.61 +        return (long)(reg);
  106.62 +    default:
  106.63 +        printf("Error: (__get_reg_value) Invalid reg size\n");
  106.64 +        domain_crash_synchronous();
  106.65 +    }
  106.66 +}
  106.67 +
  106.68 +long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs)
  106.69 +{
  106.70 +    if (size == BYTE) {
  106.71 +        switch (index) {
  106.72 +        case 0: /* %al */
  106.73 +            return (char)(regs->rax & 0xFF);
  106.74 +        case 1: /* %cl */
  106.75 +            return (char)(regs->rcx & 0xFF);
  106.76 +        case 2: /* %dl */
  106.77 +            return (char)(regs->rdx & 0xFF);
  106.78 +        case 3: /* %bl */
  106.79 +            return (char)(regs->rbx & 0xFF);
  106.80 +        case 4: /* %ah */
  106.81 +            return (char)((regs->rax & 0xFF00) >> 8);
  106.82 +        case 5: /* %ch */
  106.83 +            return (char)((regs->rcx & 0xFF00) >> 8);
  106.84 +        case 6: /* %dh */
  106.85 +            return (char)((regs->rdx & 0xFF00) >> 8);
  106.86 +        case 7: /* %bh */
  106.87 +            return (char)((regs->rbx & 0xFF00) >> 8);
  106.88 +        default:
  106.89 +            printf("Error: (get_reg_value) Invalid index value\n");
  106.90 +            domain_crash_synchronous();
  106.91 +        }
  106.92 +        /* NOTREACHED */
  106.93 +    }
  106.94 +
  106.95 +    switch (index) {
  106.96 +    case 0: return __get_reg_value(regs->rax, size);
  106.97 +    case 1: return __get_reg_value(regs->rcx, size);
  106.98 +    case 2: return __get_reg_value(regs->rdx, size);
  106.99 +    case 3: return __get_reg_value(regs->rbx, size);
 106.100 +    case 4: return __get_reg_value(regs->rsp, size);
 106.101 +    case 5: return __get_reg_value(regs->rbp, size);
 106.102 +    case 6: return __get_reg_value(regs->rsi, size);
 106.103 +    case 7: return __get_reg_value(regs->rdi, size);
 106.104 +    case 8: return __get_reg_value(regs->r8, size);
 106.105 +    case 9: return __get_reg_value(regs->r9, size);
 106.106 +    case 10: return __get_reg_value(regs->r10, size);
 106.107 +    case 11: return __get_reg_value(regs->r11, size);
 106.108 +    case 12: return __get_reg_value(regs->r12, size);
 106.109 +    case 13: return __get_reg_value(regs->r13, size);
 106.110 +    case 14: return __get_reg_value(regs->r14, size);
 106.111 +    case 15: return __get_reg_value(regs->r15, size);
 106.112 +    default:
 106.113 +        printf("Error: (get_reg_value) Invalid index value\n");
 106.114 +        domain_crash_synchronous();
 106.115 +    }
 106.116 +}
 106.117 +#elif defined (__i386__)
 106.118 +static inline long __get_reg_value(unsigned long reg, int size)
 106.119 +{
 106.120 +    switch(size) {
 106.121 +    case WORD:
 106.122 +        return (short)(reg & 0xFFFF);
 106.123 +    case LONG:
 106.124 +        return (int)(reg & 0xFFFFFFFF);
 106.125 +    default:
 106.126 +        printf("Error: (__get_reg_value) Invalid reg size\n");
 106.127 +        domain_crash_synchronous();
 106.128 +    }
 106.129 +}
 106.130 +
 106.131 +long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs)
 106.132 +{
 106.133 +    if (size == BYTE) {
 106.134 +        switch (index) {
 106.135 +        case 0: /* %al */
 106.136 +            return (char)(regs->eax & 0xFF);
 106.137 +        case 1: /* %cl */
 106.138 +            return (char)(regs->ecx & 0xFF);
 106.139 +        case 2: /* %dl */
 106.140 +            return (char)(regs->edx & 0xFF);
 106.141 +        case 3: /* %bl */
 106.142 +            return (char)(regs->ebx & 0xFF);
 106.143 +        case 4: /* %ah */
 106.144 +            return (char)((regs->eax & 0xFF00) >> 8);
 106.145 +        case 5: /* %ch */
 106.146 +            return (char)((regs->ecx & 0xFF00) >> 8);
 106.147 +        case 6: /* %dh */
 106.148 +            return (char)((regs->edx & 0xFF00) >> 8);
 106.149 +        case 7: /* %bh */
 106.150 +            return (char)((regs->ebx & 0xFF00) >> 8);
 106.151 +        default:
 106.152 +            printf("Error: (get_reg_value) Invalid index value\n");
 106.153 +            domain_crash_synchronous();
 106.154 +        }
 106.155 +    }
 106.156 +
 106.157 +    switch (index) {
 106.158 +    case 0: return __get_reg_value(regs->eax, size);
 106.159 +    case 1: return __get_reg_value(regs->ecx, size);
 106.160 +    case 2: return __get_reg_value(regs->edx, size);
 106.161 +    case 3: return __get_reg_value(regs->ebx, size);
 106.162 +    case 4: return __get_reg_value(regs->esp, size);
 106.163 +    case 5: return __get_reg_value(regs->ebp, size);
 106.164 +    case 6: return __get_reg_value(regs->esi, size);
 106.165 +    case 7: return __get_reg_value(regs->edi, size);
 106.166 +    default:
 106.167 +        printf("Error: (get_reg_value) Invalid index value\n");
 106.168 +        domain_crash_synchronous();
 106.169 +    }
 106.170 +}
 106.171 +#endif
 106.172 +
 106.173 +static inline unsigned char *check_prefix(unsigned char *inst,
 106.174 +                                          struct instruction *thread_inst, unsigned char *rex_p)
 106.175 +{
 106.176 +    while (1) {
 106.177 +        switch (*inst) {
 106.178 +            /* rex prefix for em64t instructions */
 106.179 +        case 0x40 ... 0x4e:
 106.180 +            *rex_p = *inst;
 106.181 +            break;
 106.182 +        case 0xf3: /* REPZ */
 106.183 +            thread_inst->flags = REPZ;
 106.184 +            break;
 106.185 +        case 0xf2: /* REPNZ */
 106.186 +            thread_inst->flags = REPNZ;
 106.187 +            break;
 106.188 +        case 0xf0: /* LOCK */
 106.189 +            break;
 106.190 +        case 0x2e: /* CS */
 106.191 +        case 0x36: /* SS */
 106.192 +        case 0x3e: /* DS */
 106.193 +        case 0x26: /* ES */
 106.194 +        case 0x64: /* FS */
 106.195 +        case 0x65: /* GS */
 106.196 +            thread_inst->seg_sel = *inst;
 106.197 +            break;
 106.198 +        case 0x66: /* 32bit->16bit */
 106.199 +            thread_inst->op_size = WORD;
 106.200 +            break;
 106.201 +        case 0x67:
 106.202 +            break;
 106.203 +        default:
 106.204 +            return inst;
 106.205 +        }
 106.206 +        inst++;
 106.207 +    }
 106.208 +}
 106.209 +
 106.210 +static inline unsigned long get_immediate(int op16,const unsigned char *inst, int op_size)
 106.211 +{
 106.212 +    int mod, reg, rm;
 106.213 +    unsigned long val = 0;
 106.214 +    int i;
 106.215 +
 106.216 +    mod = (*inst >> 6) & 3;
 106.217 +    reg = (*inst >> 3) & 7;
 106.218 +    rm = *inst & 7;
 106.219 +
 106.220 +    inst++; //skip ModR/M byte
 106.221 +    if (mod != 3 && rm == 4) {
 106.222 +        inst++; //skip SIB byte
 106.223 +    }
 106.224 +
 106.225 +    switch(mod) {
 106.226 +    case 0:
 106.227 +        if (rm == 5 || rm == 4) {
 106.228 +            if (op16)
 106.229 +                inst = inst + 2; //disp16, skip 2 bytes
 106.230 +            else
 106.231 +                inst = inst + 4; //disp32, skip 4 bytes
 106.232 +        }
 106.233 +        break;
 106.234 +    case 1:
 106.235 +        inst++; //disp8, skip 1 byte
 106.236 +        break;
 106.237 +    case 2:
 106.238 +        if (op16)
 106.239 +            inst = inst + 2; //disp16, skip 2 bytes
 106.240 +        else
 106.241 +            inst = inst + 4; //disp32, skip 4 bytes
 106.242 +        break;
 106.243 +    }
 106.244 +
 106.245 +    if (op_size == QUAD)
 106.246 +        op_size = LONG;
 106.247 +
 106.248 +    for (i = 0; i < op_size; i++) {
 106.249 +        val |= (*inst++ & 0xff) << (8 * i);
 106.250 +    }
 106.251 +
 106.252 +    return val;
 106.253 +}
 106.254 +
 106.255 +static inline int get_index(const unsigned char *inst, unsigned char rex)
 106.256 +{
 106.257 +    int mod, reg, rm;
 106.258 +    int rex_r, rex_b;
 106.259 +
 106.260 +    mod = (*inst >> 6) & 3;
 106.261 +    reg = (*inst >> 3) & 7;
 106.262 +    rm = *inst & 7;
 106.263 +
 106.264 +    rex_r = (rex >> 2) & 1;
 106.265 +    rex_b = rex & 1;
 106.266 +
 106.267 +    //Only one operand in the instruction is register
 106.268 +    if (mod == 3) {
 106.269 +        return (rm + (rex_b << 3));
 106.270 +    } else {
 106.271 +        return (reg + (rex_r << 3));
 106.272 +    }
 106.273 +    return 0;
 106.274 +}
 106.275 +
 106.276 +static void init_instruction(struct instruction *mmio_inst)
 106.277 +{
 106.278 +    mmio_inst->instr = 0;
 106.279 +    mmio_inst->op_size = 0;
 106.280 +    mmio_inst->immediate = 0;
 106.281 +    mmio_inst->seg_sel = 0;
 106.282 +
 106.283 +    mmio_inst->operand[0] = 0;
 106.284 +    mmio_inst->operand[1] = 0;
 106.285 +
 106.286 +    mmio_inst->flags = 0;
 106.287 +}
 106.288 +
 106.289 +#define GET_OP_SIZE_FOR_BYTE(op_size)       \
 106.290 +    do {                                    \
 106.291 +        if (rex)                            \
 106.292 +            op_size = BYTE_64;              \
 106.293 +        else                                \
 106.294 +            op_size = BYTE;                 \
 106.295 +    } while(0)
 106.296 +
 106.297 +#define GET_OP_SIZE_FOR_NONEBYTE(op_size)   \
 106.298 +    do {                                    \
 106.299 +        if (rex & 0x8)                      \
 106.300 +            op_size = QUAD;                 \
 106.301 +        else if (op_size != WORD)           \
 106.302 +            op_size = LONG;                 \
 106.303 +    } while(0)
 106.304 +
 106.305 +
 106.306 +/*
 106.307 + * Decode mem,accumulator operands (as in <opcode> m8/m16/m32, al,ax,eax)
 106.308 + */
 106.309 +static int mem_acc(unsigned char size, struct instruction *instr)
 106.310 +{
 106.311 +    instr->operand[0] = mk_operand(size, 0, 0, MEMORY);
 106.312 +    instr->operand[1] = mk_operand(size, 0, 0, REGISTER);
 106.313 +    return DECODE_success;
 106.314 +}
 106.315 +
 106.316 +/*
 106.317 + * Decode accumulator,mem operands (as in <opcode> al,ax,eax, m8/m16/m32)
 106.318 + */
 106.319 +static int acc_mem(unsigned char size, struct instruction *instr)
 106.320 +{
 106.321 +    instr->operand[0] = mk_operand(size, 0, 0, REGISTER);
 106.322 +    instr->operand[1] = mk_operand(size, 0, 0, MEMORY);
 106.323 +    return DECODE_success;
 106.324 +}
 106.325 +
 106.326 +/*
 106.327 + * Decode mem,reg operands (as in <opcode> r32/16, m32/16)
 106.328 + */
 106.329 +static int mem_reg(unsigned char size, unsigned char *opcode,
 106.330 +                   struct instruction *instr, unsigned char rex)
 106.331 +{
 106.332 +    int index = get_index(opcode + 1, rex);
 106.333 +
 106.334 +    instr->operand[0] = mk_operand(size, 0, 0, MEMORY);
 106.335 +    instr->operand[1] = mk_operand(size, index, 0, REGISTER);
 106.336 +    return DECODE_success;
 106.337 +}
 106.338 +
 106.339 +/*
 106.340 + * Decode reg,mem operands (as in <opcode> m32/16, r32/16)
 106.341 + */
 106.342 +static int reg_mem(unsigned char size, unsigned char *opcode,
 106.343 +                   struct instruction *instr, unsigned char rex)
 106.344 +{
 106.345 +    int index = get_index(opcode + 1, rex);
 106.346 +
 106.347 +    instr->operand[0] = mk_operand(size, index, 0, REGISTER);
 106.348 +    instr->operand[1] = mk_operand(size, 0, 0, MEMORY);
 106.349 +    return DECODE_success;
 106.350 +}
 106.351 +
 106.352 +static int hvm_decode(int realmode, unsigned char *opcode, struct instruction *instr)
 106.353 +{
 106.354 +    unsigned char size_reg = 0;
 106.355 +    unsigned char rex = 0;
 106.356 +    int index;
 106.357 +
 106.358 +    init_instruction(instr);
 106.359 +
 106.360 +    opcode = check_prefix(opcode, instr, &rex);
 106.361 +
 106.362 +    if (realmode) { /* meaning is reversed */
 106.363 +        if (instr->op_size == WORD)
 106.364 +            instr->op_size = LONG;
 106.365 +        else if (instr->op_size == LONG)
 106.366 +            instr->op_size = WORD;
 106.367 +        else if (instr->op_size == 0)
 106.368 +            instr->op_size = WORD;
 106.369 +    }
 106.370 +
 106.371 +    switch (*opcode) {
 106.372 +    case 0x0B: /* or m32/16, r32/16 */
 106.373 +        instr->instr = INSTR_OR;
 106.374 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.375 +        return mem_reg(instr->op_size, opcode, instr, rex);
 106.376 +
 106.377 +    case 0x20: /* and r8, m8 */
 106.378 +        instr->instr = INSTR_AND;
 106.379 +        instr->op_size = BYTE;
 106.380 +        GET_OP_SIZE_FOR_BYTE(size_reg);
 106.381 +        return reg_mem(size_reg, opcode, instr, rex);
 106.382 +
 106.383 +    case 0x21: /* and r32/16, m32/16 */
 106.384 +        instr->instr = INSTR_AND;
 106.385 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.386 +        return reg_mem(instr->op_size, opcode, instr, rex);
 106.387 +
 106.388 +    case 0x23: /* and m32/16, r32/16 */
 106.389 +        instr->instr = INSTR_AND;
 106.390 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.391 +        return mem_reg(instr->op_size, opcode, instr, rex);
 106.392 +
 106.393 +    case 0x30: /* xor r8, m8 */
 106.394 +        instr->instr = INSTR_XOR;
 106.395 +        instr->op_size = BYTE;
 106.396 +        GET_OP_SIZE_FOR_BYTE(size_reg);
 106.397 +        return reg_mem(size_reg, opcode, instr, rex);
 106.398 +
 106.399 +    case 0x31: /* xor r32/16, m32/16 */
 106.400 +        instr->instr = INSTR_XOR;
 106.401 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.402 +        return reg_mem(instr->op_size, opcode, instr, rex);
 106.403 +
 106.404 +    case 0x39: /* cmp r32/16, m32/16 */
 106.405 +        instr->instr = INSTR_CMP;
 106.406 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.407 +        return reg_mem(instr->op_size, opcode, instr, rex);
 106.408 +
 106.409 +    case 0x80:
 106.410 +    case 0x81:
 106.411 +        {
 106.412 +            unsigned char ins_subtype = (opcode[1] >> 3) & 7;
 106.413 +
 106.414 +            if (opcode[0] == 0x80) {
 106.415 +                GET_OP_SIZE_FOR_BYTE(size_reg);
 106.416 +                instr->op_size = BYTE;
 106.417 +            } else {
 106.418 +                GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.419 +                size_reg = instr->op_size;
 106.420 +            }
 106.421 +
 106.422 +            instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
 106.423 +            instr->immediate = get_immediate(realmode, opcode+1, instr->op_size);
 106.424 +            instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
 106.425 +
 106.426 +            switch (ins_subtype) {
 106.427 +                case 7: /* cmp $imm, m32/16 */
 106.428 +                    instr->instr = INSTR_CMP;
 106.429 +                    return DECODE_success;
 106.430 +
 106.431 +                case 1: /* or $imm, m32/16 */
 106.432 +                    instr->instr = INSTR_OR;
 106.433 +                    return DECODE_success;
 106.434 +
 106.435 +                default:
 106.436 +                    printf("%x, This opcode isn't handled yet!\n", *opcode);
 106.437 +                    return DECODE_failure;
 106.438 +            }
 106.439 +        }
 106.440 +
 106.441 +    case 0x84:  /* test m8, r8 */
 106.442 +        instr->instr = INSTR_TEST;
 106.443 +        instr->op_size = BYTE;
 106.444 +        GET_OP_SIZE_FOR_BYTE(size_reg);
 106.445 +        return mem_reg(size_reg, opcode, instr, rex);
 106.446 +
 106.447 +    case 0x88: /* mov r8, m8 */
 106.448 +        instr->instr = INSTR_MOV;
 106.449 +        instr->op_size = BYTE;
 106.450 +        GET_OP_SIZE_FOR_BYTE(size_reg);
 106.451 +        return reg_mem(size_reg, opcode, instr, rex);
 106.452 +
 106.453 +    case 0x89: /* mov r32/16, m32/16 */
 106.454 +        instr->instr = INSTR_MOV;
 106.455 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.456 +        return reg_mem(instr->op_size, opcode, instr, rex);
 106.457 +
 106.458 +    case 0x8A: /* mov m8, r8 */
 106.459 +        instr->instr = INSTR_MOV;
 106.460 +        instr->op_size = BYTE;
 106.461 +        GET_OP_SIZE_FOR_BYTE(size_reg);
 106.462 +        return mem_reg(size_reg, opcode, instr, rex);
 106.463 +
 106.464 +    case 0x8B: /* mov m32/16, r32/16 */
 106.465 +        instr->instr = INSTR_MOV;
 106.466 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.467 +        return mem_reg(instr->op_size, opcode, instr, rex);
 106.468 +
 106.469 +    case 0xA0: /* mov <addr>, al */
 106.470 +        instr->instr = INSTR_MOV;
 106.471 +        instr->op_size = BYTE;
 106.472 +        GET_OP_SIZE_FOR_BYTE(size_reg);
 106.473 +        return mem_acc(size_reg, instr);
 106.474 +
 106.475 +    case 0xA1: /* mov <addr>, ax/eax */
 106.476 +        instr->instr = INSTR_MOV;
 106.477 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.478 +        return mem_acc(instr->op_size, instr);
 106.479 +
 106.480 +    case 0xA2: /* mov al, <addr> */
 106.481 +        instr->instr = INSTR_MOV;
 106.482 +        instr->op_size = BYTE;
 106.483 +        GET_OP_SIZE_FOR_BYTE(size_reg);
 106.484 +        return acc_mem(size_reg, instr);
 106.485 +
 106.486 +    case 0xA3: /* mov ax/eax, <addr> */
 106.487 +        instr->instr = INSTR_MOV;
 106.488 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.489 +        return acc_mem(instr->op_size, instr);
 106.490 +
 106.491 +    case 0xA4: /* movsb */
 106.492 +        instr->instr = INSTR_MOVS;
 106.493 +        instr->op_size = BYTE;
 106.494 +        return DECODE_success;
 106.495 +
 106.496 +    case 0xA5: /* movsw/movsl */
 106.497 +        instr->instr = INSTR_MOVS;
 106.498 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.499 +        return DECODE_success;
 106.500 +
 106.501 +    case 0xAA: /* stosb */
 106.502 +        instr->instr = INSTR_STOS;
 106.503 +        instr->op_size = BYTE;
 106.504 +        return DECODE_success;
 106.505 +
 106.506 +    case 0xAB: /* stosw/stosl */
 106.507 +        instr->instr = INSTR_STOS;
 106.508 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.509 +        return DECODE_success;
 106.510 +
 106.511 +    case 0xC6:
 106.512 +        if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm8, m8 */
 106.513 +            instr->instr = INSTR_MOV;
 106.514 +            instr->op_size = BYTE;
 106.515 +
 106.516 +            instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
 106.517 +            instr->immediate = get_immediate(realmode, opcode+1, instr->op_size);
 106.518 +            instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
 106.519 +
 106.520 +            return DECODE_success;
 106.521 +        } else
 106.522 +            return DECODE_failure;
 106.523 +
 106.524 +    case 0xC7:
 106.525 +        if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm16/32, m16/32 */
 106.526 +            instr->instr = INSTR_MOV;
 106.527 +            GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.528 +
 106.529 +            instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
 106.530 +            instr->immediate = get_immediate(realmode, opcode+1, instr->op_size);
 106.531 +            instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
 106.532 +
 106.533 +            return DECODE_success;
 106.534 +        } else
 106.535 +            return DECODE_failure;
 106.536 +
 106.537 +    case 0xF6:
 106.538 +    case 0xF7:
 106.539 +        if (((opcode[1] >> 3) & 7) == 0) { /* test $imm8/16/32, m8/16/32 */
 106.540 +            instr->instr = INSTR_TEST;
 106.541 +
 106.542 +            if (opcode[0] == 0xF6) {
 106.543 +                GET_OP_SIZE_FOR_BYTE(size_reg);
 106.544 +                instr->op_size = BYTE;
 106.545 +            } else {
 106.546 +                GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.547 +                size_reg = instr->op_size;
 106.548 +            }
 106.549 +
 106.550 +            instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
 106.551 +            instr->immediate = get_immediate(realmode, opcode+1, instr->op_size);
 106.552 +            instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
 106.553 +
 106.554 +            return DECODE_success;
 106.555 +        } else
 106.556 +            return DECODE_failure;
 106.557 +
 106.558 +    case 0x0F:
 106.559 +        break;
 106.560 +
 106.561 +    default:
 106.562 +        printf("%x, This opcode isn't handled yet!\n", *opcode);
 106.563 +        return DECODE_failure;
 106.564 +    }
 106.565 +
 106.566 +    switch (*++opcode) {
 106.567 +    case 0xB6: /* movzx m8, r16/r32/r64 */
 106.568 +        instr->instr = INSTR_MOVZX;
 106.569 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.570 +        index = get_index(opcode + 1, rex);
 106.571 +        instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
 106.572 +        instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
 106.573 +        return DECODE_success;
 106.574 +
 106.575 +    case 0xB7: /* movzx m16/m32, r32/r64 */
 106.576 +        instr->instr = INSTR_MOVZX;
 106.577 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.578 +        index = get_index(opcode + 1, rex);
 106.579 +        if (rex & 0x8)
 106.580 +            instr->operand[0] = mk_operand(LONG, 0, 0, MEMORY);
 106.581 +        else
 106.582 +            instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
 106.583 +        instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
 106.584 +        return DECODE_success;
 106.585 +
 106.586 +    case 0xBE: /* movsx m8, r16/r32/r64 */
 106.587 +        instr->instr = INSTR_MOVSX;
 106.588 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.589 +        index = get_index(opcode + 1, rex);
 106.590 +        instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
 106.591 +        instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
 106.592 +        return DECODE_success;
 106.593 +
 106.594 +    case 0xBF: /* movsx m16, r32/r64 */
 106.595 +        instr->instr = INSTR_MOVSX;
 106.596 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
 106.597 +        index = get_index(opcode + 1, rex);
 106.598 +        instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
 106.599 +        instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
 106.600 +        return DECODE_success;
 106.601 +
 106.602 +    case 0xA3: /* bt r32, m32 */
 106.603 +        instr->instr = INSTR_BT;
 106.604 +        index = get_index(opcode + 1, rex);
 106.605 +        instr->op_size = LONG;
 106.606 +        instr->operand[0] = mk_operand(instr->op_size, index, 0, REGISTER);
 106.607 +        instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
 106.608 +        return DECODE_success;
 106.609 +
 106.610 +    default:
 106.611 +        printf("0f %x, This opcode isn't handled yet\n", *opcode);
 106.612 +        return DECODE_failure;
 106.613 +    }
 106.614 +}
 106.615 +
 106.616 +int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_len)
 106.617 +{
 106.618 +    if (inst_len > MAX_INST_LEN || inst_len <= 0)
 106.619 +        return 0;
 106.620 +    if (!hvm_copy(buf, guest_eip, inst_len, HVM_COPY_IN))
 106.621 +        return 0;
 106.622 +    return inst_len;
 106.623 +}
 106.624 +
 106.625 +void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
 106.626 +                  unsigned long count, int size, long value, int dir, int pvalid)
 106.627 +{
 106.628 +    struct vcpu *v = current;
 106.629 +    vcpu_iodata_t *vio;
 106.630 +    ioreq_t *p;
 106.631 +
 106.632 +    vio = get_vio(v->domain, v->vcpu_id);
 106.633 +    if (vio == NULL) {
 106.634 +        printk("bad shared page: %lx\n", (unsigned long) vio);
 106.635 +        domain_crash_synchronous();
 106.636 +    }
 106.637 +
 106.638 +    if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) {
 106.639 +        printf("HVM I/O has not yet completed\n");
 106.640 +        domain_crash_synchronous();
 106.641 +    }
 106.642 +    set_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
 106.643 +
 106.644 +    p = &vio->vp_ioreq;
 106.645 +    p->dir = dir;
 106.646 +    p->pdata_valid = pvalid;
 106.647 +
 106.648 +    p->type = IOREQ_TYPE_PIO;
 106.649 +    p->size = size;
 106.650 +    p->addr = port;
 106.651 +    p->count = count;
 106.652 +    p->df = regs->eflags & EF_DF ? 1 : 0;
 106.653 +
 106.654 +    if (pvalid) {
 106.655 +        if (hvm_paging_enabled(current))
 106.656 +            p->u.pdata = (void *) gva_to_gpa(value);
 106.657 +        else
 106.658 +            p->u.pdata = (void *) value; /* guest VA == guest PA */
 106.659 +    } else
 106.660 +        p->u.data = value;
 106.661 +
 106.662 +    if (hvm_portio_intercept(p)) {
 106.663 +        p->state = STATE_IORESP_READY;
 106.664 +        hvm_io_assist(v);
 106.665 +        return;
 106.666 +    }
 106.667 +
 106.668 +    p->state = STATE_IOREQ_READY;
 106.669 +
 106.670 +    evtchn_send(iopacket_port(v->domain));
 106.671 +    hvm_wait_io();
 106.672 +}
 106.673 +
 106.674 +void send_mmio_req(unsigned char type, unsigned long gpa,
 106.675 +                   unsigned long count, int size, long value, int dir, int pvalid)
 106.676 +{
 106.677 +    struct vcpu *v = current;
 106.678 +    vcpu_iodata_t *vio;
 106.679 +    ioreq_t *p;
 106.680 +    struct cpu_user_regs *regs;
 106.681 +    extern long evtchn_send(int lport);
 106.682 +
 106.683 +    regs = current->arch.hvm_vcpu.mmio_op.inst_decoder_regs;
 106.684 +
 106.685 +    vio = get_vio(v->domain, v->vcpu_id);
 106.686 +    if (vio == NULL) {
 106.687 +        printf("bad shared page\n");
 106.688 +        domain_crash_synchronous();
 106.689 +    }
 106.690 +
 106.691 +    p = &vio->vp_ioreq;
 106.692 +
 106.693 +    if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) {
 106.694 +        printf("HVM I/O has not yet completed\n");
 106.695 +        domain_crash_synchronous();
 106.696 +    }
 106.697 +
 106.698 +    set_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
 106.699 +    p->dir = dir;
 106.700 +    p->pdata_valid = pvalid;
 106.701 +
 106.702 +    p->type = type;
 106.703 +    p->size = size;
 106.704 +    p->addr = gpa;
 106.705 +    p->count = count;
 106.706 +    p->df = regs->eflags & EF_DF ? 1 : 0;
 106.707 +
 106.708 +    if (pvalid) {
 106.709 +        if (hvm_paging_enabled(v))
 106.710 +            p->u.pdata = (void *) gva_to_gpa(value);
 106.711 +        else
 106.712 +            p->u.pdata = (void *) value; /* guest VA == guest PA */
 106.713 +    } else
 106.714 +        p->u.data = value;
 106.715 +
 106.716 +    if (hvm_mmio_intercept(p)){
 106.717 +        p->state = STATE_IORESP_READY;
 106.718 +        hvm_io_assist(v);
 106.719 +        return;
 106.720 +    }
 106.721 +
 106.722 +    p->state = STATE_IOREQ_READY;
 106.723 +
 106.724 +    evtchn_send(iopacket_port(v->domain));
 106.725 +    hvm_wait_io();
 106.726 +}
 106.727 +
 106.728 +static void mmio_operands(int type, unsigned long gpa, struct instruction *inst,
 106.729 +                          struct mmio_op *mmio_opp, struct cpu_user_regs *regs)
 106.730 +{
 106.731 +    unsigned long value = 0;
 106.732 +    int index, size_reg;
 106.733 +
 106.734 +    size_reg = operand_size(inst->operand[0]);
 106.735 +
 106.736 +    mmio_opp->flags = inst->flags;
 106.737 +    mmio_opp->instr = inst->instr;
 106.738 +    mmio_opp->operand[0] = inst->operand[0]; /* source */
 106.739 +    mmio_opp->operand[1] = inst->operand[1]; /* destination */
 106.740 +    mmio_opp->immediate = inst->immediate;
 106.741 +
 106.742 +    if (inst->operand[0] & REGISTER) { /* dest is memory */
 106.743 +        index = operand_index(inst->operand[0]);
 106.744 +        value = get_reg_value(size_reg, index, 0, regs);
 106.745 +        send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0);
 106.746 +    } else if (inst->operand[0] & IMMEDIATE) { /* dest is memory */
 106.747 +        value = inst->immediate;
 106.748 +        send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0);
 106.749 +    } else if (inst->operand[0] & MEMORY) { /* dest is register */
 106.750 +        /* send the request and wait for the value */
 106.751 +        if ( (inst->instr == INSTR_MOVZX) || (inst->instr == INSTR_MOVSX) )
 106.752 +            send_mmio_req(type, gpa, 1, size_reg, 0, IOREQ_READ, 0);
 106.753 +        else
 106.754 +            send_mmio_req(type, gpa, 1, inst->op_size, 0, IOREQ_READ, 0);
 106.755 +    } else {
 106.756 +        printf("mmio_operands: invalid operand\n");
 106.757 +        domain_crash_synchronous();
 106.758 +    }
 106.759 +}
 106.760 +
 106.761 +#define GET_REPEAT_COUNT() \
 106.762 +     (mmio_inst.flags & REPZ ? (realmode ? regs->ecx & 0xFFFF : regs->ecx) : 1)
 106.763 +
 106.764 +void handle_mmio(unsigned long va, unsigned long gpa)
 106.765 +{
 106.766 +    unsigned long inst_len, inst_addr;
 106.767 +    struct mmio_op *mmio_opp;
 106.768 +    struct cpu_user_regs *regs;
 106.769 +    struct instruction mmio_inst;
 106.770 +    unsigned char inst[MAX_INST_LEN];
 106.771 +    int i, realmode, ret;
 106.772 +    struct vcpu *v = current;
 106.773 +
 106.774 +    mmio_opp = &v->arch.hvm_vcpu.mmio_op;
 106.775 +
 106.776 +    regs = mmio_opp->inst_decoder_regs;
 106.777 +    hvm_store_cpu_guest_regs(v, regs);
 106.778 +
 106.779 +    if ((inst_len = hvm_instruction_length(v)) <= 0) {
 106.780 +        printf("handle_mmio: failed to get instruction length\n");
 106.781 +        domain_crash_synchronous();
 106.782 +    }
 106.783 +
 106.784 +    realmode = hvm_realmode(v);
 106.785 +    if (realmode)
 106.786 +        inst_addr = (regs->cs << 4) + regs->eip;
 106.787 +    else
 106.788 +        inst_addr = regs->eip;
 106.789 +
 106.790 +    memset(inst, 0, MAX_INST_LEN);
 106.791 +    ret = inst_copy_from_guest(inst, inst_addr, inst_len);
 106.792 +    if (ret != inst_len) {
 106.793 +        printf("handle_mmio: failed to copy instruction\n");
 106.794 +        domain_crash_synchronous();
 106.795 +    }
 106.796 +
 106.797 +    init_instruction(&mmio_inst);
 106.798 +
 106.799 +    if (hvm_decode(realmode, inst, &mmio_inst) == DECODE_failure) {
 106.800 +        printf("handle_mmio: failed to decode instruction\n");
 106.801 +        printf("mmio opcode: va 0x%lx, gpa 0x%lx, len %ld:",
 106.802 +               va, gpa, inst_len);
 106.803 +        for (i = 0; i < inst_len; i++)
 106.804 +            printf(" %02x", inst[i] & 0xFF);
 106.805 +        printf("\n");
 106.806 +        domain_crash_synchronous();
 106.807 +    }
 106.808 +
 106.809 +    regs->eip += inst_len; /* advance %eip */
 106.810 +
 106.811 +    switch (mmio_inst.instr) {
 106.812 +    case INSTR_MOV:
 106.813 +        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
 106.814 +        break;
 106.815 +
 106.816 +    case INSTR_MOVS:
 106.817 +    {
 106.818 +        unsigned long count = GET_REPEAT_COUNT();
 106.819 +        unsigned long size = mmio_inst.op_size;
 106.820 +        int sign = regs->eflags & EF_DF ? -1 : 1;
 106.821 +        unsigned long addr = 0;
 106.822 +        int dir;
 106.823 +
 106.824 +        /* determine non-MMIO address */
 106.825 +        if (realmode) {
 106.826 +            if (((regs->es << 4) + (regs->edi & 0xFFFF)) == va) {
 106.827 +                dir = IOREQ_WRITE;
 106.828 +                addr = (regs->ds << 4) + (regs->esi & 0xFFFF);
 106.829 +            } else {
 106.830 +                dir = IOREQ_READ;
 106.831 +                addr = (regs->es << 4) + (regs->edi & 0xFFFF);
 106.832 +            }
 106.833 +        } else {
 106.834 +            if (va == regs->edi) {
 106.835 +                dir = IOREQ_WRITE;
 106.836 +                addr = regs->esi;
 106.837 +            } else {
 106.838 +                dir = IOREQ_READ;
 106.839 +                addr = regs->edi;
 106.840 +            }
 106.841 +        }
 106.842 +
 106.843 +        mmio_opp->flags = mmio_inst.flags;
 106.844 +        mmio_opp->instr = mmio_inst.instr;
 106.845 +
 106.846 +        /*
 106.847 +         * In case of a movs spanning multiple pages, we break the accesses
 106.848 +         * up into multiple pages (the device model works with non-continguous
 106.849 +         * physical guest pages). To copy just one page, we adjust %ecx and
 106.850 +         * do not advance %eip so that the next "rep movs" copies the next page.
 106.851 +         * Unaligned accesses, for example movsl starting at PGSZ-2, are
 106.852 +         * turned into a single copy where we handle the overlapping memory
 106.853 +         * copy ourself. After this copy succeeds, "rep movs" is executed
 106.854 +         * again.
 106.855 +         */
 106.856 +        if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
 106.857 +            unsigned long value = 0;
 106.858 +
 106.859 +            mmio_opp->flags |= OVERLAP;
 106.860 +
 106.861 +            regs->eip -= inst_len; /* do not advance %eip */
 106.862 +
 106.863 +            if (dir == IOREQ_WRITE)
 106.864 +                hvm_copy(&value, addr, size, HVM_COPY_IN);
 106.865 +            send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
 106.866 +        } else {
 106.867 +            if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) {
 106.868 +                regs->eip -= inst_len; /* do not advance %eip */
 106.869 +
 106.870 +                if (sign > 0)
 106.871 +                    count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
 106.872 +                else
 106.873 +                    count = (addr & ~PAGE_MASK) / size;
 106.874 +            }
 106.875 +
 106.876 +            send_mmio_req(IOREQ_TYPE_COPY, gpa, count, size, addr, dir, 1);
 106.877 +        }
 106.878 +        break;
 106.879 +    }
 106.880 +
 106.881 +    case INSTR_MOVZX:
 106.882 +    case INSTR_MOVSX:
 106.883 +        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
 106.884 +        break;
 106.885 +
 106.886 +    case INSTR_STOS:
 106.887 +        /*
 106.888 +         * Since the destination is always in (contiguous) mmio space we don't
 106.889 +         * need to break it up into pages.
 106.890 +         */
 106.891 +        mmio_opp->flags = mmio_inst.flags;
 106.892 +        mmio_opp->instr = mmio_inst.instr;
 106.893 +        send_mmio_req(IOREQ_TYPE_COPY, gpa,
 106.894 +                      GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax, IOREQ_WRITE, 0);
 106.895 +        break;
 106.896 +
 106.897 +    case INSTR_OR:
 106.898 +        mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mmio_opp, regs);
 106.899 +        break;
 106.900 +
 106.901 +    case INSTR_AND:
 106.902 +        mmio_operands(IOREQ_TYPE_AND, gpa, &mmio_inst, mmio_opp, regs);
 106.903 +        break;
 106.904 +
 106.905 +    case INSTR_XOR:
 106.906 +        mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mmio_opp, regs);
 106.907 +        break;
 106.908 +
 106.909 +    case INSTR_CMP:        /* Pass through */
 106.910 +    case INSTR_TEST:
 106.911 +        mmio_opp->flags = mmio_inst.flags;
 106.912 +        mmio_opp->instr = mmio_inst.instr;
 106.913 +        mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
 106.914 +        mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */
 106.915 +        mmio_opp->immediate = mmio_inst.immediate;
 106.916 +
 106.917 +        /* send the request and wait for the value */
 106.918 +        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1,
 106.919 +                      mmio_inst.op_size, 0, IOREQ_READ, 0);
 106.920 +        break;
 106.921 +
 106.922 +    case INSTR_BT: