# HG changeset patch
# User Steven Smith <ssmith@xxxxxxxxxxxxx>
# Node ID f50380324d1c6caa50a7759c905c34ea569c33d1
# Parent 0536dbde1562cfafc1366e950ab01323e2873a43
# Parent bec95280b565d0e9d6a58480ed17b0963f180e1b
Merge.
---
xen/arch/x86/hvm/vmx/io.c | 202 -------------------------
tools/python/xen/util/mkdir.py | 44 +++++
tools/python/xen/util/xmlrpclib2.py | 13 -
tools/python/xen/web/unix.py | 12 -
tools/python/xen/xend/XendConfig.py | 18 +-
tools/python/xen/xend/XendDomain.py | 37 +---
tools/python/xen/xend/XendLogging.py | 5
tools/python/xen/xend/XendStorageRepository.py | 9 -
tools/python/xen/xend/image.py | 5
tools/python/xen/xend/server/SrvDaemon.py | 4
xen/arch/x86/hvm/svm/emulate.c | 11 -
xen/arch/x86/hvm/svm/svm.c | 128 ++++++++++-----
xen/arch/x86/hvm/vlapic.c | 11 -
xen/arch/x86/hvm/vmx/Makefile | 2
xen/arch/x86/hvm/vmx/intr.c | 196 ++++++++++++++++++++++++
xen/arch/x86/hvm/vmx/vmx.c | 173 ++++++++++++---------
xen/arch/x86/mm/shadow/common.c | 11 -
xen/arch/x86/oprofile/op_model_athlon.c | 9 -
xen/arch/x86/x86_emulate.c | 40 +---
xen/include/asm-x86/hvm/hvm.h | 4
xen/include/asm-x86/hvm/vlapic.h | 1
xen/include/asm-x86/x86_32/page.h | 2
xen/include/asm-x86/x86_64/page.h | 2
23 files changed, 502 insertions(+), 437 deletions(-)
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py Fri Dec 01 12:03:15 2006 +0000
+++ b/tools/python/xen/util/xmlrpclib2.py Fri Dec 01 12:03:38 2006 +0000
@@ -29,6 +29,8 @@ from SimpleXMLRPCServer import SimpleXML
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import SocketServer
import xmlrpclib, socket, os, stat
+
+import mkdir
from xen.web import connection
from xen.xend.XendLogging import log
@@ -234,14 +236,9 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
address_family = socket.AF_UNIX
def __init__(self, addr, allowed, logRequests = 1):
- parent = os.path.dirname(addr)
- if os.path.exists(parent):
- os.chown(parent, os.geteuid(), os.getegid())
- os.chmod(parent, stat.S_IRWXU)
- if self.allow_reuse_address and os.path.exists(addr):
- os.unlink(addr)
- else:
- os.makedirs(parent, stat.S_IRWXU)
+ mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True)
+ if self.allow_reuse_address and os.path.exists(addr):
+ os.unlink(addr)
TCPXMLRPCServer.__init__(self, addr, allowed,
UnixXMLRPCRequestHandler, logRequests)
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/web/unix.py
--- a/tools/python/xen/web/unix.py Fri Dec 01 12:03:15 2006 +0000
+++ b/tools/python/xen/web/unix.py Fri Dec 01 12:03:38 2006 +0000
@@ -22,6 +22,8 @@ import socket
import socket
import stat
+from xen.util import mkdir
+
import connection
@@ -30,13 +32,9 @@ created such that only the current user
created such that only the current user may access it."""
parent = os.path.dirname(path)
- if os.path.exists(parent):
- os.chown(parent, os.geteuid(), os.getegid())
- os.chmod(parent, stat.S_IRWXU)
- if os.path.exists(path):
- os.unlink(path)
- else:
- os.makedirs(parent, stat.S_IRWXU)
+ mkdir.parents(parent, stat.S_IRWXU, True)
+ if os.path.exists(path):
+ os.unlink(path)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(path)
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Fri Dec 01 12:03:15 2006 +0000
+++ b/tools/python/xen/xend/XendConfig.py Fri Dec 01 12:03:38 2006 +0000
@@ -185,20 +185,22 @@ LEGACY_IMAGE_HVM_CFG = [
('vncconsole', int),
('pae', int),
('apic', int),
- ('acpi', int),
- ('serial', str),
]
LEGACY_IMAGE_HVM_DEVICES_CFG = [
+ ('acpi', int),
('boot', str),
('fda', str),
('fdb', str),
+ ('isa', str),
+ ('keymap', str),
+ ('localtime', str),
+ ('serial', str),
+ ('stdvga', int),
('soundhw', str),
- ('isa', str),
+ ('usb', str),
+ ('usbdevice', str),
('vcpus', int),
- ('acpi', int),
- ('usb', str),
- ('usbdevice', str),
]
@@ -985,12 +987,12 @@ class XendConfig(dict):
if 'hvm' in self['image']:
for arg, conv in LEGACY_IMAGE_HVM_CFG:
- if self['image']['hvm'].has_key(arg):
+ if self['image']['hvm'].get(arg):
image.append([arg, self['image']['hvm'][arg]])
if 'hvm' in self['image'] and 'devices' in self['image']['hvm']:
for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
- if self['image']['hvm']['devices'].has_key(arg):
+ if self['image']['hvm']['devices'].get(arg):
image.append([arg,
self['image']['hvm']['devices'][arg]])
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Fri Dec 01 12:03:15 2006 +0000
+++ b/tools/python/xen/xend/XendDomain.py Fri Dec 01 12:03:38 2006 +0000
@@ -23,6 +23,7 @@
"""
import os
+import stat
import shutil
import socket
import threading
@@ -44,7 +45,7 @@ from xen.xend.XendDevices import XendDev
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xswatch import xswatch
-from xen.util import security
+from xen.util import mkdir, security
from xen.xend import uuid
xc = xen.lowlevel.xc.xc()
@@ -99,11 +100,7 @@ class XendDomain:
"""Singleton initialisation function."""
dom_path = self._managed_path()
- try:
- os.stat(dom_path)
- except OSError:
- log.info("Making %s", dom_path)
- os.makedirs(dom_path, 0755)
+ mkdir.parents(dom_path, stat.S_IRWXU)
xstransact.Mkdir(XS_VMROOT)
xstransact.SetPermissions(XS_VMROOT, {'dom': DOM0_ID})
@@ -271,25 +268,17 @@ class XendDomain:
domains_dir = self._managed_path()
dom_uuid = dominfo.get_uuid()
domain_config_dir = self._managed_path(dom_uuid)
-
- # make sure the domain dir exists
- if not os.path.exists(domains_dir):
- os.makedirs(domains_dir, 0755)
- elif not os.path.isdir(domains_dir):
- log.error("xend_domain_dir is not a directory.")
- raise XendError("Unable to save managed configuration "
- "because %s is not a directory." %
- domains_dir)
-
- if not os.path.exists(domain_config_dir):
+
+ def make_or_raise(path):
try:
- os.makedirs(domain_config_dir, 0755)
- except IOError:
- log.exception("Failed to create directory: %s" %
- domain_config_dir)
- raise XendError("Failed to create directory: %s" %
- domain_config_dir)
-
+ mkdir.parents(path, stat.S_IRWXU)
+ except:
+ log.exception("%s could not be created." % path)
+ raise XendError("%s could not be created." % path)
+
+ make_or_raise(domains_dir)
+ make_or_raise(domain_config_dir)
+
try:
sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py Fri Dec 01 12:03:15 2006 +0000
+++ b/tools/python/xen/xend/XendLogging.py Fri Dec 01 12:03:38 2006 +0000
@@ -16,13 +16,15 @@
# Copyright (C) 2005, 2006 XenSource Ltd.
#============================================================================
-
+import os
+import stat
import tempfile
import types
import logging
import logging.handlers
import fcntl
+from xen.util import mkdir
from xen.xend.server import params
@@ -80,6 +82,7 @@ def init(filename, level):
global logfilename
def openFileHandler(fname):
+ mkdir.parents(os.path.dirname(fname), stat.S_IRWXU)
return XendRotatingFileHandler(fname, mode = 'a',
maxBytes = MAX_BYTES,
backupCount = BACKUP_COUNT)
diff -r 0536dbde1562 -r f50380324d1c
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py Fri Dec 01 12:03:15
2006 +0000
+++ b/tools/python/xen/xend/XendStorageRepository.py Fri Dec 01 12:03:38
2006 +0000
@@ -19,10 +19,12 @@
# The default QCOW Xen API Storage Repository
#
+import commands
import os
-import commands
+import stat
import threading
+from xen.util import mkdir
from xen.xend import uuid
from xen.xend.XendError import XendError
from xen.xend.XendVDI import *
@@ -98,10 +100,7 @@ class XendStorageRepository:
"""
self.lock.acquire()
try:
- # create directory if /var/lib/xend/storage does not exist
- if not os.path.exists(XEND_STORAGE_DIR):
- os.makedirs(XEND_STORAGE_DIR)
- os.chmod(XEND_STORAGE_DIR, 0700)
+ mkdir.parents(XEND_STORAGE_DIR, stat.S_IRWXU)
# scan the directory and populate self.images
total_used = 0
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Fri Dec 01 12:03:15 2006 +0000
+++ b/tools/python/xen/xend/image.py Fri Dec 01 12:03:38 2006 +0000
@@ -277,8 +277,9 @@ class HVMImageHandler(ImageHandler):
self.dmargs += self.configVNC(imageConfig)
self.pae = imageConfig['hvm'].get('pae', 0)
- self.acpi = imageConfig['hvm'].get('acpi', 0)
self.apic = imageConfig['hvm'].get('apic', 0)
+ self.acpi = imageConfig['hvm']['devices'].get('acpi', 0)
+
def buildDomain(self):
store_evtchn = self.vm.getStorePort()
@@ -317,8 +318,6 @@ class HVMImageHandler(ImageHandler):
for a in dmargs:
v = hvmDeviceConfig.get(a)
- if a == 'vcpus':
- v = hvmDeviceConfig.get('vcpus_number')
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Fri Dec 01 12:03:15 2006 +0000
+++ b/tools/python/xen/xend/server/SrvDaemon.py Fri Dec 01 12:03:38 2006 +0000
@@ -21,6 +21,7 @@ import xen.lowlevel.xc
from xen.xend.XendLogging import log
from xen.xend import osdep
+from xen.util import mkdir
import relocate
import SrvServer
@@ -108,8 +109,7 @@ class Daemon:
# so _before_ we close stderr.
try:
parent = os.path.dirname(XEND_DEBUG_LOG)
- if not os.path.exists(parent):
- os.makedirs(parent, stat.S_IRWXU)
+ mkdir.parents(parent, stat.S_IRWXU)
fd = os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND)
except Exception, exn:
print >>sys.stderr, exn
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/hvm/svm/emulate.c Fri Dec 01 12:03:38 2006 +0000
@@ -127,17 +127,6 @@ static inline unsigned long DECODE_GPR_V
*size = 0; \
return (unsigned long) -1; \
}
-
-#if 0
-/*
- * hv_is_canonical - checks if the given address is canonical
- */
-static inline u64 hv_is_canonical(u64 addr)
-{
- u64 bits = addr & (u64)0xffff800000000000;
- return (u64)((bits == (u64)0xffff800000000000) || (bits == (u64)0x0));
-}
-#endif
#define modrm operand [0]
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Fri Dec 01 12:03:38 2006 +0000
@@ -269,13 +269,11 @@ static int svm_long_mode_enabled(struct
return test_bit(SVM_CPU_STATE_LMA_ENABLED, &v->arch.hvm_svm.cpu_state);
}
-#define IS_CANO_ADDRESS(add) 1
-
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
{
u64 msr_content = 0;
- struct vcpu *vc = current;
- struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
+ struct vcpu *v = current;
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
switch ((u32)regs->ecx)
{
@@ -284,17 +282,25 @@ static inline int long_mode_do_msr_read(
msr_content &= ~EFER_SVME;
break;
+#ifdef __x86_64__
case MSR_FS_BASE:
msr_content = vmcb->fs.base;
- break;
+ goto check_long_mode;
case MSR_GS_BASE:
msr_content = vmcb->gs.base;
- break;
+ goto check_long_mode;
case MSR_SHADOW_GS_BASE:
msr_content = vmcb->kerngsbase;
- break;
+ check_long_mode:
+ if ( !svm_long_mode_enabled(v) )
+ {
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
+ }
+ break;
+#endif
case MSR_STAR:
msr_content = vmcb->star;
@@ -326,25 +332,25 @@ static inline int long_mode_do_msr_write
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
+ u32 ecx = regs->ecx;
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
HVM_DBG_LOG(DBG_LEVEL_1, "msr %x msr_content %"PRIx64"\n",
- (u32)regs->ecx, msr_content);
-
- switch ( (u32)regs->ecx )
+ ecx, msr_content);
+
+ switch ( ecx )
{
case MSR_EFER:
-#ifdef __x86_64__
/* offending reserved bit will cause #GP */
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
{
- printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
- msr_content);
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- return 0;
- }
-
+ gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
+ "EFER: %"PRIx64"\n", msr_content);
+ goto gp_fault;
+ }
+
+#ifdef __x86_64__
/* LME: 0 -> 1 */
if ( msr_content & EFER_LME &&
!test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state))
@@ -353,10 +359,9 @@ static inline int long_mode_do_msr_write
!test_bit(SVM_CPU_STATE_PAE_ENABLED,
&v->arch.hvm_svm.cpu_state) )
{
- printk("Trying to set LME bit when "
- "in paging mode or PAE bit is not set\n");
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- return 0;
+ gdprintk(XENLOG_WARNING, "Trying to set LME bit when "
+ "in paging mode or PAE bit is not set\n");
+ goto gp_fault;
}
set_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state);
}
@@ -371,37 +376,38 @@ static inline int long_mode_do_msr_write
vmcb->efer = msr_content | EFER_SVME;
break;
+#ifdef __x86_64__
case MSR_FS_BASE:
case MSR_GS_BASE:
+ case MSR_SHADOW_GS_BASE:
if ( !svm_long_mode_enabled(v) )
- goto exit_and_crash;
-
- if (!IS_CANO_ADDRESS(msr_content))
- {
- HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- }
-
- if (regs->ecx == MSR_FS_BASE)
+ goto gp_fault;
+
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+
+ if ( ecx == MSR_FS_BASE )
vmcb->fs.base = msr_content;
- else
+ else if ( ecx == MSR_GS_BASE )
vmcb->gs.base = msr_content;
- break;
-
- case MSR_SHADOW_GS_BASE:
- vmcb->kerngsbase = msr_content;
- break;
+ else
+ vmcb->kerngsbase = msr_content;
+ break;
+#endif
case MSR_STAR:
vmcb->star = msr_content;
break;
case MSR_LSTAR:
- vmcb->lstar = msr_content;
- break;
-
case MSR_CSTAR:
- vmcb->cstar = msr_content;
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+
+ if ( ecx == MSR_LSTAR )
+ vmcb->lstar = msr_content;
+ else
+ vmcb->cstar = msr_content;
break;
case MSR_SYSCALL_MASK:
@@ -414,10 +420,11 @@ static inline int long_mode_do_msr_write
return 1;
- exit_and_crash:
- gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
- domain_crash(v->domain);
- return 1; /* handled */
+ uncanonical_address:
+ HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
+ gp_fault:
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
}
@@ -1272,7 +1279,7 @@ static inline int svm_get_io_address(
#endif
/* d field of cs.attr is 1 for 32-bit, 0 for 16 or 64 bit.
- * l field combined with EFER_LMA -> longmode says whether it's 16 or 64
bit.
+ * l field combined with EFER_LMA says whether it's 16 or 64 bit.
*/
asize = (long_mode)?64:((vmcb->cs.attr.fields.db)?32:16);
@@ -1383,8 +1390,35 @@ static inline int svm_get_io_address(
*addr += seg->base;
}
- else if (seg == &vmcb->fs || seg == &vmcb->gs)
- *addr += seg->base;
+#ifdef __x86_64__
+ else
+ {
+ if (seg == &vmcb->fs || seg == &vmcb->gs)
+ *addr += seg->base;
+
+ if (!is_canonical_address(*addr) ||
+ !is_canonical_address(*addr + size - 1))
+ {
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
+ }
+ if (*count > (1UL << 48) / size)
+ *count = (1UL << 48) / size;
+ if (!(regs->eflags & EF_DF))
+ {
+ if (*addr + *count * size - 1 < *addr ||
+ !is_canonical_address(*addr + *count * size - 1))
+ *count = (*addr & ~((1UL << 48) - 1)) / size;
+ }
+ else
+ {
+ if ((*count - 1) * size > *addr ||
+ !is_canonical_address(*addr + (*count - 1) * size))
+ *count = (*addr & ~((1UL << 48) - 1)) / size + 1;
+ }
+ ASSERT(*count);
+ }
+#endif
return 1;
}
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Fri Dec 01 12:03:38 2006 +0000
@@ -119,19 +119,16 @@ static int vlapic_find_highest_vector(u3
static int vlapic_test_and_set_irr(int vector, struct vlapic *vlapic)
{
- vlapic->flush_tpr_threshold = 1;
return vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
}
static void vlapic_set_irr(int vector, struct vlapic *vlapic)
{
- vlapic->flush_tpr_threshold = 1;
vlapic_set_vector(vector, vlapic->regs + APIC_IRR);
}
static void vlapic_clear_irr(int vector, struct vlapic *vlapic)
{
- vlapic->flush_tpr_threshold = 1;
vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
}
@@ -634,7 +631,6 @@ static void vlapic_write(struct vcpu *v,
{
case APIC_TASKPRI:
vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
- vlapic->flush_tpr_threshold = 1;
break;
case APIC_EOI:
@@ -667,10 +663,7 @@ static void vlapic_write(struct vcpu *v,
}
}
else
- {
vlapic->disabled &= ~VLAPIC_SW_DISABLED;
- vlapic->flush_tpr_threshold = 1;
- }
break;
case APIC_ESR:
@@ -730,7 +723,7 @@ static void vlapic_write(struct vcpu *v,
break;
default:
- gdprintk(XENLOG_WARNING,
+ gdprintk(XENLOG_DEBUG,
"Local APIC Write to read-only register 0x%x\n", offset);
break;
}
@@ -925,8 +918,6 @@ static int vlapic_reset(struct vlapic *v
vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
vlapic->disabled |= VLAPIC_SW_DISABLED;
- vlapic->flush_tpr_threshold = 1;
-
return 1;
}
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/hvm/vmx/Makefile
--- a/xen/arch/x86/hvm/vmx/Makefile Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/Makefile Fri Dec 01 12:03:38 2006 +0000
@@ -1,6 +1,6 @@ subdir-$(x86_32) += x86_32
subdir-$(x86_32) += x86_32
subdir-$(x86_64) += x86_64
-obj-y += io.o
+obj-y += intr.o
obj-y += vmcs.o
obj-y += vmx.o
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Dec 01 12:03:38 2006 +0000
@@ -95,13 +95,7 @@ static void vmx_save_host_msrs(void)
rdmsrl(msr_index[i], host_msr_state->msrs[i]);
}
-#define CASE_READ_MSR(address) \
- case MSR_ ## address: \
- msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_ ## address]; \
- break
-
-#define CASE_WRITE_MSR(address) \
- case MSR_ ## address: \
+#define WRITE_MSR(address) \
guest_msr_state->msrs[VMX_INDEX_MSR_ ## address] = msr_content; \
if ( !test_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags) )\
set_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags); \
@@ -109,7 +103,6 @@ static void vmx_save_host_msrs(void)
set_bit(VMX_INDEX_MSR_ ## address, &host_msr_state->flags); \
break
-#define IS_CANO_ADDRESS(add) 1
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
{
u64 msr_content = 0;
@@ -123,27 +116,38 @@ static inline int long_mode_do_msr_read(
break;
case MSR_FS_BASE:
- if ( !(vmx_long_mode_enabled(v)) )
- goto exit_and_crash;
-
msr_content = __vmread(GUEST_FS_BASE);
- break;
+ goto check_long_mode;
case MSR_GS_BASE:
- if ( !(vmx_long_mode_enabled(v)) )
- goto exit_and_crash;
-
msr_content = __vmread(GUEST_GS_BASE);
- break;
+ goto check_long_mode;
case MSR_SHADOW_GS_BASE:
msr_content = guest_msr_state->shadow_gs;
- break;
-
- CASE_READ_MSR(STAR);
- CASE_READ_MSR(LSTAR);
- CASE_READ_MSR(CSTAR);
- CASE_READ_MSR(SYSCALL_MASK);
+ check_long_mode:
+ if ( !(vmx_long_mode_enabled(v)) )
+ {
+ vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
+ return 0;
+ }
+ break;
+
+ case MSR_STAR:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_STAR];
+ break;
+
+ case MSR_LSTAR:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_LSTAR];
+ break;
+
+ case MSR_CSTAR:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_CSTAR];
+ break;
+
+ case MSR_SYSCALL_MASK:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
+ break;
default:
return 0;
@@ -155,32 +159,28 @@ static inline int long_mode_do_msr_read(
regs->edx = (u32)(msr_content >> 32);
return 1;
-
- exit_and_crash:
- gdprintk(XENLOG_ERR, "Fatal error reading MSR %lx\n", (long)regs->ecx);
- domain_crash(v->domain);
- return 1; /* handled */
}
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
+ u32 ecx = regs->ecx;
struct vcpu *v = current;
struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state);
HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%x msr_content 0x%"PRIx64"\n",
- (u32)regs->ecx, msr_content);
-
- switch ( (u32)regs->ecx ) {
+ ecx, msr_content);
+
+ switch ( ecx )
+ {
case MSR_EFER:
/* offending reserved bit will cause #GP */
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
{
- printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
- msr_content);
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
+ gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
+ "EFER: %"PRIx64"\n", msr_content);
+ goto gp_fault;
}
if ( (msr_content & EFER_LME)
@@ -188,9 +188,9 @@ static inline int long_mode_do_msr_write
{
if ( unlikely(vmx_paging_enabled(v)) )
{
- printk("Trying to set EFER.LME with paging enabled\n");
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
+ gdprintk(XENLOG_WARNING,
+ "Trying to set EFER.LME with paging enabled\n");
+ goto gp_fault;
}
}
else if ( !(msr_content & EFER_LME)
@@ -198,9 +198,9 @@ static inline int long_mode_do_msr_write
{
if ( unlikely(vmx_paging_enabled(v)) )
{
- printk("Trying to clear EFER.LME with paging enabled\n");
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
+ gdprintk(XENLOG_WARNING,
+ "Trying to clear EFER.LME with paging enabled\n");
+ goto gp_fault;
}
}
@@ -209,35 +209,40 @@ static inline int long_mode_do_msr_write
case MSR_FS_BASE:
case MSR_GS_BASE:
+ case MSR_SHADOW_GS_BASE:
if ( !vmx_long_mode_enabled(v) )
- goto exit_and_crash;
-
- if ( !IS_CANO_ADDRESS(msr_content) )
- {
- HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
- }
-
- if ( regs->ecx == MSR_FS_BASE )
+ goto gp_fault;
+
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+
+ if ( ecx == MSR_FS_BASE )
__vmwrite(GUEST_FS_BASE, msr_content);
+ else if ( ecx == MSR_GS_BASE )
+ __vmwrite(GUEST_GS_BASE, msr_content);
else
- __vmwrite(GUEST_GS_BASE, msr_content);
-
- break;
-
- case MSR_SHADOW_GS_BASE:
- if ( !(vmx_long_mode_enabled(v)) )
- goto exit_and_crash;
-
- v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
- wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
- break;
-
- CASE_WRITE_MSR(STAR);
- CASE_WRITE_MSR(LSTAR);
- CASE_WRITE_MSR(CSTAR);
- CASE_WRITE_MSR(SYSCALL_MASK);
+ {
+ v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
+ wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
+ }
+
+ break;
+
+ case MSR_STAR:
+ WRITE_MSR(STAR);
+
+ case MSR_LSTAR:
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+ WRITE_MSR(LSTAR);
+
+ case MSR_CSTAR:
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+ WRITE_MSR(CSTAR);
+
+ case MSR_SYSCALL_MASK:
+ WRITE_MSR(SYSCALL_MASK);
default:
return 0;
@@ -245,10 +250,11 @@ static inline int long_mode_do_msr_write
return 1;
- exit_and_crash:
- gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
- domain_crash(v->domain);
- return 1; /* handled */
+ uncanonical_address:
+ HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
+ gp_fault:
+ vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
+ return 0;
}
/*
@@ -1283,6 +1289,32 @@ static void vmx_io_instruction(unsigned
ASSERT(count);
}
}
+#ifdef __x86_64__
+ else
+ {
+ if ( !is_canonical_address(addr) ||
+ !is_canonical_address(addr + size - 1) )
+ {
+ vmx_inject_hw_exception(current, TRAP_gp_fault, 0);
+ return;
+ }
+ if ( count > (1UL << 48) / size )
+ count = (1UL << 48) / size;
+ if ( !(regs->eflags & EF_DF) )
+ {
+ if ( addr + count * size - 1 < addr ||
+ !is_canonical_address(addr + count * size - 1) )
+ count = (addr & ~((1UL << 48) - 1)) / size;
+ }
+ else
+ {
+ if ( (count - 1) * size > addr ||
+ !is_canonical_address(addr + (count - 1) * size) )
+ count = (addr & ~((1UL << 48) - 1)) / size + 1;
+ }
+ ASSERT(count);
+ }
+#endif
/*
* Handle string pio instructions that cross pages or that
@@ -2500,7 +2532,6 @@ asmlinkage void vmx_vmexit_handler(struc
break;
case EXIT_REASON_TPR_BELOW_THRESHOLD:
- vcpu_vlapic(v)->flush_tpr_threshold = 1;
break;
default:
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/mm/shadow/common.c Fri Dec 01 12:03:38 2006 +0000
@@ -120,12 +120,17 @@ static int hvm_translate_linear_addr(
*/
addr = (uint32_t)(addr + dreg.base);
}
- else if ( (seg == x86_seg_fs) || (seg == x86_seg_gs) )
+ else
{
/*
- * LONG MODE: FS and GS add a segment base.
+ * LONG MODE: FS and GS add segment base. Addresses must be canonical.
*/
- addr += dreg.base;
+
+ if ( (seg == x86_seg_fs) || (seg == x86_seg_gs) )
+ addr += dreg.base;
+
+ if ( !is_canonical_address(addr) )
+ goto gpf;
}
*paddr = addr;
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/oprofile/op_model_athlon.c
--- a/xen/arch/x86/oprofile/op_model_athlon.c Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/oprofile/op_model_athlon.c Fri Dec 01 12:03:38 2006 +0000
@@ -113,14 +113,15 @@ static int athlon_check_ctrs(unsigned in
unsigned long eip = regs->eip;
int mode = 0;
struct vcpu *v = current;
- struct cpu_user_regs tmp_regs;
+ struct cpu_user_regs *guest_regs = guest_cpu_user_regs();
if (!guest_mode(regs) &&
(regs->eip == (unsigned long)svm_stgi_label)) {
/* SVM guest was running when NMI occurred */
- hvm_store_cpu_guest_regs(v, &tmp_regs, NULL);
- eip = tmp_regs.eip;
- mode = xenoprofile_get_mode(v, &tmp_regs);
+ ASSERT(is_hvm_vcpu(v));
+ hvm_store_cpu_guest_regs(v, guest_regs, NULL);
+ eip = guest_regs->eip;
+ mode = xenoprofile_get_mode(v, guest_regs);
} else {
eip = regs->eip;
mode = xenoprofile_get_mode(v, regs);
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/arch/x86/x86_emulate.c Fri Dec 01 12:03:38 2006 +0000
@@ -7,16 +7,14 @@
*/
#ifndef __XEN__
-#include <stdio.h>
+#include <stddef.h>
#include <stdint.h>
#include <public/xen.h>
-#define dprintf(_f, _a...) printf( _f , ## _a )
#else
#include <xen/config.h>
#include <xen/types.h>
#include <xen/lib.h>
#include <asm/regs.h>
-#define dprintf(_f, _a...) gdprintk(XENLOG_WARNING, _f , ## _a )
#undef cmpxchg
#endif
#include <asm-x86/x86_emulate.h>
@@ -440,27 +438,6 @@ decode_register(
return p;
}
-static void
-dump_instr(
- struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops)
-{
-#ifdef __XEN__
- int i;
- unsigned long x, eip = ctxt->regs->eip;
-
- dprintf("Instr:");
- for ( i = 0; i < 16; i++, eip++ )
- {
- if ( ops->read(x86_seg_cs, eip, &x, 1, ctxt) != 0 )
- printk(" ??");
- else
- printk(" %02x", (uint8_t)x);
- }
- printk("\n");
-#endif
-}
-
int
x86_emulate_memop(
struct x86_emulate_ctxt *ctxt,
@@ -579,10 +556,7 @@ x86_emulate_memop(
modrm_rm = modrm & 0x07;
if ( modrm_mod == 3 )
- {
- dprintf("Cannot parse ModRM.mod == 3.\n");
goto cannot_emulate;
- }
if ( ad_bytes == 2 )
{
@@ -1206,7 +1180,15 @@ x86_emulate_memop(
goto writeback;
cannot_emulate:
- dprintf("Cannot emulate %02x\n", b);
- dump_instr(ctxt, ops);
+#ifdef __XEN__
+ gdprintk(XENLOG_DEBUG, "Instr:");
+ for ( ea_off = ctxt->regs->eip; ea_off < _regs.eip; ea_off++ )
+ {
+ unsigned long x;
+ ops->read(x86_seg_cs, ea_off, &x, 1, ctxt);
+ printk(" %02x", (uint8_t)x);
+ }
+ printk("\n");
+#endif
return -1;
}
diff -r 0536dbde1562 -r f50380324d1c xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h Fri Dec 01 12:03:38 2006 +0000
@@ -157,11 +157,15 @@ hvm_paging_enabled(struct vcpu *v)
return hvm_funcs.paging_enabled(v);
}
+#ifdef __x86_64__
static inline int
hvm_long_mode_enabled(struct vcpu *v)
{
return hvm_funcs.long_mode_enabled(v);
}
+#else
+#define hvm_long_mode_enabled(v) 0
+#endif
static inline int
hvm_pae_enabled(struct vcpu *v)
diff -r 0536dbde1562 -r f50380324d1c xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/include/asm-x86/hvm/vlapic.h Fri Dec 01 12:03:38 2006 +0000
@@ -54,7 +54,6 @@ struct vlapic {
uint32_t timer_divisor;
struct timer vlapic_timer;
int timer_pending_count;
- int flush_tpr_threshold;
s_time_t timer_last_update;
struct page_info *regs_page;
void *regs;
diff -r 0536dbde1562 -r f50380324d1c xen/include/asm-x86/x86_32/page.h
--- a/xen/include/asm-x86/x86_32/page.h Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/include/asm-x86/x86_32/page.h Fri Dec 01 12:03:38 2006 +0000
@@ -6,6 +6,8 @@
#define VADDR_BITS 32
#define VADDR_MASK (~0UL)
+
+#define is_canonical_address(x) 1
#include <xen/config.h>
#ifdef CONFIG_X86_PAE
diff -r 0536dbde1562 -r f50380324d1c xen/include/asm-x86/x86_64/page.h
--- a/xen/include/asm-x86/x86_64/page.h Fri Dec 01 12:03:15 2006 +0000
+++ b/xen/include/asm-x86/x86_64/page.h Fri Dec 01 12:03:38 2006 +0000
@@ -23,6 +23,8 @@
#define VADDR_BITS 48
#define PADDR_MASK ((1UL << PADDR_BITS)-1)
#define VADDR_MASK ((1UL << VADDR_BITS)-1)
+
+#define is_canonical_address(x) (((long)(x) >> 47) == ((long)(x) >> 63))
#ifndef __ASSEMBLY__
diff -r 0536dbde1562 -r f50380324d1c tools/python/xen/util/mkdir.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/mkdir.py Fri Dec 01 12:03:38 2006 +0000
@@ -0,0 +1,44 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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) 2006 XenSource Inc.
+#============================================================================
+
+import errno
+import os
+import os.path
+import stat
+
+
+def parents(dir, perms, enforcePermissions = False):
+ """
+ Ensure that the given directory exists, creating it if necessary, but not
+ complaining if it's already there.
+
+ @param dir The directory name.
+ @param perms One of the stat.S_ constants.
+ @param enforcePermissions Enforce our ownership and the given permissions,
+ even if the directory pre-existed with different ones.
+ """
+ # Catch the exception here, rather than checking for the directory's
+ # existence first, to avoid races.
+ try:
+ os.makedirs(dir, perms)
+ except OSError, exn:
+ if exn.args[0] != errno.EEXIST or not os.path.isdir(dir):
+ raise
+ if enforcePermissions:
+ os.chown(dir, os.geteuid(), os.getegid())
+ os.chmod(dir, stat.S_IRWXU)
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/hvm/vmx/intr.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/hvm/vmx/intr.c Fri Dec 01 12:03:38 2006 +0000
@@ -0,0 +1,196 @@
+/*
+ * io.c: handling I/O, interrupts related VMX entry/exit
+ * Copyright (c) 2004, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/mm.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/trace.h>
+#include <xen/event.h>
+
+#include <asm/current.h>
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/hvm/hvm.h>
+#include <asm/hvm/io.h>
+#include <asm/hvm/support.h>
+#include <asm/hvm/vmx/vmx.h>
+#include <asm/hvm/vmx/vmcs.h>
+#include <asm/hvm/vpic.h>
+#include <asm/hvm/vlapic.h>
+#include <public/hvm/ioreq.h>
+
+
+static inline 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)) {
+ *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);
+}
+
+#ifdef __x86_64__
+static void update_tpr_threshold(struct vlapic *vlapic)
+{
+ int max_irr, tpr;
+
+ if ( !vlapic_enabled(vlapic) ||
+ ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
+ {
+ __vmwrite(TPR_THRESHOLD, 0);
+ return;
+ }
+
+ tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
+ __vmwrite(TPR_THRESHOLD, (max_irr > tpr) ? (tpr >> 4) : (max_irr >> 4));
+}
+#else
+#define update_tpr_threshold(v) ((void)0)
+#endif
+
+asmlinkage void vmx_intr_assist(void)
+{
+ int intr_type = 0;
+ int highest_vector;
+ unsigned long eflags;
+ struct vcpu *v = current;
+ struct hvm_domain *plat=&v->domain->arch.hvm_domain;
+ struct periodic_time *pt = &plat->pl_time.periodic_tm;
+ unsigned int idtv_info_field;
+ unsigned long inst_len;
+ int has_ext_irq;
+
+ if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr )
+ {
+ hvm_isa_irq_deassert(current->domain, pt->irq);
+ hvm_isa_irq_assert(current->domain, pt->irq);
+ }
+
+ hvm_set_callback_irq_level();
+
+ update_tpr_threshold(vcpu_vlapic(v));
+
+ has_ext_irq = cpu_has_pending_irq(v);
+
+ if ( unlikely(v->arch.hvm_vmx.vector_injected) )
+ {
+ v->arch.hvm_vmx.vector_injected=0;
+ if (unlikely(has_ext_irq)) enable_irq_window(v);
+ return;
+ }
+
+ /* This could be moved earlier in the VMX resume sequence. */
+ idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
+ if ( unlikely(idtv_info_field & INTR_INFO_VALID_MASK) )
+ {
+ __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
+
+ /*
+ * Safe: the length will only be interpreted for software exceptions
+ * and interrupts. If we get here then delivery of some event caused a
+ * fault, and this always results in defined VM_EXIT_INSTRUCTION_LEN.
+ */
+ inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */
+ __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
+
+ 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))
+ enable_irq_window(v);
+
+ HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
+
+ return;
+ }
+
+ if ( likely(!has_ext_irq) )
+ return;
+
+ if ( unlikely(is_interruptibility_state()) )
+ {
+ /* pre-cleared for emulated instruction */
+ enable_irq_window(v);
+ HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
+ return;
+ }
+
+ eflags = __vmread(GUEST_RFLAGS);
+ if ( irq_masked(eflags) )
+ {
+ enable_irq_window(v);
+ return;
+ }
+
+ highest_vector = cpu_get_interrupt(v, &intr_type);
+ if ( highest_vector < 0 )
+ return;
+
+ switch ( intr_type )
+ {
+ case APIC_DM_EXTINT:
+ case APIC_DM_FIXED:
+ case APIC_DM_LOWEST:
+ vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
+ TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, highest_vector, 0);
+ break;
+
+ case APIC_DM_SMI:
+ case APIC_DM_NMI:
+ case APIC_DM_INIT:
+ case APIC_DM_STARTUP:
+ default:
+ printk("Unsupported interrupt type\n");
+ BUG();
+ break;
+ }
+
+ hvm_interrupt_post(v, highest_vector, intr_type);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 0536dbde1562 -r f50380324d1c xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Fri Dec 01 12:03:15 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/*
- * io.c: handling I/O, interrupts related VMX entry/exit
- * Copyright (c) 2004, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- */
-
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/mm.h>
-#include <xen/lib.h>
-#include <xen/errno.h>
-#include <xen/trace.h>
-#include <xen/event.h>
-
-#include <asm/current.h>
-#include <asm/cpufeature.h>
-#include <asm/processor.h>
-#include <asm/msr.h>
-#include <asm/hvm/hvm.h>
-#include <asm/hvm/io.h>
-#include <asm/hvm/support.h>
-#include <asm/hvm/vmx/vmx.h>
-#include <asm/hvm/vmx/vmcs.h>
-#include <asm/hvm/vpic.h>
-#include <asm/hvm/vlapic.h>
-#include <public/hvm/ioreq.h>
-
-
-static inline 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)) {
- *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);
-}
-
-#ifdef __x86_64__
-static void update_tpr_threshold(struct vlapic *vlapic)
-{
- int max_irr, tpr;
-
- /* Clear the work-to-do flag /then/ do the work. */
- vlapic->flush_tpr_threshold = 0;
- mb();
-
- if ( !vlapic_enabled(vlapic) ||
- ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
- {
- __vmwrite(TPR_THRESHOLD, 0);
- return;
- }
-
- tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
- __vmwrite(TPR_THRESHOLD, (max_irr > tpr) ? (tpr >> 4) : (max_irr >> 4));
-}
-#else
-#define update_tpr_threshold(v) ((void)0)
-#endif
-
-asmlinkage void vmx_intr_assist(void)
-{
- int intr_type = 0;
- int highest_vector;
- unsigned long eflags;
- struct vcpu *v = current;
- struct vlapic *vlapic = vcpu_vlapic(v);
- struct hvm_domain *plat=&v->domain->arch.hvm_domain;
- struct periodic_time *pt = &plat->pl_time.periodic_tm;
- unsigned int idtv_info_field;
- unsigned long inst_len;
- int has_ext_irq;
-
- if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr )
- {
- hvm_isa_irq_deassert(current->domain, pt->irq);
- hvm_isa_irq_assert(current->domain, pt->irq);
- }
-
- hvm_set_callback_irq_level();
-
- if ( vlapic->flush_tpr_threshold )
- update_tpr_threshold(vlapic);
-
- has_ext_irq = cpu_has_pending_irq(v);
-
- if ( unlikely(v->arch.hvm_vmx.vector_injected) )
- {
- v->arch.hvm_vmx.vector_injected=0;
- if (unlikely(has_ext_irq)) enable_irq_window(v);
- return;
- }
-
- /* This could be moved earlier in the VMX resume sequence. */
- idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
- if ( unlikely(idtv_info_field & INTR_INFO_VALID_MASK) )
- {
- __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
-
- /*
- * Safe: the length will only be interpreted for software exceptions
- * and interrupts. If we get here then delivery of some event caused a
- * fault, and this always results in defined VM_EXIT_INSTRUCTION_LEN.
- */
- inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */
- __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
-
- 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))
- enable_irq_window(v);
-
- HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
-
- return;
- }
-
- if ( likely(!has_ext_irq) )
- return;
-
- if ( unlikely(is_interruptibility_state()) )
- {
- /* pre-cleared for emulated instruction */
- enable_irq_window(v);
- HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
- return;
- }
-
- eflags = __vmread(GUEST_RFLAGS);
- if ( irq_masked(eflags) )
- {
- enable_irq_window(v);
- return;
- }
-
- highest_vector = cpu_get_interrupt(v, &intr_type);
- if ( highest_vector < 0 )
- return;
-
- switch ( intr_type )
- {
- case APIC_DM_EXTINT:
- case APIC_DM_FIXED:
- case APIC_DM_LOWEST:
- vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
- TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, highest_vector, 0);
- break;
-
- case APIC_DM_SMI:
- case APIC_DM_NMI:
- case APIC_DM_INIT:
- case APIC_DM_STARTUP:
- default:
- printk("Unsupported interrupt type\n");
- BUG();
- break;
- }
-
- hvm_interrupt_post(v, highest_vector, intr_type);
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|