[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User Alex Williamson <alex.williamson@xxxxxx> # Date 1181935991 21600 # Node ID 3b51eebdf9ab83e4473913358d4924370fa75763 # Parent fe42519fb10eba65cf7034e105738f71010933ca # Parent f1ba2e652724cb505a85eef64eaafe9774421011 merge with xen-unstable.hg --- buildconfigs/mk.linux-2.6-xen | 6 docs/src/user.tex | 2 tools/libxen/src/xen_vbd.c | 4 tools/libxen/src/xen_vm.c | 6 tools/python/xen/xend/XendAPI.py | 17 + tools/python/xen/xend/osdep.py | 10 tools/python/xen/xend/server/DevController.py | 32 +- tools/xenfb/xenfb.c | 1 tools/xenstat/xentop/xentop.c | 53 ++- unmodified_drivers/linux-2.6/mkbuildtree | 3 xen/arch/x86/genapic/es7000plat.c | 4 xen/arch/x86/hvm/hpet.c | 3 xen/arch/x86/hvm/hvm.c | 4 xen/arch/x86/hvm/i8254.c | 379 ++++++++++++-------------- xen/arch/x86/hvm/pmtimer.c | 15 - xen/arch/x86/hvm/rtc.c | 139 ++++----- xen/arch/x86/hvm/svm/svm.c | 9 xen/arch/x86/hvm/vlapic.c | 4 xen/arch/x86/hvm/vmx/intr.c | 73 ++--- xen/arch/x86/hvm/vmx/vmcs.c | 5 xen/arch/x86/hvm/vmx/vmx.c | 18 + xen/arch/x86/hvm/vpt.c | 105 +++---- xen/arch/x86/io_apic.c | 9 xen/include/asm-x86/hvm/vmx/vmcs.h | 10 xen/include/asm-x86/hvm/vmx/vmx.h | 14 xen/include/asm-x86/hvm/vpt.h | 8 xen/include/asm-x86/msr.h | 1 xen/include/public/io/ring.h | 2 xen/include/public/io/xs_wire.h | 6 29 files changed, 509 insertions(+), 433 deletions(-) diff -r fe42519fb10e -r 3b51eebdf9ab buildconfigs/mk.linux-2.6-xen --- a/buildconfigs/mk.linux-2.6-xen Fri Jun 15 12:38:35 2007 -0600 +++ b/buildconfigs/mk.linux-2.6-xen Fri Jun 15 13:33:11 2007 -0600 @@ -49,7 +49,7 @@ endif mkdir -p $(INSTALL_BOOT_PATH) $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(INSTALL_BOOT_PATH) install -$(LINUX_DIR)/include/linux/autoconf.h: CONFIG_FILE=$(PWD)/$(LINUX_DIR)/.config +$(LINUX_DIR)/include/linux/autoconf.h: CONFIG_FILE=$(CURDIR)/$(LINUX_DIR)/.config $(LINUX_DIR)/include/linux/autoconf.h: $(LINUX_SRCDIR)/.valid-src rm -rf $(LINUX_DIR) mkdir -p $(LINUX_DIR) @@ -90,8 +90,8 @@ endif echo "VERSION = 2"; \ echo "PATCHLEVEL = 6"; \ echo ""; \ - echo "KERNELSRC := $(PWD)/$(LINUX_SRCDIR)"; \ - echo "KERNELOUTPUT := $(PWD)/$(LINUX_DIR)"; \ + echo "KERNELSRC := $(CURDIR)/$(LINUX_SRCDIR)"; \ + echo "KERNELOUTPUT := $(CURDIR)/$(LINUX_DIR)"; \ echo ""; \ echo "MAKEFLAGS += --no-print-directory"; \ echo ""; \ diff -r fe42519fb10e -r 3b51eebdf9ab docs/src/user.tex --- a/docs/src/user.tex Fri Jun 15 12:38:35 2007 -0600 +++ b/docs/src/user.tex Fri Jun 15 13:33:11 2007 -0600 @@ -3195,6 +3195,8 @@ writing to the VGA console after domain \item [ edid=no,force ] (x86 only) Either force retrieval of monitor EDID information via VESA DDC, or disable it (edid=no). This option should not normally be required except for debugging purposes. +\item [ edd=off,on,skipmbr ] (x86 only) Control retrieval of Extended + Disc Data (EDD) from the BIOS during boot. \item [ console\_to\_ring ] Place guest console output into the hypervisor console ring buffer. This is disabled by default. When enabled, both hypervisor output and guest console output diff -r fe42519fb10e -r 3b51eebdf9ab tools/libxen/src/xen_vbd.c --- a/tools/libxen/src/xen_vbd.c Fri Jun 15 12:38:35 2007 -0600 +++ b/tools/libxen/src/xen_vbd.c Fri Jun 15 13:33:11 2007 -0600 @@ -463,7 +463,7 @@ xen_vbd_set_mode(xen_session *session, x { .type = &abstract_type_string, .u.string_val = vbd }, { .type = &xen_vbd_mode_abstract_type_, - .u.string_val = xen_vbd_mode_to_string(mode) } + .u.enum_val = mode } }; xen_call_(session, "VBD.set_mode", param_values, 2, NULL, NULL); @@ -479,7 +479,7 @@ xen_vbd_set_type(xen_session *session, x { .type = &abstract_type_string, .u.string_val = vbd }, { .type = &xen_vbd_type_abstract_type_, - .u.string_val = xen_vbd_type_to_string(type) } + .u.enum_val = type } }; xen_call_(session, "VBD.set_type", param_values, 2, NULL, NULL); diff -r fe42519fb10e -r 3b51eebdf9ab tools/libxen/src/xen_vm.c --- a/tools/libxen/src/xen_vm.c Fri Jun 15 12:38:35 2007 -0600 +++ b/tools/libxen/src/xen_vm.c Fri Jun 15 13:33:11 2007 -0600 @@ -1142,7 +1142,7 @@ xen_vm_set_actions_after_shutdown(xen_se { .type = &abstract_type_string, .u.string_val = vm }, { .type = &xen_on_normal_exit_abstract_type_, - .u.string_val = xen_on_normal_exit_to_string(after_shutdown) } + .u.enum_val = after_shutdown } }; xen_call_(session, "VM.set_actions_after_shutdown", param_values, 2, NULL, NULL); @@ -1158,7 +1158,7 @@ xen_vm_set_actions_after_reboot(xen_sess { .type = &abstract_type_string, .u.string_val = vm }, { .type = &xen_on_normal_exit_abstract_type_, - .u.string_val = xen_on_normal_exit_to_string(after_reboot) } + .u.enum_val = after_reboot } }; xen_call_(session, "VM.set_actions_after_reboot", param_values, 2, NULL, NULL); @@ -1174,7 +1174,7 @@ xen_vm_set_actions_after_crash(xen_sessi { .type = &abstract_type_string, .u.string_val = vm }, { .type = &xen_on_crash_behaviour_abstract_type_, - .u.string_val = xen_on_crash_behaviour_to_string(after_crash) } + .u.enum_val = after_crash } }; xen_call_(session, "VM.set_actions_after_crash", param_values, 2, NULL, NULL); diff -r fe42519fb10e -r 3b51eebdf9ab tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Fri Jun 15 12:38:35 2007 -0600 +++ b/tools/python/xen/xend/XendAPI.py Fri Jun 15 13:33:11 2007 -0600 @@ -1483,6 +1483,12 @@ class XendAPI(object): else: return xen_api_success_void() + def VM_set_VCPUs_at_startup(self, session, vm_ref, num): + return self.VM_set('VCPUs_at_startup', session, vm_ref, num) + + def VM_set_VCPUs_max(self, session, vm_ref, num): + return self.VM_set('VCPUs_max', session, vm_ref, num) + def VM_set_actions_after_shutdown(self, session, vm_ref, action): if action not in XEN_API_ON_NORMAL_EXIT: return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) @@ -1887,6 +1893,17 @@ class XendAPI(object): xd.managed_config_save(vm) return xen_api_success_void() + def VBD_set_mode(self, session, vbd_ref, mode): + if mode == 'RW': + mode = 'w' + else: + mode = 'r' + xd = XendDomain.instance() + vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref) + vm.set_dev_property('vbd', vbd_ref, 'mode', mode) + xd.managed_config_save(vm) + return xen_api_success_void() + def VBD_get_all(self, session): xendom = XendDomain.instance() vbds = [d.get_vbds() for d in XendDomain.instance().list('all')] diff -r fe42519fb10e -r 3b51eebdf9ab tools/python/xen/xend/osdep.py --- a/tools/python/xen/xend/osdep.py Fri Jun 15 12:38:35 2007 -0600 +++ b/tools/python/xen/xend/osdep.py Fri Jun 15 13:33:11 2007 -0600 @@ -65,11 +65,11 @@ def _solaris_balloon_stat(label): import fcntl import array DEV_XEN_BALLOON = '/dev/xen/balloon' - BLN_IOCTL_CURRENT = 0x4201 - BLN_IOCTL_TARGET = 0x4202 - BLN_IOCTL_LOW = 0x4203 - BLN_IOCTL_HIGH = 0x4204 - BLN_IOCTL_LIMIT = 0x4205 + BLN_IOCTL_CURRENT = 0x42410001 + BLN_IOCTL_TARGET = 0x42410002 + BLN_IOCTL_LOW = 0x42410003 + BLN_IOCTL_HIGH = 0x42410004 + BLN_IOCTL_LIMIT = 0x42410005 label_to_ioctl = { 'Current allocation' : BLN_IOCTL_CURRENT, 'Requested target' : BLN_IOCTL_TARGET, 'Low-mem balloon' : BLN_IOCTL_LOW, diff -r fe42519fb10e -r 3b51eebdf9ab tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Fri Jun 15 12:38:35 2007 -0600 +++ b/tools/python/xen/xend/server/DevController.py Fri Jun 15 13:33:11 2007 -0600 @@ -213,7 +213,7 @@ class DevController: devid = int(devid) frontpath = self.frontendPath(devid) - if frontpath: + if frontpath: backpath = xstransact.Read(frontpath, "backend") # Modify online status /before/ updating state (latter is watched by @@ -224,22 +224,22 @@ class DevController: if force: if backpath: xstransact.Remove(backpath) - if frontpath: + if frontpath: xstransact.Remove(frontpath) - return - - # Wait till both frontpath and backpath are removed from - # xenstore, or timed out - if frontpath: - status = self.waitUntilDestroyed(frontpath) - if status == Timeout: - # Exception will be caught by destroyDevice in XendDomainInfo.py - raise EnvironmentError - if backpath: - status = self.waitUntilDestroyed(backpath) - if status == Timeout: - # Exception will be caught by destroyDevice in XendDomainInfo.py - raise EnvironmentError + return + + # Wait till both frontpath and backpath are removed from + # xenstore, or timed out + if frontpath: + status = self.waitUntilDestroyed(frontpath) + if status == Timeout: + # Exception will be caught by destroyDevice in XendDomainInfo.py + raise EnvironmentError + if backpath: + status = self.waitUntilDestroyed(backpath) + if status == Timeout: + # Exception will be caught by destroyDevice in XendDomainInfo.py + raise EnvironmentError self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid)) diff -r fe42519fb10e -r 3b51eebdf9ab tools/xenfb/xenfb.c --- a/tools/xenfb/xenfb.c Fri Jun 15 12:38:35 2007 -0600 +++ b/tools/xenfb/xenfb.c Fri Jun 15 13:33:11 2007 -0600 @@ -10,7 +10,6 @@ #include <xen/io/protocols.h> #include <sys/select.h> #include <stdbool.h> -#include <xen/linux/evtchn.h> #include <xen/event_channel.h> #include <sys/mman.h> #include <errno.h> diff -r fe42519fb10e -r 3b51eebdf9ab tools/xenstat/xentop/xentop.c --- a/tools/xenstat/xentop/xentop.c Fri Jun 15 12:38:35 2007 -0600 +++ b/tools/xenstat/xentop/xentop.c Fri Jun 15 13:33:11 2007 -0600 @@ -290,12 +290,24 @@ static void print(const char *fmt, ...) } } +static void xentop_attron(int attr) +{ + if (!batch) + attron(attr); +} + +static void xentop_attroff(int attr) +{ + if (!batch) + attroff(attr); +} + /* Print a string with the given attributes set. */ static void attr_addstr(int attr, const char *str) { - attron(attr); + xentop_attron(attr); addstr((curses_str_t)str); - attroff(attr); + xentop_attroff(attr); } /* Handle setting the delay from the user-supplied value in prompt_val */ @@ -780,18 +792,18 @@ void do_header(void) field_id i; /* Turn on REVERSE highlight attribute for headings */ - attron(A_REVERSE); + xentop_attron(A_REVERSE); for(i = 0; i < NUM_FIELDS; i++) { - if(i != 0) + if (i != 0) print(" "); /* The BOLD attribute is turned on for the sort column */ - if(i == sort_field) - attron(A_BOLD); + if (i == sort_field) + xentop_attron(A_BOLD); print("%*s", fields[i].default_width, fields[i].header); - if(i == sort_field) - attroff(A_BOLD); - } - attroff(A_REVERSE); + if (i == sort_field) + xentop_attroff(A_BOLD); + } + xentop_attroff(A_REVERSE); print("\n"); } @@ -838,14 +850,14 @@ void do_domain(xenstat_domain *domain) void do_domain(xenstat_domain *domain) { unsigned int i; - for(i = 0; i < NUM_FIELDS; i++) { - if(i != 0) + for (i = 0; i < NUM_FIELDS; i++) { + if (i != 0) print(" "); - if(i == sort_field) - attron(A_BOLD); + if (i == sort_field) + xentop_attron(A_BOLD); fields[i].print(domain); - if(i == sort_field) - attroff(A_BOLD); + if (i == sort_field) + xentop_attroff(A_BOLD); } print("\n"); } @@ -956,7 +968,8 @@ static void top(void) fail("Failed to retrieve statistics from libxenstat\n"); /* dump summary top information */ - do_summary(); + if (!batch) + do_summary(); /* Count the number of domains for which to report data */ num_domains = xenstat_node_num_domains(cur_node); @@ -976,7 +989,7 @@ static void top(void) first_domain_index = num_domains-1; for (i = first_domain_index; i < num_domains; i++) { - if(current_row() == lines()-1) + if(!batch && current_row() == lines()-1) break; if (i == first_domain_index || repeat_header) do_header(); @@ -989,8 +1002,8 @@ static void top(void) do_vbd(domains[i]); } - if(!batch) - do_bottom_line(); + if (!batch) + do_bottom_line(); free(domains); } diff -r fe42519fb10e -r 3b51eebdf9ab unmodified_drivers/linux-2.6/mkbuildtree --- a/unmodified_drivers/linux-2.6/mkbuildtree Fri Jun 15 12:38:35 2007 -0600 +++ b/unmodified_drivers/linux-2.6/mkbuildtree Fri Jun 15 13:33:11 2007 -0600 @@ -51,6 +51,7 @@ in ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypercall.h include/asm ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/synch_bitops.h include/asm ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/maddr.h include/asm + ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/gnttab_dma.h include/asm mkdir -p include/asm-i386 lndir -silent ${XL}/include/asm-i386 include/asm-i386 ;; @@ -59,12 +60,14 @@ i[34567]86) ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm + ln -sf ${XL}/include/asm-i386/mach-xen/asm/gnttab_dma.h include/asm ;; "ia64") ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm ln -sf ${XL}/include/asm-ia64/maddr.h include/asm + ln -sf ${XL}/include/asm-ia64/gnttab_dma.h include/asm mkdir -p include/asm/xen ln -sf ${XL}/include/asm-ia64/xen/xcom_hcall.h include/asm/xen ln -sf ${XL}/include/asm-ia64/xen/xencomm.h include/asm/xen diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/genapic/es7000plat.c --- a/xen/arch/x86/genapic/es7000plat.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/genapic/es7000plat.c Fri Jun 15 13:33:11 2007 -0600 @@ -299,12 +299,12 @@ void __init void __init es7000_sw_apic() { - if (es7000_plat) { + if (es7000_plat && (es7000_plat != ES7000_ZORRO)) { int mip_status; struct mip_reg es7000_mip_reg; printk("ES7000: Enabling APIC mode.\n"); - memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); + memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); es7000_mip_reg.off_0 = MIP_SW_APIC; es7000_mip_reg.off_38 = (MIP_VALID); while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/hpet.c --- a/xen/arch/x86/hvm/hpet.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/hpet.c Fri Jun 15 13:33:11 2007 -0600 @@ -381,6 +381,9 @@ void hpet_migrate_timers(struct vcpu *v) struct HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet; int i; + if ( v != h->vcpu ) + return; + for ( i = 0; i < HPET_TIMER_NUM; i++ ) migrate_timer(&h->timers[i], v->processor); } diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/hvm.c Fri Jun 15 13:33:11 2007 -0600 @@ -109,11 +109,9 @@ u64 hvm_get_guest_time(struct vcpu *v) void hvm_migrate_timers(struct vcpu *v) { - pit_migrate_timers(v); rtc_migrate_timers(v); hpet_migrate_timers(v); - if ( vcpu_vlapic(v)->pt.enabled ) - migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor); + pt_migrate(v); } void hvm_do_resume(struct vcpu *v) diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/i8254.c --- a/xen/arch/x86/hvm/i8254.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/i8254.c Fri Jun 15 13:33:11 2007 -0600 @@ -3,12 +3,13 @@ * * Copyright (c) 2003-2004 Fabrice Bellard * Copyright (c) 2006 Intel Corperation + * Copyright (c) 2007 Keir Fraser, XenSource Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in @@ -18,14 +19,9 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -/* Edwin Zhai <edwin.zhai@xxxxxxxxx>, Eddie Dong <eddie.dong@xxxxxxxxx> - * Ported to xen: - * Add a new layer of periodic time on top of PIT; - * move speaker io access to hypervisor; + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #include <xen/config.h> @@ -41,8 +37,11 @@ #include <asm/hvm/vpt.h> #include <asm/current.h> -/* Enable DEBUG_PIT may cause guest calibration inaccuracy */ -/* #define DEBUG_PIT */ +#define domain_vpit(d) (&(d)->arch.hvm_domain.pl_time.vpit) +#define vcpu_vpit(vcpu) (domain_vpit((vcpu)->domain)) +#define vpit_domain(pit) (container_of((pit), struct domain, \ + arch.hvm_domain.pl_time.vpit)) +#define vpit_vcpu(pit) (vpit_domain(pit)->vcpu[0]) #define RW_STATE_LSB 1 #define RW_STATE_MSB 2 @@ -52,8 +51,8 @@ static int handle_pit_io(ioreq_t *p); static int handle_pit_io(ioreq_t *p); static int handle_speaker_io(ioreq_t *p); -/* compute with 96 bit intermediate result: (a*b)/c */ -uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) +/* Compute with 96 bit intermediate result: (a*b)/c */ +static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) { union { uint64_t ll; @@ -76,16 +75,18 @@ uint64_t muldiv64(uint64_t a, uint32_t b return res.ll; } -static int pit_get_count(PITState *s, int channel) +static int pit_get_count(PITState *pit, int channel) { uint64_t d; int counter; - struct hvm_hw_pit_channel *c = &s->hw.channels[channel]; - struct periodic_time *pt = &s->pt[channel]; - - d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel], - PIT_FREQ, ticks_per_sec(pt->vcpu)); - switch(c->mode) { + struct hvm_hw_pit_channel *c = &pit->hw.channels[channel]; + struct vcpu *v = vpit_vcpu(pit); + + d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel], + PIT_FREQ, ticks_per_sec(v)); + + switch ( c->mode ) + { case 0: case 1: case 4: @@ -103,16 +104,18 @@ static int pit_get_count(PITState *s, in return counter; } -/* get pit output bit */ -int pit_get_out(PITState *pit, int channel, int64_t current_time) +static int pit_get_out(PITState *pit, int channel) { struct hvm_hw_pit_channel *s = &pit->hw.channels[channel]; uint64_t d; int out; - - d = muldiv64(current_time - pit->count_load_time[channel], - PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu)); - switch(s->mode) { + struct vcpu *v = vpit_vcpu(pit); + + d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel], + PIT_FREQ, ticks_per_sec(v)); + + switch ( s->mode ) + { default: case 0: out = (d >= s->count); @@ -121,29 +124,27 @@ int pit_get_out(PITState *pit, int chann out = (d < s->count); break; case 2: - if ((d % s->count) == 0 && d != 0) - out = 1; - else - out = 0; + out = (((d % s->count) == 0) && (d != 0)); break; case 3: - out = (d % s->count) < ((s->count + 1) >> 1); + out = ((d % s->count) < ((s->count + 1) >> 1)); break; case 4: case 5: out = (d == s->count); break; } + return out; } -/* val must be 0 or 1 */ -void pit_set_gate(PITState *pit, int channel, int val) +static void pit_set_gate(PITState *pit, int channel, int val) { struct hvm_hw_pit_channel *s = &pit->hw.channels[channel]; - struct periodic_time *pt = &pit->pt[channel]; - - switch(s->mode) { + struct vcpu *v = vpit_vcpu(pit); + + switch ( s->mode ) + { default: case 0: case 4: @@ -151,22 +152,14 @@ void pit_set_gate(PITState *pit, int cha break; case 1: case 5: - if (s->gate < val) { - /* restart counting on rising edge */ - pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); -// pit_irq_timer_update(s, s->count_load_time); - } - break; case 2: case 3: - if (s->gate < val) { - /* restart counting on rising edge */ - pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); -// pit_irq_timer_update(s, s->count_load_time); - } - /* XXX: disable/enable counting */ - break; - } + /* Restart counting on rising edge. */ + if ( s->gate < val ) + pit->count_load_time[channel] = hvm_get_guest_time(v); + break; + } + s->gate = val; } @@ -175,57 +168,40 @@ int pit_get_gate(PITState *pit, int chan return pit->hw.channels[channel].gate; } -void pit_time_fired(struct vcpu *v, void *priv) +static void pit_time_fired(struct vcpu *v, void *priv) { uint64_t *count_load_time = priv; *count_load_time = hvm_get_guest_time(v); } -static inline void pit_load_count(PITState *pit, int channel, int val) +static void pit_load_count(PITState *pit, int channel, int val) { u32 period; struct hvm_hw_pit_channel *s = &pit->hw.channels[channel]; struct periodic_time *pt = &pit->pt[channel]; - struct vcpu *v; - - if (val == 0) + struct vcpu *v = vpit_vcpu(pit); + + if ( val == 0 ) val = 0x10000; + pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); s->count = val; period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ); - if (channel != 0) + if ( (v == NULL) || !is_hvm_vcpu(v) || (channel != 0) ) return; -#ifdef DEBUG_PIT - printk("HVM_PIT: pit-load-counter(%p), count=0x%x, period=%uns mode=%d, load_time=%lld\n", - s, - val, - period, - s->mode, - (long long)pit->count_load_time[channel]); -#endif - - /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */ - if ( likely(pit == ¤t->domain->arch.hvm_domain.pl_time.vpit) ) - v = current; - else - v = container_of(pit, struct domain, - arch.hvm_domain.pl_time.vpit)->vcpu[0]; - - switch (s->mode) { + switch ( s->mode ) + { case 2: - /* create periodic time */ + /* Periodic timer. */ create_periodic_time(v, pt, period, 0, 0, pit_time_fired, &pit->count_load_time[channel]); break; case 1: - /* create one shot time */ + /* One-shot timer. */ create_periodic_time(v, pt, period, 0, 1, pit_time_fired, &pit->count_load_time[channel]); -#ifdef DEBUG_PIT - printk("HVM_PIT: create one shot time.\n"); -#endif break; default: destroy_periodic_time(pt); @@ -233,63 +209,84 @@ static inline void pit_load_count(PITSta } } -/* if already latched, do not latch again */ static void pit_latch_count(PITState *s, int channel) { struct hvm_hw_pit_channel *c = &s->hw.channels[channel]; - if (!c->count_latched) { + if ( !c->count_latched ) + { c->latched_count = pit_get_count(s, channel); c->count_latched = c->rw_mode; } } -static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) -{ - PITState *pit = opaque; +static void pit_latch_status(PITState *s, int channel) +{ + struct hvm_hw_pit_channel *c = &s->hw.channels[channel]; + if ( !c->status_latched ) + { + /* TODO: Return NULL COUNT (bit 6). */ + c->status = ((pit_get_out(s, channel) << 7) | + (c->rw_mode << 4) | + (c->mode << 1) | + c->bcd); + c->status_latched = 1; + } +} + +static void pit_ioport_write(struct PITState *pit, uint32_t addr, uint32_t val) +{ int channel, access; struct hvm_hw_pit_channel *s; - val &= 0xff; - + + val &= 0xff; addr &= 3; - if (addr == 3) { + + if ( addr == 3 ) + { channel = val >> 6; - if (channel == 3) { - /* read back command */ - for(channel = 0; channel < 3; channel++) { + if ( channel == 3 ) + { + /* Read-Back Command. */ + for ( channel = 0; channel < 3; channel++ ) + { s = &pit->hw.channels[channel]; - if (val & (2 << channel)) { - if (!(val & 0x20)) { + if ( val & (2 << channel) ) + { + if ( !(val & 0x20) ) pit_latch_count(pit, channel); - } - if (!(val & 0x10) && !s->status_latched) { - /* status latch */ - /* XXX: add BCD and null count */ - s->status = (pit_get_out(pit, channel, hvm_get_guest_time(pit->pt[channel].vcpu)) << 7) | - (s->rw_mode << 4) | - (s->mode << 1) | - s->bcd; - s->status_latched = 1; - } + if ( !(val & 0x10) ) + pit_latch_status(pit, channel); } } - } else { + } + else + { + /* Select Counter <channel>. */ s = &pit->hw.channels[channel]; access = (val >> 4) & 3; - if (access == 0) { + if ( access == 0 ) + { pit_latch_count(pit, channel); - } else { + } + else + { s->rw_mode = access; s->read_state = access; s->write_state = access; - s->mode = (val >> 1) & 7; + if ( s->mode > 5 ) + s->mode -= 4; s->bcd = val & 1; /* XXX: update irq timer ? */ } } - } else { + } + else + { + /* Write Count. */ s = &pit->hw.channels[addr]; - switch(s->write_state) { + switch ( s->write_state ) + { default: case RW_STATE_LSB: pit_load_count(pit, addr, val); @@ -309,19 +306,23 @@ static void pit_ioport_write(void *opaqu } } -static uint32_t pit_ioport_read(void *opaque, uint32_t addr) -{ - PITState *pit = opaque; +static uint32_t pit_ioport_read(struct PITState *pit, uint32_t addr) +{ int ret, count; struct hvm_hw_pit_channel *s; addr &= 3; s = &pit->hw.channels[addr]; - if (s->status_latched) { + + if ( s->status_latched ) + { s->status_latched = 0; ret = s->status; - } else if (s->count_latched) { - switch(s->count_latched) { + } + else if ( s->count_latched ) + { + switch ( s->count_latched ) + { default: case RW_STATE_LSB: ret = s->latched_count & 0xff; @@ -336,8 +337,11 @@ static uint32_t pit_ioport_read(void *op s->count_latched = RW_STATE_MSB; break; } - } else { - switch(s->read_state) { + } + else + { + switch ( s->read_state ) + { default: case RW_STATE_LSB: count = pit_get_count(pit, addr); @@ -359,10 +363,11 @@ static uint32_t pit_ioport_read(void *op break; } } + return ret; } -void pit_stop_channel0_irq(PITState * pit) +void pit_stop_channel0_irq(PITState *pit) { destroy_periodic_time(&pit->pt[0]); } @@ -374,7 +379,8 @@ static void pit_info(PITState *pit) struct periodic_time *pt; int i; - for(i = 0; i < 3; i++) { + for ( i = 0; i < 3; i++ ) + { printk("*****pit channel %d's state:*****\n", i); s = &pit->hw.channels[i]; printk("pit 0x%x.\n", s->count); @@ -392,7 +398,8 @@ static void pit_info(PITState *pit) printk("pit %"PRId64"\n", pit->count_load_time[i]); pt = &pit->pt[i]; - if (pt) { + if ( pt ) + { printk("pit channel %d has a periodic timer:\n", i); printk("pt %d.\n", pt->enabled); printk("pt %d.\n", pt->one_shot); @@ -405,7 +412,6 @@ static void pit_info(PITState *pit) printk("pt %"PRId64"\n", pt->last_plt_gtime); } } - } #else static void pit_info(PITState *pit) @@ -415,7 +421,7 @@ static void pit_info(PITState *pit) static int pit_save(struct domain *d, hvm_domain_context_t *h) { - PITState *pit = &d->arch.hvm_domain.pl_time.vpit; + PITState *pit = domain_vpit(d); pit_info(pit); @@ -425,7 +431,7 @@ static int pit_save(struct domain *d, hv static int pit_load(struct domain *d, hvm_domain_context_t *h) { - PITState *pit = &d->arch.hvm_domain.pl_time.vpit; + PITState *pit = domain_vpit(d); int i; /* Restore the PIT hardware state */ @@ -435,8 +441,8 @@ static int pit_load(struct domain *d, hv /* Recreate platform timers from hardware state. There will be some * time jitter here, but the wall-clock will have jumped massively, so * we hope the guest can handle it. */ - - for(i = 0; i < 3; i++) { + for ( i = 0; i < 3; i++ ) + { pit_load_count(pit, i, pit->hw.channels[i].count); pit->pt[i].last_plt_gtime = hvm_get_guest_time(d->vcpu[0]); } @@ -447,121 +453,94 @@ static int pit_load(struct domain *d, hv HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM); -static void pit_reset(void *opaque) -{ - PITState *pit = opaque; +void pit_init(struct vcpu *v, unsigned long cpu_khz) +{ + PITState *pit = vcpu_vpit(v); + struct periodic_time *pt; struct hvm_hw_pit_channel *s; int i; - for(i = 0;i < 3; i++) { - s = &pit->hw.channels[i]; - destroy_periodic_time(&pit->pt[i]); - s->mode = 0xff; /* the init mode */ - s->gate = (i != 2); - pit_load_count(pit, i, 0); - } -} - -void pit_init(struct vcpu *v, unsigned long cpu_khz) -{ - PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit; - struct periodic_time *pt; - pt = &pit->pt[0]; - pt->vcpu = v; - /* the timer 0 is connected to an IRQ */ - init_timer(&pt->timer, pt_timer_fn, pt, v->processor); - pt++; pt->vcpu = v; - pt++; pt->vcpu = v; + pt[0].vcpu = v; + pt[1].vcpu = v; + pt[2].vcpu = v; register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io); /* register the speaker port */ register_portio_handler(v->domain, 0x61, 1, handle_speaker_io); ticks_per_sec(v) = cpu_khz * (int64_t)1000; -#ifdef DEBUG_PIT - printk("HVM_PIT: guest frequency =%lld\n", (long long)ticks_per_sec(v)); -#endif - pit_reset(pit); - return; -} - -void pit_migrate_timers(struct vcpu *v) -{ - PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit; - struct periodic_time *pt; - - pt = &pit->pt[0]; - if ( pt->vcpu == v && pt->enabled ) - migrate_timer(&pt->timer, v->processor); + + for ( i = 0; i < 3; i++ ) + { + s = &pit->hw.channels[i]; + s->mode = 0xff; /* the init mode */ + s->gate = (i != 2); + pit_load_count(pit, i, 0); + } } void pit_deinit(struct domain *d) { - PITState *pit = &d->arch.hvm_domain.pl_time.vpit; - - kill_timer(&pit->pt[0].timer); + PITState *pit = domain_vpit(d); + destroy_periodic_time(&pit->pt[0]); } /* the intercept action for PIT DM retval:0--not handled; 1--handled */ static int handle_pit_io(ioreq_t *p) { - struct vcpu *v = current; - struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit); - - if (p->size != 1 || - p->data_is_ptr || - p->type != IOREQ_TYPE_PIO){ - printk("HVM_PIT:wrong PIT IO!\n"); + struct PITState *vpit = vcpu_vpit(current); + + if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) ) + { + gdprintk(XENLOG_WARNING, "HVM_PIT bad access\n"); return 1; } - if (p->dir == 0) {/* write */ + if ( p->dir == IOREQ_WRITE ) + { pit_ioport_write(vpit, p->addr, p->data); - } else if (p->dir == 1) { /* read */ - if ( (p->addr & 3) != 3 ) { + } + else + { + if ( (p->addr & 3) != 3 ) p->data = pit_ioport_read(vpit, p->addr); - } else { - printk("HVM_PIT: read A1:A0=3!\n"); - } - } + else + gdprintk(XENLOG_WARNING, "HVM_PIT: read A1:A0=3!\n"); + } + return 1; } -static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val) -{ - PITState *pit = opaque; +static void speaker_ioport_write( + struct PITState *pit, uint32_t addr, uint32_t val) +{ pit->hw.speaker_data_on = (val >> 1) & 1; pit_set_gate(pit, 2, val & 1); } -static uint32_t speaker_ioport_read(void *opaque, uint32_t addr) -{ - PITState *pit = opaque; - int out = pit_get_out(pit, 2, - hvm_get_guest_time(pit->pt[2].vcpu)); +static uint32_t speaker_ioport_read( + struct PITState *pit, uint32_t addr) +{ /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */ unsigned int refresh_clock = ((unsigned int)NOW() >> 14) & 1; return ((pit->hw.speaker_data_on << 1) | pit_get_gate(pit, 2) | - (out << 5) | refresh_clock << 4); + (pit_get_out(pit, 2) << 5) | (refresh_clock << 4)); } static int handle_speaker_io(ioreq_t *p) { - struct vcpu *v = current; - struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit); - - if (p->size != 1 || - p->data_is_ptr || - p->type != IOREQ_TYPE_PIO){ - printk("HVM_SPEAKER:wrong SPEAKER IO!\n"); + struct PITState *vpit = vcpu_vpit(current); + + if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) ) + { + gdprintk(XENLOG_WARNING, "HVM_SPEAKER bad access\n"); return 1; } - if (p->dir == 0) {/* write */ + if ( p->dir == IOREQ_WRITE ) speaker_ioport_write(vpit, p->addr, p->data); - } else if (p->dir == 1) {/* read */ + else p->data = speaker_ioport_read(vpit, p->addr); - } return 1; } @@ -576,7 +555,7 @@ int pv_pit_handler(int port, int data, i .data = write ? data : 0, }; - if (port == 0x61) + if ( port == 0x61 ) handle_speaker_io(&ioreq); else handle_pit_io(&ioreq); diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/pmtimer.c --- a/xen/arch/x86/hvm/pmtimer.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/pmtimer.c Fri Jun 15 13:33:11 2007 -0600 @@ -50,7 +50,6 @@ #define TMR_VAL_MASK (0xffffffff) #define TMR_VAL_MSB (0x80000000) - /* Dispatch SCIs based on the PM1a_STS and PM1a_EN registers */ static void pmt_update_sci(PMTState *s) { @@ -89,19 +88,19 @@ static void pmt_timer_callback(void *opa PMTState *s = opaque; uint32_t pmt_cycles_until_flip; uint64_t time_until_flip; - + /* Recalculate the timer and make sure we get an SCI if we need one */ pmt_update_time(s); - + /* How close are we to the next MSB flip? */ pmt_cycles_until_flip = TMR_VAL_MSB - (s->pm.tmr_val & (TMR_VAL_MSB - 1)); - + /* Overall time between MSB flips */ - time_until_flip = (1000000000ULL << 31) / FREQUENCE_PMTIMER; - + time_until_flip = (1000000000ULL << 23) / FREQUENCE_PMTIMER; + /* Reduced appropriately */ - time_until_flip = (time_until_flip * pmt_cycles_until_flip) / (1ULL<<31); - + time_until_flip = (time_until_flip * pmt_cycles_until_flip) >> 23; + /* Wake up again near the next bit-flip */ set_timer(&s->timer, NOW() + time_until_flip + MILLISECS(1)); } diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/rtc.c --- a/xen/arch/x86/hvm/rtc.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/rtc.c Fri Jun 15 13:33:11 2007 -0600 @@ -28,7 +28,11 @@ #include <asm/hvm/support.h> #include <asm/current.h> -/* #define DEBUG_RTC */ +#define domain_vrtc(d) (&(d)->arch.hvm_domain.pl_time.vrtc) +#define vcpu_vrtc(vcpu) (domain_vrtc((vcpu)->domain)) +#define vrtc_domain(rtc) (container_of((rtc), struct domain, \ + arch.hvm_domain.pl_time.vrtc)) +#define vrtc_vcpu(rtc) (vrtc_domain(rtc)->vcpu[0]) void rtc_periodic_cb(struct vcpu *v, void *opaque) { @@ -41,31 +45,31 @@ int is_rtc_periodic_irq(void *opaque) RTCState *s = opaque; return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || - s->hw.cmos_data[RTC_REG_C] & RTC_UF); + s->hw.cmos_data[RTC_REG_C] & RTC_UF); } /* Enable/configure/disable the periodic timer based on the RTC_PIE and * RTC_RATE_SELECT settings */ -static void rtc_timer_update(RTCState *s, struct vcpu *v) -{ - int period_code; - int period; +static void rtc_timer_update(RTCState *s) +{ + int period_code, period; + struct vcpu *v = vrtc_vcpu(s); period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT; if ( (period_code != 0) && (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) ) { if ( period_code <= 2 ) period_code += 7; - + period = 1 << (period_code - 1); /* period in 32 Khz cycles */ period = DIV_ROUND((period * 1000000000ULL), 32768); /* period in ns */ -#ifdef DEBUG_RTC - printk("HVM_RTC: period = %uns\n", period); -#endif - create_periodic_time(v, &s->pt, period, RTC_IRQ, 0, rtc_periodic_cb, s); - } - else + create_periodic_time(v, &s->pt, period, RTC_IRQ, + 0, rtc_periodic_cb, s); + } + else + { destroy_periodic_time(&s->pt); + } } static void rtc_set_time(RTCState *s); @@ -80,13 +84,8 @@ static int rtc_ioport_write(void *opaque return (s->hw.cmos_index < RTC_CMOS_SIZE); } - if (s->hw.cmos_index >= RTC_CMOS_SIZE) + if ( s->hw.cmos_index >= RTC_CMOS_SIZE ) return 0; - -#ifdef DEBUG_RTC - printk("HVM_RTC: write index=0x%02x val=0x%02x\n", - s->hw.cmos_index, data); -#endif switch ( s->hw.cmos_index ) { @@ -111,7 +110,7 @@ static int rtc_ioport_write(void *opaque /* UIP bit is read only */ s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (s->hw.cmos_data[RTC_REG_A] & RTC_UIP); - rtc_timer_update(s, current); + rtc_timer_update(s); break; case RTC_REG_B: if ( data & RTC_SET ) @@ -127,7 +126,7 @@ static int rtc_ioport_write(void *opaque rtc_set_time(s); } s->hw.cmos_data[RTC_REG_B] = data; - rtc_timer_update(s, current); + rtc_timer_update(s); break; case RTC_REG_C: case RTC_REG_D: @@ -181,10 +180,12 @@ static void rtc_copy_date(RTCState *s) static void rtc_copy_date(RTCState *s) { const struct tm *tm = &s->current_tm; - - if (s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds) { - s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain)); - s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds; + struct domain *d = vrtc_domain(s); + + if ( s->time_offset_seconds != d->time_offset_seconds ) + { + s->current_tm = gmtime(get_localtime(d)); + s->time_offset_seconds = d->time_offset_seconds; } s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec); @@ -228,34 +229,43 @@ static void rtc_next_second(RTCState *s) { struct tm *tm = &s->current_tm; int days_in_month; - - if (s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds) { - s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain)); - s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds; + struct domain *d = vrtc_domain(s); + + if ( s->time_offset_seconds != d->time_offset_seconds ) + { + s->current_tm = gmtime(get_localtime(d)); + s->time_offset_seconds = d->time_offset_seconds; } tm->tm_sec++; - if ((unsigned)tm->tm_sec >= 60) { + if ( (unsigned)tm->tm_sec >= 60 ) + { tm->tm_sec = 0; tm->tm_min++; - if ((unsigned)tm->tm_min >= 60) { + if ( (unsigned)tm->tm_min >= 60 ) + { tm->tm_min = 0; tm->tm_hour++; - if ((unsigned)tm->tm_hour >= 24) { + if ( (unsigned)tm->tm_hour >= 24 ) + { tm->tm_hour = 0; /* next day */ tm->tm_wday++; - if ((unsigned)tm->tm_wday >= 7) + if ( (unsigned)tm->tm_wday >= 7 ) tm->tm_wday = 0; days_in_month = get_days_in_month(tm->tm_mon, tm->tm_year + 1900); tm->tm_mday++; - if (tm->tm_mday < 1) { + if ( tm->tm_mday < 1 ) + { tm->tm_mday = 1; - } else if (tm->tm_mday > days_in_month) { + } + else if ( tm->tm_mday > days_in_month ) + { tm->tm_mday = 1; tm->tm_mon++; - if (tm->tm_mon >= 12) { + if ( tm->tm_mon >= 12 ) + { tm->tm_mon = 0; tm->tm_year++; } @@ -290,6 +300,7 @@ static void rtc_update_second2(void *opa static void rtc_update_second2(void *opaque) { RTCState *s = opaque; + struct domain *d = vrtc_domain(s); if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) rtc_copy_date(s); @@ -308,8 +319,8 @@ static void rtc_update_second2(void *opa s->current_tm.tm_hour) ) { s->hw.cmos_data[RTC_REG_C] |= 0xa0; - hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); - hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ); + hvm_isa_irq_deassert(d, RTC_IRQ); + hvm_isa_irq_assert(d, RTC_IRQ); } } @@ -317,8 +328,8 @@ static void rtc_update_second2(void *opa if ( s->hw.cmos_data[RTC_REG_B] & RTC_UIE ) { s->hw.cmos_data[RTC_REG_C] |= 0x90; - hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); - hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ); + hvm_isa_irq_deassert(d, RTC_IRQ); + hvm_isa_irq_assert(d, RTC_IRQ); } /* clear update in progress bit */ @@ -352,39 +363,33 @@ static uint32_t rtc_ioport_read(void *op break; case RTC_REG_C: ret = s->hw.cmos_data[s->hw.cmos_index]; - hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); - s->hw.cmos_data[RTC_REG_C] = 0x00; + hvm_isa_irq_deassert(vrtc_domain(s), RTC_IRQ); + s->hw.cmos_data[RTC_REG_C] = 0x00; break; default: ret = s->hw.cmos_data[s->hw.cmos_index]; break; } -#ifdef DEBUG_RTC - printk("HVM_RTC: read index=0x%02x val=0x%02x\n", - s->hw.cmos_index, ret); -#endif - return ret; } static int handle_rtc_io(ioreq_t *p) { - struct vcpu *v = current; - struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc; + struct RTCState *vrtc = vcpu_vrtc(current); if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) ) { - printk("HVM_RTC: wrong RTC IO!\n"); + gdprintk(XENLOG_WARNING, "HVM_RTC bas access\n"); return 1; } - if ( p->dir == 0 ) /* write */ + if ( p->dir == IOREQ_WRITE ) { if ( rtc_ioport_write(vrtc, p->addr, p->data & 0xFF) ) return 1; } - else if ( (p->dir == 1) && (vrtc->hw.cmos_index < RTC_CMOS_SIZE) ) /* read */ + else if ( vrtc->hw.cmos_index < RTC_CMOS_SIZE ) { p->data = rtc_ioport_read(vrtc, p->addr); return 1; @@ -393,15 +398,12 @@ static int handle_rtc_io(ioreq_t *p) return 0; } -/* Move the RTC timers on to this vcpu's current cpu */ void rtc_migrate_timers(struct vcpu *v) { - RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; - - if ( s->pt.vcpu == v ) - { - if ( s->pt.enabled ) - migrate_timer(&s->pt.timer, v->processor); + RTCState *s = vcpu_vrtc(v); + + if ( v->vcpu_id == 0 ) + { migrate_timer(&s->second_timer, v->processor); migrate_timer(&s->second_timer2, v->processor); } @@ -410,13 +412,14 @@ void rtc_migrate_timers(struct vcpu *v) /* Save RTC hardware state */ static int rtc_save(struct domain *d, hvm_domain_context_t *h) { - return hvm_save_entry(RTC, 0, h, &d->arch.hvm_domain.pl_time.vrtc.hw); + RTCState *s = domain_vrtc(d); + return hvm_save_entry(RTC, 0, h, &s->hw); } /* Reload the hardware state from a saved domain */ static int rtc_load(struct domain *d, hvm_domain_context_t *h) { - RTCState *s = &d->arch.hvm_domain.pl_time.vrtc; + RTCState *s = domain_vrtc(d); /* Restore the registers */ if ( hvm_load_entry(RTC, h, &s->hw) != 0 ) @@ -431,7 +434,7 @@ static int rtc_load(struct domain *d, hv set_timer(&s->second_timer2, s->next_second_time); /* Reset the periodic interrupt timer based on the registers */ - rtc_timer_update(s, d->vcpu[0]); + rtc_timer_update(s); return 0; } @@ -441,9 +444,8 @@ HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, void rtc_init(struct vcpu *v, int base) { - RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; - - s->pt.vcpu = v; + RTCState *s = vcpu_vrtc(v); + s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */ s->hw.cmos_data[RTC_REG_B] = RTC_24H; s->hw.cmos_data[RTC_REG_C] = 0; @@ -452,7 +454,6 @@ void rtc_init(struct vcpu *v, int base) s->current_tm = gmtime(get_localtime(v->domain)); rtc_copy_date(s); - init_timer(&s->pt.timer, pt_timer_fn, &s->pt, v->processor); init_timer(&s->second_timer, rtc_update_second, s, v->processor); init_timer(&s->second_timer2, rtc_update_second2, s, v->processor); @@ -464,9 +465,9 @@ void rtc_init(struct vcpu *v, int base) void rtc_deinit(struct domain *d) { - RTCState *s = &d->arch.hvm_domain.pl_time.vrtc; - - kill_timer(&s->pt.timer); + RTCState *s = domain_vrtc(d); + + destroy_periodic_time(&s->pt); kill_timer(&s->second_timer); kill_timer(&s->second_timer2); } diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/svm/svm.c Fri Jun 15 13:33:11 2007 -0600 @@ -2089,6 +2089,15 @@ static inline void svm_do_msr_access( msr_content = 1ULL << 61; /* MC4_MISC.Locked */ break; + case MSR_IA32_EBC_FREQUENCY_ID: + /* + * This Intel-only register may be accessed if this HVM guest + * has been migrated from an Intel host. The value zero is not + * particularly meaningful, but at least avoids the guest crashing! + */ + msr_content = 0; + break; + default: if ( rdmsr_hypervisor_regs(ecx, &eax, &edx) || rdmsr_safe(ecx, eax, edx) == 0 ) diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/vlapic.c Fri Jun 15 13:33:11 2007 -0600 @@ -944,8 +944,6 @@ int vlapic_init(struct vcpu *v) if ( v->vcpu_id == 0 ) vlapic->hw.apic_base_msr |= MSR_IA32_APICBASE_BSP; - init_timer(&vlapic->pt.timer, pt_timer_fn, &vlapic->pt, v->processor); - return 0; } @@ -953,7 +951,7 @@ void vlapic_destroy(struct vcpu *v) { struct vlapic *vlapic = vcpu_vlapic(v); - kill_timer(&vlapic->pt.timer); + destroy_periodic_time(&vlapic->pt); unmap_domain_page_global(vlapic->regs); free_domheap_page(vlapic->regs_page); } diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vmx/intr.c --- a/xen/arch/x86/hvm/vmx/intr.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/vmx/intr.c Fri Jun 15 13:33:11 2007 -0600 @@ -1,6 +1,7 @@ /* - * io.c: handling I/O, interrupts related VMX entry/exit + * intr.c: handling I/O, interrupts related VMX entry/exit * Copyright (c) 2004, Intel Corporation. + * Copyright (c) 2004-2007, XenSource Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -14,7 +15,6 @@ * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. - * */ #include <xen/config.h> @@ -24,7 +24,6 @@ #include <xen/errno.h> #include <xen/trace.h> #include <xen/event.h> - #include <asm/current.h> #include <asm/cpufeature.h> #include <asm/processor.h> @@ -39,32 +38,48 @@ #include <public/hvm/ioreq.h> #include <asm/hvm/trace.h> +/* + * A few notes on virtual NMI and INTR delivery, and interactions with + * interruptibility states: + * + * We can only inject an ExtInt if EFLAGS.IF = 1 and no blocking by + * STI nor MOV SS. Otherwise the VM entry fails. The 'virtual interrupt + * pending' control causes a VM exit when all these checks succeed. It will + * exit immediately after VM entry if the checks succeed at that point. + * + * We can only inject an NMI if no blocking by MOV SS (also, depending on + * implementation, if no blocking by STI). If pin-based 'virtual NMIs' + * control is specified then the NMI-blocking interruptibility flag is + * also checked. The 'virtual NMI pending' control (available only in + * conjunction with 'virtual NMIs') causes a VM exit when all these checks + * succeed. It will exit immediately after VM entry if the checks succeed + * at that point. + * + * Because a processor may or may not check blocking-by-STI when injecting + * a virtual NMI, it will be necessary to convert that to block-by-MOV-SS + * before specifying the 'virtual NMI pending' control. Otherwise we could + * enter an infinite loop where we check blocking-by-STI in software and + * thus delay delivery of a virtual NMI, but the processor causes immediate + * VM exit because it does not check blocking-by-STI. + * + * Injecting a virtual NMI sets the NMI-blocking interruptibility flag only + * if the 'virtual NMIs' control is set. Injecting *any* kind of event clears + * the STI- and MOV-SS-blocking interruptibility-state flags. + * + * If MOV/POP SS is executed while MOV-SS-blocking is in effect, the effect + * is cleared. If STI is executed while MOV-SS- or STI-blocking is in effect, + * the effect is cleared. (i.e., MOV-SS-blocking 'dominates' STI-blocking). + */ -static inline void -enable_irq_window(struct vcpu *v) +static void enable_irq_window(struct vcpu *v) { u32 *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control; - if (!(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) { + if ( !(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING) ) + { *cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING; __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control); } -} - -static inline void -disable_irq_window(struct vcpu *v) -{ - u32 *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control; - - if ( *cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) { - *cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; - __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control); - } -} - -static inline int is_interruptibility_state(void) -{ - return __vmread(GUEST_INTERRUPTIBILITY_INFO); } static void update_tpr_threshold(struct vlapic *vlapic) @@ -87,13 +102,11 @@ static void update_tpr_threshold(struct asmlinkage void vmx_intr_assist(void) { - int intr_type = 0; - int intr_vector; - unsigned long eflags; + int has_ext_irq, intr_vector, intr_type = 0; + unsigned long eflags, intr_shadow; struct vcpu *v = current; unsigned int idtv_info_field; unsigned long inst_len; - int has_ext_irq; pt_update_irq(v); @@ -125,10 +138,10 @@ asmlinkage void vmx_intr_assist(void) inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */ __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len); - if (unlikely(idtv_info_field & 0x800)) /* valid error code */ + if ( unlikely(idtv_info_field & 0x800) ) /* valid error code */ __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, __vmread(IDT_VECTORING_ERROR_CODE)); - if (unlikely(has_ext_irq)) + if ( unlikely(has_ext_irq) ) enable_irq_window(v); HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field); @@ -138,9 +151,9 @@ asmlinkage void vmx_intr_assist(void) if ( likely(!has_ext_irq) ) return; - if ( unlikely(is_interruptibility_state()) ) + intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); + if ( unlikely(intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS)) ) { - /* pre-cleared for emulated instruction */ enable_irq_window(v); HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility"); return; diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Jun 15 13:33:11 2007 -0600 @@ -70,8 +70,9 @@ void vmx_init_vmcs_config(void) u32 _vmx_vmexit_control; u32 _vmx_vmentry_control; - min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING; - opt = 0; + min = (PIN_BASED_EXT_INTR_MASK | + PIN_BASED_NMI_EXITING); + opt = 0; /*PIN_BASED_VIRTUAL_NMIS*/ _vmx_pin_based_exec_control = adjust_vmx_controls( min, opt, MSR_IA32_VMX_PINBASED_CTLS); diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Jun 15 13:33:11 2007 -0600 @@ -1300,11 +1300,17 @@ static int __get_instruction_length(void static void inline __update_guest_eip(unsigned long inst_len) { - unsigned long current_eip; + unsigned long current_eip, intr_shadow; current_eip = __vmread(GUEST_RIP); __vmwrite(GUEST_RIP, current_eip + inst_len); - __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0); + + intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); + if ( intr_shadow & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) ) + { + intr_shadow &= ~(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS); + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); + } } static void vmx_do_no_device_fault(void) @@ -2902,9 +2908,15 @@ asmlinkage void vmx_vmexit_handler(struc case EXIT_REASON_TRIPLE_FAULT: hvm_triple_fault(); break; - case EXIT_REASON_PENDING_INTERRUPT: + case EXIT_REASON_PENDING_VIRT_INTR: /* Disable the interrupt window. */ v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, + v->arch.hvm_vcpu.u.vmx.exec_control); + break; + case EXIT_REASON_PENDING_VIRT_NMI: + /* Disable the NMI window. */ + v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING; __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vcpu.u.vmx.exec_control); break; diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vpt.c --- a/xen/arch/x86/hvm/vpt.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/hvm/vpt.c Fri Jun 15 13:33:11 2007 -0600 @@ -22,31 +22,31 @@ #include <asm/hvm/vpt.h> #include <asm/event.h> -static __inline__ void missed_ticks(struct periodic_time *pt) +static void missed_ticks(struct periodic_time *pt) { s_time_t missed_ticks; missed_ticks = NOW() - pt->scheduled; - if ( missed_ticks > 0 ) - { - missed_ticks = missed_ticks / (s_time_t) pt->period + 1; - if ( missed_ticks > 1000 ) - { - /* TODO: Adjust guest time together */ - pt->pending_intr_nr++; - } - else - { - pt->pending_intr_nr += missed_ticks; - } - pt->scheduled += missed_ticks * pt->period; - } + if ( missed_ticks <= 0 ) + return; + + missed_ticks = missed_ticks / (s_time_t) pt->period + 1; + if ( missed_ticks > 1000 ) + { + /* TODO: Adjust guest time together */ + pt->pending_intr_nr++; + } + else + { + pt->pending_intr_nr += missed_ticks; + } + + pt->scheduled += missed_ticks * pt->period; } void pt_freeze_time(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; - struct list_head *list; struct periodic_time *pt; if ( test_bit(_VPF_blocked, &v->pause_flags) ) @@ -54,17 +54,13 @@ void pt_freeze_time(struct vcpu *v) v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); - list_for_each( list, head ) - { - pt = list_entry(list, struct periodic_time, list); + list_for_each_entry ( pt, head, list ) stop_timer(&pt->timer); - } } void pt_thaw_time(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; - struct list_head *list; struct periodic_time *pt; if ( v->arch.hvm_vcpu.guest_time ) @@ -72,17 +68,15 @@ void pt_thaw_time(struct vcpu *v) hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); v->arch.hvm_vcpu.guest_time = 0; - list_for_each( list, head ) - { - pt = list_entry(list, struct periodic_time, list); + list_for_each_entry ( pt, head, list ) + { missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); } } } -/* Hook function for the platform periodic time */ -void pt_timer_fn(void *data) +static void pt_timer_fn(void *data) { struct periodic_time *pt = data; @@ -100,14 +94,12 @@ void pt_update_irq(struct vcpu *v) void pt_update_irq(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; - struct list_head *list; struct periodic_time *pt; uint64_t max_lag = -1ULL; int irq = -1; - list_for_each( list, head ) - { - pt = list_entry(list, struct periodic_time, list); + list_for_each_entry ( pt, head, list ) + { if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr && ((pt->last_plt_gtime + pt->period_cycles) < max_lag) ) { @@ -130,14 +122,12 @@ struct periodic_time *is_pt_irq(struct v struct periodic_time *is_pt_irq(struct vcpu *v, int vector, int type) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; - struct list_head *list; struct periodic_time *pt; struct RTCState *rtc = &v->domain->arch.hvm_domain.pl_time.vrtc; int vec; - list_for_each( list, head ) - { - pt = list_entry(list, struct periodic_time, list); + list_for_each_entry ( pt, head, list ) + { if ( !pt->pending_intr_nr ) continue; @@ -177,17 +167,14 @@ void pt_intr_post(struct vcpu *v, int ve pt->cb(pt->vcpu, pt->priv); } -/* If pt is enabled, discard pending intr */ void pt_reset(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; - struct list_head *list; - struct periodic_time *pt; - - list_for_each( list, head ) - { - pt = list_entry(list, struct periodic_time, list); - if ( pt->enabled ) + struct periodic_time *pt; + + list_for_each_entry ( pt, head, list ) + { + if ( pt->enabled ) { pt->pending_intr_nr = 0; pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu); @@ -197,11 +184,25 @@ void pt_reset(struct vcpu *v) } } -void create_periodic_time(struct vcpu *v, struct periodic_time *pt, uint64_t period, - uint8_t irq, char one_shot, time_cb *cb, void *data) +void pt_migrate(struct vcpu *v) +{ + struct list_head *head = &v->arch.hvm_vcpu.tm_list; + struct periodic_time *pt; + + list_for_each_entry ( pt, head, list ) + { + if ( pt->enabled ) + migrate_timer(&pt->timer, v->processor); + } +} + +void create_periodic_time( + struct vcpu *v, struct periodic_time *pt, uint64_t period, + uint8_t irq, char one_shot, time_cb *cb, void *data) { destroy_periodic_time(pt); + init_timer(&pt->timer, pt_timer_fn, pt, v->processor); pt->enabled = 1; if ( period < 900000 ) /* < 0.9 ms */ { @@ -226,11 +227,11 @@ void create_periodic_time(struct vcpu *v void destroy_periodic_time(struct periodic_time *pt) { - if ( pt->enabled ) - { - pt->enabled = 0; - pt->pending_intr_nr = 0; - list_del(&pt->list); - stop_timer(&pt->timer); - } -} + if ( !pt->enabled ) + return; + + pt->enabled = 0; + pt->pending_intr_nr = 0; + list_del(&pt->list); + kill_timer(&pt->timer); +} diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/arch/x86/io_apic.c Fri Jun 15 13:33:11 2007 -0600 @@ -2114,6 +2114,15 @@ int ioapic_guest_write(unsigned long phy return 0; } + /* Special delivery modes (SMI,NMI,INIT,ExtInt) should have no vector. */ + if ( (old_rte.delivery_mode > dest_LowestPrio) && (old_rte.vector != 0) ) + { + WARN_BOGUS_WRITE("Special delivery mode %d with non-zero vector " + "%02x\n", old_rte.delivery_mode, old_rte.vector); + /* Nobble the vector here as it does not relate to a valid irq. */ + old_rte.vector = 0; + } + if ( old_rte.vector >= FIRST_DYNAMIC_VECTOR ) old_irq = vector_irq[old_rte.vector]; if ( new_rte.vector >= FIRST_DYNAMIC_VECTOR ) diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Jun 15 13:33:11 2007 -0600 @@ -104,6 +104,7 @@ void vmx_vmcs_exit(struct vcpu *v); #define CPU_BASED_CR8_LOAD_EXITING 0x00080000 #define CPU_BASED_CR8_STORE_EXITING 0x00100000 #define CPU_BASED_TPR_SHADOW 0x00200000 +#define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000 #define CPU_BASED_MOV_DR_EXITING 0x00800000 #define CPU_BASED_UNCOND_IO_EXITING 0x01000000 #define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000 @@ -115,6 +116,7 @@ extern u32 vmx_cpu_based_exec_control; #define PIN_BASED_EXT_INTR_MASK 0x00000001 #define PIN_BASED_NMI_EXITING 0x00000008 +#define PIN_BASED_VIRTUAL_NMIS 0x00000020 extern u32 vmx_pin_based_exec_control; #define VM_EXIT_IA32E_MODE 0x00000200 @@ -137,7 +139,13 @@ extern u32 vmx_secondary_exec_control; (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP) extern char *vmx_msr_bitmap; -/* VMCS Encordings */ +/* GUEST_INTERRUPTIBILITY_INFO flags. */ +#define VMX_INTR_SHADOW_STI 0x00000001 +#define VMX_INTR_SHADOW_MOV_SS 0x00000002 +#define VMX_INTR_SHADOW_SMI 0x00000004 +#define VMX_INTR_SHADOW_NMI 0x00000008 + +/* VMCS field encodings. */ enum vmcs_field { GUEST_ES_SELECTOR = 0x00000800, GUEST_CS_SELECTOR = 0x00000802, diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Fri Jun 15 13:33:11 2007 -0600 @@ -46,8 +46,8 @@ void vmx_vlapic_msr_changed(struct vcpu #define EXIT_REASON_SIPI 4 #define EXIT_REASON_IO_SMI 5 #define EXIT_REASON_OTHER_SMI 6 -#define EXIT_REASON_PENDING_INTERRUPT 7 - +#define EXIT_REASON_PENDING_VIRT_INTR 7 +#define EXIT_REASON_PENDING_VIRT_NMI 8 #define EXIT_REASON_TASK_SWITCH 9 #define EXIT_REASON_CPUID 10 #define EXIT_REASON_HLT 12 @@ -295,7 +295,14 @@ static inline void __vmx_inject_exceptio { unsigned long intr_fields; - /* Reflect it back into the guest */ + /* + * NB. Callers do not need to worry about clearing STI/MOV-SS blocking: + * "If the VM entry is injecting, there is no blocking by STI or by + * MOV SS following the VM entry, regardless of the contents of the + * interruptibility-state field [in the guest-state area before the + * VM entry]", PRM Vol. 3, 22.6.1 (Interruptibility State). + */ + intr_fields = (INTR_INFO_VALID_MASK | type | trap); if ( error_code != VMX_DELIVER_NO_ERROR_CODE ) { __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); @@ -332,7 +339,6 @@ static inline void vmx_inject_extint(str static inline void vmx_inject_extint(struct vcpu *v, int trap, int error_code) { __vmx_inject_exception(v, trap, INTR_TYPE_EXT_INTR, error_code, 0); - __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0); } #endif /* __ASM_X86_HVM_VMX_VMX_H__ */ diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/include/asm-x86/hvm/vpt.h Fri Jun 15 13:33:11 2007 -0600 @@ -115,19 +115,19 @@ struct pl_time { /* platform time */ void pt_freeze_time(struct vcpu *v); void pt_thaw_time(struct vcpu *v); -void pt_timer_fn(void *data); void pt_update_irq(struct vcpu *v); struct periodic_time *is_pt_irq(struct vcpu *v, int vector, int type); void pt_intr_post(struct vcpu *v, int vector, int type); void pt_reset(struct vcpu *v); -void create_periodic_time(struct vcpu *v, struct periodic_time *pt, uint64_t period, - uint8_t irq, char one_shot, time_cb *cb, void *data); +void pt_migrate(struct vcpu *v); +void create_periodic_time( + struct vcpu *v, struct periodic_time *pt, uint64_t period, + uint8_t irq, char one_shot, time_cb *cb, void *data); void destroy_periodic_time(struct periodic_time *pt); int pv_pit_handler(int port, int data, int write); void pit_init(struct vcpu *v, unsigned long cpu_khz); void pit_stop_channel0_irq(PITState * pit); -void pit_migrate_timers(struct vcpu *v); void pit_deinit(struct domain *d); void rtc_init(struct vcpu *v, int base); void rtc_migrate_timers(struct vcpu *v); diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/msr.h --- a/xen/include/asm-x86/msr.h Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/include/asm-x86/msr.h Fri Jun 15 13:33:11 2007 -0600 @@ -96,6 +96,7 @@ static inline void wrmsrl(unsigned int m #define MSR_IA32_TIME_STAMP_COUNTER 0x10 #define MSR_IA32_PLATFORM_ID 0x17 #define MSR_IA32_EBL_CR_POWERON 0x2a +#define MSR_IA32_EBC_FREQUENCY_ID 0x2c #define MSR_IA32_APICBASE 0x1b #define MSR_IA32_APICBASE_BSP (1<<8) diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/public/io/ring.h --- a/xen/include/public/io/ring.h Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/include/public/io/ring.h Fri Jun 15 13:33:11 2007 -0600 @@ -133,7 +133,7 @@ typedef struct __name##_back_ring __name #define SHARED_RING_INIT(_s) do { \ (_s)->req_prod = (_s)->rsp_prod = 0; \ (_s)->req_event = (_s)->rsp_event = 1; \ - memset((_s)->pad, 0, sizeof((_s)->pad)); \ + (void)memset((_s)->pad, 0, sizeof((_s)->pad)); \ } while(0) #define FRONT_RING_INIT(_r, _s, __size) do { \ diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/public/io/xs_wire.h --- a/xen/include/public/io/xs_wire.h Fri Jun 15 12:38:35 2007 -0600 +++ b/xen/include/public/io/xs_wire.h Fri Jun 15 13:33:11 2007 -0600 @@ -60,7 +60,11 @@ struct xsd_errors const char *errstring; }; #define XSD_ERROR(x) { x, #x } -static struct xsd_errors xsd_errors[] __attribute__((unused)) = { +static struct xsd_errors xsd_errors[] +#if defined(__GNUC__) +__attribute__((unused)) +#endif + = { XSD_ERROR(EINVAL), XSD_ERROR(EACCES), XSD_ERROR(EEXIST), _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |