aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.hgignore1
-rw-r--r--docs/xen-api/xenapi-datamodel.tex33
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S3
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c8
-rw-r--r--tools/ioemu/hw/xen_platform.c8
-rw-r--r--tools/ioemu/target-i386-dm/helper2.c7
-rw-r--r--tools/python/xen/xend/XendAPI.py5
-rw-r--r--tools/python/xen/xend/XendTask.py10
-rw-r--r--unmodified_drivers/linux-2.6/overrides.mk3
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/platform-pci.c10
-rw-r--r--xen/arch/x86/hvm/hvm.c65
-rw-r--r--xen/arch/x86/hvm/io.c12
-rw-r--r--xen/arch/x86/hvm/platform.c28
-rw-r--r--xen/arch/x86/hvm/svm/svm.c11
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c10
-rw-r--r--xen/include/asm-x86/hvm/io.h1
-rw-r--r--xen/include/asm-x86/hvm/support.h3
-rw-r--r--xen/include/public/hvm/ioreq.h1
18 files changed, 107 insertions, 112 deletions
diff --git a/.hgignore b/.hgignore
index 161f740eaf..e3bca07c23 100644
--- a/.hgignore
+++ b/.hgignore
@@ -14,6 +14,7 @@
.*\.orig$
.*\.rej$
.*/a\.out$
+.*/Modules\.symvers$
.*/cscope\..*$
^cscope.*$
^[^/]*\.bz2$
diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex
index eadcf7e3f4..c794eb3085 100644
--- a/docs/xen-api/xenapi-datamodel.tex
+++ b/docs/xen-api/xenapi-datamodel.tex
@@ -512,7 +512,6 @@ $\mathit{RO}_\mathit{run}$ & {\tt session} & session ref & the session that cre
$\mathit{RO}_\mathit{run}$ & {\tt progress} & int & if the task is still pending, this field contains the estimated percentage complete (0-100). If task has completed (successfully or unsuccessfully) this should be 100. \\
$\mathit{RO}_\mathit{run}$ & {\tt type} & string & if the task has completed successfully, this field contains the type of the encoded result (i.e. name of the class whose reference is in the result field). Undefined otherwise. \\
$\mathit{RO}_\mathit{run}$ & {\tt result} & string & if the task has completed successfully, this field contains the result value (either Void or an object reference). Undefined otherwise. \\
-$\mathit{RO}_\mathit{run}$ & {\tt error\_code} & int & if the task has failed, this field contains the error code. Undefined otherwise. \\
$\mathit{RO}_\mathit{run}$ & {\tt error\_info} & string Set & if the task has failed, this field contains the set of associated error strings. Undefined otherwise. \\
$\mathit{RO}_\mathit{run}$ & {\tt allowed\_operations} & (task\_allowed\_operations) Set & Operations allowed on this task \\
\hline
@@ -833,38 +832,6 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~get\_error\_code}
-
-{\bf Overview:}
-Get the error\_code field of the given task.
-
- \noindent {\bf Signature:}
-\begin{verbatim} int get_error_code (session_id s, task ref self)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt task ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-int
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
\subsubsection{RPC name:~get\_error\_info}
{\bf Overview:}
diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
index aa5de72a82..4dbd7a7b0f 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
@@ -205,7 +205,6 @@ END(ret_from_fork)
*/
.macro _frame ref
CFI_STARTPROC simple
- CFI_SIGNAL_FRAME
CFI_DEF_CFA rsp,SS+8-\ref
/*CFI_REL_OFFSET ss,SS-\ref*/
CFI_REL_OFFSET rsp,RSP-\ref
@@ -1198,7 +1197,7 @@ END(int3)
ENTRY(overflow)
zeroentry do_overflow
-END(debug)
+END(overflow)
ENTRY(bounds)
zeroentry do_bounds
diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
index 4978ea58dc..158c3b10cd 100644
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
@@ -306,14 +306,6 @@ static int decrease_reservation(unsigned long nr_pages)
balloon_append(pfn_to_page(pfn));
}
-#ifndef CONFIG_XEN
- /* XXX Temporary hack. */
- {
- extern void xen_invalidate_foreign_mappings(void);
- xen_invalidate_foreign_mappings();
- }
-#endif
-
set_xen_guest_handle(reservation.extent_start, frame_list);
reservation.nr_extents = nr_pages;
ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
diff --git a/tools/ioemu/hw/xen_platform.c b/tools/ioemu/hw/xen_platform.c
index cdff19c9d8..47dd03b43d 100644
--- a/tools/ioemu/hw/xen_platform.c
+++ b/tools/ioemu/hw/xen_platform.c
@@ -29,16 +29,10 @@
extern FILE *logfile;
-static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- if (val == 0)
- qemu_invalidate_map_cache();
-}
-
static void platform_ioport_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
- register_ioport_write(addr, 1, 1, platform_ioport_write, NULL);
+ /* nothing yet */
}
static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c
index 7e6b56e961..7beda011c6 100644
--- a/tools/ioemu/target-i386-dm/helper2.c
+++ b/tools/ioemu/target-i386-dm/helper2.c
@@ -506,8 +506,11 @@ void __handle_ioreq(CPUState *env, ioreq_t *req)
cpu_ioreq_xchg(env, req);
break;
case IOREQ_TYPE_TIMEOFFSET:
- cpu_ioreq_timeoffset(env, req);
- break;
+ cpu_ioreq_timeoffset(env, req);
+ break;
+ case IOREQ_TYPE_INVALIDATE:
+ qemu_invalidate_map_cache();
+ break;
default:
hw_error("Invalid ioreq type 0x%x\n", req->type);
}
diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py
index 78128f35b4..b31a00899b 100644
--- a/tools/python/xen/xend/XendAPI.py
+++ b/tools/python/xen/xend/XendAPI.py
@@ -789,7 +789,6 @@ class XendAPI(object):
'progress',
'type',
'result',
- 'error_code',
'error_info',
'allowed_operations',
'session'
@@ -824,10 +823,6 @@ class XendAPI(object):
task = XendTaskManager.get_task(task_ref)
return xen_api_success(task.result)
- def task_get_error_code(self, session, task_ref):
- task = XendTaskManager.get_task(task_ref)
- return xen_api_success(task.error_code)
-
def task_get_error_info(self, session, task_ref):
task = XendTaskManager.get_task(task_ref)
return xen_api_success(task.error_info)
diff --git a/tools/python/xen/xend/XendTask.py b/tools/python/xen/xend/XendTask.py
index 0485c39207..5045a06d75 100644
--- a/tools/python/xen/xend/XendTask.py
+++ b/tools/python/xen/xend/XendTask.py
@@ -24,7 +24,7 @@ class XendTask(threading.Thread):
"""Represents a Asynchronous Task used by Xen API.
Basically proxies the callable object in a thread and returns the
- results via self.{type,result,error_code,error_info}.
+ results via self.{type,result,error_info}.
@cvar task_progress: Thread local storage for progress tracking.
It is a dict indexed by thread_id. Note that the
@@ -71,7 +71,6 @@ class XendTask(threading.Thread):
self.uuid = uuid
self.result = None
- self.error_code = ''
self.error_info = []
self.name_label = label or func.__name__
@@ -118,13 +117,11 @@ class XendTask(threading.Thread):
self.result = result['Value']
self.set_status(XEN_API_TASK_STATUS_TYPE[1])
else:
- self.error_code = result['ErrorDescription'][0]
- self.error_info = result['ErrorDescription'][1:]
+ self.error_info = result['ErrorDescription']
self.set_status(XEN_API_TASK_STATUS_TYPE[2])
except Exception, e:
log.exception('Error running Async Task')
- self.error_code = 'INTERNAL ERROR'
- self.error_info = [str(e)]
+ self.error_info = ['INTERNAL ERROR', str(e)]
self.set_status(XEN_API_TASK_STATUS_TYPE[2])
self.task_progress_lock.acquire()
@@ -144,7 +141,6 @@ class XendTask(threading.Thread):
'progress': self.get_progress(),
'type': self.type,
'result': self.result,
- 'error_code': self.error_code,
'error_info': self.error_info,
'allowed_operations': {},
'session': self.session,
diff --git a/unmodified_drivers/linux-2.6/overrides.mk b/unmodified_drivers/linux-2.6/overrides.mk
index b00c63d4f0..db791e75ef 100644
--- a/unmodified_drivers/linux-2.6/overrides.mk
+++ b/unmodified_drivers/linux-2.6/overrides.mk
@@ -4,7 +4,8 @@
#
# (i.e. we need the native config for things like -mregparm, but
# a Xen kernel to find the right headers)
-EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202
+EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030205
+EXTRA_CFLAGS += -DCONFIG_XEN_COMPAT=0xffffff
EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H
ifeq ($(ARCH),ia64)
EXTRA_CFLAGS += -DCONFIG_VMX_GUEST
diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
index c9f6d73109..8e69557ac8 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
@@ -208,14 +208,6 @@ static uint64_t get_callback_via(struct pci_dev *pdev)
((uint64_t)(pin - 1) & 3));
}
-/* Invalidate foreign mappings (e.g., in qemu-based device model). */
-static uint16_t invlmap_port;
-void xen_invalidate_foreign_mappings(void)
-{
- outb(0, invlmap_port);
-}
-EXPORT_SYMBOL(xen_invalidate_foreign_mappings);
-
static int __devinit platform_pci_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -240,8 +232,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
return -ENOENT;
}
- invlmap_port = ioaddr;
-
if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL)
{
printk(KERN_ERR ":MEM I/O resource 0x%lx @ 0x%lx busy\n",
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c68341662f..5cb283bf2e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -521,32 +521,19 @@ static hvm_hypercall_t *hvm_hypercall_table[NR_hypercalls] = {
HYPERCALL(hvm_op)
};
-int hvm_do_hypercall(struct cpu_user_regs *pregs)
+static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
{
- if ( unlikely(ring_3(pregs)) )
- {
- pregs->eax = -EPERM;
- return 0;
- }
-
if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] )
{
if ( pregs->eax != __HYPERVISOR_grant_table_op )
gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %d.\n",
current->domain->domain_id, current->vcpu_id, pregs->eax);
pregs->eax = -ENOSYS;
- return 0;
+ return;
}
- /* Check for preemption: EIP will be modified from this dummy value. */
- pregs->eip = 0xF0F0F0FF;
-
pregs->eax = hvm_hypercall_table[pregs->eax](
pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
-
- /* XXX: put fake IO instr here to inform the emulator to flush mapcache */
-
- return (pregs->eip != 0xF0F0F0FF); /* preempted? */
}
#else /* defined(__x86_64__) */
@@ -606,14 +593,8 @@ static hvm_hypercall_t *hvm_hypercall32_table[NR_hypercalls] = {
HYPERCALL(event_channel_op)
};
-int hvm_do_hypercall(struct cpu_user_regs *pregs)
+static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
{
- if ( unlikely(ring_3(pregs)) )
- {
- pregs->rax = -EPERM;
- return 0;
- }
-
pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */
if ( (pregs->rax >= NR_hypercalls) || !hvm_hypercall64_table[pregs->rax] )
{
@@ -621,12 +602,9 @@ int hvm_do_hypercall(struct cpu_user_regs *pregs)
gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %ld.\n",
current->domain->domain_id, current->vcpu_id, pregs->rax);
pregs->rax = -ENOSYS;
- return 0;
+ return;
}
- /* Check for preemption: RIP will be modified from this dummy value. */
- pregs->rip = 0xF0F0F0FF;
-
if ( current->arch.paging.mode->guest_levels == 4 )
{
pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi,
@@ -643,14 +621,41 @@ int hvm_do_hypercall(struct cpu_user_regs *pregs)
(uint32_t)pregs->esi,
(uint32_t)pregs->edi);
}
-
- /* XXX: put fake IO instr here to inform the emulator to flush mapcache */
-
- return (pregs->rip != 0xF0F0F0FF); /* preempted? */
}
#endif /* defined(__x86_64__) */
+int hvm_do_hypercall(struct cpu_user_regs *pregs)
+{
+ int flush, preempted;
+ unsigned long old_eip;
+
+ if ( unlikely(ring_3(pregs)) )
+ {
+ pregs->eax = -EPERM;
+ return 0;
+ }
+
+ /*
+ * NB. In future flush only on decrease_reservation.
+ * For now we also need to flush when pages are added, as qemu-dm is not
+ * yet capable of faulting pages into an existing valid mapcache bucket.
+ */
+ flush = ((uint32_t)pregs->eax == __HYPERVISOR_memory_op);
+
+ /* Check for preemption: RIP will be modified from this dummy value. */
+ old_eip = pregs->eip;
+ pregs->eip = 0xF0F0F0FF;
+
+ __hvm_do_hypercall(pregs);
+
+ preempted = (pregs->eip != 0xF0F0F0FF);
+ pregs->eip = old_eip;
+
+ return (preempted ? HVM_HCALL_preempted :
+ flush ? HVM_HCALL_invalidate : HVM_HCALL_completed);
+}
+
void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3)
{
v->arch.hvm_vcpu.hw_cr3 = guest_cr3;
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 3177426484..03820f0ebd 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -845,10 +845,17 @@ void hvm_io_assist(void)
p->state = STATE_IOREQ_NONE;
- if ( p->type == IOREQ_TYPE_PIO )
+ switch ( p->type )
+ {
+ case IOREQ_TYPE_INVALIDATE:
+ goto out;
+ case IOREQ_TYPE_PIO:
hvm_pio_assist(regs, p, io_opp);
- else
+ break;
+ default:
hvm_mmio_assist(regs, p, io_opp);
+ break;
+ }
/* Copy register changes back into current guest state. */
hvm_load_cpu_guest_regs(v, regs);
@@ -861,6 +868,7 @@ void hvm_io_assist(void)
mark_dirty(d, gmfn);
}
+ out:
vcpu_end_shutdown_deferral(v);
}
diff --git a/xen/arch/x86/hvm/platform.c b/xen/arch/x86/hvm/platform.c
index 0862da2753..d333a92ace 100644
--- a/xen/arch/x86/hvm/platform.c
+++ b/xen/arch/x86/hvm/platform.c
@@ -941,6 +941,34 @@ void send_timeoffset_req(unsigned long timeoff)
printk("Unsuccessful timeoffset update\n");
}
+/* Ask ioemu mapcache to invalidate mappings. */
+void send_invalidate_req(void)
+{
+ struct vcpu *v = current;
+ vcpu_iodata_t *vio;
+ ioreq_t *p;
+
+ vio = get_vio(v->domain, v->vcpu_id);
+ if ( vio == NULL )
+ {
+ printk("bad shared page: %lx\n", (unsigned long) vio);
+ domain_crash_synchronous();
+ }
+
+ p = &vio->vp_ioreq;
+ if ( p->state != STATE_IOREQ_NONE )
+ printk("WARNING: send invalidate req with something "
+ "already pending (%d)?\n", p->state);
+
+ p->type = IOREQ_TYPE_INVALIDATE;
+ p->size = 4;
+ p->dir = IOREQ_WRITE;
+ p->data = ~0UL; /* flush all */
+ p->io_count++;
+
+ hvm_send_assist_req(v);
+}
+
static void mmio_operands(int type, unsigned long gpa,
struct hvm_io_op *mmio_op,
unsigned char op_size)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 39c94bdb31..ae0b42ae66 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -2166,7 +2166,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
unsigned long eip;
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- int inst_len;
+ int inst_len, rc;
exit_reason = vmcb->exitcode;
save_svm_cpu_user_regs(v, regs);
@@ -2275,8 +2275,13 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
ASSERT(inst_len > 0);
HVMTRACE_1D(VMMCALL, v, regs->eax);
- if ( !hvm_do_hypercall(regs) )
- __update_guest_eip(vmcb, inst_len); /* not preempted */
+ rc = hvm_do_hypercall(regs);
+ if ( rc != HVM_HCALL_preempted )
+ {
+ __update_guest_eip(vmcb, inst_len);
+ if ( rc == HVM_HCALL_invalidate )
+ send_invalidate_req();
+ }
break;
case VMEXIT_CR0_READ:
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 855274b8da..b4cfe17b29 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2626,10 +2626,16 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
}
case EXIT_REASON_VMCALL:
{
+ int rc;
HVMTRACE_1D(VMMCALL, v, regs->eax);
inst_len = __get_instruction_length(); /* Safe: VMCALL */
- if ( !hvm_do_hypercall(regs) )
- __update_guest_eip(inst_len); /* not preempted */
+ rc = hvm_do_hypercall(regs);
+ if ( rc != HVM_HCALL_preempted )
+ {
+ __update_guest_eip(inst_len);
+ if ( rc == HVM_HCALL_invalidate )
+ send_invalidate_req();
+ }
break;
}
case EXIT_REASON_CR_ACCESS:
diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h
index c0663ccb0d..17c2f5831a 100644
--- a/xen/include/asm-x86/hvm/io.h
+++ b/xen/include/asm-x86/hvm/io.h
@@ -147,6 +147,7 @@ static inline int irq_masked(unsigned long eflags)
extern void send_pio_req(unsigned long port, unsigned long count, int size,
paddr_t value, int dir, int df, int value_is_ptr);
void send_timeoffset_req(unsigned long timeoff);
+void send_invalidate_req(void);
extern void handle_mmio(unsigned long gpa);
extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
extern void hvm_io_assist(void);
diff --git a/xen/include/asm-x86/hvm/support.h b/xen/include/asm-x86/hvm/support.h
index 9880f920a0..1d331ef5da 100644
--- a/xen/include/asm-x86/hvm/support.h
+++ b/xen/include/asm-x86/hvm/support.h
@@ -228,6 +228,9 @@ int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size);
void hvm_print_line(struct vcpu *v, const char c);
void hlt_timer_fn(void *data);
+#define HVM_HCALL_completed 0 /* hypercall completed - no further action */
+#define HVM_HCALL_preempted 1 /* hypercall preempted - re-execute VMCALL */
+#define HVM_HCALL_invalidate 2 /* invalidate ioemu-dm memory cache */
int hvm_do_hypercall(struct cpu_user_regs *pregs);
void hvm_hlt(unsigned long rflags);
diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h
index 646246e854..063810cc74 100644
--- a/xen/include/public/hvm/ioreq.h
+++ b/xen/include/public/hvm/ioreq.h
@@ -40,6 +40,7 @@
#define IOREQ_TYPE_XCHG 5
#define IOREQ_TYPE_ADD 6
#define IOREQ_TYPE_TIMEOFFSET 7
+#define IOREQ_TYPE_INVALIDATE 8 /* mapcache */
/*
* VMExit dispatcher should cooperate with instruction decoder to