[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.0.5-testing] Merge with xen-unstable for 3.0.5-rc4.
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1177752539 -3600 # Node ID 1668299c0ea4bbd530cdf67e71c64ff8baa10efb # Parent ee16cdeddade3ba0e826c85e84d10431edccdb15 # Parent 0f9b97523450aae06d42852bdac9bbca3d6033d1 Merge with xen-unstable for 3.0.5-rc4. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- tools/firmware/hvmloader/smbios.h | 38 - tools/xm-test/tests/network-attach/network_utils.py | 56 - xen/common/compat/acm_ops.c | 47 - docs/man/xm.pod.1 | 18 docs/xen-api/xenapi-coversheet.tex | 6 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c | 1 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 1 tools/blktap/drivers/block-qcow.c | 67 + tools/examples/init.d/xend | 12 tools/firmware/hvmloader/acpi/acpi2_0.h | 2 tools/firmware/hvmloader/config.h | 9 tools/firmware/hvmloader/hvmloader.c | 58 + tools/firmware/hvmloader/hypercall.h | 11 tools/firmware/hvmloader/smbios.c | 14 tools/firmware/hvmloader/util.c | 1 tools/firmware/hvmloader/util.h | 1 tools/firmware/rombios/rombios.c | 12 tools/ioemu/hw/pc.c | 11 tools/libxc/xc_core_x86.c | 8 tools/libxc/xc_dom_core.c | 4 tools/libxc/xc_domain_save.c | 2 tools/libxc/xc_hvm_build.c | 15 tools/libxen/Makefile | 4 tools/libxen/Makefile.dist | 4 tools/python/xen/xend/XendAPI.py | 347 ++------- tools/python/xen/xend/XendAPIStore.py | 59 + tools/python/xen/xend/XendAPIVersion.py | 4 tools/python/xen/xend/XendBase.py | 126 +++ tools/python/xen/xend/XendConfig.py | 10 tools/python/xen/xend/XendDomain.py | 6 tools/python/xen/xend/XendDomainInfo.py | 41 - tools/python/xen/xend/XendError.py | 120 +++ tools/python/xen/xend/XendNetwork.py | 175 ++++ tools/python/xen/xend/XendNode.py | 269 +++---- tools/python/xen/xend/XendPBD.py | 108 +- tools/python/xen/xend/XendPIF.py | 372 +++++++--- tools/python/xen/xend/XendPIFMetrics.py | 40 - tools/python/xen/xend/XendQCoWStorageRepo.py | 2 tools/python/xen/xend/XendStateStore.py | 65 - tools/python/xen/xend/XendStorageRepository.py | 2 tools/python/xen/xend/XendVMMetrics.py | 55 - tools/python/xen/xend/server/SrvServer.py | 2 tools/python/xen/xm/create.dtd | 9 tools/python/xen/xm/create.py | 7 tools/python/xen/xm/main.py | 130 +++ tools/python/xen/xm/messages/en/xen-xm.po | 24 tools/python/xen/xm/xenapi_create.py | 69 + tools/vnet/vnet-module/00README | 4 tools/vnet/vnet-module/Makefile.ver | 14 tools/vnet/vnet-module/varp.c | 5 tools/vnet/vnet-module/vnet.c | 9 tools/vnet/vnetd/Makefile | 4 tools/vnet/vnetd/sys_kernel.h | 1 tools/xenstore/xenstored_core.c | 2 tools/xm-test/lib/XmTestLib/network_utils.py | 60 + tools/xm-test/tests/network-attach/01_network_attach_pos.py | 2 tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py | 2 tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py | 2 tools/xm-test/tests/xapi/03_xapi-network_pos.py | 71 + tools/xm-test/tests/xapi/Makefile.am | 3 xen/Makefile | 2 xen/acm/acm_policy.c | 8 xen/arch/x86/domain.c | 87 +- xen/arch/x86/domain_build.c | 53 - xen/arch/x86/domctl.c | 8 xen/arch/x86/hvm/hvm.c | 4 xen/arch/x86/hvm/save.c | 2 xen/arch/x86/hvm/vmx/intr.c | 3 xen/arch/x86/hvm/vmx/vmcs.c | 86 +- xen/arch/x86/machine_kexec.c | 5 xen/arch/x86/mm.c | 67 - xen/arch/x86/mm/shadow/common.c | 14 xen/arch/x86/mm/shadow/multi.c | 35 xen/arch/x86/traps.c | 18 xen/arch/x86/x86_32/entry.S | 11 xen/arch/x86/x86_64/asm-offsets.c | 2 xen/arch/x86/x86_64/compat/entry.S | 26 xen/arch/x86/x86_64/entry.S | 30 xen/arch/x86/x86_64/mm.c | 6 xen/arch/x86/x86_64/traps.c | 7 xen/common/Makefile | 1 xen/common/acm_ops.c | 49 - xen/common/compat/grant_table.c | 4 xen/common/sched_credit.c | 4 xen/include/Makefile | 2 xen/include/acm/acm_core.h | 8 xen/include/asm-x86/desc.h | 4 xen/include/asm-x86/domain.h | 24 xen/include/asm-x86/hvm/vmx/vmcs.h | 2 xen/include/asm-x86/ldt.h | 2 xen/include/asm-x86/shadow.h | 10 xen/include/asm-x86/shared.h | 94 +- xen/include/asm-x86/x86_64/page.h | 4 xen/include/asm-x86/x86_64/regs.h | 10 xen/include/public/domctl.h | 6 xen/include/public/hvm/save.h | 7 xen/include/xen/sched.h | 8 xen/include/xen/shared.h | 20 xen/include/xlat.lst | 1 99 files changed, 2010 insertions(+), 1347 deletions(-) diff -r ee16cdeddade -r 1668299c0ea4 docs/man/xm.pod.1 --- a/docs/man/xm.pod.1 Wed Apr 25 10:39:08 2007 +0100 +++ b/docs/man/xm.pod.1 Sat Apr 28 10:28:59 2007 +0100 @@ -555,29 +555,29 @@ I<normal EDF (20ms/5ms):> I<normal EDF (20ms/5ms):> xm sched-sedf <dom-id> 20000000 5000000 0 0 0 - + I<best-effort domains (i.e. non-realtime):> xm sched-sedf <dom-id> 20000000 0 0 1 0 - + I<normal EDF (20ms/5ms) + share of extra-time:> - + xm sched-sedf <dom-id> 20000000 5000000 0 1 0 I<4 domains with weights 2:3:4:2> xm sched-sedf <d1> 0 0 0 0 2 - xm sched-sedf <d2> 0 0 0 0 3 - xm sched-sedf <d3> 0 0 0 0 4 - xm sched-sedf <d4> 0 0 0 0 2 + xm sched-sedf <d2> 0 0 0 0 3 + xm sched-sedf <d3> 0 0 0 0 4 + xm sched-sedf <d4> 0 0 0 0 2 I<1 fully-specified (10ms/3ms) domain, 3 other domains share available rest in 2:7:3 ratio:> - xm sched-sedf <d1> 10000000 3000000 0 0 0 - xm sched-sedf <d2> 0 0 0 0 2 + xm sched-sedf <d1> 10000000 3000000 0 0 0 + xm sched-sedf <d2> 0 0 0 0 2 xm sched-sedf <d3> 0 0 0 0 7 - xm sched-sedf <d4> 0 0 0 0 3 + xm sched-sedf <d4> 0 0 0 0 3 =back diff -r ee16cdeddade -r 1668299c0ea4 docs/xen-api/xenapi-coversheet.tex --- a/docs/xen-api/xenapi-coversheet.tex Wed Apr 25 10:39:08 2007 +0100 +++ b/docs/xen-api/xenapi-coversheet.tex Sat Apr 28 10:28:59 2007 +0100 @@ -17,12 +17,12 @@ \newcommand{\coversheetlogo}{xen.eps} %% Document date -\newcommand{\datestring}{21st April 2007} +\newcommand{\datestring}{27th April 2007} -\newcommand{\releasestatement}{Candidate for Release\\Comments are welcome!} +\newcommand{\releasestatement}{Stable Release} %% Document revision -\newcommand{\revstring}{API Revision 0.9.1} +\newcommand{\revstring}{API Revision 1.0.0} %% Document authors \newcommand{\docauthors}{ diff -r ee16cdeddade -r 1668299c0ea4 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Wed Apr 25 10:39:08 2007 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Sat Apr 28 10:28:59 2007 +0100 @@ -136,6 +136,7 @@ int blkif_map(blkif_t *blkif, unsigned l { unmap_frontend_page(blkif); free_vm_area(blkif->blk_ring_area); + blkif->blk_rings.common.sring = NULL; return err; } blkif->irq = err; diff -r ee16cdeddade -r 1668299c0ea4 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Wed Apr 25 10:39:08 2007 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Sat Apr 28 10:28:59 2007 +0100 @@ -137,6 +137,7 @@ int tap_blkif_map(blkif_t *blkif, unsign if (err < 0) { unmap_frontend_page(blkif); free_vm_area(blkif->blk_ring_area); + blkif->blk_rings.common.sring = NULL; return err; } blkif->irq = err; diff -r ee16cdeddade -r 1668299c0ea4 tools/blktap/drivers/block-qcow.c --- a/tools/blktap/drivers/block-qcow.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/blktap/drivers/block-qcow.c Sat Apr 28 10:28:59 2007 +0100 @@ -55,7 +55,6 @@ /******AIO DEFINES******/ #define REQUEST_ASYNC_FD 1 -#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ) struct pending_aio { td_callback_t cb; @@ -146,18 +145,37 @@ struct tdqcow_state { AES_KEY aes_encrypt_key; /*AES key*/ AES_KEY aes_decrypt_key; /*AES key*/ /* libaio state */ - io_context_t aio_ctx; - struct iocb iocb_list [MAX_AIO_REQS]; - struct iocb *iocb_free [MAX_AIO_REQS]; - struct pending_aio pending_aio[MAX_AIO_REQS]; - int iocb_free_count; - struct iocb *iocb_queue[MAX_AIO_REQS]; - int iocb_queued; - int poll_fd; /* NB: we require aio_poll support */ - struct io_event aio_events[MAX_AIO_REQS]; + io_context_t aio_ctx; + int max_aio_reqs; + struct iocb *iocb_list; + struct iocb **iocb_free; + struct pending_aio *pending_aio; + int iocb_free_count; + struct iocb **iocb_queue; + int iocb_queued; + int poll_fd; /* NB: we require aio_poll support */ + struct io_event *aio_events; }; static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset); + +static void free_aio_state(struct disk_driver *dd) +{ + struct tdqcow_state *s = (struct tdqcow_state *)dd->private; + + if (s->sector_lock) + free(s->sector_lock); + if (s->iocb_list) + free(s->iocb_list); + if (s->pending_aio) + free(s->pending_aio); + if (s->aio_events) + free(s->aio_events); + if (s->iocb_free) + free(s->iocb_free); + if (s->iocb_queue) + free(s->iocb_queue); +} static int init_aio_state(struct disk_driver *dd) { @@ -166,6 +184,12 @@ static int init_aio_state(struct disk_dr struct tdqcow_state *s = (struct tdqcow_state *)dd->private; long ioidx; + s->iocb_list = NULL; + s->pending_aio = NULL; + s->aio_events = NULL; + s->iocb_free = NULL; + s->iocb_queue = NULL; + /*Initialize Locking bitmap*/ s->sector_lock = calloc(1, bs->size); @@ -174,13 +198,26 @@ static int init_aio_state(struct disk_dr goto fail; } + /* A segment (i.e. a page) can span multiple clusters */ + s->max_aio_reqs = (getpagesize() / s->cluster_size) + 1; + /* Initialize AIO */ - s->iocb_free_count = MAX_AIO_REQS; + s->iocb_free_count = s->max_aio_reqs; s->iocb_queued = 0; + + if (!(s->iocb_list = malloc(sizeof(struct iocb) * s->max_aio_reqs)) || + !(s->pending_aio = malloc(sizeof(struct pending_aio) * s->max_aio_reqs)) || + !(s->aio_events = malloc(sizeof(struct io_event) * s->max_aio_reqs)) || + !(s->iocb_free = malloc(sizeof(struct iocb *) * s->max_aio_reqs)) || + !(s->iocb_queue = malloc(sizeof(struct iocb *) * s->max_aio_reqs))) { + DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n", + s->max_aio_reqs); + goto fail; + } /*Signal kernel to create Poll FD for Asyc completion events*/ s->aio_ctx = (io_context_t) REQUEST_ASYNC_FD; - s->poll_fd = io_setup(MAX_AIO_REQS, &s->aio_ctx); + s->poll_fd = io_setup(s->max_aio_reqs, &s->aio_ctx); if (s->poll_fd < 0) { if (s->poll_fd == -EAGAIN) { @@ -198,7 +235,7 @@ static int init_aio_state(struct disk_dr goto fail; } - for (i=0;i<MAX_AIO_REQS;i++) + for (i=0;i<s->max_aio_reqs;i++) s->iocb_free[i] = &s->iocb_list[i]; DPRINTF("AIO state initialised\n"); @@ -946,6 +983,7 @@ int tdqcow_open (struct disk_driver *dd, end_xenhdr: if (init_aio_state(dd)!=0) { DPRINTF("Unable to initialise AIO state\n"); + free_aio_state(dd); goto fail; } init_fds(dd); @@ -962,6 +1000,7 @@ int tdqcow_open (struct disk_driver *dd, fail: DPRINTF("QCOW Open failed\n"); + free_aio_state(dd); free(s->l1_table); free(s->l2_cache); free(s->cluster_cache); @@ -1145,7 +1184,7 @@ int tdqcow_do_callbacks(struct disk_driv if (sid > MAX_IOFD) return 1; /* Non-blocking test for completed io. */ - ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events, + ret = io_getevents(prv->aio_ctx, 0, prv->max_aio_reqs, prv->aio_events, NULL); for (ep = prv->aio_events, i = ret; i-- > 0; ep++) { diff -r ee16cdeddade -r 1668299c0ea4 tools/examples/init.d/xend --- a/tools/examples/init.d/xend Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/examples/init.d/xend Sat Apr 28 10:28:59 2007 +0100 @@ -6,6 +6,18 @@ # # chkconfig: 2345 98 01 # description: Starts and stops the Xen control daemon. +### BEGIN INIT INFO +# Provides: xend +# Required-Start: $syslog $remote_fs +# Should-Start: +# Required-Stop: $syslog $remote_fs +# Should-Stop: +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +# Default-Enabled: yes +# Short-Description: Start/stop xend +# Description: Starts and stops the Xen control daemon. +### END INIT INFO if ! grep -q "control_d" /proc/xen/capabilities ; then exit 0 diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/acpi/acpi2_0.h --- a/tools/firmware/hvmloader/acpi/acpi2_0.h Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Sat Apr 28 10:28:59 2007 +0100 @@ -394,8 +394,6 @@ struct acpi_20_madt_intsrcovr { #pragma pack () -#define ACPI_PHYSICAL_ADDRESS 0xEA000 - int acpi_build_tables(uint8_t *); #endif /* _ACPI_2_0_H_ */ diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/hvmloader/config.h Sat Apr 28 10:28:59 2007 +0100 @@ -17,5 +17,14 @@ #define ROMBIOS_MAXOFFSET 0x0000FFFF #define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE) +/* Memory map. */ +#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 +#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000 +#define ETHERBOOT_PHYSICAL_ADDRESS 0x000C8000 +#define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000 +#define SMBIOS_PHYSICAL_ADDRESS 0x000E9000 +#define SMBIOS_MAXIMUM_SIZE 0x00001000 +#define ACPI_PHYSICAL_ADDRESS 0x000EA000 +#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 #endif /* __HVMLOADER_CONFIG_H__ */ diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Sat Apr 28 10:28:59 2007 +0100 @@ -19,23 +19,16 @@ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. */ + #include "roms.h" -#include "acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */ +#include "acpi/acpi2_0.h" #include "hypercall.h" #include "util.h" -#include "smbios.h" #include "config.h" #include "apic_regs.h" #include "pci_regs.h" #include <xen/version.h> #include <xen/hvm/params.h> - -/* memory map */ -#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 -#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000 -#define ETHERBOOT_PHYSICAL_ADDRESS 0x000C8000 -#define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000 -#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 asm( " .text \n" @@ -103,7 +96,8 @@ asm( "stack_top: \n" ); -extern void create_mp_tables(void); +void create_mp_tables(void); +int hvm_write_smbios_tables(void); static int cirrus_check(void) @@ -351,17 +345,20 @@ static void cmos_write_memory_size(void) int main(void) { - int acpi_sz; + int acpi_sz = 0, vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz; printf("HVM Loader\n"); init_hypercalls(); printf("Writing SMBIOS tables ...\n"); - hvm_write_smbios_tables(); + smbios_sz = hvm_write_smbios_tables(); printf("Loading ROMBIOS ...\n"); - memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios)); + rombios_sz = sizeof(rombios); + if ( rombios_sz > 0x10000 ) + rombios_sz = 0x10000; + memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz); highbios_setup(); apic_setup(); @@ -375,12 +372,14 @@ int main(void) printf("Loading Cirrus VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_cirrusvga, sizeof(vgabios_cirrusvga)); + vgabios_sz = sizeof(vgabios_cirrusvga); } else { printf("Loading Standard VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_stdvga, sizeof(vgabios_stdvga)); + vgabios_sz = sizeof(vgabios_stdvga); } if ( must_load_nic() ) @@ -388,9 +387,10 @@ int main(void) printf("Loading ETHERBOOT ...\n"); memcpy((void *)ETHERBOOT_PHYSICAL_ADDRESS, etherboot, sizeof(etherboot)); - } - - if ( get_acpi_enabled() != 0 ) + etherboot_sz = sizeof(etherboot); + } + + if ( get_acpi_enabled() ) { printf("Loading ACPI ...\n"); acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS); @@ -398,6 +398,32 @@ int main(void) } cmos_write_memory_size(); + + printf("BIOS map:\n"); + if ( vgabios_sz ) + printf(" %05x-%05x: VGA BIOS\n", + VGABIOS_PHYSICAL_ADDRESS, + VGABIOS_PHYSICAL_ADDRESS + vgabios_sz - 1); + if ( etherboot_sz ) + printf(" %05x-%05x: Etherboot ROM\n", + ETHERBOOT_PHYSICAL_ADDRESS, + ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1); + if ( !check_amd() ) + printf(" %05x-%05x: VMXAssist\n", + VMXASSIST_PHYSICAL_ADDRESS, + VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1); + if ( smbios_sz ) + printf(" %05x-%05x: SMBIOS tables\n", + SMBIOS_PHYSICAL_ADDRESS, + SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1); + if ( acpi_sz ) + printf(" %05x-%05x: ACPI tables\n", + ACPI_PHYSICAL_ADDRESS, + ACPI_PHYSICAL_ADDRESS + acpi_sz - 1); + if ( rombios_sz ) + printf(" %05x-%05x: Main BIOS\n", + ROMBIOS_PHYSICAL_ADDRESS, + ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1); if ( !check_amd() ) { diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/hypercall.h --- a/tools/firmware/hvmloader/hypercall.h Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/hvmloader/hypercall.h Sat Apr 28 10:28:59 2007 +0100 @@ -31,17 +31,18 @@ #ifndef __HVMLOADER_HYPERCALL_H__ #define __HVMLOADER_HYPERCALL_H__ +#include <stdint.h> #include <xen/xen.h> +#include "config.h" + +#define __STR(...) #__VA_ARGS__ +#define STR(...) __STR(__VA_ARGS__) /* * NB. Hypercall address needs to be relative to a linkage symbol for * some version of ld to relocate the relative calls properly. - * Keep this in sync with HYPERCALL_PHYSICAL_ADDRESS in hvmloader.c! */ -#define hypercall_pa "_start - 0x80000" - -#define __STR(x) #x -#define STR(x) __STR(x) +#define hypercall_pa "_start - " STR(HYPERCALL_PHYSICAL_ADDRESS) #define _hypercall0(type, name) \ ({ \ diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/hvmloader/smbios.c Sat Apr 28 10:28:59 2007 +0100 @@ -22,12 +22,11 @@ #include <stdint.h> #include <xen/version.h> -#include "smbios.h" #include "smbios_types.h" #include "util.h" #include "hypercall.h" -static size_t +static int write_smbios_tables(void *start, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, @@ -82,7 +81,7 @@ get_cpu_manufacturer(char *buf, int len) strncpy(buf, "unknown", len); } -static size_t +static int write_smbios_tables(void *start, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, @@ -125,7 +124,7 @@ write_smbios_tables(void *start, SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point), nr_structs); - return (size_t)((char *)p - (char *)start); + return ((char *)p - (char *)start); } /* Calculate how much pseudo-physical memory (in MB) is allocated to us. */ @@ -156,7 +155,7 @@ get_memsize(void) return (memsize + (1 << 20) - 1) >> 20; } -void +int hvm_write_smbios_tables(void) { uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is @@ -221,16 +220,17 @@ hvm_write_smbios_tables(void) get_vcpu_nr(), get_memsize(), uuid, xen_version_str, xen_major_version, xen_minor_version); - if ( len > SMBIOS_SIZE_LIMIT ) + if ( len > SMBIOS_MAXIMUM_SIZE ) goto error_out; /* Okay, not too large: copy out of scratch to final location. */ memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len); - return; + return len; error_out: printf("Could not write SMBIOS tables, error in hvmloader.c:" "hvm_write_smbios_tables()\n"); + return 0; } diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/smbios.h --- a/tools/firmware/hvmloader/smbios.h Wed Apr 25 10:39:08 2007 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * smbios.h - interface for Xen HVM SMBIOS generation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) IBM Corporation, 2006 - * - * Authors: Andrew D. Ball <aball@xxxxxxxxxx> - */ - -#ifndef SMBIOS_H -#define SMBIOS_H - -#include <stdint.h> -#include <stdlib.h> - -/* These constants must agree with the ACPI e820 memory map as defined - in tools/libxc/xc_hvm_build.c and the address the ROMBIOS pulls the - SMBIOS entry point from in the smbios_init subroutine. - */ -#define SMBIOS_PHYSICAL_ADDRESS 0x9f000 -#define SMBIOS_SIZE_LIMIT 0x800 - -void hvm_write_smbios_tables(void); - -#endif /* SMBIOS_H */ diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/hvmloader/util.c Sat Apr 28 10:28:59 2007 +0100 @@ -18,7 +18,6 @@ * Place - Suite 330, Boston, MA 02111-1307 USA. */ -#include "acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */ #include "util.h" #include "config.h" #include <stdint.h> diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/hvmloader/util.h Sat Apr 28 10:28:59 2007 +0100 @@ -2,6 +2,7 @@ #define __HVMLOADER_UTIL_H__ #include <stdarg.h> +#include <stdint.h> #undef offsetof #define offsetof(t, m) ((unsigned long)&((t *)0)->m) diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/firmware/rombios/rombios.c Sat Apr 28 10:28:59 2007 +0100 @@ -25,6 +25,8 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // ROM BIOS for use with Bochs/Plex x86 emulation environment + +#include "../hvmloader/config.h" #define HVMASSIST #undef HVMTEST @@ -9409,9 +9411,9 @@ rom_scan_increment: #ifdef HVMASSIST -; Copy the SMBIOS entry point over from 0x9f000, where hvmloader left it. +; Copy the SMBIOS entry point from where hvmloader left it. ; The entry point must be somewhere in 0xf0000-0xfffff on a 16-byte boundary, -; but the tables themeselves can be elsewhere. +; but the tables themselves can be elsewhere. smbios_init: push ax push cx @@ -9424,9 +9426,9 @@ smbios_init: mov ax, #0xf000 mov es, ax ; destination segment is 0xf0000 mov di, #smbios_entry_point ; destination offset - mov ax, #0x9f00 - mov ds, ax ; source segment is 0x9f000 - mov si, #0x0000 ; source offset is 0 + mov ax, #(SMBIOS_PHYSICAL_ADDRESS>>4) + mov ds, ax + mov si, #(SMBIOS_PHYSICAL_ADDRESS&15) cld rep movsb diff -r ee16cdeddade -r 1668299c0ea4 tools/ioemu/hw/pc.c --- a/tools/ioemu/hw/pc.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/ioemu/hw/pc.c Sat Apr 28 10:28:59 2007 +0100 @@ -922,12 +922,13 @@ static void pc_init1(uint64_t ram_size, #endif #else if (pci_enabled) { - void *scsi; - - scsi = lsi_scsi_init(pci_bus, -1); + void *scsi = NULL; for (i = 0; i < MAX_SCSI_DISKS ; i++) { - if (bs_table[i + MAX_DISKS]) - lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1); + if (!bs_table[i + MAX_DISKS]) + continue; + if (!scsi) + scsi = lsi_scsi_init(pci_bus, -1); + lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1); } } #endif /* !CONFIG_DM */ diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_core_x86.c --- a/tools/libxc/xc_core_x86.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/libxc/xc_core_x86.c Sat Apr 28 10:28:59 2007 +0100 @@ -21,9 +21,9 @@ #include "xg_private.h" #include "xc_core.h" -static int max_gpfn(int xc_handle, domid_t domid) +static int nr_gpfns(int xc_handle, domid_t domid) { - return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid); + return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid) + 1; } int @@ -38,7 +38,7 @@ xc_core_arch_memory_map_get(int xc_handl xc_core_memory_map_t **mapp, unsigned int *nr_entries) { - unsigned long p2m_size = max_gpfn(xc_handle, info->domid); + unsigned long p2m_size = nr_gpfns(xc_handle, info->domid); xc_core_memory_map_t *map; map = malloc(sizeof(*map)); @@ -65,7 +65,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d xen_pfn_t *live_p2m_frame_list_list = NULL; xen_pfn_t *live_p2m_frame_list = NULL; uint32_t dom = info->domid; - unsigned long p2m_size = max_gpfn(xc_handle, info->domid); + unsigned long p2m_size = nr_gpfns(xc_handle, info->domid); int ret = -1; int err; diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_dom_core.c --- a/tools/libxc/xc_dom_core.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/libxc/xc_dom_core.c Sat Apr 28 10:28:59 2007 +0100 @@ -209,13 +209,13 @@ size_t xc_dom_check_gzip(void *blob, siz unsigned char *gzlen; size_t unziplen; - if (strncmp(blob, "\037\213", 2)) + if ( strncmp(blob, "\037\213", 2) ) /* not gzipped */ return 0; gzlen = blob + ziplen - 4; unziplen = gzlen[3] << 24 | gzlen[2] << 16 | gzlen[1] << 8 | gzlen[0]; - if ( (unziplen < ziplen) || (unziplen > (ziplen * 8)) ) + if ( (unziplen < 0) || (unziplen > (1024*1024*1024)) ) /* 1GB limit */ { xc_dom_printf ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n", diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_domain_save.c --- a/tools/libxc/xc_domain_save.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/libxc/xc_domain_save.c Sat Apr 28 10:28:59 2007 +0100 @@ -870,7 +870,7 @@ int xc_domain_save(int xc_handle, int io } /* Get the size of the P2M table */ - p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom); + p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom) + 1; /* Domain is still running at this point */ if ( live ) diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/libxc/xc_hvm_build.c Sat Apr 28 10:28:59 2007 +0100 @@ -47,20 +47,15 @@ static void build_e820map(void *e820_pag mem_size = HVM_BELOW_4G_RAM_END; } - /* 0x0-0x9F000: Ordinary RAM. */ + /* 0x0-0x9FC00: Ordinary RAM. */ e820entry[nr_map].addr = 0x0; - e820entry[nr_map].size = 0x9F000; + e820entry[nr_map].size = 0x9FC00; e820entry[nr_map].type = E820_RAM; nr_map++; - /* - * 0x9F000-0x9F800: SMBIOS tables. - * 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA). - * TODO: SMBIOS tables should be moved higher (>=0xE0000). - * They are unusually low in our memory map: could cause problems? - */ - e820entry[nr_map].addr = 0x9F000; - e820entry[nr_map].size = 0x1000; + /* 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA). */ + e820entry[nr_map].addr = 0x9FC00; + e820entry[nr_map].size = 0x400; e820entry[nr_map].type = E820_RESERVED; nr_map++; diff -r ee16cdeddade -r 1668299c0ea4 tools/libxen/Makefile --- a/tools/libxen/Makefile Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/libxen/Makefile Sat Apr 28 10:28:59 2007 +0100 @@ -18,8 +18,8 @@ XEN_ROOT=../.. XEN_ROOT=../.. include $(XEN_ROOT)/tools/Rules.mk -MAJOR = 0.9 -MINOR = 1 +MAJOR = 1.0 +MINOR = 0 CFLAGS = -Iinclude \ $(shell xml2-config --cflags) \ diff -r ee16cdeddade -r 1668299c0ea4 tools/libxen/Makefile.dist --- a/tools/libxen/Makefile.dist Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/libxen/Makefile.dist Sat Apr 28 10:28:59 2007 +0100 @@ -16,8 +16,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -MAJOR = 0.9 -MINOR = 1 +MAJOR = 1.0 +MINOR = 0 CFLAGS = -Iinclude \ $(shell xml2-config --cflags) \ diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendAPI.py Sat Apr 28 10:28:59 2007 +0100 @@ -27,7 +27,7 @@ import xmlrpclib import xmlrpclib import XendDomain, XendDomainInfo, XendNode, XendDmesg -import XendLogging, XendTaskManager +import XendLogging, XendTaskManager, XendAPIStore from XendAPIVersion import * from XendAuthSessions import instance as auth_manager @@ -38,8 +38,8 @@ from XendTask import XendTask from XendTask import XendTask from XendPIFMetrics import XendPIFMetrics from XendVMMetrics import XendVMMetrics - -import XendPBD +from XendPIF import XendPIF +from XendPBD import XendPBD from XendAPIConstants import * from xen.util.xmlrpclib2 import stringify @@ -237,6 +237,8 @@ def catch_typeerror(func): finally: del tb raise + except XendAPIError, exn: + return xen_api_error(exn.get_api_error()) return f @@ -307,26 +309,6 @@ def valid_vm(func): _check_ref(XendDomain.instance().is_valid_vm, 'VM', func, *args, **kwargs) -def valid_vm_metrics(func): - """Decorator to verify if vm_metrics_ref is valid before calling method. - - @param func: function with params: (self, session, vm_metrics_ref, ...) - @rtype: callable object - """ - return lambda *args, **kwargs: \ - _check_ref(XendVMMetrics.is_valid_vm_metrics, - 'VM_metrics', func, *args, **kwargs) - -def valid_network(func): - """Decorator to verify if network_ref is valid before calling method. - - @param func: function with params: (self, session, network_ref, ...) - @rtype: callable object - """ - return lambda *args, **kwargs: \ - _check_ref(XendNode.instance().is_valid_network, - 'network', func, *args, **kwargs) - def valid_vbd(func): """Decorator to verify if vbd_ref is valid before calling method. @@ -409,39 +391,6 @@ def valid_sr(func): _check_ref(lambda r: XendNode.instance().is_valid_sr, 'SR', func, *args, **kwargs) -def valid_pbd(func): - """Decorator to verify if pbd_ref is valid before calling - method. - - @param func: function with params: (self, session, pbd_ref) - @rtype: callable object - """ - return lambda *args, **kwargs: \ - _check_ref(lambda r: r in XendPBD.get_all_refs(), - 'PBD', func, *args, **kwargs) - -def valid_pif(func): - """Decorator to verify if pif_ref is valid before calling - method. - - @param func: function with params: (self, session, pif_ref) - @rtype: callable object - """ - return lambda *args, **kwargs: \ - _check_ref(lambda r: r in XendNode.instance().pifs, - 'PIF', func, *args, **kwargs) - -def valid_pif_metrics(func): - """Decorator to verify if pif_metrics_ref is valid before calling - method. - - @param func: function with params: (self, session, pif_metrics_ref) - @rtype: callable object - """ - return lambda *args, **kwargs: \ - _check_ref(lambda r: r in XendNode.instance().pif_metrics, - 'PIF_metrics', func, *args, **kwargs) - def valid_task(func): """Decorator to verify if task_ref is valid before calling method. @@ -463,6 +412,20 @@ def valid_debug(func): return lambda *args, **kwargs: \ _check_ref(lambda r: r in XendAPI._debug, 'debug', func, *args, **kwargs) + + +def valid_object(class_name): + """Decorator to verify if object is valid before calling + method. + + @param func: function with params: (self, session, pif_ref) + @rtype: callable object + """ + return lambda func: \ + lambda *args, **kwargs: \ + _check_ref(lambda r: \ + XendAPIStore.get(r, class_name) is not None, + 'PIF', func, *args, **kwargs) # ----------------------------- # Bridge to Legacy XM API calls @@ -494,9 +457,7 @@ classes = { 'host' : valid_host, 'host_cpu' : valid_host_cpu, 'host_metrics' : valid_host_metrics, - 'network' : valid_network, 'VM' : valid_vm, - 'VM_metrics' : valid_vm_metrics, 'VBD' : valid_vbd, 'VBD_metrics' : valid_vbd_metrics, 'VIF' : valid_vif, @@ -505,20 +466,22 @@ classes = { 'VTPM' : valid_vtpm, 'console' : valid_console, 'SR' : valid_sr, - 'PBD' : valid_pbd, - 'PIF' : valid_pif, - 'PIF_metrics' : valid_pif_metrics, 'task' : valid_task, 'debug' : valid_debug, + 'network' : valid_object("network"), + 'PIF' : valid_object("PIF"), + 'VM_metrics' : valid_object("VM_metrics"), + 'PBD' : valid_object("PBD"), + 'PIF_metrics' : valid_object("PIF_metrics") } autoplug_classes = { 'network' : XendNetwork, + 'PIF' : XendPIF, 'VM_metrics' : XendVMMetrics, - 'PBD' : XendPBD.XendPBD, + 'PBD' : XendPBD, 'PIF_metrics' : XendPIFMetrics, } - class XendAPI(object): """Implementation of the Xen-API in Xend. Expects to be @@ -570,7 +533,9 @@ class XendAPI(object): # all get_by_uuid() methods. for api_cls in classes.keys(): - if api_cls == 'session': + # We'll let the autoplug classes implement these functions + # themselves - its much cleaner to do it in the base class + if api_cls == 'session' or api_cls in autoplug_classes.keys(): continue get_by_uuid = '%s_get_by_uuid' % api_cls @@ -588,8 +553,8 @@ class XendAPI(object): def _get_all_records(_api_cls): return lambda s, session: \ - xen_api_success([unpack(getattr(cls, '%s_get_record' % _api_cls)(s, session, ref))\ - for ref in unpack(getattr(cls, '%s_get_all' % _api_cls)(s, session))]) + xen_api_success(dict([(ref, unpack(getattr(cls, '%s_get_record' % _api_cls)(s, session, ref)))\ + for ref in unpack(getattr(cls, '%s_get_all' % _api_cls)(s, session))])) setattr(cls, get_by_uuid, _get_by_uuid) setattr(cls, get_uuid, _get_uuid) @@ -599,34 +564,48 @@ class XendAPI(object): # -------------------- # These have all of their methods grabbed out from the implementation # class, and wrapped up to be compatible with the Xen-API. + + def getter(ref, type): + return XendAPIStore.get(ref, type) for api_cls, impl_cls in autoplug_classes.items(): - def doit(n): - getter = getattr(cls, '_%s_get' % api_cls) + def doit(n): dot_n = '%s.%s' % (api_cls, n) full_n = '%s_%s' % (api_cls, n) if not hasattr(cls, full_n): f = getattr(impl_cls, n) argcounts[dot_n] = f.func_code.co_argcount + 1 - setattr(cls, full_n, + g = lambda api_cls: \ + setattr(cls, full_n, \ lambda s, session, ref, *args: \ xen_api_success( \ - f(getter(s, session, ref), *args))) - - ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) - rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) - methods = getattr(cls, '%s_methods' % api_cls, []) - funcs = getattr(cls, '%s_funcs' % api_cls, []) + f(getter(ref, api_cls), *args))) + g(api_cls) # Force api_cls to be captured + + def doit_func(n): + dot_n = '%s.%s' % (api_cls, n) + full_n = '%s_%s' % (api_cls, n) + if not hasattr(cls, full_n): + f = getattr(impl_cls, n) + argcounts[dot_n] = f.func_code.co_argcount + setattr(cls, full_n, \ + lambda s, session, *args: \ + xen_api_success( \ + f(*args))) + + ro_attrs = impl_cls.getAttrRO() + rw_attrs = impl_cls.getAttrRW() + methods = impl_cls.getMethods() + funcs = impl_cls.getFuncs() for attr_name in ro_attrs + rw_attrs: doit('get_%s' % attr_name) - for attr_name in rw_attrs + cls.Base_attr_rw: + for attr_name in rw_attrs: doit('set_%s' % attr_name) - for method_name, return_type in methods + cls.Base_methods: - doit('%s' % method_name) - for func_name, return_type in funcs + cls.Base_funcs: - doit('%s' % func_name) - + for method in methods: + doit('%s' % method) + for func in funcs: + doit_func('%s' % func) def wrap_method(name, new_f): try: @@ -692,31 +671,42 @@ class XendAPI(object): except AttributeError: log.warn("API call: %s not found" % n) - - ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) - rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) - methods = getattr(cls, '%s_methods' % api_cls, []) - funcs = getattr(cls, '%s_funcs' % api_cls, []) + if api_cls in autoplug_classes.keys(): + impl_cls = autoplug_classes[api_cls] + ro_attrs = impl_cls.getAttrRO() + rw_attrs = impl_cls.getAttrRW() + methods = map(lambda x: (x, ""), impl_cls.getMethods()) + funcs = map(lambda x: (x, ""), impl_cls.getFuncs()) + else: + ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) \ + + cls.Base_attr_ro + rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) \ + + cls.Base_attr_rw + methods = getattr(cls, '%s_methods' % api_cls, []) \ + + cls.Base_methods + funcs = getattr(cls, '%s_funcs' % api_cls, []) \ + + cls.Base_funcs # wrap validators around readable class attributes - for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro: + for attr_name in ro_attrs + rw_attrs: doit('%s.get_%s' % (api_cls, attr_name), True, async_support = False) # wrap validators around writable class attrributes - for attr_name in rw_attrs + cls.Base_attr_rw: + for attr_name in rw_attrs: doit('%s.set_%s' % (api_cls, attr_name), True, async_support = False) setter_event_wrapper(api_cls, attr_name) # wrap validators around methods - for method_name, return_type in methods + cls.Base_methods: + for method_name, return_type in methods: doit('%s.%s' % (api_cls, method_name), True, async_support = True) # wrap validators around class functions - for func_name, return_type in funcs + cls.Base_funcs: - doit('%s.%s' % (api_cls, func_name), False, async_support = True, + for func_name, return_type in funcs: + doit('%s.%s' % (api_cls, func_name), False, + async_support = True, return_type = return_type) ctor_event_wrapper(api_cls) @@ -952,7 +942,7 @@ class XendAPI(object): def host_get_resident_VMs(self, session, host_ref): return xen_api_success(XendDomain.instance().get_domain_refs()) def host_get_PBDs(self, _, ref): - return xen_api_success(XendPBD.get_all_refs()) + return xen_api_success(XendPBD.get_all()) def host_get_PIFs(self, session, ref): return xen_api_success(XendNode.instance().get_PIF_refs()) def host_get_host_CPUs(self, session, host_ref): @@ -1130,130 +1120,6 @@ class XendAPI(object): def _host_metrics_get_memory_free(self): node = XendNode.instance() return node.xc.physinfo()['free_memory'] * 1024 - - - # Xen API: Class network - # ---------------------------------------------------------------- - - network_attr_ro = ['VIFs', 'PIFs'] - network_attr_rw = ['name_label', - 'name_description', - 'other_config'] - network_methods = [('add_to_other_config', None), - ('remove_from_other_config', None), - ('destroy', None)] - network_funcs = [('create', None)] - - def _network_get(self, _, ref): - return XendNode.instance().get_network(ref) - - def network_get_all(self, _): - return xen_api_success(XendNode.instance().get_network_refs()) - - def network_create(self, _, record): - return xen_api_success(XendNode.instance().network_create(record)) - - def network_destroy(self, _, ref): - return xen_api_success(XendNode.instance().network_destroy(ref)) - - - # Xen API: Class PIF - # ---------------------------------------------------------------- - - PIF_attr_ro = ['network', - 'host', - 'metrics'] - PIF_attr_rw = ['device', - 'MAC', - 'MTU', - 'VLAN'] - - PIF_attr_inst = PIF_attr_rw - - PIF_methods = [('create_VLAN', 'int'), ('destroy', None)] - - def _get_PIF(self, ref): - return XendNode.instance().pifs[ref] - - def PIF_destroy(self, _, ref): - try: - return xen_api_success(XendNode.instance().PIF_destroy(ref)) - except PIFIsPhysical, exn: - return xen_api_error(['PIF_IS_PHYSICAL', ref]) - - # object methods - def PIF_get_record(self, _, ref): - return xen_api_success(self._get_PIF(ref).get_record()) - - def PIF_get_all(self, _): - return xen_api_success(XendNode.instance().pifs.keys()) - - def PIF_get_metrics(self, _, ref): - return xen_api_success(self._get_PIF(ref).metrics.uuid) - - def PIF_get_device(self, _, ref): - return xen_api_success(self._get_PIF(ref).device) - - def PIF_get_network(self, _, ref): - return xen_api_success(self._get_PIF(ref).network.uuid) - - def PIF_get_host(self, _, ref): - return xen_api_success(self._get_PIF(ref).host.uuid) - - def PIF_get_MAC(self, _, ref): - return xen_api_success(self._get_PIF(ref).mac) - - def PIF_get_MTU(self, _, ref): - return xen_api_success(self._get_PIF(ref).mtu) - - def PIF_get_VLAN(self, _, ref): - return xen_api_success(self._get_PIF(ref).vlan) - - def PIF_set_device(self, _, ref, device): - return xen_api_success(self._get_PIF(ref).set_device(device)) - - def PIF_set_MAC(self, _, ref, mac): - return xen_api_success(self._get_PIF(ref).set_mac(mac)) - - def PIF_set_MTU(self, _, ref, mtu): - return xen_api_success(self._get_PIF(ref).set_mtu(mtu)) - - def PIF_create_VLAN(self, _, ref, network, vlan): - try: - vlan = int(vlan) - except: - return xen_api_error(['VLAN_TAG_INVALID', vlan]) - - try: - node = XendNode.instance() - - if _is_valid_ref(network, node.is_valid_network): - return xen_api_success( - node.PIF_create_VLAN(ref, network, vlan)) - else: - return xen_api_error(['HANDLE_INVALID', 'network', network]) - except NetworkAlreadyConnected, exn: - return xen_api_error(['NETWORK_ALREADY_CONNECTED', - network, exn.pif_uuid]) - except VLANTagInvalid: - return xen_api_error(['VLAN_TAG_INVALID', vlan]) - - - # Xen API: Class PIF_metrics - # ---------------------------------------------------------------- - - PIF_metrics_attr_ro = ['io_read_kbs', - 'io_write_kbs', - 'last_updated'] - PIF_metrics_attr_rw = [] - PIF_metrics_methods = [] - - def PIF_metrics_get_all(self, _): - return xen_api_success(XendNode.instance().pif_metrics.keys()) - - def _PIF_metrics_get(self, _, ref): - return XendNode.instance().pif_metrics[ref] - # Xen API: Class VM # ---------------------------------------------------------------- @@ -1865,28 +1731,6 @@ class XendAPI(object): return xen_api_success_void() - # Xen API: Class VM_metrics - # ---------------------------------------------------------------- - - VM_metrics_attr_ro = ['memory_actual', - 'VCPUs_number', - 'VCPUs_utilisation', - 'VCPUs_CPU', - 'VCPUs_flags', - 'VCPUs_params', - 'state', - 'start_time', - 'last_updated'] - VM_metrics_attr_rw = [] - VM_metrics_methods = [] - - def _VM_metrics_get(self, _, ref): - return XendVMMetrics.get_by_uuid(ref) - - def VM_metrics_get_all(self, _): - return xen_api_success(XendVMMetrics.get_all()) - - # Xen API: Class VBD # ---------------------------------------------------------------- @@ -2570,33 +2414,6 @@ class XendAPI(object): return xen_api_success_void() - # Xen API: Class PBD - # ---------------------------------------------------------------- - - PBD_attr_ro = ['host', - 'SR', - 'device_config', - 'currently_attached'] - PBD_attr_rw = [] - PBD_methods = [('destroy', None)] - PBD_funcs = [('create', None)] - - def PBD_get_all(self, _): - return xen_api_success(XendPBD.get_all_refs()) - - def _PBD_get(self, _, ref): - return XendPBD.get(ref) - - def PBD_create(self, _, record): - if 'uuid' in record: - return xen_api_error(['VALUE_NOT_SUPPORTED', - 'uuid', record['uuid'], - 'You may not specify a UUID on creation']) - new_uuid = XendPBD.XendPBD(record).get_uuid() - XendNode.instance().save() - return xen_api_success(new_uuid) - - # Xen API: Class event # ---------------------------------------------------------------- diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPIStore.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/xend/XendAPIStore.py Sat Apr 28 10:28:59 2007 +0100 @@ -0,0 +1,59 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2007 Tom Wilkie <tom.wilkie@xxxxxxxxx> +#============================================================================ +""" +This is a place to put instances of XenAPI objects, +instead of just holding them in arbitrary places. + +All objects which subclass XendBase should use this +mechanism. + +You must register both the uuid and type, and get objects +by type, to ensure safety +""" + +__classes = {} + +def register(uuid, type, inst): + __classes[(uuid, type)] = inst + return inst + +def deregister(uuid, type): + old = get(uuid, type) + del __classes[(uuid, type)] + return old + +def get(uuid, type): + """ + Get the instances by uuid and type + """ + return __classes.get((uuid, type), None) + +def get_all(all_type): + """ + Get all instances by type + """ + return [inst + for ((uuid, t), inst) in __classes.items() + if t == all_type] + +def get_all_uuid(all_type): + """ + Get all uuids by type + """ + return [uuid + for (uuid, t) in __classes.keys() + if t == all_type] diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPIVersion.py --- a/tools/python/xen/xend/XendAPIVersion.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendAPIVersion.py Sat Apr 28 10:28:59 2007 +0100 @@ -16,7 +16,7 @@ #============================================================================ -XEN_API_VERSION_MAJOR = 0 -XEN_API_VERSION_MINOR = 5 +XEN_API_VERSION_MAJOR = 1 +XEN_API_VERSION_MINOR = 0 XEN_API_VERSION_VENDOR = 'xenbits' XEN_API_VERSION_VENDOR_IMPLEMENTATION = {} diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendBase.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/xend/XendBase.py Sat Apr 28 10:28:59 2007 +0100 @@ -0,0 +1,126 @@ +#!/usr/bin/python +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2007 Tom Wilkie <tom.wilkie@xxxxxxxxx> +#============================================================================ +""" +Base class for all XenAPI classes +""" + +from xen.xend.XendError import * +from xen.xend import XendAPIStore + +class XendBase: + # + # These functions describe the object, and what is exposed via the API + # + def getClass(self): + return "Base" + + def getAttrRO(self): + return ['uuid'] + + def getAttrRW(self): + return [] + + def getAttrInst(self): + return [] + + def getMethods(self): + return ["get_record"] + + def getFuncs(self): + return ["get_all", "get_by_uuid", "get_all_records"] + + getClass = classmethod(getClass) + getAttrRO = classmethod(getAttrRO) + getAttrRW = classmethod(getAttrRW) + getAttrInst = classmethod(getAttrInst) + getMethods = classmethod(getMethods) + getFuncs = classmethod(getFuncs) + + def __init__(self, uuid, record): + self.__uuid = uuid + + # First check this class implements all the correct methods: + for attr_ro in self.getAttrRO() + self.getAttrRW(): + if not hasattr(self, "get_%s" % attr_ro): + raise ImplementationError(self.getClass(), + "get_%s" % attr_ro) + + for attr_rw in self.getAttrRW(): + if not hasattr(self, "set_%s" % attr_rw): + raise ImplementationError(self.getClass(), + "set_%s" % attr_rw) + + for method in self.getMethods(): + if not hasattr(self, method): + raise ImplementationError(self.getClass(), + method) + + for func in self.getFuncs(): + if not hasattr(self.__class__, func): + raise ImplementationError(self.getClass(), + func) + + # Next check that the class is being created with the correct + # parameters + if not isinstance(record, dict): + raise CreateUnspecifiedAttributeError( + "record" , self.getClass()) + + for attr_inst in self.getAttrInst(): + if attr_inst not in record: + raise CreateUnspecifiedAttributeError( + attr_inst, self.getClass()) + setattr(self, attr_inst, record[attr_inst]) + + # Finally register it + XendAPIStore.register(uuid, self.getClass(), self) + + def destroy(self): + XendAPIStore.deregister(self.get_uuid(), self.getClass()) + + def get_uuid(self): + return self.__uuid + + def get_record(self): + keys = self.getAttrRO() + self.getAttrRW() + return dict([(key, getattr(self, "get_%s" % key)()) + for key in keys]) + + # + # Class methods + # + + def get_all(cls): + return XendAPIStore.get_all_uuid(cls.getClass()) + + def get_by_uuid(cls, uuid): + # Sanity check the uuid is one of us + me = XendAPIStore.get(uuid, cls.getClass()) + if me is not None and me.getClass() == cls.getClass(): + # In OSS, ref == uuid + return uuid + else: + raise "Big Error.. TODO!" + + def get_all_records(cls): + return dict([(inst.get_uuid(), inst.get_record()) + for inst in XendAPIStore.get_all(cls.getClass())]) + + get_all = classmethod(get_all) + get_by_uuid = classmethod(get_by_uuid) + get_all_records = classmethod(get_all_records) diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendConfig.py Sat Apr 28 10:28:59 2007 +0100 @@ -22,6 +22,7 @@ import types from xen.xend import sxp from xen.xend import uuid +from xen.xend import XendAPIStore from xen.xend.XendError import VmError from xen.xend.XendDevices import XendDevices from xen.xend.PrettyPrint import prettyprintstring @@ -341,7 +342,7 @@ class XendConfig(dict): # try and 'fix it up' but acutually fix the cause ;-) # def _memory_sanity_check(self): - log.debug("_memory_sanity_check memory_static_min: %s, " + log.trace("_memory_sanity_check memory_static_min: %s, " "memory_static_max: %i, " "memory_dynamic_min: %i, " "memory_dynamic_max: %i", @@ -353,9 +354,6 @@ class XendConfig(dict): if not self["memory_static_min"] <= self["memory_static_max"]: raise XendConfigError("memory_static_min must be less " \ "than or equal to memory_static_max") - if not self["memory_dynamic_min"] <= self["memory_dynamic_max"]: - raise XendConfigError("memory_dynamic_min must be less " \ - "than or equal to memory_dynamic_max") if not self["memory_static_min"] <= self["memory_dynamic_min"]: raise XendConfigError("memory_static_min must be less " \ "than or equal to memory_dynamic_min") @@ -1049,6 +1047,10 @@ class XendConfig(dict): dev_info['type'] = cfg_xenapi.get('type') if cfg_xenapi.get('name'): dev_info['name'] = cfg_xenapi.get('name') + if cfg_xenapi.get('network'): + network = XendAPIStore.get( + cfg_xenapi.get('network'), 'network') + dev_info['bridge'] = network.get_name_label() dev_uuid = cfg_xenapi.get('uuid', None) if not dev_uuid: diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendDomain.py Sat Apr 28 10:28:59 2007 +0100 @@ -293,10 +293,12 @@ class XendDomain: width = 78) finally: f.close() + try: - os.rename(fn, self._managed_config_path(dom_uuid)) + shutil.move(fn, self._managed_config_path(dom_uuid)) except: - log.exception("Renaming %s" % fn) + log.exception("Renaming %s to %s", fn, + self._managed_config_path(dom_uuid)) os.remove(fn) except: log.exception("Error occurred saving configuration file " + diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Sat Apr 28 10:28:59 2007 +0100 @@ -580,12 +580,9 @@ class XendDomainInfo: log.debug("Setting memory target of domain %s (%s) to %d MiB.", self.info['name_label'], str(self.domid), target) - if target <= 0: - raise XendError('Invalid memory size') - MiB = 1024 * 1024 - self.info['memory_dynamic_min'] = target * MiB - self.info['memory_dynamic_max'] = target * MiB + self._safe_set_memory('memory_dynamic_min', target * MiB) + self._safe_set_memory('memory_dynamic_max', target * MiB) if self.domid >= 0: self.storeVm("memory", target) @@ -1422,6 +1419,9 @@ class XendDomainInfo: raise VmError("HVM guest support is unavailable: is VT/AMD-V " "supported by your CPU and enabled in your " "BIOS?") + # Hack to pre-reserve some memory for HVM setup. + # Needed because Xen allocates 1MB by default immediately. + balloon.free(2*1024) # 2MB should be plenty self.domid = xc.domain_create( domid = 0, @@ -1820,7 +1820,7 @@ class XendDomainInfo: log.info("Unmounting %s from %s." % (fn, BOOTLOADER_LOOPBACK_DEVICE)) - dom0.destroyDevice('tap', '/dev/xvdp') + dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE) if blcfg is None: msg = "Had a bootloader specified, but can't find disk" @@ -2134,14 +2134,24 @@ class XendDomainInfo: def get_memory_dynamic_min(self): return self.info.get('memory_dynamic_min', 0) + # only update memory-related config values if they maintain sanity + def _safe_set_memory(self, key, newval): + oldval = self.info.get(key, 0) + try: + self.info[key] = newval + self.info._memory_sanity_check() + except Exception, ex: + self.info[key] = oldval + raise + def set_memory_static_max(self, val): - self.info['memory_static_max'] = val + self._safe_set_memory('memory_static_max', val) def set_memory_static_min(self, val): - self.info['memory_static_min'] = val + self._safe_set_memory('memory_static_min', val) def set_memory_dynamic_max(self, val): - self.info['memory_dynamic_max'] = val + self._safe_set_memory('memory_dynamic_max', val) def set_memory_dynamic_min(self, val): - self.info['memory_dynamic_min'] = val + self._safe_set_memory('memory_dynamic_min', val) def get_vcpus_params(self): if self.getDomid() is None: @@ -2246,9 +2256,18 @@ class XendDomainInfo: if not config.has_key('network'): try: + bridge = config.get('bridge', None) + if bridge is None: + from xen.util import Brctl + if_to_br = dict([(i,b) + for (b,ifs) in Brctl.get_state().items() + for i in ifs]) + vifname = "vif%s.%s" % (self.getDomid(), + config.get('id')) + bridge = if_to_br.get(vifname, None) config['network'] = \ XendNode.instance().bridge_to_network( - config.get('bridge')).uuid + config.get('bridge')).get_uuid() except Exception: log.exception('bridge_to_network') # Ignore this for now -- it may happen if the device diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendError.py --- a/tools/python/xen/xend/XendError.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendError.py Sat Apr 28 10:28:59 2007 +0100 @@ -48,10 +48,6 @@ class PIFIsPhysical(XendError): def __init__(self): XendError.__init__(self, 'PIF is physical') -class VLANTagInvalid(XendError): - def __init__(self): - XendError.__init__(self, 'VLAN tag invalid') - class VmError(XendError): """Vm construction error.""" pass @@ -62,7 +58,123 @@ class HVMRequired(VmError): 'HVM guest support is unavailable: is VT/AMD-V ' 'supported by your CPU and enabled in your BIOS?') +class XendAPIError(XendError): + """Extend this class for all error thrown by + autoplugged classes""" + def __init__(self): + XendError.__init__(self, 'XendAPI Error: You should never see this' + ' message; this class need to be overidden') + def get_api_error(self): + return ['INTERNAL_ERROR', 'You should never see this message; ' + 'this method needs to be overidden'] + +class CreateUnspecifiedAttributeError(XendAPIError): + def __init__(self, attr_name, class_name): + XendAPIError.__init__(self) + self.attr_name = attr_name + self.class_name = class_name + + def get_api_error(self): + return ['CREATE_UNSPECIFIED_ATTRIBUTE', self.attr_name, + self.class_name] + + def __str__(self): + return "CREATE_UNSPECIFIED_ATTRIBUTE: %s, %s" % (self.attr_name, + self.class_name) + +class UnmanagedNetworkError(XendAPIError): + def __init__(self, attr_name): + XendAPIError.__init__(self) + self.attr_name = attr_name + + def get_api_error(self): + return ['UNMANAGED_NETWORK_ERROR', self.attr_name] + + def __str__(self): + return "UNMANAGED_NETWORK_ERROR: %s" % self.attr_name + +class UniqueNameError(XendAPIError): + def __init__(self, name, class_name): + XendAPIError.__init__(self) + self.name = name + self.class_name = class_name + + def get_api_error(self): + return ['UNIQUE_NAME_ERROR', self.name, self.class_name] + + def __str__(self): + return 'UNIQUE_NAME_ERROR: %s, %s' % (self.name, self.class_name) + +class InvalidDeviceError(XendAPIError): + def __init__(self, dev): + XendAPIError.__init__(self) + self.dev = dev + + def get_api_error(self): + return ['INVALID_DEVICE_ERROR', self.dev] + + def __str__(self): + return 'INVALID_DEVICE_ERROR: %s' % self.dev + +class DeviceExistsError(XendAPIError): + def __init__(self, dev): + XendAPIError.__init__(self) + self.dev = dev + + def get_api_error(self): + return ['DEVICE_EXISTS_ERROR', self.dev] + + def __str__(self): + return 'DEVICE_EXISTS_ERROR: %s' % self.dev + +class InvalidHandleError(XendAPIError): + def __init__(self, klass, handle): + XendAPIError.__init__(self) + self.klass = klass + self.handle = handle + + def get_api_error(self): + return ['HANDLE_INVALID', self.klass, self.handle] + + def __str__(self): + return 'HANDLE_INVALID: %s %s' % (self.klass, self.handle) + +class ImplementationError(XendAPIError): + def __init__(self, klass, func): + XendAPIError.__init__(self) + self.klass = klass + self.func = func + + def get_api_error(self): + return ['IMPLEMENTATION_ERROR', self.klass, self.func] + + def __str__(self): + return 'IMPLEMENTATION_ERROR: %s %s' % (self.klass, self.func) + +class VLANTagInvalid(XendAPIError): + def __init__(self, vlan): + XendAPIError.__init__(self) + self.vlan = vlan + + def get_api_error(self): + return ['VLAN_TAG_INVALID', self.vlan] + + def __str__(self): + return 'VLAN_TAG_INVALID: %s' % self.vlan + +class NetworkError(XendAPIError): + def __init__(self, error, network): + XendAPIError.__init__(self) + self.network = network + self.error = error + + def get_api_error(self): + return ['NETWORK_ERROR', self.error, self.network] + + def __str__(self): + return 'NETWORK_ERROR: %s %s' % (self.error, self.network) + XEND_ERROR_AUTHENTICATION_FAILED = ('ELUSER', 'Authentication Failed') XEND_ERROR_SESSION_INVALID = ('EPERMDENIED', 'Session Invalid') XEND_ERROR_DOMAIN_INVALID = ('EINVALIDDOMAIN', 'Domain Invalid') diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendNetwork.py --- a/tools/python/xen/xend/XendNetwork.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendNetwork.py Sat Apr 28 10:28:59 2007 +0100 @@ -24,15 +24,139 @@ import XendDomain import XendDomain import XendNode from XendLogging import log +from xen.xend import uuid as genuuid +from xen.xend.XendBase import XendBase +from xen.xend.XendError import * +from xen.util import Brctl +from xen.xend import XendAPIStore IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)' -class XendNetwork: - def __init__(self, uuid, record): - self.uuid = uuid - self.name_label = record.get('name_label', '') - self.name_description = record.get('name_description', '') - self.other_config = record.get('other_config', {}) +def bridge_exists(name): + return name in Brctl.get_state().keys() + +class XendNetwork(XendBase): + """We're going to assert that the name_label of this + network is just the name of the bridge""" + + def getClass(self): + return "network" + + def getAttrRW(self): + attrRW = ['name_label', + 'name_description', + 'other_config', + 'default_gateway', + 'default_netmask'] + return XendBase.getAttrRW() + attrRW + + def getAttrRO(self): + attrRO = ['VIFs', + 'PIFs'] + return XendBase.getAttrRO() + attrRO + + def getAttrInst(self): + return XendBase.getAttrInst() + self.getAttrRW() + + def getMethods(self): + methods = ['add_to_other_config', + 'remove_from_other_config', + 'destroy'] + return XendBase.getMethods() + methods + + def getFuncs(self): + funcs = ['create'] + return XendBase.getFuncs() + funcs + + getClass = classmethod(getClass) + getAttrRO = classmethod(getAttrRO) + getAttrRW = classmethod(getAttrRW) + getAttrInst = classmethod(getAttrInst) + getMethods = classmethod(getMethods) + getFuncs = classmethod(getFuncs) + + def create_phy(self, name): + """ + Called when a new bridge is found on xend start + """ + # Create new uuids + uuid = genuuid.createString() + + # Create instance + record = { + 'name_label': name, + 'name_description': '', + 'other_config': {}, + 'default_gateway': '', + 'default_netmask': '' + } + network = XendNetwork(record, uuid) + + return uuid + + def recreate(self, record, uuid): + """ + Called on xend start / restart, or machine + restart, when read from saved config. + Needs to check network exists, create it otherwise + """ + + # Create instance (do this first, to check record) + network = XendNetwork(record, uuid) + + # Create network if it doesn't already exist + if not bridge_exists(network.name_label): + Brctl.bridge_create(network.name_label) + + return uuid + + def create(self, record): + """ + Called from API, to create a new network + """ + # Create new uuids + uuid = genuuid.createString() + + # Create instance (do this first, to check record) + network = XendNetwork(record, uuid) + + # Check network doesn't already exist + name_label = network.name_label + if bridge_exists(name_label): + del network + raise UniqueNameError(name_label, "network") + + # Create the bridge + Brctl.bridge_create(network.name_label) + + XendNode.instance().save_networks() + + return uuid + + create_phy = classmethod(create_phy) + recreate = classmethod(recreate) + create = classmethod(create) + + def __init__(self, record, uuid): + XendBase.__init__(self, uuid, record) + + # + # XenAPI Mehtods + # + + def destroy(self): + # check no VIFs or PIFs attached + if len(self.get_VIFs()) > 0: + raise NetworkError("Cannot destroy network with VIFs attached", + self.get_name_label()) + + if len(self.get_PIFs()) > 0: + raise NetworkError("Cannot destroy network with PIFs attached", + self.get_name_label()) + + XendBase.destroy(self) + Brctl.bridge_del(self.get_name_label()) + XendNode.instance().save_networks() def get_name_label(self): return self.name_label @@ -41,9 +165,8 @@ class XendNetwork: return self.name_description def set_name_label(self, new_name): - self.name_label = new_name - XendNode.instance().save_networks() - + pass + def set_name_description(self, new_desc): self.name_description = new_desc XendNode.instance().save_networks() @@ -55,13 +178,14 @@ class XendNetwork: vifs = vm.get_vifs() for vif in vifs: vif_cfg = vm.get_dev_xenapi_config('vif', vif) - if vif_cfg.get('network') == self.uuid: + if vif_cfg.get('network') == self.get_uuid(): result.append(vif) return result def get_PIFs(self): - return [x.uuid for x in XendNode.instance().pifs.values() - if x.network == self] + pifs = XendAPIStore.get_all("PIF") + return [pif.get_uuid() for pif in pifs + if pif.get_network() == self.get_uuid()] def get_other_config(self): return self.other_config @@ -79,17 +203,16 @@ class XendNetwork: del self.other_config[key] XendNode.instance().save_networks() - def get_record(self): - return self.get_record_internal(True) - - def get_record_internal(self, transient): - result = { - 'uuid': self.uuid, - 'name_label': self.name_label, - 'name_description': self.name_description, - 'other_config' : self.other_config, - } - if transient: - result['VIFs'] = self.get_VIFs() - result['PIFs'] = self.get_PIFs() - return result + def get_default_gateway(self): + return self.default_gateway + + def set_default_gateway(self, gateway): + self.default_gateway = gateway + XendNode.instance().save_networks() + + def get_default_netmask(self): + return self.default_netmask + + def set_default_netmask(self, netmask): + self.default_netmask = netmask + XendNode.instance().save_networks() diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendNode.py --- a/tools/python/xen/xend/XendNode.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendNode.py Sat Apr 28 10:28:59 2007 +0100 @@ -21,9 +21,10 @@ import xen.lowlevel.xc import xen.lowlevel.xc from xen.util import Brctl +from xen.xend import XendAPIStore import uuid, arch -import XendPBD +from XendPBD import XendPBD from XendError import * from XendOptions import instance as xendoptions from XendQCoWStorageRepo import XendQCoWStorageRepo @@ -34,7 +35,7 @@ from XendNetwork import * from XendNetwork import * from XendStateStore import XendStateStore from XendMonitor import XendMonitor - + class XendNode: """XendNode - Represents a Domain 0 Host.""" @@ -133,70 +134,78 @@ class XendNode: 'features' : cpu_features, }) - self.pifs = {} - self.pif_metrics = {} - self.networks = {} self.srs = {} - - # initialise networks + + # Initialise networks + # First configure ones off disk saved_networks = self.state_store.load_state('network') if saved_networks: for net_uuid, network in saved_networks.items(): - self.network_create(network, False, net_uuid) - else: - bridges = Brctl.get_state().keys() - for bridge in bridges: - self.network_create({'name_label' : bridge }, False) + try: + XendNetwork.recreate(network, net_uuid) + except CreateUnspecifiedAttributeError: + log.warn("Error recreating network %s", net_uuid) - # Get a mapping from interface to bridge - - if_to_br = dict([(i,b) - for (b,ifs) in Brctl.get_state().items() - for i in ifs]) - - # initialise PIFs + # Next discover any existing bridges and check + # they are not already configured + bridges = Brctl.get_state().keys() + configured_bridges = [XendAPIStore.get( + network_uuid, "network") + .get_name_label() + for network_uuid in XendNetwork.get_all()] + unconfigured_bridges = [bridge + for bridge in bridges + if bridge not in configured_bridges] + for unconfigured_bridge in unconfigured_bridges: + XendNetwork.create_phy(unconfigured_bridge) + + # Initialise PIFs + # First configure ones off disk saved_pifs = self.state_store.load_state('pif') if saved_pifs: for pif_uuid, pif in saved_pifs.items(): - if pif.get('network') in self.networks: - network = self.networks[pif['network']] - try: - if 'device' not in pif and 'name' in pif: - # Compatibility hack, can go pretty soon. - pif['device'] = pif['name'] - if 'metrics' not in pif: - # Compatibility hack, can go pretty soon. - pif['metrics'] = uuid.createString() - - try: - pif['VLAN'] = int(pif.get('VLAN', -1)) - except (ValueError, TypeError): - pif['VLAN'] = -1 - - self._PIF_create(pif['device'], pif['MTU'], - pif['VLAN'], - pif['MAC'], network, False, pif_uuid, - pif['metrics']) - except NetworkAlreadyConnected, exn: - log.error('Cannot load saved PIF %s, as network %s ' + - 'is already connected to PIF %s', - pif_uuid, pif['network'], exn.pif_uuid) - else: - for name, mtu, mac in linux_get_phy_ifaces(): - bridge_name = if_to_br.get(name, None) - if bridge_name is not None: - networks = [network for - network in self.networks.values() - if network.get_name_label() == bridge_name] - if len(networks) > 0: - network = networks[0] - self._PIF_create(name, mtu, -1, mac, network, False) - + try: + XendPIF.recreate(pif, pif_uuid) + except CreateUnspecifiedAttributeError: + log.warn("Error recreating PIF %s", pif_uuid) + + # Next discover any existing PIFs and check + # they are not already configured + configured_pifs = [XendAPIStore.get( + pif_uuid, "PIF") + .get_interface_name() + for pif_uuid in XendPIF.get_all()] + unconfigured_pifs = [(name, mtu, mac) + for name, mtu, mac in linux_get_phy_ifaces() + if name not in configured_pifs] + + # Get a mapping from interface to bridge + if_to_br = dict([(i,b) + for (b,ifs) in Brctl.get_state().items() + for i in ifs]) + + for name, mtu, mac in unconfigured_pifs: + # Check PIF is on bridge + # if not, ignore + bridge_name = if_to_br.get(name, None) + if bridge_name is not None: + # Translate bridge name to network uuid + for network_uuid in XendNetwork.get_all(): + network = XendAPIStore.get( + network_uuid, 'network') + if network.get_name_label() == bridge_name: + XendPIF.create_phy(network_uuid, name, + mtu, mac) + break + else: + log.debug("Cannot find network for bridge %s " + "when configuring PIF %s", + (bridge_name, name)) + # initialise storage saved_srs = self.state_store.load_state('sr') if saved_srs: for sr_uuid, sr_cfg in saved_srs.items(): - log.error("SAved SRS %s %s", sr_uuid, sr_cfg['type']) if sr_cfg['type'] == 'qcow_file': self.srs[sr_uuid] = XendQCoWStorageRepo(sr_uuid) elif sr_cfg['type'] == 'local': @@ -214,69 +223,50 @@ class XendNode: saved_pbds = self.state_store.load_state('pbd') if saved_pbds: for pbd_uuid, pbd_cfg in saved_pbds.items(): - pbd_cfg['uuid'] = pbd_uuid - XendPBD.XendPBD(pbd_cfg) - - - def network_create(self, record, persist = True, net_uuid = None): - if net_uuid is None: - net_uuid = uuid.createString() - self.networks[net_uuid] = XendNetwork(net_uuid, record) - if persist: - self.save_networks() - return net_uuid - - - def network_destroy(self, net_uuid): - del self.networks[net_uuid] - self.save_networks() - - - def get_PIF_refs(self): - return self.pifs.keys() - - - def _PIF_create(self, name, mtu, vlan, mac, network, persist = True, - pif_uuid = None, metrics_uuid = None): - for pif in self.pifs.values(): - if pif.network == network: - raise NetworkAlreadyConnected(pif.uuid) - - if pif_uuid is None: - pif_uuid = uuid.createString() - if metrics_uuid is None: - metrics_uuid = uuid.createString() - - metrics = XendPIFMetrics(metrics_uuid) - pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, self) - metrics.set_PIF(pif) - - self.pif_metrics[metrics_uuid] = metrics - self.pifs[pif_uuid] = pif - - if persist: - self.save_PIFs() - self.refreshBridges() - return pif_uuid - - - def PIF_create_VLAN(self, pif_uuid, network_uuid, vlan): - if vlan < 0 or vlan >= 4096: - raise VLANTagInvalid() - - pif = self.pifs[pif_uuid] - network = self.networks[network_uuid] - return self._PIF_create(pif.device, pif.mtu, vlan, pif.mac, network) - - - def PIF_destroy(self, pif_uuid): - pif = self.pifs[pif_uuid] - - if pif.vlan == -1: - raise PIFIsPhysical() - - del self.pifs[pif_uuid] - self.save_PIFs() + try: + XendPBD.recreate(pbd_uuid, pbd_cfg) + except CreateUnspecifiedAttributeError: + log.warn("Error recreating PBD %s", pbd_uuid) + +## def network_destroy(self, net_uuid): + ## del self.networks[net_uuid] + ## self.save_networks() + + +## def get_PIF_refs(self): +## return self.pifs[:] + +## def _PIF_create(self, name, mtu, vlan, mac, network, persist = True, +## pif_uuid = None, metrics_uuid = None): +## for pif in self.pifs.values(): +## if pif.network == network: +## raise NetworkAlreadyConnected(pif.uuid) + +## if pif_uuid is None: +## pif_uuid = uuid.createString() +## if metrics_uuid is None: +## metrics_uuid = uuid.createString() + +## metrics = XendPIFMetrics(metrics_uuid) +## pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, self) +## metrics.set_PIF(pif) + +## self.pif_metrics[metrics_uuid] = metrics +## self.pifs[pif_uuid] = pif + +## if persist: +## self.save_PIFs() +## self.refreshBridges() +## return pif_uuid + +## def PIF_destroy(self, pif_uuid): +## pif = self.pifs[pif_uuid] + +## if pif.vlan == -1: +## raise PIFIsPhysical() + +## del self.pifs[pif_uuid] +## self.save_PIFs() def save(self): @@ -284,7 +274,7 @@ class XendNode: host_record = {self.uuid: {'name_label':self.name, 'name_description':self.desc, 'metrics_uuid': self.host_metrics_uuid, - 'other_config': repr(self.other_config)}} + 'other_config': self.other_config}} self.state_store.save_state('host',host_record) self.state_store.save_state('cpu', self.cpus) self.save_PIFs() @@ -293,18 +283,21 @@ class XendNode: self.save_SRs() def save_PIFs(self): - pif_records = dict([(k, v.get_record()) - for k, v in self.pifs.items()]) + pif_records = dict([(pif_uuid, XendAPIStore.get( + pif_uuid, "PIF").get_record()) + for pif_uuid in XendPIF.get_all()]) self.state_store.save_state('pif', pif_records) def save_networks(self): - net_records = dict([(k, v.get_record_internal(False)) - for k, v in self.networks.items()]) + net_records = dict([(network_uuid, XendAPIStore.get( + network_uuid, "network").get_record()) + for network_uuid in XendNetwork.get_all()]) self.state_store.save_state('network', net_records) def save_PBDs(self): - pbd_records = dict([(v.get_uuid(), v.get_record()) - for v in XendPBD.get_all()]) + pbd_records = dict([(pbd_uuid, XendAPIStore.get( + pbd_uuid, "PBD").get_record()) + for pbd_uuid in XendPBD.get_all()]) self.state_store.save_state('pbd', pbd_records) def save_SRs(self): @@ -330,9 +323,6 @@ class XendNode: def is_valid_cpu(self, cpu_ref): return (cpu_ref in self.cpus) - - def is_valid_network(self, network_ref): - return (network_ref in self.networks) def is_valid_sr(self, sr_ref): return (sr_ref in self.srs) @@ -495,12 +485,6 @@ class XendNode: # Network Functions # - def get_network_refs(self): - return self.networks.keys() - - def get_network(self, network_ref): - return self.networks[network_ref] - def bridge_to_network(self, bridge): """ Determine which network a particular bridge is attached to. @@ -518,13 +502,12 @@ class XendNode: raise Exception( 'Could not find default bridge, and none was specified') - bridges = Brctl.get_state() - if bridge not in bridges: - raise Exception('Bridge %s is not up' % bridge) - for pif in self.pifs.values(): - if pif.interface_name() in bridges[bridge]: - return pif.network - raise Exception('Bridge %s is not connected to a network' % bridge) + for network_uuid in XendNetwork.get_all(): + network = XendAPIStore.get(network_uuid, "network") + if network.get_name_label() == bridge: + return network + else: + raise Exception('Cannot find network for bridge %s' % bridge) # # Debug keys. @@ -641,12 +624,6 @@ class XendNode: return dict(self.physinfo()) def info_dict(self): return dict(self.info()) - - - def refreshBridges(self): - for pif in self.pifs.values(): - pif.refresh(Brctl.get_state()) - def parse_proc_cpuinfo(): cpuinfo = {} diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPBD.py --- a/tools/python/xen/xend/XendPBD.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendPBD.py Sat Apr 28 10:28:59 2007 +0100 @@ -18,62 +18,82 @@ import uuid from XendLogging import log +from xen.xend.XendBase import XendBase +from xen.xend import XendAPIStore +class XendPBD(XendBase): + """Physical block devices.""" -attr_inst = ['uuid', - 'host', - 'SR', - 'device_config'] -attr_ro = attr_inst + ['currently_attached'] + def getClass(self): + return "PBD" + + def getAttrRO(self): + attrRO = ['host', + 'SR', + 'device_config', + 'currently_attached'] + return XendBase.getAttrRO() + attrRO + def getAttrRW(self): + attrRW = [] + return XendBase.getAttrRW() + attrRW -_all = {} + def getAttrInst(self): + return ['uuid', + 'host', + 'SR', + 'device_config'] + def getMethods(self): + methods = ['destroy'] + return XendBase.getMethods() + methods -def get(ref): - return _all[ref] + def getFuncs(self): + funcs = ['create', + 'get_by_SR'] + return XendBase.getFuncs() + funcs + getClass = classmethod(getClass) + getAttrRO = classmethod(getAttrRO) + getAttrRW = classmethod(getAttrRW) + getAttrInst = classmethod(getAttrInst) + getMethods = classmethod(getMethods) + getFuncs = classmethod(getFuncs) -def get_all(): - return _all.values() + def recreate(uuid, record): + pbd = XendPBD(uuid, record) + return uuid + + def create(cls, record): + uuid = genuuid.createString() + pbd = XendPBD(uuid, record) + return uuid + create = classmethod(create) + + def __init__(self, uuid, record): + XendBase.__init__(self, uuid, record) + this.currently_attached = True -def get_all_refs(): - return _all.keys() + def get_host(self): + return this.host + + def get_SR(self): + return this.SR + def get_device_config(self): + return this.device_config -def get_by_SR(sr_ref): - return [k for (k, v) in _all.items() if v.get_SR() == sr_ref] - - -class XendPBD: - """Physical block devices.""" - - def __init__(self, record): - if 'uuid' not in record: - record['uuid'] = uuid.createString() - - import XendAPI - for v in attr_inst: - setattr(self, v, record[v]) - self.currently_attached = True - _all[record['uuid']] = self - + def get_currently_attached(self): + return this.currently_attached def destroy(self): - if self.uuid in _all: - del _all[self.uuid] + pass + + def get_by_SR(cls, sr_ref): + pbds = XendAPIStore.get_all("PBD") + return [pbd.get_uuid() + for pbd in pbds + if pbd.get_SR() == sr_ref] - - def get_record(self): - import XendAPI - result = {} - for v in attr_ro: - result[v] = getattr(self, v) - return result - - -for v in attr_ro: - def f(v_): - setattr(XendPBD, 'get_' + v_, lambda s: getattr(s, v_)) - f(v) + get_by_SR = classmethod(get_by_SR) diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPIF.py --- a/tools/python/xen/xend/XendPIF.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendPIF.py Sat Apr 28 10:28:59 2007 +0100 @@ -19,11 +19,14 @@ import logging import logging import os import re - +from xen.xend import uuid as genuuid +from xen.xend import XendAPIStore +from xen.xend.XendBase import XendBase +from xen.xend.XendPIFMetrics import XendPIFMetrics +from xen.xend.XendError import * log = logging.getLogger("xend.XendPIF") log.setLevel(logging.TRACE) - MAC_RE = re.compile(':'.join(['[0-9a-f]{2}'] * 6)) IP_IFACE_RE = re.compile(r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)') @@ -87,106 +90,279 @@ def linux_set_mtu(iface, mtu): except ValueError: return False -class XendPIF: +def _create_VLAN(dev, vlan): + rc, _ = commands.getstatusoutput('vconfig add %s %d' % + (dev, vlan)) + if rc != 0: + return False + + rc, _ = commands.getstatusoutput('ifconfig %s.%d up' % + (dev, vlan)) + return rc == 0 + +def _destroy_VLAN(dev, vlan): + rc, _ = commands.getstatusoutput('ifconfig %s.%d down' % + (dev, vlan)) + if rc != 0: + return False + + rc, _ = commands.getstatusoutput('vconfig rem %s.%d' % + (dev, vlan)) + return rc == 0 + +class XendPIF(XendBase): """Representation of a Physical Network Interface.""" - - def __init__(self, uuid, metrics, device, mtu, vlan, mac, network, - host): - self.uuid = uuid - self.metrics = metrics - self.device = device - self.mac = mac - self.mtu = mtu - self.vlan = vlan - self.network = network - self.host = host - - def set_device(self, new_device): - self.device = new_device - - def set_mac(self, new_mac): - success = linux_set_mac(new_mac) + + def getClass(self): + return "PIF" + + def getAttrRO(self): + attrRO = ['network', + 'host', + 'metrics', + 'device', + 'VLAN'] + return XendBase.getAttrRO() + attrRO + + def getAttrRW(self): + attrRW = ['MAC', + 'MTU'] + return XendBase.getAttrRW() + attrRW + + def getAttrInst(self): + attrInst = ['network', + 'device', + 'MAC', + 'MTU', + 'VLAN'] + return attrInst + + def getMethods(self): + methods = ['plug', + 'unplug', + 'destroy'] + return XendBase.getMethods() + methods + + def getFuncs(self): + funcs = ['create_VLAN'] + return XendBase.getFuncs() + funcs + + getClass = classmethod(getClass) + getAttrRO = classmethod(getAttrRO) + getAttrRW = classmethod(getAttrRW) + getAttrInst = classmethod(getAttrInst) + getMethods = classmethod(getMethods) + getFuncs = classmethod(getFuncs) + + def create_phy(self, network_uuid, device, + MAC, MTU): + """ + Called when a new physical PIF is found + Could be a VLAN... + """ + # Create new uuids + pif_uuid = genuuid.createString() + metrics_uuid = genuuid.createString() + + # Create instances + metrics = XendPIFMetrics(metrics_uuid, pif_uuid) + + # Is this a VLAN? + VLANdot = device.split(".") + VLANcolon = device.split(":") + + if len(VLANdot) > 1: + VLAN = VLANdot[1] + device = VLANdot[0] + elif len(VLANcolon) > 1: + VLAN = VLANcolon[1] + device = VLANcolon[0] + else: + VLAN = -1 + + record = { + 'network': network_uuid, + 'device': device, + 'MAC': MAC, + 'MTU': MTU, + 'VLAN': VLAN + } + pif = XendPIF(record, pif_uuid, metrics_uuid) + + return pif_uuid + + def recreate(self, record, uuid): + """Called on xend start / restart""" + pif_uuid = uuid + metrics_uuid = record['metrics'] + + # Create instances + metrics = XendPIFMetrics(metrics_uuid, pif_uuid) + pif = XendPIF(record, pif_uuid, metrics_uuid) + + # If physical PIF, check exists + # If VLAN, create if not exist + ifs = [dev for dev, _1, _2 in linux_get_phy_ifaces()] + if pif.get_VLAN() == -1: + if pif.get_device() not in ifs: + pif.destroy() + metrics.destroy() + return None + else: + if pif.get_interface_name() not in ifs: + _create_VLAN(pif.get_device(), pif.get_VLAN()) + pif.plug() + + return pif_uuid + + def create_VLAN(self, device, network_uuid, host_ref, vlan): + """Exposed via API - create a new VLAN from existing VIF""" + + ifs = [name for name, _, _ in linux_get_phy_ifaces()] + + vlan = int(vlan) + + # Check VLAN tag is valid + if vlan < 0 or vlan >= 4096: + raise VLANTagInvalid(vlan) + + # Check device exists + if device not in ifs: + raise InvalidDeviceError(device) + + # Check VLAN doesn't already exist + if "%s.%d" % (device, vlan) in ifs: + raise DeviceExistsError("%s.%d" % (device, vlan)) + + # Check network ref is valid + from XendNetwork import XendNetwork + if network_uuid not in XendNetwork.get_all(): + raise InvalidHandleError("Network", network_uuid) + + # Check host_ref is this host + import XendNode + if host_ref != XendNode.instance().get_uuid(): + raise InvalidHandleError("Host", host_ref) + + # Create the VLAN + _create_VLAN(device, vlan) + + # Create new uuids + pif_uuid = genuuid.createString() + metrics_uuid = genuuid.createString() + + # Create the record + record = { + "device": device, + "MAC": '', + "MTU": '', + "network": network_uuid, + "VLAN": vlan + } + + # Create instances + metrics = XendPIFMetrics(metrics_uuid, pif_uuid) + pif = XendPIF(record, pif_uuid, metrics_uuid) + + # Not sure if they should be created plugged or not... + pif.plug() + + XendNode.instance().save_PIFs() + return pif_uuid + + create_phy = classmethod(create_phy) + recreate = classmethod(recreate) + create_VLAN = classmethod(create_VLAN) + + def __init__(self, record, uuid, metrics_uuid): + XendBase.__init__(self, uuid, record) + self.metrics = metrics_uuid + + def plug(self): + """Plug the PIF into the network""" + network = XendAPIStore.get(self.network, + "network") + bridge_name = network.get_name_label() + + from xen.util import Brctl + Brctl.vif_bridge_add({ + "bridge": bridge_name, + "vif": self.get_interface_name() + }) + + def unplug(self): + """Unplug the PIF from the network""" + network = XendAPIStore.get(self.network, + "network") + bridge_name = network.get_name_label() + + from xen.util import Brctl + Brctl.vif_bridge_rem({ + "bridge": bridge_name, + "vif": self.get_interface_name() + }) + + def destroy(self): + # Figure out if this is a physical device + if self.get_interface_name() == \ + self.get_device(): + raise PIFIsPhysical(self.get_uuid()) + + self.unplug() + + if _destroy_VLAN(self.get_device(), self.get_VLAN()): + XendBase.destroy(self) + import XendNode + XendNode.instance().save_PIFs() + else: + raise NetworkError("Unable to delete VLAN", self.get_uuid()) + + def get_interface_name(self): + if self.get_VLAN() == -1: + return self.get_device() + else: + return "%s.%d" % (self.get_device(), self.get_VLAN()) + + def get_device(self): + """ + This is the base interface. + For phy if (VLAN == -1) this is same as + if name. + For VLANs, this it the bit before the period + """ + return self.device + + def get_network(self): + return self.network + + def get_host(self): + from xen.xend import XendNode + return XendNode.instance().get_uuid() + + def get_metrics(self): + return self.metrics + + def get_MAC(self): + return self.MAC + + def set_MAC(self, new_mac): + success = linux_set_mac(self.device, new_mac) if success: - self.mac = new_mac + self.MAC = new_mac + import XendNode + XendNode.instance().save_PIFs() return success - def set_mtu(self, new_mtu): - success = linux_set_mtu(new_mtu) + def get_MTU(self): + return self.MTU + + def set_MTU(self, new_mtu): + success = linux_set_mtu(self.device, new_mtu) if success: - self.mtu = new_mtu + self.MTU = new_mtu + import XendNode + XendNode.instance().save_PIFs() return success - def get_record(self): - return {'uuid': self.uuid, - 'device': self.device, - 'MAC': self.mac, - 'MTU': self.mtu, - 'VLAN': self.vlan, - 'host': self.host.uuid, - 'network': self.network.uuid, - 'metrics': self.metrics.uuid} - - def refresh(self, bridges): - ifname = self.interface_name() - rc, _ = _cmd('ip link show %s', ifname) - if rc != 0: - # Interface does not exist. If it's a physical interface, then - # there's nothing we can do -- this should have been set up with - # the network script. Otherwise, we can use vconfig to derive - # a subinterface. - if self.vlan == -1: - return - - rc, _ = _cmd('vconfig add %s %d', self.device, self.vlan) - if rc != 0: - log.error('Could not refresh VLAN for interface %s', ifname) - return - - log.info('Created network interface %s', ifname) - - for brname, nics in bridges.items(): - if ifname in nics: - log.debug('%s is already attached to %s', ifname, brname) - return - - # The interface is not attached to a bridge. Create one, and attach - # the interface to it. - brname = _new_bridge_name(bridges) - rc, _ = _cmd('brctl addbr %s', brname) - if rc != 0: - log.error('Could not create bridge %s for interface %s', brname, - ifname) - return - log.info('Created network bridge %s', brname) - - rc, _ = _cmd('brctl addif %s %s', brname, ifname) - if rc != 0: - log.error('Could not add %s to %s', ifname, brname) - return - log.info('Added network interface %s to bridge %s', ifname, brname) - - - def interface_name(self): - if self.vlan != -1: - return '%s.%d' % (self.device, self.vlan) - else: - return self.device - - -def _cmd(cmd, *args): - if len(args) > 0: - cmd = cmd % args - rc, output = commands.getstatusoutput(cmd) - if rc != 0: - log.debug('%s failed with code %d' % (cmd, rc)) - log.trace('%s: %s' % (cmd, output)) - return rc, output - - -def _new_bridge_name(bridges): - n = 0 - while True: - brname = 'xenbr%d' % n - if brname not in bridges: - return brname - n += 1 + def get_VLAN(self): + return self.VLAN diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPIFMetrics.py --- a/tools/python/xen/xend/XendPIFMetrics.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendPIFMetrics.py Sat Apr 28 10:28:59 2007 +0100 @@ -15,15 +15,30 @@ # Copyright (c) 2006-2007 Xensource Inc. #============================================================================ +from XendBase import XendBase -class XendPIFMetrics: +class XendPIFMetrics(XendBase): """PIF Metrics.""" + + def getClass(self): + return "PIF_metrics" - def __init__(self, uuid): - self.uuid = uuid + def getAttrRO(self): + attrRO = ['io_read_kbs', + 'io_write_kbs', + 'last_updated', + 'pif'] + return XendBase.getAttrRO() + attrRO - def set_PIF(self, pif): - self.pif = pif + getClass = classmethod(getClass) + getAttrRO = classmethod(getAttrRO) + + def __init__(self, uuid, pif_uuid): + XendBase.__init__(self, uuid, {}) + self.pif_uuid = pif_uuid + + def get_pif(self): + return self.pif_uuid def get_io_read_kbs(self): return self._get_stat(0) @@ -33,19 +48,12 @@ class XendPIFMetrics: def _get_stat(self, n): from xen.xend.XendNode import instance as xennode - pifname = self.pif.device - pifs_util = xennode().monitor.get_pifs_util() - if pifname in pifs_util: - return pifs_util[pifname][n] + #pifname = self.pif.device + #pifs_util = xennode().monitor.get_pifs_util() + #if pifname in pifs_util: + # return pifs_util[pifname][n] return 0.0 def get_last_updated(self): import xen.xend.XendAPI as XendAPI return XendAPI.now() - - def get_record(self): - return {'uuid' : self.uuid, - 'io_read_kbs' : self.get_io_read_kbs(), - 'io_write_kbs' : self.get_io_write_kbs(), - 'last_updated' : self.get_last_updated(), - } diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendQCoWStorageRepo.py --- a/tools/python/xen/xend/XendQCoWStorageRepo.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendQCoWStorageRepo.py Sat Apr 28 10:28:59 2007 +0100 @@ -30,7 +30,7 @@ import struct from xen.util import mkdir import uuid -import XendPBD +from XendPBD import XendPBD from XendError import XendError from XendVDI import * from XendTask import XendTask diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendStateStore.py --- a/tools/python/xen/xend/XendStateStore.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendStateStore.py Sat Apr 28 10:28:59 2007 +0100 @@ -57,10 +57,12 @@ class XendStateStore: <hosts> <host uuid='49c01812-3c28-1ad4-a59d-2a3f81b13ec2'> - <name type='string'>norwich</name> - <description type='string'>Test Xen Host</description> - <cpu uuid='6fc2d1ed-7eb0-4c9d-8006-3657d5483ae0' /> - <cpu uuid='669df3b8-62be-4e61-800b-bbe8ee63a760' /> + <name type='string'>norwich</name> + <description type='string'>Test Xen Host</description> + <cpu type='dict'> + <item uuid='6fc2d1ed-7eb0-4c9d-8006-3657d5483ae0' /> + <item uuid='669df3b8-62be-4e61-800b-bbe8ee63a760' /> + </cpu> </host> </hosts> @@ -121,18 +123,20 @@ class XendStateStore: if val_elem.firstChild: val_text = val_elem.firstChild.nodeValue.strip() - if val_type == '' and val_uuid != '': - # this is a reference - if val_name not in cls_dict: - cls_dict[val_name] = {} - cls_dict[val_name][val_uuid] = None - elif val_type == '': - # dictionary - k = val_elem.getAttribute('key').encode('utf8') - v = val_elem.getAttribute('value').encode('utf8') - if val_name not in cls_dict: - cls_dict[val_name] = {} - cls_dict[val_name][k] = v + if val_type == 'list': + cls_dict[val_name] = [] + for item in val_elem.childNodes: + if item.nodeType != Node.ELEMENT_NODE: + continue # skip non element nodes + cls_dict[val_name].append(item.getAttribute('uuid')) + elif val_type == 'dict': + cls_dict[val_name] = {} + for item in val_elem.childNodes: + if item.nodeType != Node.ELEMENT_NODE: + continue # skip non element nodes + k = item.getAttribute('key').encode('utf8') + v = item.getAttribute('value').encode('utf8') + cls_dict[val_name][k] = v elif val_type == 'string': cls_dict[val_name] = val_text.encode('utf8') elif val_type == 'float': @@ -158,8 +162,7 @@ class XendStateStore: @param state: a Xen API struct of the state of the class. @type state: dict @rtype: None - """ - + """ xml_path = self._xml_file(cls) doc = minidom.getDOMImplementation().createDocument(None, @@ -191,7 +194,7 @@ class XendStateStore: store_val = str(int(val)) store_type = 'bool' - if store_type != None: + if store_type is not None: val_node = doc.createElement(key) val_node.setAttribute('type', store_type) node.appendChild(val_node) @@ -202,19 +205,25 @@ class XendStateStore: # deal with dicts and lists if type(val) == dict: - for val_uuid in val.keys(): - val_node = doc.createElement(key) + val_node = doc.createElement(key) + val_node.setAttribute('type', 'dict') + for val_item in val.keys(): + tmp = doc.createElement("item") if key in ['other_config', 'device_config']: - val_node.setAttribute('key', str(val_uuid)) - val_node.setAttribute('value', str(val[val_uuid])) + tmp.setAttribute('key', str(val_item)) + tmp.setAttribute('value', str(val[val_item])) else: - val_node.setAttribute('uuid', val_uuid) - node.appendChild(val_node) + tmp.setAttribute('uuid', val_uuid) + val_node.appendChild(tmp) + node.appendChild(val_node) elif type(val) in (list, tuple): + val_node = doc.createElement(key) + val_node.setAttribute('type', 'list') for val_uuid in val: - val_node = doc.createElement(key) - val_node.setAttribute('uuid', val_uuid) - node.appendChild(val_node) + tmp = doc.createElement("item") + tmp.setAttribute('uuid', val_uuid) + val_node.appendChild(tmp) + node.appendChild(val_node) open(xml_path, 'w').write(doc.toprettyxml()) diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendStorageRepository.py --- a/tools/python/xen/xend/XendStorageRepository.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendStorageRepository.py Sat Apr 28 10:28:59 2007 +0100 @@ -24,7 +24,7 @@ import sys from XendError import XendError from XendVDI import * -import XendPBD +from XendPBD import XendPBD XEND_STORAGE_NO_MAXIMUM = sys.maxint diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendVMMetrics.py --- a/tools/python/xen/xend/XendVMMetrics.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/XendVMMetrics.py Sat Apr 28 10:28:59 2007 +0100 @@ -17,38 +17,36 @@ #============================================================================ from xen.xend.XendLogging import log +from xen.xend.XendBase import XendBase import xen.lowlevel.xc xc = xen.lowlevel.xc.xc() -instances = {} - -class XendVMMetrics: +class XendVMMetrics(XendBase): """VM Metrics.""" - def get_by_uuid(_, uuid): - return instances[uuid] + def getClass(self): + return "VM_metrics" + + def getAttrRO(self): + attrRO = ['memory_actual', + 'VCPUs_number', + 'VCPUs_utilisation', + 'VCPUs_CPU', + 'VCPUs_flags', + 'VCPUs_params', + 'state', + 'start_time', + 'last_updated'] + return XendBase.getAttrRO() + attrRO - get_by_uuid = classmethod(get_by_uuid) + getClass = classmethod(getClass) + getAttrRO = classmethod(getAttrRO) - def is_valid_vm_metrics(_, uuid): - return uuid in instances - - is_valid_vm_metrics = classmethod(is_valid_vm_metrics) - - def get_all(_): - return instances.keys() - - get_all = classmethod(get_all) - def __init__(self, uuid, xend_domain_instance): - self.uuid = uuid + XendBase.__init__(self, uuid, {}) self.xend_domain_instance = xend_domain_instance - instances[uuid] = self - - def get_uuid(self): - return self.uuid - + def get_memory_actual(self): domInfo = self.xend_domain_instance.getDomInfo() if domInfo: @@ -145,16 +143,3 @@ class XendVMMetrics: def get_last_updated(self): import xen.xend.XendAPI as XendAPI return XendAPI.now() - - def get_record(self): - return { 'uuid' : self.uuid, - 'memory_actual' : self.get_memory_actual(), - 'VCPUs_number' : self.get_VCPUs_number(), - 'VCPUs_utilisation' : self.get_VCPUs_utilisation(), - 'VCPUs_CPU' : self.get_VCPUs_CPU(), - 'VCPUs_flags' : self.get_VCPUs_flags(), - 'VCPUs_params' : self.get_VCPUs_params(), - 'start_time' : self.get_start_time(), - 'state' : self.get_state(), - 'last_updated' : self.get_last_updated(), - } diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/server/SrvServer.py --- a/tools/python/xen/xend/server/SrvServer.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xend/server/SrvServer.py Sat Apr 28 10:28:59 2007 +0100 @@ -109,8 +109,6 @@ class XendServers: signal.signal(signal.SIGHUP, self.reloadConfig) while True: - XendNode.instance().refreshBridges() - threads = [] for server in self.servers: if server.ready: diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/create.dtd --- a/tools/python/xen/xm/create.dtd Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xm/create.dtd Sat Apr 28 10:28:59 2007 +0100 @@ -27,7 +27,8 @@ | crashdump )"> <!ELEMENT xm (vm*, - vdi*)> + vdi*, + network*)> <!ELEMENT version (#PCDATA)> @@ -98,6 +99,12 @@ sharable CDATA #REQUIRED read_only CDATA #REQUIRED> +<!ELEMENT network (name, + other_config*)> +<!ATTLIST network %NAMEID; + default_gateway CDATA #REQUIRED + default_netmask CDATA #REQUIRED> + <!ELEMENT name (label, description)> diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xm/create.py Sat Apr 28 10:28:59 2007 +0100 @@ -777,8 +777,11 @@ def make_config(vals): config.append(['bootloader', vals.bootloader]) if vals.bootargs: config.append(['bootloader_args', vals.bootargs]) - else: - config.append(['bootloader_args', '-q']) + else: + if vals.console_autoconnect: + config.append(['bootloader_args', '']) + else: + config.append(['bootloader_args', '-q']) config.append(['image', config_image]) config_devs = [] diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xm/main.py Sat Apr 28 10:28:59 2007 +0100 @@ -510,6 +510,10 @@ def xenapi_unsupported(): if serverType == SERVER_XEN_API: raise XenAPIUnsupportedException, "This function is not supported by Xen-API" +def xenapi_only(): + if serverType != SERVER_XEN_API: + raise XenAPIUnsupportedException, "This function is only supported by Xen-API" + def map2sxp(m): return [[k, m[k]] for k in m.keys()] @@ -565,14 +569,14 @@ def get_single_vm(dom): try: domid = int(dom) - uuids = [server.xenapi.VM.get_domid(vm_ref) - for vm_ref in server.xenapi.VM.get_all() - if int(server.xenapi.VM.get_domid(vm_ref)) == domid] + refs = [vm_ref + for vm_ref in server.xenapi.VM.get_all() + if int(server.xenapi.VM.get_domid(vm_ref)) == domid] except: pass - if len(uuids) > 0: - return uuids[0] + if len(refs) > 0: + return refs[0] raise OptionError("Domain '%s' not found." % dom) else: @@ -743,15 +747,15 @@ def getDomains(domain_names, state, full doms_dict = [] dom_recs = server.xenapi.VM.get_all_records() - dom_metrics_recs = dict(map(lambda x: (x['uuid'], x), server.xenapi.VM_metrics.get_all_records())) - - for dom_rec in dom_recs: - dom_metrics = dom_metrics_recs[dom_rec['metrics']] + dom_metrics_recs = server.xenapi.VM_metrics.get_all_records() + + for dom_ref, dom_rec in dom_recs.items(): + dom_metrics_rec = dom_metrics_recs[dom_rec['metrics']] states = ('running', 'blocked', 'paused', 'shutdown', 'crashed', 'dying') def state_on_off(state): - if state in dom_metrics['state']: + if state in dom_metrics_rec['state']: return state[0] else: return "-" @@ -759,12 +763,12 @@ def getDomains(domain_names, state, full for state in states]) dom_rec.update({'name': dom_rec['name_label'], - 'memory_actual': int(dom_metrics['memory_actual'])/1024, - 'vcpus': dom_metrics['VCPUs_number'], + 'memory_actual': int(dom_metrics_rec['memory_actual'])/1024, + 'vcpus': dom_metrics_rec['VCPUs_number'], 'state': state_str, - 'cpu_time': dom_metrics['VCPUs_utilisation'], + 'cpu_time': dom_metrics_rec['VCPUs_utilisation'], 'start_time': datetime_to_secs( - dom_metrics['start_time'])}) + dom_metrics_rec['start_time'])}) doms_sxp.append(['domain'] + map2sxp(dom_rec)) doms_dict.append(dom_rec) @@ -2070,8 +2074,14 @@ def xm_network_attach(args): record[keys[-1]] = val def get_net_from_bridge(bridge): - raise "Not supported just yet" - + # In OSS, we just assert network.name_label == bridge name + networks = dict([(record['name_label'], ref) + for ref, record in server.xenapi.network + .get_all_records().items()]) + if bridge not in networks.keys(): + raise "Unknown bridge name!" + return networks[bridge] + vif_conv = { 'type': lambda x: None, @@ -2102,7 +2112,6 @@ def xm_network_attach(args): else: vif_conv[vif_param[0]](vif_param[1]) - print str(vif_record) server.xenapi.VIF.create(vif_record) else: for a in args[1:]: @@ -2222,6 +2231,87 @@ def xm_vnet_delete(args): vnet = args[0] server.xend_vnet_delete(vnet) +def xm_network_new(args): + xenapi_only() + arg_check(args, "network-new", 1) + network = args[0] + + record = { + "name_label": network, + "name_description": "", + "other_config": {}, + "default_gateway": "", + "default_netmask": "" + } + + server.xenapi.network.create(record) + +def xm_network_del(args): + xenapi_only() + arg_check(args, "network-del", 1) + network = args[0] + + networks = dict([(record['name_label'], ref) + for ref, record in + server.xenapi.network.get_all_records().items()]) + + if network not in networks.keys(): + raise ValueError("'%s' is not a valid network name" % network) + + server.xenapi.network.destroy(networks[network]) + +def xm_network_show(args): + xenapi_only() + arg_check(args, "network-show", 0) + + networks = server.xenapi.network.get_all_records() + pifs = server.xenapi.PIF.get_all_records() + vifs = server.xenapi.VIF.get_all_records() + + print '%-20s %-40s %-10s' % \ + ('Name', 'VIFs', 'PIFs') + + format2 = "%(name_label)-20s %(vif)-40s %(pif)-10s" + + for network_ref, network in networks.items(): + for i in range(max(len(network['PIFs']), + len(network['VIFs']), 1)): + if i < len(network['PIFs']): + pif_uuid = network['PIFs'][i] + else: + pif_uuid = None + + if i < len(network['VIFs']): + vif_uuid = network['VIFs'][i] + else: + vif_uuid = None + + pif = pifs.get(pif_uuid, None) + vif = vifs.get(vif_uuid, None) + + if vif: + dom_name = server.xenapi.VM.get_name_label(vif['VM']) + vif = "%s.%s" % (dom_name, vif['device']) + else: + vif = '' + + if pif: + if int(pif['VLAN']) > -1: + pif = '%s.%s' % (pif['device'], pif['VLAN']) + else: + pif = pif['device'] + else: + pif = '' + + if i == 0: + r = {'name_label':network['name_label'], + 'vif':vif, 'pif':pif} + else: + r = {'name_label':'', 'vif':vif, 'pif':pif} + + print format2 % r + + commands = { "shell": xm_shell, "event-monitor": xm_event_monitor, @@ -2271,10 +2361,14 @@ commands = { "block-detach": xm_block_detach, "block-list": xm_block_list, "block-configure": xm_block_configure, - # network + # network (AKA vifs) "network-attach": xm_network_attach, "network-detach": xm_network_detach, "network-list": xm_network_list, + # network (as in XenAPI) + "network-new": xm_network_new, + "network-del": xm_network_del, + "network-show": xm_network_show, # vnet "vnet-list": xm_vnet_list, "vnet-create": xm_vnet_create, diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/messages/en/xen-xm.po --- a/tools/python/xen/xm/messages/en/xen-xm.po Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xm/messages/en/xen-xm.po Sat Apr 28 10:28:59 2007 +0100 @@ -67,3 +67,27 @@ msgstr "HVM guest support is unavailable msgid "SESSION_NOT_REGISTERED" msgstr "This session is not registered to receive events. You must call event.register before event.next. (Session handle is %(1)s.)" + +msgid "CREATE_UNSPECIFIED_ATTRIBUTE" +msgstr "You need to specify %s when creating a new %s" + +msgid "UNMANAGED_NETWORK_ERROR" +msgstr "Cannot change %s on an unmanaged network" + +msgid "UNIQUE_NAME_ERROR" +msgstr "Name %s for class %s is not unique" + +msgid "INVALID_DEVICE_ERROR" +msgstr "Invalid device %s" + +msgid "DEVICE_EXISTS_ERROR" +msgstr "Device already exists %s" + +msgid "IMPLEMENTATION_ERROR" +msgstr "Class %s does not implement %s" + +msgid "VLAN_TAG_INVALID" +msgstr "VLAN tag invalid %s" + +msgid "NETWORK_ERROR" +msgstr "Network Error: %s - %s" \ No newline at end of file diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xm/xenapi_create.py --- a/tools/python/xen/xm/xenapi_create.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/python/xen/xm/xenapi_create.py Sat Apr 28 10:28:59 2007 +0100 @@ -93,10 +93,13 @@ class xenapi_create: vdis = document.getElementsByTagName("vdi") vdi_refs_dict = self.create_vdis(vdis) + + networks = document.getElementsByTagName("network") + network_refs_dict = self.create_networks(networks) try: vms = document.getElementsByTagName("vm") - return self.create_vms(vms, vdi_refs_dict) + return self.create_vms(vms, vdi_refs_dict, network_refs_dict) except Exception, exn: try_quietly(self.cleanup_vdis(vdi_refs_dict)) raise exn @@ -223,11 +226,33 @@ class xenapi_create: return (key, value) - def create_vms(self, vms, vdis): + def create_networks(self, networks): + log(DEBUG, "create_networks") + return dict(map(self.create_network, networks)) + + def create_network(self, network): + log(DEBUG, "create_network") + + network_record = { + "name_label": get_name_label(network), + "name_description": get_name_description(network), + "other_config": + get_child_nodes_as_dict(network, "other_config", + "key", "value"), + "default_netmask": network.attributes["default_netmask"].value, + "default_gateway": network.attributes["default_gateway"].value + } + + key = network.attributes["name"].value + value = server.xenapi.network.create(network_record) + + return (key, value) + + def create_vms(self, vms, vdis, networks): log(DEBUG, "create_vms") - return map(lambda vm: self.create_vm(vm, vdis), vms) - - def create_vm(self, vm, vdis): + return map(lambda vm: self.create_vm(vm, vdis, networks), vms) + + def create_vm(self, vm, vdis, networks): log(DEBUG, "create_vm") vm_record = { @@ -321,7 +346,7 @@ class xenapi_create: vifs = vm.getElementsByTagName("vif") - self.create_vifs(vm_ref, vifs) + self.create_vifs(vm_ref, vifs, networks) # Now create consoles @@ -363,31 +388,35 @@ class xenapi_create: return server.xenapi.VBD.create(vbd_record) - def create_vifs(self, vm_ref, vifs): + def create_vifs(self, vm_ref, vifs, networks): log(DEBUG, "create_vifs") - return map(lambda vif: self.create_vif(vm_ref, vif), vifs) - - def create_vif(self, vm_ref, vif): + return map(lambda vif: self.create_vif(vm_ref, vif, networks), vifs) + + def create_vif(self, vm_ref, vif, networks): log(DEBUG, "create_vif") - if "network" in vif.attributes.keys(): - networks = [network_ref - for network_ref in server.xenapi.network.get_all() - if server.xenapi.network.get_name_label(network_ref) - == vif.attributes["network"].value] - if len(networks) > 0: - network = networks[0] + if 'network' in vif.attributes.keys(): + network_name = vif.attributes['network'].value + + if network_name in networks.keys(): + network_uuid = networks[network_name] else: - raise OptionError("Network %s doesn't exist" + networks = dict([(record['name_label'], record['uuid']) + for record in + server.xenapi.network.get_all_records()]) + if network_name in networks.keys(): + network_uuid = networks[network_name] + else: + raise OptionError("Network %s doesn't exist" % vif.attributes["network"].value) else: - network = self._get_network_ref() + network_uuid = self._get_network_ref() vif_record = { "device": vif.attributes["device"].value, "network": - network, + network_uuid, "VM": vm_ref, "MAC": diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/00README --- a/tools/vnet/vnet-module/00README Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/vnet/vnet-module/00README Sat Apr 28 10:28:59 2007 +0100 @@ -9,8 +9,8 @@ LINUX_SERIES: linux release to compile LINUX_SERIES: linux release to compile for: 2.4, or 2.6 (default). XEN_ROOT: root of the xen tree containing kernel source. KERNEL_VERSION: kernel version, default got from XEN_ROOT. -KERNEL_MINOR: kernel minor version, default -xen0. -KERNEL_SRC: path to kernel source, default linux-<VERSION> under XEN_ROOT. +KERNEL_SRC: path to kernel source, default build-linux-<VERSION> + under XEN_ROOT. *) For 2.4 kernel diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/Makefile.ver --- a/tools/vnet/vnet-module/Makefile.ver Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/vnet/vnet-module/Makefile.ver Sat Apr 28 10:28:59 2007 +0100 @@ -19,7 +19,6 @@ #============================================================================ LINUX_SERIES?=2.6 -KERNEL_MINOR=-xen LINUX_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \ sed -e 's!^.*linux-\(.\+\)!\1!' ) @@ -28,22 +27,25 @@ ifeq ($(LINUX_VERSION),) $(error Kernel source for linux $(LINUX_SERIES) not found) endif -KERNEL_VERSION=$(LINUX_VERSION)$(KERNEL_MINOR) +KERNEL_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/build-linux-$(LINUX_VERSION)-xen* 2>/dev/null) | \ + grep -v -m 1 -e '-xenU' | \ + sed -e 's!^.*linux-\(.\+\)!\1!' ) -KERNEL_SRC?=$(shell cd $(XEN_ROOT)/linux-$(KERNEL_VERSION) && pwd) +KERNEL_SRC ?= $(XEN_ROOT)/build-linux-$(KERNEL_VERSION) ifeq ($(KERNEL_SRC),) $(error Kernel source for kernel $(KERNEL_VERSION) not found) endif # Get the full kernel release version from its makefile, as the source path -# may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release 2.6.12.6-xen0. +# may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release +# 2.6.12.6-xen0. KERNEL_RELEASE=$(shell make -s -C $(KERNEL_SRC) kernelrelease) -KERNEL_MODULE_DIR=/lib/modules/$$(KERNEL_RELEASE)/kernel +KERNEL_MODULE_DIR=/lib/modules/$(KERNEL_RELEASE)/kernel $(warning KERNEL_SRC $(KERNEL_SRC)) $(warning LINUX_VERSION $(LINUX_VERSION)) $(warning KERNEL_VERSION $(KERNEL_VERSION)) $(warning KERNEL_RELEASE $(KERNEL_RELEASE)) -$(warning KERNEL_ MODULE_DIR $(KERNEL_MODULE_DIR)) +$(warning KERNEL_MODULE_DIR $(KERNEL_MODULE_DIR)) diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/varp.c --- a/tools/vnet/vnet-module/varp.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/vnet/vnet-module/varp.c Sat Apr 28 10:28:59 2007 +0100 @@ -1530,12 +1530,7 @@ void varp_exit(void){ dprintf("<\n"); } -#ifdef MODULE_PARM -MODULE_PARM(varp_mcaddr, "s"); -MODULE_PARM(varp_device, "s"); -#else module_param(varp_mcaddr, charp, 0644); module_param(varp_device, charp, 0644); -#endif MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address"); MODULE_PARM_DESC(varp_device, "VARP network device"); diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnet-module/vnet.c --- a/tools/vnet/vnet-module/vnet.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/vnet/vnet-module/vnet.c Sat Apr 28 10:28:59 2007 +0100 @@ -693,12 +693,7 @@ module_exit(vnet_module_exit); module_exit(vnet_module_exit); MODULE_LICENSE("GPL"); -#ifdef MODULE_PARM -MODULE_PARM(vnet_encaps, "s"); -#else module_param(vnet_encaps, charp, 0644); +MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp."); + #endif - -MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp."); - -#endif diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnetd/Makefile --- a/tools/vnet/vnetd/Makefile Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/vnet/vnetd/Makefile Sat Apr 28 10:28:59 2007 +0100 @@ -16,7 +16,7 @@ # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #---------------------------------------------------------------------------- -VNET_ROOT = $(shell cd .. && pwd) +VNET_ROOT ?= $(shell cd .. && pwd) include $(VNET_ROOT)/Make.env .PHONY: all @@ -26,6 +26,8 @@ all: vnetd # Comment out when outside xen. #include $(XEN_ROOT)/tools/Rules.mk + +INSTALL_PROG ?= $(INSTALL) -m0755 -p VNETD_INSTALL_DIR = /usr/sbin diff -r ee16cdeddade -r 1668299c0ea4 tools/vnet/vnetd/sys_kernel.h --- a/tools/vnet/vnetd/sys_kernel.h Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/vnet/vnetd/sys_kernel.h Sat Apr 28 10:28:59 2007 +0100 @@ -45,6 +45,7 @@ #define module_exit(x) #define MODULE_LICENSE(x) #define MODULE_PARM(v, t) +#define module_param(v, t, s) #define MODULE_PARM_DESC(v, s) enum { diff -r ee16cdeddade -r 1668299c0ea4 tools/xenstore/xenstored_core.c --- a/tools/xenstore/xenstored_core.c Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/xenstore/xenstored_core.c Sat Apr 28 10:28:59 2007 +0100 @@ -1336,7 +1336,7 @@ static void handle_input(struct connecti bytes = conn->read(conn, in->buffer + in->used, in->hdr.msg.len - in->used); - if (bytes < 0) + if (bytes <= 0) goto bad_client; in->used += bytes; diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/lib/XmTestLib/network_utils.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/xm-test/lib/XmTestLib/network_utils.py Sat Apr 28 10:28:59 2007 +0100 @@ -0,0 +1,60 @@ +#!/usr/bin/python + +# Copyright (C) International Business Machines Corp., 2005 +# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx> + +from XmTestLib import * + +def count_eth(console): + try: + run = console.runCmd("ifconfig -a | grep eth") + except ConsoleError, e: + FAIL(str(e)) + return len(run['output'].splitlines()) + +def get_state(domain_name, number): + s, o = traceCommand("xm network-list %s | awk '/^%d/ {print $5}'" % + (domain_name, number)) + print o + + if s != 0: + FAIL("network-list failed") + if o == "": + return 0 + else: + return int(o) + +def network_attach(domain_name, console, bridge=None): + eths_before = count_eth(console) + if bridge: + status, output = traceCommand("xm network-attach %s bridge=%s" + % (domain_name, bridge)) + else: + status, output = traceCommand("xm network-attach %s" % domain_name) + if status != 0: + return -1, "xm network-attach returned invalid %i != 0" % status + + eths_after = count_eth(console) + if (eths_after != (eths_before+1)): + return -2, "Network device is not actually connected to domU" + + return 0, None + +def network_detach(domain_name, console, num=0): + eths_before = count_eth(console) + status, output = traceCommand("xm network-detach %s %d" % (domain_name, num)) + if status != 0: + return -1, "xm network-detach returned invalid %i != 0" % status + + for i in range(10): + if get_state(domain_name, num) == 0: + break + time.sleep(1) + else: + FAIL("network-detach failed: device did not disappear") + + eths_after = count_eth(console) + if eths_after != (eths_before-1): + return -2, "Network device was not actually disconnected from domU" + + return 0, None diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/tests/network-attach/01_network_attach_pos.py --- a/tools/xm-test/tests/network-attach/01_network_attach_pos.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/xm-test/tests/network-attach/01_network_attach_pos.py Sat Apr 28 10:28:59 2007 +0100 @@ -6,7 +6,7 @@ import sys import sys from XmTestLib import * -from network_utils import * +from XmTestLib.network_utils import * if ENABLE_HVM_SUPPORT: SKIP("Network-attach not supported for HVM domains") diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py --- a/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py Sat Apr 28 10:28:59 2007 +0100 @@ -8,7 +8,7 @@ import time import time from XmTestLib import * -from network_utils import * +from XmTestLib.network_utils import * if ENABLE_HVM_SUPPORT: SKIP("Network-attach not supported for HVM domains") diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py --- a/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py Sat Apr 28 10:28:59 2007 +0100 @@ -8,7 +8,7 @@ import time import time from XmTestLib import * -from network_utils import * +from XmTestLib.network_utils import * if ENABLE_HVM_SUPPORT: SKIP("Network-attach not supported for HVM domains") diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/tests/network-attach/network_utils.py --- a/tools/xm-test/tests/network-attach/network_utils.py Wed Apr 25 10:39:08 2007 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -#!/usr/bin/python - -# Copyright (C) International Business Machines Corp., 2005 -# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx> - -from XmTestLib import * - -def count_eth(console): - try: - run = console.runCmd("ifconfig -a | grep eth") - except ConsoleError, e: - FAIL(str(e)) - return len(run['output'].splitlines()) - -def get_state(domain_name, number): - s, o = traceCommand("xm network-list %s | awk '/^%d/ {print $5}'" % - (domain_name, number)) - print o - - if s != 0: - FAIL("network-list failed") - if o == "": - return 0 - else: - return int(o) - -def network_attach(domain_name, console): - eths_before = count_eth(console) - status, output = traceCommand("xm network-attach %s" % domain_name) - if status != 0: - return -1, "xm network-attach returned invalid %i != 0" % status - - eths_after = count_eth(console) - if (eths_after != (eths_before+1)): - return -2, "Network device is not actually connected to domU" - - return 0, None - -def network_detach(domain_name, console, num=0): - eths_before = count_eth(console) - status, output = traceCommand("xm network-detach %s %d" % (domain_name, num)) - if status != 0: - return -1, "xm network-detach returned invalid %i != 0" % status - - for i in range(10): - if get_state(domain_name, num) == 0: - break - time.sleep(1) - else: - FAIL("network-detach failed: device did not disappear") - - eths_after = count_eth(console) - if eths_after != (eths_before-1): - return -2, "Network device was not actually disconnected from domU" - - return 0, None diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/tests/xapi/03_xapi-network_pos.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/xm-test/tests/xapi/03_xapi-network_pos.py Sat Apr 28 10:28:59 2007 +0100 @@ -0,0 +1,71 @@ +#!/usr/bin/python + +# Try and create two VMs and a private network betwene the two + +import sys + +from XmTestLib import * +from XmTestLib.network_utils import * + +# Create two domains (default XmTestDomain, with our ramdisk) +try: + domain1 = XmTestDomain() + console1 = domain1.start() + domain2 = XmTestDomain() + console2 = domain2.start() +except DomainError, e: + if verbose: + print "Failed to create test domain because:" + print e.extra + FAIL(str(e)) + +# Create a network + +status, ouptut = traceCommand("xm network-new xapi-network") +if status: + FAIL(output) + +# Attach two domains to it +status, msg = network_attach(domain1.getName(), + console1, bridge='xapi-network') +if status: + FAIL(msg) + +status, msg = network_attach(domain2.getName(), + console2, bridge='xapi-network') +if status: + FAIL(msg) + +# Configure IP addresses on two domains +try: + # Run 'ls' + run = console1.runCmd("ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up") + run = console2.runCmd("ifconfig eth0 192.168.0.2 netmask 255.255.255.0 up") +except ConsoleError, e: + saveLog(console.getHistory()) + FAIL(str(e)) + +# Now ping... +try: + run = console1.runCmd("ping -c 4 192.168.0.2") + if run['return'] > 0: + FAIL("Could not ping other host") + run = console2.runCmd("ping -c 4 192.168.0.1") + if run['return'] > 0: + FAIL("Could not pint other host") +except ConsoleError, e: + saveLog(console.getHistory()) + FAIL(str(e)) + +status, msg = network_detach(domain1.getName(), console1) +status, msg = network_detach(domain2.getName(), console2) + +# Clean up +domain1.closeConsole() +domain1.stop() +domain2.closeConsole() +domain2.stop() + +status, ouptut = traceCommand("xm network-del xapi-network") +if status: + FAIL(output) diff -r ee16cdeddade -r 1668299c0ea4 tools/xm-test/tests/xapi/Makefile.am --- a/tools/xm-test/tests/xapi/Makefile.am Wed Apr 25 10:39:08 2007 +0100 +++ b/tools/xm-test/tests/xapi/Makefile.am Sat Apr 28 10:28:59 2007 +0100 @@ -1,7 +1,8 @@ SUBDIRS = SUBDIRS = TESTS = 01_xapi-vm_basic.test \ - 02_xapi-vbd_basic.test + 02_xapi-vbd_basic.test \ + 03_xapi-network_pos.test XFAIL_TESTS = diff -r ee16cdeddade -r 1668299c0ea4 xen/Makefile --- a/xen/Makefile Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/Makefile Sat Apr 28 10:28:59 2007 +0100 @@ -2,7 +2,7 @@ # All other places this is stored (eg. compile.h) should be autogenerated. export XEN_VERSION = 3 export XEN_SUBVERSION = 0 -export XEN_EXTRAVERSION ?= .5-rc3$(XEN_VENDORVERSION) +export XEN_EXTRAVERSION ?= .5-rc4$(XEN_VENDORVERSION) export XEN_FULLVERSION = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) -include xen-version diff -r ee16cdeddade -r 1668299c0ea4 xen/acm/acm_policy.c --- a/xen/acm/acm_policy.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/acm/acm_policy.c Sat Apr 28 10:28:59 2007 +0100 @@ -46,7 +46,7 @@ static ssidref_t oldssid_to_newssid(cons int -acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size) +acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size) { u8 *policy_buffer = NULL; int ret = -EFAULT; @@ -213,7 +213,7 @@ do_acm_set_policy(void *buf, u32 buf_siz } int -acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size) +acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size) { u8 *policy_buffer; int ret; @@ -278,7 +278,7 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu } int -acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size) +acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size) { /* send stats to user space */ u8 *stats_buffer; @@ -324,7 +324,7 @@ acm_dump_statistics(XEN_GUEST_HANDLE(voi int -acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size) +acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) buf, u16 buf_size) { /* send stats to user space */ u8 *ssid_buffer; diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/domain.c Sat Apr 28 10:28:59 2007 +0100 @@ -237,7 +237,8 @@ static int setup_compat_l4(struct vcpu * l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] = l4e_from_page(pg, __PAGE_HYPERVISOR); l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = - l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); + l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3), + __PAGE_HYPERVISOR); v->arch.guest_table = pagetable_from_page(pg); v->arch.guest_table_user = v->arch.guest_table; @@ -259,7 +260,7 @@ static void release_compat_l4(struct vcp static inline int may_switch_mode(struct domain *d) { - return (d->tot_pages == 0); + return (!is_hvm_domain(d) && (d->tot_pages == 0)); } int switch_native(struct domain *d) @@ -271,10 +272,10 @@ int switch_native(struct domain *d) return -EINVAL; if ( !may_switch_mode(d) ) return -EACCES; - if ( !IS_COMPAT(d) ) + if ( !is_pv_32on64_domain(d) ) return 0; - d->is_compat = 0; + d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 0; release_arg_xlat_area(d); /* switch gdt */ @@ -303,10 +304,10 @@ int switch_compat(struct domain *d) return -ENOSYS; if ( !may_switch_mode(d) ) return -EACCES; - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) return 0; - d->is_compat = 1; + d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 1; /* switch gdt */ gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR); @@ -371,15 +372,12 @@ int vcpu_initialise(struct vcpu *v) v->arch.perdomain_ptes = d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT); - if ( IS_COMPAT(d) && (rc = setup_compat_l4(v)) != 0 ) - return rc; - - return 0; + return (is_pv_32on64_vcpu(v) ? setup_compat_l4(v) : 0); } void vcpu_destroy(struct vcpu *v) { - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_vcpu(v) ) release_compat_l4(v); } @@ -455,7 +453,20 @@ int arch_domain_create(struct domain *d) virt_to_page(d->shared_info), d, XENSHARE_writable); } - return is_hvm_domain(d) ? hvm_domain_initialise(d) : 0; + if ( is_hvm_domain(d) ) + { + if ( (rc = hvm_domain_initialise(d)) != 0 ) + goto fail; + } + else + { + /* 32-bit PV guest by default only if Xen is not 64-bit. */ + d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = + (CONFIG_PAGING_LEVELS != 4); + } + + + return 0; fail: free_xenheap_page(d->shared_info); @@ -491,7 +502,7 @@ void arch_domain_destroy(struct domain * free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3)); #endif - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) release_arg_xlat_area(d); free_xenheap_page(d->shared_info); @@ -508,7 +519,7 @@ int arch_set_info_guest( /* The context is a compat-mode one if the target domain is compat-mode; * we expect the tools to DTRT even in compat-mode callers. */ - compat = IS_COMPAT(d); + compat = is_pv_32on64_domain(d); #ifdef CONFIG_COMPAT #define c(fld) (compat ? (c.cmp->fld) : (c.nat->fld)) @@ -833,7 +844,7 @@ static void load_segments(struct vcpu *n all_segs_okay &= loadsegment(gs, nctxt->user_regs.gs); } - if ( !IS_COMPAT(n->domain) ) + if ( !is_pv_32on64_domain(n->domain) ) { /* This can only be non-zero if selector is NULL. */ if ( nctxt->fs_base ) @@ -867,7 +878,7 @@ static void load_segments(struct vcpu *n (unsigned long *)nctxt->kernel_sp; unsigned long cs_and_mask, rflags; - if ( IS_COMPAT(n->domain) ) + if ( is_pv_32on64_domain(n->domain) ) { unsigned int *esp = ring_1(regs) ? (unsigned int *)regs->rsp : @@ -977,7 +988,7 @@ static void save_segments(struct vcpu *v if ( regs->es ) dirty_segment_mask |= DIRTY_ES; - if ( regs->fs || IS_COMPAT(v->domain) ) + if ( regs->fs || is_pv_32on64_domain(v->domain) ) { dirty_segment_mask |= DIRTY_FS; ctxt->fs_base = 0; /* != 0 selector kills fs_base */ @@ -987,7 +998,7 @@ static void save_segments(struct vcpu *v dirty_segment_mask |= DIRTY_FS_BASE; } - if ( regs->gs || IS_COMPAT(v->domain) ) + if ( regs->gs || is_pv_32on64_domain(v->domain) ) { dirty_segment_mask |= DIRTY_GS; ctxt->gs_base_user = 0; /* != 0 selector kills gs_base_user */ @@ -1123,15 +1134,17 @@ void context_switch(struct vcpu *prev, s __context_switch(); #ifdef CONFIG_COMPAT - if ( is_idle_vcpu(prev) - || IS_COMPAT(prev->domain) != IS_COMPAT(next->domain) ) + if ( is_idle_vcpu(prev) || + (is_pv_32on64_domain(prev->domain) != + is_pv_32on64_domain(next->domain)) ) { uint32_t efer_lo, efer_hi; - local_flush_tlb_one(GDT_VIRT_START(next) + FIRST_RESERVED_GDT_BYTE); + local_flush_tlb_one(GDT_VIRT_START(next) + + FIRST_RESERVED_GDT_BYTE); rdmsr(MSR_EFER, efer_lo, efer_hi); - if ( !IS_COMPAT(next->domain) == !(efer_lo & EFER_SCE) ) + if ( !is_pv_32on64_domain(next->domain) == !(efer_lo & EFER_SCE) ) { efer_lo ^= EFER_SCE; wrmsr(MSR_EFER, efer_lo, efer_hi); @@ -1154,7 +1167,7 @@ void context_switch(struct vcpu *prev, s /* Update per-VCPU guest runstate shared memory area (if registered). */ if ( !guest_handle_is_null(runstate_guest(next)) ) { - if ( !IS_COMPAT(next->domain) ) + if ( !is_pv_32on64_domain(next->domain) ) __copy_to_guest(runstate_guest(next), &next->runstate, 1); #ifdef CONFIG_COMPAT else @@ -1236,7 +1249,7 @@ unsigned long hypercall_create_continuat for ( i = 0; *p != '\0'; i++ ) mcs->call.args[i] = next_arg(p, args); - if ( IS_COMPAT(current->domain) ) + if ( is_pv_32on64_domain(current->domain) ) { for ( ; i < 6; i++ ) mcs->call.args[i] = 0; @@ -1249,7 +1262,7 @@ unsigned long hypercall_create_continuat regs->eip -= 2; /* re-execute 'syscall' / 'int 0x82' */ #ifdef __x86_64__ - if ( !IS_COMPAT(current->domain) ) + if ( !is_pv_32on64_domain(current->domain) ) { for ( i = 0; *p != '\0'; i++ ) { @@ -1268,7 +1281,7 @@ unsigned long hypercall_create_continuat else #endif { - if ( supervisor_mode_kernel || is_hvm_vcpu(current) ) + if ( supervisor_mode_kernel ) regs->eip &= ~31; /* re-execute entire hypercall entry stub */ for ( i = 0; *p != '\0'; i++ ) @@ -1449,14 +1462,11 @@ static void vcpu_destroy_pagetables(stru struct domain *d = v->domain; unsigned long pfn; -#ifdef CONFIG_COMPAT - if ( IS_COMPAT(d) ) - { - if ( is_hvm_vcpu(v) ) - pfn = pagetable_get_pfn(v->arch.guest_table); - else - pfn = l4e_get_pfn(*(l4_pgentry_t *) - __va(pagetable_get_paddr(v->arch.guest_table))); +#ifdef __x86_64__ + if ( is_pv_32on64_vcpu(v) ) + { + pfn = l4e_get_pfn(*(l4_pgentry_t *) + __va(pagetable_get_paddr(v->arch.guest_table))); if ( pfn != 0 ) { @@ -1466,12 +1476,9 @@ static void vcpu_destroy_pagetables(stru put_page_and_type(mfn_to_page(pfn)); } - if ( is_hvm_vcpu(v) ) - v->arch.guest_table = pagetable_null(); - else - l4e_write( - (l4_pgentry_t *) __va(pagetable_get_paddr(v->arch.guest_table)), - l4e_empty()); + l4e_write( + (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)), + l4e_empty()); v->arch.cr3 = 0; return; diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/domain_build.c Sat Apr 28 10:28:59 2007 +0100 @@ -320,11 +320,11 @@ int construct_dom0(struct domain *d, } #ifdef CONFIG_COMPAT - if (compat32) + if ( compat32 ) { l1_pgentry_t gdt_l1e; - d->is_compat = 1; + d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 1; v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0]; if ( nr_pages != (unsigned int)nr_pages ) @@ -350,19 +350,19 @@ int construct_dom0(struct domain *d, #if CONFIG_PAGING_LEVELS < 4 unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1; #else - unsigned long mask = !IS_COMPAT(d) - ? (1UL << L4_PAGETABLE_SHIFT) - 1 - : (1UL << L2_PAGETABLE_SHIFT) - 1; + unsigned long mask = is_pv_32bit_domain(d) + ? (1UL << L2_PAGETABLE_SHIFT) - 1 + : (1UL << L4_PAGETABLE_SHIFT) - 1; #endif value = (parms.virt_hv_start_low + mask) & ~mask; #ifdef CONFIG_COMPAT HYPERVISOR_COMPAT_VIRT_START(d) = max_t(unsigned int, m2p_compat_vstart, value); - d->arch.physaddr_bitsize = !IS_COMPAT(d) ? 64 : + d->arch.physaddr_bitsize = !is_pv_32on64_domain(d) ? 64 : fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1 + (PAGE_SIZE - 2); - if ( value > (!IS_COMPAT(d) ? + if ( value > (!is_pv_32on64_domain(d) ? HYPERVISOR_VIRT_START : __HYPERVISOR_COMPAT_VIRT_START) ) #else @@ -387,7 +387,7 @@ int construct_dom0(struct domain *d, vinitrd_start = round_pgup(vkern_end); vinitrd_end = vinitrd_start + initrd_len; vphysmap_start = round_pgup(vinitrd_end); - vphysmap_end = vphysmap_start + (nr_pages * (!IS_COMPAT(d) ? + vphysmap_end = vphysmap_start + (nr_pages * (!is_pv_32on64_domain(d) ? sizeof(unsigned long) : sizeof(unsigned int))); vstartinfo_start = round_pgup(vphysmap_end); @@ -418,7 +418,7 @@ int construct_dom0(struct domain *d, ((_l) & ~((1UL<<(_s))-1))) >> (_s)) if ( (1 + /* # L4 */ NR(v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */ - (!IS_COMPAT(d) ? + (!is_pv_32on64_domain(d) ? NR(v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */ 4) + /* # compat L2 */ NR(v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */ @@ -613,7 +613,7 @@ int construct_dom0(struct domain *d, #elif defined(__x86_64__) /* Overlap with Xen protected area? */ - if ( !IS_COMPAT(d) ? + if ( !is_pv_32on64_domain(d) ? ((v_start < HYPERVISOR_VIRT_END) && (v_end > HYPERVISOR_VIRT_START)) : (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) ) @@ -622,14 +622,14 @@ int construct_dom0(struct domain *d, return -EINVAL; } - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) { v->arch.guest_context.failsafe_callback_cs = FLAT_COMPAT_KERNEL_CS; v->arch.guest_context.event_callback_cs = FLAT_COMPAT_KERNEL_CS; } /* WARNING: The new domain must have its 'processor' field filled in! */ - if ( !IS_COMPAT(d) ) + if ( !is_pv_32on64_domain(d) ) { maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; @@ -647,7 +647,7 @@ int construct_dom0(struct domain *d, l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); v->arch.guest_table = pagetable_from_paddr(__pa(l4start)); - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) { v->arch.guest_table_user = v->arch.guest_table; if ( setup_arg_xlat_area(v, l4start) < 0 ) @@ -689,7 +689,8 @@ int construct_dom0(struct domain *d, *l2tab = l2e_from_paddr(__pa(l1start), L2_PROT); l2tab++; } - *l1tab = l1e_from_pfn(mfn, !IS_COMPAT(d) ? L1_PROT : COMPAT_L1_PROT); + *l1tab = l1e_from_pfn(mfn, (!is_pv_32on64_domain(d) ? + L1_PROT : COMPAT_L1_PROT)); l1tab++; page = mfn_to_page(mfn); @@ -701,7 +702,7 @@ int construct_dom0(struct domain *d, } #ifdef CONFIG_COMPAT - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) { /* Ensure the first four L3 entries are all populated. */ for ( i = 0, l3tab = l3start; i < 4; ++i, ++l3tab ) @@ -743,7 +744,8 @@ int construct_dom0(struct domain *d, /* Top-level p.t. is pinned. */ if ( (page->u.inuse.type_info & PGT_type_mask) == - (!IS_COMPAT(d) ? PGT_l4_page_table : PGT_l3_page_table) ) + (!is_pv_32on64_domain(d) ? + PGT_l4_page_table : PGT_l3_page_table) ) { page->count_info += 1; page->u.inuse.type_info += 1 | PGT_pinned; @@ -823,7 +825,7 @@ int construct_dom0(struct domain *d, si->shared_info = virt_to_maddr(d->shared_info); si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; - si->pt_base = vpt_start + 2 * PAGE_SIZE * !!IS_COMPAT(d); + si->pt_base = vpt_start + 2 * PAGE_SIZE * !!is_pv_32on64_domain(d); si->nr_pt_frames = nr_pt_pages; si->mfn_list = vphysmap_start; snprintf(si->magic, sizeof(si->magic), "xen-%i.%i-x86_%d%s", @@ -840,7 +842,7 @@ int construct_dom0(struct domain *d, if ( pfn > REVERSE_START ) mfn = alloc_epfn - (pfn - REVERSE_START); #endif - if ( !IS_COMPAT(d) ) + if ( !is_pv_32on64_domain(d) ) ((unsigned long *)vphysmap_start)[pfn] = mfn; else ((unsigned int *)vphysmap_start)[pfn] = mfn; @@ -856,7 +858,7 @@ int construct_dom0(struct domain *d, #ifndef NDEBUG #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn))) #endif - if ( !IS_COMPAT(d) ) + if ( !is_pv_32on64_domain(d) ) ((unsigned long *)vphysmap_start)[pfn] = mfn; else ((unsigned int *)vphysmap_start)[pfn] = mfn; @@ -885,7 +887,7 @@ int construct_dom0(struct domain *d, } #ifdef CONFIG_COMPAT - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) xlat_start_info(si, XLAT_start_info_console_dom0); #endif @@ -913,11 +915,12 @@ int construct_dom0(struct domain *d, * [EAX,EBX,ECX,EDX,EDI,EBP are zero] */ regs = &v->arch.guest_context.user_regs; - regs->ds = regs->es = regs->fs = regs->gs = !IS_COMPAT(d) - ? FLAT_KERNEL_DS - : FLAT_COMPAT_KERNEL_DS; - regs->ss = !IS_COMPAT(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS; - regs->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS; + regs->ds = regs->es = regs->fs = regs->gs = + !is_pv_32on64_domain(d) ? FLAT_KERNEL_DS : FLAT_COMPAT_KERNEL_DS; + regs->ss = (!is_pv_32on64_domain(d) ? + FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS); + regs->cs = (!is_pv_32on64_domain(d) ? + FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS); regs->eip = parms.virt_entry; regs->esp = vstack_end; regs->esi = vstartinfo_start; diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/domctl.c Sat Apr 28 10:28:59 2007 +0100 @@ -435,12 +435,12 @@ void arch_get_info_guest(struct vcpu *v, void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) { #ifdef CONFIG_COMPAT -#define c(fld) (!IS_COMPAT(v->domain) ? (c.nat->fld) : (c.cmp->fld)) +#define c(fld) (!is_pv_32on64_domain(v->domain) ? (c.nat->fld) : (c.cmp->fld)) #else #define c(fld) (c.nat->fld) #endif - if ( !IS_COMPAT(v->domain) ) + if ( !is_pv_32on64_domain(v->domain) ) memcpy(c.nat, &v->arch.guest_context, sizeof(*c.nat)); #ifdef CONFIG_COMPAT else @@ -455,7 +455,7 @@ void arch_get_info_guest(struct vcpu *v, if ( is_hvm_vcpu(v) ) { - if ( !IS_COMPAT(v->domain) ) + if ( !is_pv_32on64_domain(v->domain) ) hvm_store_cpu_guest_regs(v, &c.nat->user_regs, c.nat->ctrlreg); #ifdef CONFIG_COMPAT else @@ -477,7 +477,7 @@ void arch_get_info_guest(struct vcpu *v, BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0); c(user_regs.eflags |= v->arch.iopl << 12); - if ( !IS_COMPAT(v->domain) ) + if ( !is_pv_32on64_domain(v->domain) ) { c.nat->ctrlreg[3] = xen_pfn_to_cr3( pagetable_get_pfn(v->arch.guest_table)); diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/hvm/hvm.c Sat Apr 28 10:28:59 2007 +0100 @@ -1049,15 +1049,13 @@ long do_hvm_op(unsigned long op, XEN_GUE break; case HVM_PARAM_CALLBACK_IRQ: hvm_set_callback_via(d, a.value); -#if defined(__x86_64__) /* * Since this operation is one of the very first executed * by PV drivers on initialisation or after save/restore, it * is a sensible point at which to sample the execution mode of * the guest and latch 32- or 64-bit format for shared state. */ - d->is_compat = (hvm_guest_x86_mode(current) == 4); -#endif + d->arch.has_32bit_shinfo = (hvm_guest_x86_mode(current) != 8); break; } d->arch.hvm_domain.params[a.index] = a.value; diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/save.c --- a/xen/arch/x86/hvm/save.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/hvm/save.c Sat Apr 28 10:28:59 2007 +0100 @@ -99,6 +99,8 @@ int hvm_save(struct domain *d, hvm_domai hdr.changeset = simple_strtoll(c, NULL, 16); else hdr.changeset = -1ULL; /* Unknown */ + + hdr.pad0 = 0; if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 ) { diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/vmx/intr.c --- a/xen/arch/x86/hvm/vmx/intr.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/intr.c Sat Apr 28 10:28:59 2007 +0100 @@ -71,6 +71,9 @@ static void update_tpr_threshold(struct static void update_tpr_threshold(struct vlapic *vlapic) { int max_irr, tpr; + + if ( !cpu_has_vmx_tpr_shadow ) + return; if ( !vlapic_enabled(vlapic) || ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) ) diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Sat Apr 28 10:28:59 2007 +0100 @@ -38,16 +38,16 @@ #include <asm/shadow.h> /* Dynamic (run-time adjusted) execution control flags. */ -u32 vmx_pin_based_exec_control; -u32 vmx_cpu_based_exec_control; -u32 vmx_vmexit_control; -u32 vmx_vmentry_control; - -static u32 vmcs_revision_id; - -static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_max, u32 msr) -{ - u32 vmx_msr_low, vmx_msr_high, ctl = ctl_max; +u32 vmx_pin_based_exec_control __read_mostly; +u32 vmx_cpu_based_exec_control __read_mostly; +u32 vmx_vmexit_control __read_mostly; +u32 vmx_vmentry_control __read_mostly; + +static u32 vmcs_revision_id __read_mostly; + +static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr) +{ + u32 vmx_msr_low, vmx_msr_high, ctl = ctl_min | ctl_opt; rdmsr(msr, vmx_msr_low, vmx_msr_high); @@ -56,46 +56,55 @@ static u32 adjust_vmx_controls(u32 ctl_m /* Ensure minimum (required) set of control bits are supported. */ BUG_ON(ctl_min & ~ctl); - BUG_ON(ctl_min & ~ctl_max); return ctl; } void vmx_init_vmcs_config(void) { - u32 vmx_msr_low, vmx_msr_high, min, max; + u32 vmx_msr_low, vmx_msr_high, min, opt; u32 _vmx_pin_based_exec_control; u32 _vmx_cpu_based_exec_control; u32 _vmx_vmexit_control; u32 _vmx_vmentry_control; - min = max = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING; + min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING; + opt = 0; _vmx_pin_based_exec_control = adjust_vmx_controls( - min, max, MSR_IA32_VMX_PINBASED_CTLS_MSR); - - min = max = (CPU_BASED_HLT_EXITING | - CPU_BASED_INVDPG_EXITING | - CPU_BASED_MWAIT_EXITING | - CPU_BASED_MOV_DR_EXITING | - CPU_BASED_ACTIVATE_IO_BITMAP | - CPU_BASED_USE_TSC_OFFSETING); + min, opt, MSR_IA32_VMX_PINBASED_CTLS_MSR); + + min = (CPU_BASED_HLT_EXITING | + CPU_BASED_INVDPG_EXITING | + CPU_BASED_MWAIT_EXITING | + CPU_BASED_MOV_DR_EXITING | + CPU_BASED_ACTIVATE_IO_BITMAP | + CPU_BASED_USE_TSC_OFFSETING); + opt = CPU_BASED_ACTIVATE_MSR_BITMAP; #ifdef __x86_64__ - min = max |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING; -#endif - max |= CPU_BASED_ACTIVATE_MSR_BITMAP; + opt |= CPU_BASED_TPR_SHADOW; +#endif _vmx_cpu_based_exec_control = adjust_vmx_controls( - min, max, MSR_IA32_VMX_PROCBASED_CTLS_MSR); - - min = max = VM_EXIT_ACK_INTR_ON_EXIT; + min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR); #ifdef __x86_64__ - min = max |= VM_EXIT_IA32E_MODE; + if ( !(_vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) ) + { + min |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING; + _vmx_cpu_based_exec_control = adjust_vmx_controls( + min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR); + } +#endif + + min = VM_EXIT_ACK_INTR_ON_EXIT; + opt = 0; +#ifdef __x86_64__ + min |= VM_EXIT_IA32E_MODE; #endif _vmx_vmexit_control = adjust_vmx_controls( - min, max, MSR_IA32_VMX_EXIT_CTLS_MSR); - - min = max = 0; + min, opt, MSR_IA32_VMX_EXIT_CTLS_MSR); + + min = opt = 0; _vmx_vmentry_control = adjust_vmx_controls( - min, max, MSR_IA32_VMX_ENTRY_CTLS_MSR); + min, opt, MSR_IA32_VMX_ENTRY_CTLS_MSR); rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high); @@ -414,13 +423,12 @@ static void construct_vmcs(struct vcpu * #ifdef __x86_64__ /* VLAPIC TPR optimisation. */ - v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_TPR_SHADOW; - v->arch.hvm_vcpu.u.vmx.exec_control &= - ~(CPU_BASED_CR8_STORE_EXITING | CPU_BASED_CR8_LOAD_EXITING); - __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vcpu.u.vmx.exec_control); - __vmwrite(VIRTUAL_APIC_PAGE_ADDR, - page_to_maddr(vcpu_vlapic(v)->regs_page)); - __vmwrite(TPR_THRESHOLD, 0); + if ( cpu_has_vmx_tpr_shadow ) + { + __vmwrite(VIRTUAL_APIC_PAGE_ADDR, + page_to_maddr(vcpu_vlapic(v)->regs_page)); + __vmwrite(TPR_THRESHOLD, 0); + } #endif __vmwrite(GUEST_LDTR_SELECTOR, 0); diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/machine_kexec.c --- a/xen/arch/x86/machine_kexec.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/machine_kexec.c Sat Apr 28 10:28:59 2007 +0100 @@ -44,9 +44,8 @@ int machine_kexec_load(int type, int slo else { /* Odd pages: va for previous ma. */ - if ( IS_COMPAT(dom0) ) + if ( is_pv_32on64_domain(dom0) ) { - /* * The compatability bounce code sets up a page table * with a 1-1 mapping of the first 1G of memory so @@ -119,7 +118,7 @@ void machine_kexec(xen_kexec_image_t *im void machine_kexec(xen_kexec_image_t *image) { #ifdef CONFIG_COMPAT - if ( IS_COMPAT(dom0) ) + if ( is_pv_32on64_domain(dom0) ) { extern void compat_machine_kexec(unsigned long rnk, unsigned long indirection_page, diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/mm.c Sat Apr 28 10:28:59 2007 +0100 @@ -149,8 +149,8 @@ unsigned long total_pages; #ifdef CONFIG_COMPAT l2_pgentry_t *compat_idle_pg_table_l2 = NULL; -#define l3_disallow_mask(d) (!IS_COMPAT(d) ? \ - L3_DISALLOW_MASK : \ +#define l3_disallow_mask(d) (!is_pv_32on64_domain(d) ? \ + L3_DISALLOW_MASK : \ COMPAT_L3_DISALLOW_MASK) #else #define l3_disallow_mask(d) L3_DISALLOW_MASK @@ -249,7 +249,10 @@ int memory_is_conventional_ram(paddr_t p unsigned long domain_get_maximum_gpfn(struct domain *d) { - return is_hvm_domain(d) ? d->arch.p2m.max_mapped_pfn : arch_get_max_pfn(d); + if ( is_hvm_domain(d) ) + return d->arch.p2m.max_mapped_pfn; + /* NB. PV guests specify nr_pfns rather than max_pfn so we adjust here. */ + return arch_get_max_pfn(d) - 1; } void share_xen_page_with_guest( @@ -718,7 +721,7 @@ get_page_from_l4e( #define adjust_guest_l1e(pl1e, d) \ do { \ if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) && \ - likely(!IS_COMPAT(d)) ) \ + likely(!is_pv_32on64_domain(d)) ) \ { \ /* _PAGE_GUEST_KERNEL page cannot have the Global bit set. */ \ if ( (l1e_get_flags((pl1e)) & (_PAGE_GUEST_KERNEL|_PAGE_GLOBAL)) \ @@ -735,7 +738,7 @@ get_page_from_l4e( #define adjust_guest_l1e(pl1e, d) \ do { \ if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) && \ - likely(!IS_COMPAT(d)) ) \ + likely(!is_pv_32on64_domain(d)) ) \ l1e_add_flags((pl1e), _PAGE_USER); \ } while ( 0 ) #endif @@ -743,22 +746,22 @@ get_page_from_l4e( #define adjust_guest_l2e(pl2e, d) \ do { \ if ( likely(l2e_get_flags((pl2e)) & _PAGE_PRESENT) && \ - likely(!IS_COMPAT(d)) ) \ + likely(!is_pv_32on64_domain(d)) ) \ l2e_add_flags((pl2e), _PAGE_USER); \ } while ( 0 ) -#define adjust_guest_l3e(pl3e, d) \ - do { \ - if ( likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ - l3e_add_flags((pl3e), likely(!IS_COMPAT(d)) ? \ - _PAGE_USER : \ - _PAGE_USER|_PAGE_RW); \ +#define adjust_guest_l3e(pl3e, d) \ + do { \ + if ( likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ + l3e_add_flags((pl3e), likely(!is_pv_32on64_domain(d)) ? \ + _PAGE_USER : \ + _PAGE_USER|_PAGE_RW); \ } while ( 0 ) #define adjust_guest_l4e(pl4e, d) \ do { \ if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) && \ - likely(!IS_COMPAT(d)) ) \ + likely(!is_pv_32on64_domain(d)) ) \ l4e_add_flags((pl4e), _PAGE_USER); \ } while ( 0 ) @@ -771,11 +774,11 @@ get_page_from_l4e( #endif #ifdef CONFIG_COMPAT -#define unadjust_guest_l3e(pl3e, d) \ - do { \ - if ( unlikely(IS_COMPAT(d)) && \ - likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ - l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED); \ +#define unadjust_guest_l3e(pl3e, d) \ + do { \ + if ( unlikely(is_pv_32on64_domain(d)) && \ + likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ + l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED); \ } while ( 0 ) #else #define unadjust_guest_l3e(_p, _d) ((void)(_d)) @@ -907,11 +910,10 @@ static int create_pae_xen_mappings(struc #ifndef CONFIG_COMPAT l2_pgentry_t l2e; int i; -#else - - if ( !IS_COMPAT(d) ) +#endif + + if ( !is_pv_32bit_domain(d) ) return 1; -#endif pl3e = (l3_pgentry_t *)((unsigned long)pl3e & PAGE_MASK); @@ -1106,13 +1108,13 @@ static int alloc_l3_table(struct page_in * 512 entries must be valid/verified, which is most easily achieved * by clearing them out. */ - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) memset(pl3e + 4, 0, (L3_PAGETABLE_ENTRIES - 4) * sizeof(*pl3e)); for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ ) { #if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT) - if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) && i == 3 ) + if ( is_pv_32bit_domain(d) && (i == 3) ) { if ( !(l3e_get_flags(pl3e[i]) & _PAGE_PRESENT) || (l3e_get_flags(pl3e[i]) & l3_disallow_mask(d)) || @@ -1176,7 +1178,7 @@ static int alloc_l4_table(struct page_in pl4e[l4_table_offset(PERDOMAIN_VIRT_START)] = l4e_from_page(virt_to_page(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) pl4e[l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] = l4e_from_page(virt_to_page(d->arch.mm_arg_xlat_l3), __PAGE_HYPERVISOR); @@ -1443,8 +1445,7 @@ static int mod_l3_entry(l3_pgentry_t *pl * Disallow updates to final L3 slot. It contains Xen mappings, and it * would be a pain to ensure they remain continuously valid throughout. */ - if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) && - pgentry_ptr_to_slot(pl3e) >= 3 ) + if ( is_pv_32bit_domain(d) && (pgentry_ptr_to_slot(pl3e) >= 3) ) return 0; #endif @@ -1791,7 +1792,7 @@ int new_guest_cr3(unsigned long mfn) unsigned long old_base_mfn; #ifdef CONFIG_COMPAT - if ( IS_COMPAT(d) ) + if ( is_pv_32on64_domain(d) ) { okay = paging_mode_refcounts(d) ? 0 /* Old code was broken, but what should it be? */ @@ -2023,7 +2024,7 @@ int do_mmuext_op( goto pin_page; case MMUEXT_PIN_L4_TABLE: - if ( IS_COMPAT(FOREIGNDOM) ) + if ( is_pv_32bit_domain(FOREIGNDOM) ) break; type = PGT_l4_page_table; @@ -2768,7 +2769,7 @@ int do_update_va_mapping(unsigned long v flush_tlb_mask(d->domain_dirty_cpumask); break; default: - if ( unlikely(!IS_COMPAT(d) ? + if ( unlikely(!is_pv_32on64_domain(d) ? get_user(vmask, (unsigned long *)bmap_ptr) : get_user(vmask, (unsigned int *)bmap_ptr)) ) rc = -EFAULT; @@ -2790,7 +2791,7 @@ int do_update_va_mapping(unsigned long v flush_tlb_one_mask(d->domain_dirty_cpumask, va); break; default: - if ( unlikely(!IS_COMPAT(d) ? + if ( unlikely(!is_pv_32on64_domain(d) ? get_user(vmask, (unsigned long *)bmap_ptr) : get_user(vmask, (unsigned int *)bmap_ptr)) ) rc = -EFAULT; @@ -3247,7 +3248,7 @@ static int ptwr_emulated_update( nl1e = l1e_from_intpte(val); if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) ) { - if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) && + if ( (CONFIG_PAGING_LEVELS >= 3) && is_pv_32bit_domain(d) && (bytes == 4) && (addr & 4) && !do_cmpxchg && (l1e_get_flags(nl1e) & _PAGE_PRESENT) ) { @@ -3384,7 +3385,7 @@ int ptwr_do_page_fault(struct vcpu *v, u ptwr_ctxt.ctxt.regs = regs; ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size = - IS_COMPAT(d) ? 32 : BITS_PER_LONG; + is_pv_32on64_domain(d) ? 32 : BITS_PER_LONG; ptwr_ctxt.cr2 = addr; ptwr_ctxt.pte = pte; diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/mm/shadow/common.c Sat Apr 28 10:28:59 2007 +0100 @@ -1577,9 +1577,7 @@ void sh_destroy_shadow(struct vcpu *v, m t == SH_type_fl1_pae_shadow || t == SH_type_fl1_64_shadow || t == SH_type_monitor_table || -#ifdef CONFIG_COMPAT - (IS_COMPAT(v->domain) && t == SH_type_l4_64_shadow) || -#endif + (is_pv_32on64_vcpu(v) && t == SH_type_l4_64_shadow) || (page_get_owner(mfn_to_page(_mfn(sp->backpointer))) == v->domain)); @@ -1622,7 +1620,7 @@ void sh_destroy_shadow(struct vcpu *v, m SHADOW_INTERNAL_NAME(sh_destroy_l1_shadow, 4, 4)(v, smfn); break; case SH_type_l2h_64_shadow: - ASSERT( IS_COMPAT(v->domain) ); + ASSERT(is_pv_32on64_vcpu(v)); /* Fall through... */ case SH_type_l2_64_shadow: SHADOW_INTERNAL_NAME(sh_destroy_l2_shadow, 4, 4)(v, smfn); @@ -2668,8 +2666,7 @@ sh_alloc_log_dirty_bitmap(struct domain { ASSERT(d->arch.paging.shadow.dirty_bitmap == NULL); d->arch.paging.shadow.dirty_bitmap_size = - (domain_get_maximum_gpfn(d) + (BITS_PER_LONG - 1)) & - ~(BITS_PER_LONG - 1); + (domain_get_maximum_gpfn(d) + BITS_PER_LONG) & ~(BITS_PER_LONG - 1); d->arch.paging.shadow.dirty_bitmap = xmalloc_array(unsigned long, d->arch.paging.shadow.dirty_bitmap_size / BITS_PER_LONG); @@ -2717,7 +2714,10 @@ static int shadow_log_dirty_enable(struc } #if (SHADOW_OPTIMIZATIONS & SHOPT_LINUX_L3_TOPLEVEL) - if ( IS_COMPAT(d) ) + /* 32bit PV guests on 64bit xen behave like older 64bit linux: they + * change an l4e instead of cr3 to switch tables. Give them the + * same optimization */ + if ( is_pv_32on64_domain(d) ) d->arch.paging.shadow.opt_flags = SHOPT_LINUX_L3_TOPLEVEL; #endif diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/mm/shadow/multi.c Sat Apr 28 10:28:59 2007 +0100 @@ -134,9 +134,8 @@ set_shadow_status(struct vcpu *v, mfn_t d->domain_id, v->vcpu_id, mfn_x(gmfn), shadow_type, mfn_x(smfn)); -#ifdef CONFIG_COMPAT - if ( !IS_COMPAT(d) || shadow_type != SH_type_l4_64_shadow ) -#endif + /* 32-on-64 PV guests don't own their l4 pages so can't get_page them */ + if ( !is_pv_32on64_vcpu(v) || shadow_type != SH_type_l4_64_shadow ) { res = get_page(mfn_to_page(gmfn), d); ASSERT(res == 1); @@ -162,9 +161,8 @@ delete_shadow_status(struct vcpu *v, mfn v->domain->domain_id, v->vcpu_id, mfn_x(gmfn), shadow_type, mfn_x(smfn)); shadow_hash_delete(v, mfn_x(gmfn), shadow_type, smfn); -#ifdef CONFIG_COMPAT - if ( !IS_COMPAT(v->domain) || shadow_type != SH_type_l4_64_shadow ) -#endif + /* 32-on-64 PV guests don't own their l4 pages; see set_shadow_status */ + if ( !is_pv_32on64_vcpu(v) || shadow_type != SH_type_l4_64_shadow ) put_page(mfn_to_page(gmfn)); } @@ -746,7 +744,8 @@ _sh_propagate(struct vcpu *v, // PV guests in 64-bit mode use two different page tables for user vs // supervisor permissions, making the guest's _PAGE_USER bit irrelevant. // It is always shadowed as present... - if ( (GUEST_PAGING_LEVELS == 4) && !IS_COMPAT(d) && !is_hvm_domain(d) ) + if ( (GUEST_PAGING_LEVELS == 4) && !is_pv_32on64_domain(d) + && !is_hvm_domain(d) ) { sflags |= _PAGE_USER; } @@ -1300,7 +1299,7 @@ do { for ( _i = 0; _i < SHADOW_L2_PAGETABLE_ENTRIES; _i++ ) \ { \ if ( (!(_xen)) \ - || !IS_COMPAT(_dom) \ + || !is_pv_32on64_domain(_dom) \ || mfn_to_shadow_page(_sl2mfn)->type != SH_type_l2h_64_shadow \ || (_i < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_dom)) ) \ { \ @@ -1411,7 +1410,7 @@ void sh_install_xen_entries_in_l4(struct __PAGE_HYPERVISOR); } - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_domain(v->domain) ) { /* install compat arg xlat entry */ sl4e[shadow_l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] = @@ -1437,7 +1436,7 @@ static void sh_install_xen_entries_in_l2 int i; #else - if ( !pv_32bit_guest(v) ) + if ( !is_pv_32on64_vcpu(v) ) return; #endif @@ -1622,9 +1621,6 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf #endif #if CONFIG_PAGING_LEVELS >= 3 && GUEST_PAGING_LEVELS >= 3 case SH_type_l2h_shadow: -#ifdef CONFIG_COMPAT - ASSERT( IS_COMPAT(v->domain) ); -#endif sh_install_xen_entries_in_l2h(v, smfn); break; #endif #if CONFIG_PAGING_LEVELS == 2 && GUEST_PAGING_LEVELS == 2 @@ -1685,7 +1681,7 @@ sh_make_monitor_table(struct vcpu *v) l4e = sh_map_domain_page(m4mfn); l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR); sh_unmap_domain_page(l4e); - if ( pv_32bit_guest(v) ) + if ( is_pv_32on64_vcpu(v) ) { // Install a monitor l2 table in slot 3 of the l3 table. // This is used for all Xen entries. @@ -1840,13 +1836,12 @@ static shadow_l2e_t * shadow_get_and_cre shadow_l3e_t new_sl3e; unsigned int t = SH_type_l2_shadow; -#ifdef CONFIG_COMPAT /* Tag compat L2 containing hypervisor (m2p) mappings */ - if ( IS_COMPAT(v->domain) && + if ( is_pv_32on64_domain(v->domain) && guest_l4_table_offset(gw->va) == 0 && guest_l3_table_offset(gw->va) == 3 ) t = SH_type_l2h_shadow; -#endif + /* No l2 shadow installed: find and install it. */ *sl2mfn = get_shadow_status(v, gw->l2mfn, t); if ( !mfn_valid(*sl2mfn) ) @@ -2111,7 +2106,7 @@ void sh_destroy_monitor_table(struct vcp l4_pgentry_t *l4e = sh_map_domain_page(mmfn); ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT); m3mfn = _mfn(l4e_get_pfn(l4e[0])); - if ( pv_32bit_guest(v) ) + if ( is_pv_32on64_vcpu(v) ) { /* Need to destroy the l2 monitor page in slot 3 too */ l3_pgentry_t *l3e = sh_map_domain_page(m3mfn); @@ -3474,7 +3469,7 @@ sh_update_cr3(struct vcpu *v, int do_loc (unsigned long)pagetable_get_pfn(v->arch.guest_table)); #if GUEST_PAGING_LEVELS == 4 - if ( !(v->arch.flags & TF_kernel_mode) && !IS_COMPAT(v->domain) ) + if ( !(v->arch.flags & TF_kernel_mode) && !is_pv_32on64_vcpu(v) ) gmfn = pagetable_get_mfn(v->arch.guest_table_user); else #endif @@ -4285,7 +4280,7 @@ int sh_audit_l3_table(struct vcpu *v, mf mfn = shadow_l3e_get_mfn(*sl3e); gmfn = get_shadow_status(v, audit_gfn_to_mfn(v, gfn, gl3mfn), ((GUEST_PAGING_LEVELS == 3 || - IS_COMPAT(v->domain)) + is_pv_32on64_vcpu(v)) && !shadow_mode_external(v->domain) && (guest_index(gl3e) % 4) == 3) ? SH_type_l2h_shadow diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/traps.c Sat Apr 28 10:28:59 2007 +0100 @@ -124,7 +124,7 @@ static void show_guest_stack(struct cpu_ if ( is_hvm_vcpu(current) ) return; - if ( IS_COMPAT(container_of(regs, struct cpu_info, guest_cpu_user_regs)->current_vcpu->domain) ) + if ( is_pv_32on64_vcpu(current) ) { compat_show_guest_stack(regs, debug_stack_lines); return; @@ -1568,7 +1568,7 @@ static int emulate_privileged_op(struct break; case 3: /* Read CR3 */ - if ( !IS_COMPAT(v->domain) ) + if ( !is_pv_32on64_vcpu(v) ) *reg = xen_pfn_to_cr3(mfn_to_gmfn( v->domain, pagetable_get_pfn(v->arch.guest_table))); #ifdef CONFIG_COMPAT @@ -1625,7 +1625,7 @@ static int emulate_privileged_op(struct case 3: /* Write CR3 */ LOCK_BIGLOCK(v->domain); - if ( !IS_COMPAT(v->domain) ) + if ( !is_pv_32on64_vcpu(v) ) rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg))); #ifdef CONFIG_COMPAT else @@ -1663,7 +1663,7 @@ static int emulate_privileged_op(struct { #ifdef CONFIG_X86_64 case MSR_FS_BASE: - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_vcpu(v) ) goto fail; if ( wrmsr_safe(MSR_FS_BASE, regs->eax, regs->edx) ) goto fail; @@ -1671,7 +1671,7 @@ static int emulate_privileged_op(struct ((u64)regs->edx << 32) | regs->eax; break; case MSR_GS_BASE: - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_vcpu(v) ) goto fail; if ( wrmsr_safe(MSR_GS_BASE, regs->eax, regs->edx) ) goto fail; @@ -1679,7 +1679,7 @@ static int emulate_privileged_op(struct ((u64)regs->edx << 32) | regs->eax; break; case MSR_SHADOW_GS_BASE: - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_vcpu(v) ) goto fail; if ( wrmsr_safe(MSR_SHADOW_GS_BASE, regs->eax, regs->edx) ) goto fail; @@ -1705,19 +1705,19 @@ static int emulate_privileged_op(struct { #ifdef CONFIG_X86_64 case MSR_FS_BASE: - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_vcpu(v) ) goto fail; regs->eax = v->arch.guest_context.fs_base & 0xFFFFFFFFUL; regs->edx = v->arch.guest_context.fs_base >> 32; break; case MSR_GS_BASE: - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_vcpu(v) ) goto fail; regs->eax = v->arch.guest_context.gs_base_kernel & 0xFFFFFFFFUL; regs->edx = v->arch.guest_context.gs_base_kernel >> 32; break; case MSR_SHADOW_GS_BASE: - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32on64_vcpu(v) ) goto fail; regs->eax = v->arch.guest_context.gs_base_user & 0xFFFFFFFFUL; regs->edx = v->arch.guest_context.gs_base_user >> 32; diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/x86_32/entry.S Sat Apr 28 10:28:59 2007 +0100 @@ -75,6 +75,7 @@ ALIGN restore_all_guest: + ASSERT_INTERRUPTS_DISABLED testl $X86_EFLAGS_VM,UREGS_eflags(%esp) jnz restore_all_vm86 #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL @@ -129,10 +130,10 @@ failsafe_callback: movl %eax,TRAPBOUNCE_eip(%edx) movl VCPU_failsafe_sel(%ebx),%eax movw %ax,TRAPBOUNCE_cs(%edx) - movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%edx) + movb $TBF_FAILSAFE,TRAPBOUNCE_flags(%edx) bt $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%ebx) jnc 1f - orw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) + orb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) 1: call create_bounce_frame xorl %eax,%eax movl %eax,UREGS_ds(%esp) @@ -247,7 +248,7 @@ test_guest_events: movl %eax,TRAPBOUNCE_eip(%edx) movl VCPU_event_sel(%ebx),%eax movw %ax,TRAPBOUNCE_cs(%edx) - movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) + movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) call create_bounce_frame jmp test_all_events @@ -270,7 +271,7 @@ process_nmi: leal VCPU_trap_bounce(%ebx),%edx movl %eax,TRAPBOUNCE_eip(%edx) movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx) - movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) + movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) call create_bounce_frame jmp test_all_events @@ -383,7 +384,6 @@ 2: testl $X86_EFLAGS_VM,UREGS_eflag movl %eax,UREGS_cs+4(%esp) movl TRAPBOUNCE_eip(%edx),%eax movl %eax,UREGS_eip+4(%esp) - movb $0,TRAPBOUNCE_flags(%edx) ret .section __ex_table,"a" .long .Lft6,domain_crash_synchronous , .Lft7,domain_crash_synchronous @@ -441,6 +441,7 @@ 1: xorl %eax,%eax testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%edx) jz test_all_events call create_bounce_frame + movb $0,TRAPBOUNCE_flags(%edx) jmp test_all_events exception_with_ints_disabled: diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/asm-offsets.c --- a/xen/arch/x86/x86_64/asm-offsets.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/x86_64/asm-offsets.c Sat Apr 28 10:28:59 2007 +0100 @@ -91,7 +91,7 @@ void __dummy__(void) OFFSET(VCPU_vmx_cr2, struct vcpu, arch.hvm_vmx.cpu_cr2); BLANK(); - OFFSET(DOMAIN_is_compat, struct domain, is_compat); + OFFSET(DOMAIN_is_32bit_pv, struct domain, arch.is_32bit_pv); BLANK(); OFFSET(VMCB_rax, struct vmcb_struct, rax); diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/compat/entry.S --- a/xen/arch/x86/x86_64/compat/entry.S Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/x86_64/compat/entry.S Sat Apr 28 10:28:59 2007 +0100 @@ -101,8 +101,8 @@ compat_test_guest_events: movl VCPU_event_addr(%rbx),%eax movl %eax,TRAPBOUNCE_eip(%rdx) movl VCPU_event_sel(%rbx),%eax - movl %eax,TRAPBOUNCE_cs(%rdx) - movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + movw %ax,TRAPBOUNCE_cs(%rdx) + movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) call compat_create_bounce_frame jmp compat_test_all_events @@ -126,8 +126,8 @@ compat_process_nmi: sti leaq VCPU_trap_bounce(%rbx),%rdx movl %eax,TRAPBOUNCE_eip(%rdx) - movl $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx) - movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + movw $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx) + movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) call compat_create_bounce_frame jmp compat_test_all_events @@ -164,13 +164,12 @@ compat_failsafe_callback: movl VCPU_failsafe_addr(%rbx),%eax movl %eax,TRAPBOUNCE_eip(%rdx) movl VCPU_failsafe_sel(%rbx),%eax - movl %eax,TRAPBOUNCE_cs(%rdx) - movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) + movw %ax,TRAPBOUNCE_cs(%rdx) + movb $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) btq $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx) jnc 1f - orw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) -1: - call compat_create_bounce_frame + orb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) +1: call compat_create_bounce_frame jmp compat_test_all_events .previous .section __pre_ex_table,"a" @@ -185,6 +184,7 @@ ENTRY(compat_post_handle_exception) testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) jz compat_test_all_events call compat_create_bounce_frame + movb $0,TRAPBOUNCE_flags(%rdx) jmp compat_test_all_events ENTRY(compat_int80_direct_trap) @@ -194,7 +194,7 @@ ENTRY(compat_int80_direct_trap) /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK: */ /* {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]} */ /* %rdx: trap_bounce, %rbx: struct vcpu */ -/* On return only %rbx is guaranteed non-clobbered. */ +/* On return only %rbx and %rdx are guaranteed non-clobbered. */ compat_create_bounce_frame: ASSERT_INTERRUPTS_ENABLED mov %fs,%edi @@ -253,7 +253,6 @@ 2: 2: /* Rewrite our stack frame and return to guest-OS mode. */ /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */ - movl $TRAP_syscall,UREGS_entry_vector+8(%rsp) andl $~(X86_EFLAGS_VM|X86_EFLAGS_RF|\ X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp) mov %fs,UREGS_ss+8(%rsp) @@ -266,7 +265,6 @@ 2: movl %eax,UREGS_cs+8(%rsp) movl TRAPBOUNCE_eip(%rdx),%eax movl %eax,UREGS_rip+8(%rsp) - movb $0,TRAPBOUNCE_flags(%rdx) ret .section .fixup,"ax" .Lfx13: @@ -333,7 +331,7 @@ ENTRY(compat_hypercall_table) .quad compat_vcpu_op .quad compat_ni_hypercall /* 25 */ .quad compat_mmuext_op - .quad compat_acm_op + .quad do_acm_op .quad compat_nmi_op .quad compat_sched_op .quad compat_callback_op /* 30 */ @@ -376,7 +374,7 @@ ENTRY(compat_hypercall_args_table) .byte 3 /* compat_vcpu_op */ .byte 0 /* compat_ni_hypercall */ /* 25 */ .byte 4 /* compat_mmuext_op */ - .byte 1 /* compat_acm_op */ + .byte 1 /* do_acm_op */ .byte 2 /* compat_nmi_op */ .byte 2 /* compat_sched_op */ .byte 2 /* compat_callback_op */ /* 30 */ diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/x86_64/entry.S Sat Apr 28 10:28:59 2007 +0100 @@ -29,10 +29,10 @@ switch_to_kernel: leaq VCPU_trap_bounce(%rbx),%rdx movq VCPU_syscall_addr(%rbx),%rax movq %rax,TRAPBOUNCE_eip(%rdx) - movw $0,TRAPBOUNCE_flags(%rdx) + movb $0,TRAPBOUNCE_flags(%rdx) bt $_VGCF_syscall_disables_events,VCPU_guest_context_flags(%rbx) jnc 1f - orw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) 1: call create_bounce_frame jmp test_all_events @@ -80,10 +80,10 @@ failsafe_callback: leaq VCPU_trap_bounce(%rbx),%rdx movq VCPU_failsafe_addr(%rbx),%rax movq %rax,TRAPBOUNCE_eip(%rdx) - movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) + movb $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) bt $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx) jnc 1f - orw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + orb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) 1: call create_bounce_frame jmp test_all_events .previous @@ -191,7 +191,7 @@ test_guest_events: leaq VCPU_trap_bounce(%rbx),%rdx movq VCPU_event_addr(%rbx),%rax movq %rax,TRAPBOUNCE_eip(%rdx) - movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) call create_bounce_frame jmp test_all_events @@ -215,7 +215,7 @@ process_nmi: sti leaq VCPU_trap_bounce(%rbx),%rdx movq %rax,TRAPBOUNCE_eip(%rdx) - movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) call create_bounce_frame jmp test_all_events @@ -231,11 +231,11 @@ ENTRY(int80_direct_trap) /* Check that the callback is non-null. */ leaq VCPU_int80_bounce(%rbx),%rdx - cmp $0,TRAPBOUNCE_flags(%rdx) + cmpb $0,TRAPBOUNCE_flags(%rdx) jz int80_slow_path movq VCPU_domain(%rbx),%rax - testb $1,DOMAIN_is_compat(%rax) + testb $1,DOMAIN_is_32bit_pv(%rax) jnz compat_int80_direct_trap call create_bounce_frame @@ -249,13 +249,13 @@ int80_slow_path: movl $((0x80 << 3) | 0x2),UREGS_error_code(%rsp) movl $TRAP_gp_fault,UREGS_entry_vector(%rsp) /* A GPF wouldn't have incremented the instruction pointer. */ - sub $2,UREGS_rip(%rsp) + subq $2,UREGS_rip(%rsp) jmp handle_exception_saved /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK: */ /* { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS } */ -/* %rdx: trap_bounce, %rbx: struct vcpu */ -/* On return only %rbx is guaranteed non-clobbered. */ +/* %rdx: trap_bounce, %rbx: struct vcpu */ +/* On return only %rbx and %rdx are guaranteed non-clobbered. */ create_bounce_frame: ASSERT_INTERRUPTS_ENABLED testb $TF_kernel_mode,VCPU_thread_flags(%rbx) @@ -336,7 +336,6 @@ 2: subq $16,%rsi testq %rax,%rax jz domain_crash_synchronous movq %rax,UREGS_rip+8(%rsp) - movb $0,TRAPBOUNCE_flags(%rdx) ret .section __ex_table,"a" .quad .Lft2,domain_crash_synchronous , .Lft3,domain_crash_synchronous @@ -357,7 +356,7 @@ ENTRY(domain_crash_synchronous) # create_bounce_frame() temporarily clobbers CS.RPL. Fix up. movq CPUINFO_current_vcpu(%rax),%rax movq VCPU_domain(%rax),%rax - testb $1,DOMAIN_is_compat(%rax) + testb $1,DOMAIN_is_32bit_pv(%rax) setz %al leal (%rax,%rax,2),%eax orb %al,UREGS_cs(%rsp) @@ -374,7 +373,7 @@ ENTRY(ret_from_intr) testb $3,UREGS_cs(%rsp) jz restore_all_xen movq VCPU_domain(%rbx),%rax - testb $1,DOMAIN_is_compat(%rax) + testb $1,DOMAIN_is_32bit_pv(%rax) jz test_all_events jmp compat_test_all_events @@ -396,11 +395,12 @@ 1: movq %rsp,%rdi jz restore_all_xen leaq VCPU_trap_bounce(%rbx),%rdx movq VCPU_domain(%rbx),%rax - testb $1,DOMAIN_is_compat(%rax) + testb $1,DOMAIN_is_32bit_pv(%rax) jnz compat_post_handle_exception testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) jz test_all_events call create_bounce_frame + movb $0,TRAPBOUNCE_flags(%rdx) jmp test_all_events /* No special register assumptions. */ diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/x86_64/mm.c Sat Apr 28 10:28:59 2007 +0100 @@ -384,9 +384,9 @@ int check_descriptor(const struct domain /* All code and data segments are okay. No base/limit checking. */ if ( (b & _SEGMENT_S) ) { - if ( !IS_COMPAT(dom) || !(b & _SEGMENT_L) ) - goto good; - goto bad; + if ( is_pv_32bit_domain(dom) && (b & _SEGMENT_L) ) + goto bad; + goto good; } /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */ diff -r ee16cdeddade -r 1668299c0ea4 xen/arch/x86/x86_64/traps.c --- a/xen/arch/x86/x86_64/traps.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/arch/x86/x86_64/traps.c Sat Apr 28 10:28:59 2007 +0100 @@ -179,7 +179,7 @@ asmlinkage void do_double_fault(struct c void toggle_guest_mode(struct vcpu *v) { - if ( IS_COMPAT(v->domain) ) + if ( is_pv_32bit_vcpu(v) ) return; v->arch.flags ^= TF_kernel_mode; __asm__ __volatile__ ( "swapgs" ); @@ -356,9 +356,6 @@ void init_int80_direct_trap(struct vcpu { struct trap_info *ti = &v->arch.guest_context.trap_ctxt[0x80]; struct trap_bounce *tb = &v->arch.int80_bounce; - - if ( !guest_gate_selector_okay(v->domain, ti->cs) ) - return; tb->flags = TBF_EXCEPTION; tb->cs = ti->cs; @@ -537,7 +534,7 @@ void hypercall_page_initialise(struct do { if ( is_hvm_domain(d) ) hvm_hypercall_page_initialise(d, hypercall_page); - else if ( !IS_COMPAT(d) ) + else if ( !is_pv_32bit_domain(d) ) hypercall_page_initialise_ring3_kernel(hypercall_page); else hypercall_page_initialise_ring1_kernel(hypercall_page); diff -r ee16cdeddade -r 1668299c0ea4 xen/common/Makefile --- a/xen/common/Makefile Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/common/Makefile Sat Apr 28 10:28:59 2007 +0100 @@ -43,7 +43,6 @@ version.o: $(BASEDIR)/include/xen/compil ifeq ($(CONFIG_COMPAT),y) # extra dependencies -acm_ops.o: compat/acm_ops.c grant_table.o: compat/grant_table.c kexec.o: compat/kexec.c schedule.o: compat/schedule.c diff -r ee16cdeddade -r 1668299c0ea4 xen/common/acm_ops.c --- a/xen/common/acm_ops.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/common/acm_ops.c Sat Apr 28 10:28:59 2007 +0100 @@ -12,10 +12,8 @@ * License. * * Process acm command requests from guest OS. - * */ -#ifndef COMPAT #include <xen/config.h> #include <xen/types.h> #include <xen/lib.h> @@ -29,38 +27,25 @@ #include <xen/guest_access.h> #include <acm/acm_hooks.h> -typedef long ret_t; - -#endif /* !COMPAT */ - #ifndef ACM_SECURITY - long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) { return -ENOSYS; } - #else - -#ifndef COMPAT int acm_authorize_acm_ops(struct domain *d) { - /* currently, policy management functions are restricted to privileged domains */ - if (!IS_PRIV(d)) - return -EPERM; - return 0; -} -#endif - - -ret_t do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) -{ - ret_t rc = -EFAULT; - - if (acm_authorize_acm_ops(current->domain)) + return (IS_PRIV(d) ? 0 : -EPERM); +} + +long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) +{ + long rc = -EFAULT; + + if ( acm_authorize_acm_ops(current->domain) ) return -EPERM; switch ( cmd ) @@ -226,11 +211,9 @@ ret_t do_acm_op(int cmd, XEN_GUEST_HANDL rc = acm_change_policy(&chgpolicy); - if (rc == 0) { - if (copy_to_guest(arg, &chgpolicy, 1) != 0) { + if (rc == 0) + if (copy_to_guest(arg, &chgpolicy, 1) != 0) rc = -EFAULT; - } - } break; } @@ -244,11 +227,9 @@ ret_t do_acm_op(int cmd, XEN_GUEST_HANDL rc = acm_relabel_domains(&relabeldoms); - if (rc == 0) { - if (copy_to_guest(arg, &relabeldoms, 1) != 0) { + if (rc == 0) + if (copy_to_guest(arg, &relabeldoms, 1) != 0) rc = -EFAULT; - } - } break; } @@ -260,11 +241,7 @@ ret_t do_acm_op(int cmd, XEN_GUEST_HANDL return rc; } -#endif - -#if defined(CONFIG_COMPAT) && !defined(COMPAT) -#include "compat/acm_ops.c" -#endif +#endif /* defined(ACM_SECURITY) */ /* * Local variables: diff -r ee16cdeddade -r 1668299c0ea4 xen/common/compat/acm_ops.c --- a/xen/common/compat/acm_ops.c Wed Apr 25 10:39:08 2007 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/****************************************************************************** - * compat/acm_ops.c - */ - -#include <compat/acm.h> -#include <compat/acm_ops.h> - -#define COMPAT -#define ret_t int - -#define do_acm_op compat_acm_op - -static inline XEN_GUEST_HANDLE(void) acm_xlat_handle(COMPAT_HANDLE(void) cmp) -{ - XEN_GUEST_HANDLE(void) nat; - - guest_from_compat_handle(nat, cmp); - return nat; -} - -#define acm_setpolicy compat_acm_setpolicy -#define acm_set_policy(h, sz) acm_set_policy(acm_xlat_handle(h), sz) - -#define acm_getpolicy compat_acm_getpolicy -#define acm_get_policy(h, sz) acm_get_policy(acm_xlat_handle(h), sz) - -#define acm_dumpstats compat_acm_dumpstats -#define acm_dump_statistics(h, sz) acm_dump_statistics(acm_xlat_handle(h), sz) - -#define acm_getssid compat_acm_getssid -#define acm_get_ssid(r, h, sz) acm_get_ssid(r, acm_xlat_handle(h), sz) - -#define xen_acm_getdecision acm_getdecision -CHECK_acm_getdecision; -#undef xen_acm_getdecision - -#include "../acm_ops.c" - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff -r ee16cdeddade -r 1668299c0ea4 xen/common/compat/grant_table.c --- a/xen/common/compat/grant_table.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/common/compat/grant_table.c Sat Apr 28 10:28:59 2007 +0100 @@ -133,7 +133,7 @@ int compat_grant_table_op(unsigned int c break; case GNTTABOP_transfer: - for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < count && rc == 0; ++i, ++n ) + for ( n = 0; n < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < count && rc == 0; ++i, ++n ) { if ( unlikely(__copy_from_guest_offset(&cmp.xfer, cmp_uop, i, 1)) ) rc = -EFAULT; @@ -160,7 +160,7 @@ int compat_grant_table_op(unsigned int c break; case GNTTABOP_copy: - for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < count && rc == 0; ++i, ++n ) + for ( n = 0; n < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < count && rc == 0; ++i, ++n ) { if ( unlikely(__copy_from_guest_offset(&cmp.copy, cmp_uop, i, 1)) ) rc = -EFAULT; diff -r ee16cdeddade -r 1668299c0ea4 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/common/sched_credit.c Sat Apr 28 10:28:59 2007 +0100 @@ -1355,6 +1355,10 @@ static __init int csched_start_tickers(v struct csched_pcpu *spc; unsigned int cpu; + /* Is the credit scheduler initialised? */ + if ( csched_priv.ncpus == 0 ) + return 0; + for_each_online_cpu ( cpu ) { spc = CSCHED_PCPU(cpu); diff -r ee16cdeddade -r 1668299c0ea4 xen/include/Makefile --- a/xen/include/Makefile Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/Makefile Sat Apr 28 10:28:59 2007 +0100 @@ -3,8 +3,6 @@ compat-arch-$(CONFIG_X86) := x86_32 compat-arch-$(CONFIG_X86) := x86_32 headers-y := \ - compat/acm.h \ - compat/acm_ops.h \ compat/callback.h \ compat/elfnote.h \ compat/event_channel.h \ diff -r ee16cdeddade -r 1668299c0ea4 xen/include/acm/acm_core.h --- a/xen/include/acm/acm_core.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/acm/acm_core.h Sat Apr 28 10:28:59 2007 +0100 @@ -155,13 +155,13 @@ int acm_init_domain_ssid_new(struct doma int acm_init_domain_ssid_new(struct domain *, ssidref_t ssidref); void acm_free_domain_ssid(struct acm_ssid_domain *ssid); int acm_init_binary_policy(u32 policy_code); -int acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size); +int acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size); int do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy, struct acm_sized_buffer *, struct acm_sized_buffer *, struct acm_sized_buffer *); -int acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size); -int acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size); -int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size); +int acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size); +int acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size); +int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) buf, u16 buf_size); int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook); int acm_set_policy_reference(u8 * buf, u32 buf_size); int acm_dump_policy_reference(u8 *buf, u32 buf_size); diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/desc.h --- a/xen/include/asm-x86/desc.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/desc.h Sat Apr 28 10:28:59 2007 +0100 @@ -64,7 +64,7 @@ #define load_TR(n) __asm__ __volatile__ ("ltr %%ax" : : "a" (__TSS(n)<<3) ) #if defined(__x86_64__) -#define GUEST_KERNEL_RPL(d) (!IS_COMPAT(d) ? 3 : 1) +#define GUEST_KERNEL_RPL(d) (is_pv_32bit_domain(d) ? 1 : 3) #elif defined(__i386__) #define GUEST_KERNEL_RPL(d) ((void)(d), 1) #endif @@ -104,7 +104,7 @@ */ #define guest_gate_selector_okay(d, sel) \ ((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */ \ - ((sel) == (!IS_COMPAT(d) ? \ + ((sel) == (!is_pv_32on64_domain(d) ? \ FLAT_KERNEL_CS : /* Xen default seg? */ \ FLAT_COMPAT_KERNEL_CS)) || \ ((sel) & 4)) /* LDT seg? */ diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/domain.h Sat Apr 28 10:28:59 2007 +0100 @@ -7,11 +7,22 @@ #include <asm/hvm/domain.h> #include <asm/e820.h> +#define has_32bit_shinfo(d) ((d)->arch.has_32bit_shinfo) +#define is_pv_32bit_domain(d) ((d)->arch.is_32bit_pv) +#define is_pv_32bit_vcpu(v) (is_pv_32bit_domain((v)->domain)) +#ifdef __x86_64__ +#define is_pv_32on64_domain(d) (is_pv_32bit_domain(d)) +#else +#define is_pv_32on64_domain(d) (0) +#endif +#define is_pv_32on64_vcpu(v) (is_pv_32on64_domain((v)->domain)) +#define IS_COMPAT(d) (is_pv_32on64_domain(d)) + struct trap_bounce { - unsigned long error_code; - unsigned short flags; /* TBF_ */ - unsigned short cs; - unsigned long eip; + uint32_t error_code; + uint8_t flags; /* TBF_ */ + uint16_t cs; + unsigned long eip; }; #define MAPHASH_ENTRIES 8 @@ -200,6 +211,11 @@ struct arch_domain /* Maximum physical-address bitwidth supported by this guest. */ unsigned int physaddr_bitsize; + + /* Is a 32-bit PV (non-HVM) guest? */ + bool_t is_32bit_pv; + /* Is shared-info page in 32-bit format? */ + bool_t has_32bit_shinfo; } __cacheline_aligned; #ifdef CONFIG_X86_PAE diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Sat Apr 28 10:28:59 2007 +0100 @@ -119,6 +119,8 @@ extern u32 vmx_vmexit_control; #define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 extern u32 vmx_vmentry_control; +#define cpu_has_vmx_tpr_shadow \ + (vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) #define cpu_has_vmx_msr_bitmap \ (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP) extern char *vmx_msr_bitmap; diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/ldt.h --- a/xen/include/asm-x86/ldt.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/ldt.h Sat Apr 28 10:28:59 2007 +0100 @@ -17,7 +17,7 @@ static inline void load_LDT(struct vcpu else { cpu = smp_processor_id(); - desc = (!IS_COMPAT(v->domain) ? gdt_table : compat_gdt_table) + desc = (!is_pv_32on64_vcpu(v) ? gdt_table : compat_gdt_table) + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY; _set_tssldt_desc(desc, LDT_VIRT_START(v), ents*8-1, 2); __asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) ); diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/shadow.h --- a/xen/include/asm-x86/shadow.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/shadow.h Sat Apr 28 10:28:59 2007 +0100 @@ -48,16 +48,6 @@ * not yet supported */ #define shadow_mode_trap_reads(_d) ({ (void)(_d); 0; }) -/* - * 32on64 support - */ -#ifdef __x86_64__ -#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v) && IS_COMPAT((_v)->domain)) -#else -#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v)) -#endif - - /***************************************************************************** * Entry points into the shadow code */ diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/shared.h --- a/xen/include/asm-x86/shared.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/shared.h Sat Apr 28 10:28:59 2007 +0100 @@ -3,66 +3,66 @@ #ifdef CONFIG_COMPAT -#define nmi_reason(d) (!IS_COMPAT(d) ? \ +#define nmi_reason(d) (!has_32bit_shinfo(d) ? \ (void *)&(d)->shared_info->native.arch.nmi_reason : \ (void *)&(d)->shared_info->compat.arch.nmi_reason) -#define GET_SET_SHARED(type, field) \ -static inline type arch_get_##field(const struct domain *d) \ -{ \ - return !IS_COMPAT(d) ? \ - d->shared_info->native.arch.field : \ - d->shared_info->compat.arch.field; \ -} \ -static inline void arch_set_##field(struct domain *d, \ - type val) \ -{ \ - if ( !IS_COMPAT(d) ) \ - d->shared_info->native.arch.field = val; \ - else \ - d->shared_info->compat.arch.field = val; \ +#define GET_SET_SHARED(type, field) \ +static inline type arch_get_##field(const struct domain *d) \ +{ \ + return !has_32bit_shinfo(d) ? \ + d->shared_info->native.arch.field : \ + d->shared_info->compat.arch.field; \ +} \ +static inline void arch_set_##field(struct domain *d, \ + type val) \ +{ \ + if ( !has_32bit_shinfo(d) ) \ + d->shared_info->native.arch.field = val; \ + else \ + d->shared_info->compat.arch.field = val; \ } -#define GET_SET_VCPU(type, field) \ -static inline type arch_get_##field(const struct vcpu *v) \ -{ \ - return !IS_COMPAT(v->domain) ? \ - v->vcpu_info->native.arch.field : \ - v->vcpu_info->compat.arch.field; \ -} \ -static inline void arch_set_##field(struct vcpu *v, \ - type val) \ -{ \ - if ( !IS_COMPAT(v->domain) ) \ - v->vcpu_info->native.arch.field = val; \ - else \ - v->vcpu_info->compat.arch.field = val; \ +#define GET_SET_VCPU(type, field) \ +static inline type arch_get_##field(const struct vcpu *v) \ +{ \ + return !has_32bit_shinfo(v->domain) ? \ + v->vcpu_info->native.arch.field : \ + v->vcpu_info->compat.arch.field; \ +} \ +static inline void arch_set_##field(struct vcpu *v, \ + type val) \ +{ \ + if ( !has_32bit_shinfo(v->domain) ) \ + v->vcpu_info->native.arch.field = val; \ + else \ + v->vcpu_info->compat.arch.field = val; \ } #else #define nmi_reason(d) ((void *)&(d)->shared_info->arch.nmi_reason) -#define GET_SET_SHARED(type, field) \ -static inline type arch_get_##field(const struct domain *d) \ -{ \ - return d->shared_info->arch.field; \ -} \ -static inline void arch_set_##field(struct domain *d, \ - type val) \ -{ \ - d->shared_info->arch.field = val; \ +#define GET_SET_SHARED(type, field) \ +static inline type arch_get_##field(const struct domain *d) \ +{ \ + return d->shared_info->arch.field; \ +} \ +static inline void arch_set_##field(struct domain *d, \ + type val) \ +{ \ + d->shared_info->arch.field = val; \ } -#define GET_SET_VCPU(type, field) \ -static inline type arch_get_##field(const struct vcpu *v) \ -{ \ - return v->vcpu_info->arch.field; \ -} \ -static inline void arch_set_##field(struct vcpu *v, \ - type val) \ -{ \ - v->vcpu_info->arch.field = val; \ +#define GET_SET_VCPU(type, field) \ +static inline type arch_get_##field(const struct vcpu *v) \ +{ \ + return v->vcpu_info->arch.field; \ +} \ +static inline void arch_set_##field(struct vcpu *v, \ + type val) \ +{ \ + v->vcpu_info->arch.field = val; \ } #endif diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/x86_64/page.h --- a/xen/include/asm-x86/x86_64/page.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/x86_64/page.h Sat Apr 28 10:28:59 2007 +0100 @@ -55,12 +55,12 @@ typedef l4_pgentry_t root_pgentry_t; #define is_guest_l1_slot(_s) (1) #define is_guest_l2_slot(_d, _t, _s) \ - ( !IS_COMPAT(_d) || \ + ( !is_pv_32bit_domain(_d) || \ !((_t) & PGT_pae_xen_l2) || \ ((_s) < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_d)) ) #define is_guest_l3_slot(_s) (1) #define is_guest_l4_slot(_d, _s) \ - ( IS_COMPAT(_d) \ + ( is_pv_32bit_domain(_d) \ ? ((_s) == 0) \ : (((_s) < ROOT_PAGETABLE_FIRST_XEN_SLOT) || \ ((_s) > ROOT_PAGETABLE_LAST_XEN_SLOT))) diff -r ee16cdeddade -r 1668299c0ea4 xen/include/asm-x86/x86_64/regs.h --- a/xen/include/asm-x86/x86_64/regs.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/asm-x86/x86_64/regs.h Sat Apr 28 10:28:59 2007 +0100 @@ -10,17 +10,17 @@ #define ring_2(r) (((r)->cs & 3) == 2) #define ring_3(r) (((r)->cs & 3) == 3) -#define guest_kernel_mode(v, r) \ - (!IS_COMPAT((v)->domain) ? \ - ring_3(r) && ((v)->arch.flags & TF_kernel_mode) : \ - ring_1(r)) +#define guest_kernel_mode(v, r) \ + (!is_pv_32bit_vcpu(v) ? \ + (ring_3(r) && ((v)->arch.flags & TF_kernel_mode)) : \ + (ring_1(r))) #define permit_softint(dpl, v, r) \ ((dpl) >= (guest_kernel_mode(v, r) ? 1 : 3)) /* Check for null trap callback handler: Is the EIP null? */ #define null_trap_bounce(v, tb) \ - (!IS_COMPAT((v)->domain) ? (tb)->eip == 0 : ((tb)->cs & ~3) == 0) + (!is_pv_32bit_vcpu(v) ? ((tb)->eip == 0) : (((tb)->cs & ~3) == 0)) /* Number of bytes of on-stack execution state to be context-switched. */ /* NB. Segment registers and bases are not saved/restored on x86/64 stack. */ diff -r ee16cdeddade -r 1668299c0ea4 xen/include/public/domctl.h --- a/xen/include/public/domctl.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/public/domctl.h Sat Apr 28 10:28:59 2007 +0100 @@ -394,8 +394,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_setti #define XEN_DOMCTL_sethvmcontext 34 typedef struct xen_domctl_hvmcontext { uint32_t size; /* IN/OUT: size of buffer / bytes filled */ - XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT: data, or call gethvmcontext - * with NULL buffer to get size req'd */ + XEN_GUEST_HANDLE_64(uint8_t) buffer; /* IN/OUT: data, or call + * gethvmcontext with NULL + * buffer to get size + * req'd */ } xen_domctl_hvmcontext_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t); diff -r ee16cdeddade -r 1668299c0ea4 xen/include/public/hvm/save.h --- a/xen/include/public/hvm/save.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/public/hvm/save.h Sat Apr 28 10:28:59 2007 +0100 @@ -32,7 +32,8 @@ /* * Structures in this header *must* have the same layout in 32bit * and 64bit environments: this means that all fields must be explicitly - * sized types and aligned to their sizes. + * sized types and aligned to their sizes, and the structs must be + * a multiple of eight bytes long. * * Only the state necessary for saving and restoring (i.e. fields * that are analogous to actual hardware state) should go in this file. @@ -77,6 +78,7 @@ struct hvm_save_header { uint32_t version; /* File format version */ uint64_t changeset; /* Version of Xen that saved this file */ uint32_t cpuid; /* CPUID[0x01][%eax] on the saving machine */ + uint32_t pad0; }; DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header); @@ -340,6 +342,7 @@ struct hvm_hw_pci_link { * The router provides a programmable mapping from each link to a GSI. */ uint8_t route[4]; + uint8_t pad0[4]; }; DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link); @@ -364,6 +367,7 @@ struct hvm_hw_pit { uint8_t gate; /* timer start */ } channels[3]; /* 3 x 16 bytes */ uint32_t speaker_data_on; + uint32_t pad0; }; DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit); @@ -379,6 +383,7 @@ struct hvm_hw_rtc { uint8_t cmos_data[RTC_CMOS_SIZE]; /* Index register for 2-part operations */ uint8_t cmos_index; + uint8_t pad0; }; DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc); diff -r ee16cdeddade -r 1668299c0ea4 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/xen/sched.h Sat Apr 28 10:28:59 2007 +0100 @@ -188,8 +188,6 @@ struct domain bool_t is_privileged; /* Is this guest being debugged by dom0? */ bool_t debugger_attached; - /* Is a 'compatibility mode' guest (semantics are arch specific)? */ - bool_t is_compat; /* Are any VCPUs polling event channels (SCHEDOP_poll)? */ bool_t is_polling; /* Is this guest dying (i.e., a zombie)? */ @@ -489,10 +487,8 @@ static inline void vcpu_unblock(struct v #define IS_PRIV(_d) ((_d)->is_privileged) -#ifdef CONFIG_COMPAT -#define IS_COMPAT(_d) ((_d)->is_compat) -#else -#define IS_COMPAT(_d) 0 +#ifndef IS_COMPAT +#define IS_COMPAT(d) 0 #endif #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist)) diff -r ee16cdeddade -r 1668299c0ea4 xen/include/xen/shared.h --- a/xen/include/xen/shared.h Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/xen/shared.h Sat Apr 28 10:28:59 2007 +0100 @@ -12,25 +12,27 @@ typedef union { struct compat_shared_info compat; } shared_info_t; -#define __shared_info(d, s, field) (*(!IS_COMPAT(d) ? \ - &(s)->native.field : \ +#define __shared_info(d, s, field) (*(!has_32bit_shinfo(d) ? \ + &(s)->native.field : \ &(s)->compat.field)) -#define __shared_info_addr(d, s, field) (!IS_COMPAT(d) ? \ - (void *)&(s)->native.field : \ +#define __shared_info_addr(d, s, field) (!has_32bit_shinfo(d) ? \ + (void *)&(s)->native.field : \ (void *)&(s)->compat.field) -#define shared_info(d, field) __shared_info(d, (d)->shared_info, field) -#define shared_info_addr(d, field) __shared_info_addr(d, (d)->shared_info, field) +#define shared_info(d, field) \ + __shared_info(d, (d)->shared_info, field) +#define shared_info_addr(d, field) \ + __shared_info_addr(d, (d)->shared_info, field) typedef union { struct vcpu_info native; struct compat_vcpu_info compat; } vcpu_info_t; -#define vcpu_info(v, field) (*(!IS_COMPAT((v)->domain) ? \ - &(v)->vcpu_info->native.field : \ +#define vcpu_info(v, field) (*(!has_32bit_shinfo((v)->domain) ? \ + &(v)->vcpu_info->native.field : \ &(v)->vcpu_info->compat.field)) -#define vcpu_info_addr(v, field) (!IS_COMPAT((v)->domain) ? \ +#define vcpu_info_addr(v, field) (!has_32bit_shinfo((v)->domain) ? \ (void *)&(v)->vcpu_info->native.field : \ (void *)&(v)->vcpu_info->compat.field) diff -r ee16cdeddade -r 1668299c0ea4 xen/include/xlat.lst --- a/xen/include/xlat.lst Wed Apr 25 10:39:08 2007 +0100 +++ b/xen/include/xlat.lst Sat Apr 28 10:28:59 2007 +0100 @@ -9,7 +9,6 @@ ! cpu_user_regs arch-x86/xen-@arch@.h ! trap_info arch-x86/xen.h ! vcpu_guest_context arch-x86/xen.h -? acm_getdecision acm_ops.h ? evtchn_alloc_unbound event_channel.h ? evtchn_bind_interdomain event_channel.h ? evtchn_bind_ipi event_channel.h _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |