# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1181932564 21600
# Node ID 65956e1d1aec4fa7d67ca51fa28e0a344b4778e2
# Parent fd0103b55504bac392864de87d21506e18ba2d6b
[IA64] RBS is now in vcpu_guest_context_regs.
As there is not anymore local variable of type vcpu_guest_context_regs in
the hypervisor the rbs field (16KB) can be put in the structure.
Code to read/write the field added.
Signed-off-by: Tristan Gingold <tgingold@xxxxxxx>
---
xen/arch/ia64/xen/domain.c | 22 +++++++++++++++++++---
xen/include/public/arch-ia64.h | 22 +++++++++++-----------
xen/include/public/foreign/reference.size | 4 ++--
3 files changed, 32 insertions(+), 16 deletions(-)
diff -r fd0103b55504 -r 65956e1d1aec xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Fri Jun 15 11:34:34 2007 -0600
+++ b/xen/arch/ia64/xen/domain.c Fri Jun 15 12:36:04 2007 -0600
@@ -361,6 +361,10 @@ void startup_cpu_idle_loop(void)
# error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)."
#endif
+#if (IA64_RBS_OFFSET % 512) != IA64_GUEST_CONTEXT_RBS_OFFSET
+# error "arch-ia64.h: IA64_GUEST_CONTEXT_RBS_OFFSET must be adjusted."
+#endif
+
void hlt_timer_fn(void *data)
{
struct vcpu *v = data;
@@ -610,6 +614,7 @@ void arch_get_info_guest(struct vcpu *v,
struct vcpu_tr_regs *tr = &c.nat->regs.tr;
struct cpu_user_regs *uregs = vcpu_regs(v);
int is_hvm = VMX_DOMAIN(v);
+ unsigned int rbs_size;
c.nat->regs.b[6] = uregs->b6;
c.nat->regs.b[7] = uregs->b7;
@@ -638,7 +643,8 @@ void arch_get_info_guest(struct vcpu *v,
c.nat->regs.pr = uregs->pr;
c.nat->regs.b[0] = uregs->b0;
- c.nat->regs.ar.bsp = uregs->ar_bspstore + (uregs->loadrs >> 16);
+ rbs_size = uregs->loadrs >> 16;
+ c.nat->regs.ar.bsp = uregs->ar_bspstore + rbs_size;
c.nat->regs.r[1] = uregs->r1;
c.nat->regs.r[12] = uregs->r12;
@@ -683,6 +689,9 @@ void arch_get_info_guest(struct vcpu *v,
/* FIXME: to be reordered. */
c.nat->regs.nats = uregs->eml_unat;
+ if (rbs_size < sizeof (c.nat->regs.rbs))
+ memcpy (c.nat->regs.rbs, (char *)v + IA64_RBS_OFFSET, rbs_size);
+
c.nat->privregs_pfn = get_gpfn_from_mfn
(virt_to_maddr(v->arch.privregs) >> PAGE_SHIFT);
@@ -713,10 +722,12 @@ int arch_set_info_guest(struct vcpu *v,
{
struct cpu_user_regs *uregs = vcpu_regs(v);
struct domain *d = v->domain;
+ int was_initialised = v->is_initialised;
+ unsigned int rbs_size;
int rc;
/* Finish vcpu initialization. */
- if (!v->is_initialised) {
+ if (!was_initialised) {
if (d->arch.is_vti)
rc = vmx_final_setup_guest(v);
else
@@ -761,7 +772,12 @@ int arch_set_info_guest(struct vcpu *v,
uregs->pr = c.nat->regs.pr;
uregs->b0 = c.nat->regs.b[0];
- uregs->loadrs = (c.nat->regs.ar.bsp - c.nat->regs.ar.bspstore) << 16;
+ rbs_size = c.nat->regs.ar.bsp - c.nat->regs.ar.bspstore;
+ /* Protection against crazy user code. */
+ if (!was_initialised)
+ uregs->loadrs = (rbs_size) << 16;
+ if (rbs_size == (uregs->loadrs >> 16))
+ memcpy ((char *)v + IA64_RBS_OFFSET, c.nat->regs.rbs, rbs_size);
uregs->r1 = c.nat->regs.r[1];
uregs->r12 = c.nat->regs.r[12];
diff -r fd0103b55504 -r 65956e1d1aec xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h Fri Jun 15 11:34:34 2007 -0600
+++ b/xen/include/public/arch-ia64.h Fri Jun 15 12:36:04 2007 -0600
@@ -451,7 +451,8 @@ struct vcpu_guest_context_regs {
unsigned long psr;
unsigned long cfm;
unsigned long pr;
- unsigned long nats; /* NaT bits for r1-r31. */
+ unsigned int nats; /* NaT bits for r1-r31. */
+ unsigned int bnats; /* Nat bits for banked registers. */
union vcpu_ar_regs ar;
union vcpu_cr_regs cr;
struct pt_fpreg f[128];
@@ -469,18 +470,17 @@ struct vcpu_guest_context_regs {
struct vcpu_tr_regs tr;
-#if 0
- /*
- * The vcpu_guest_context structure is allocated on the stack in
- * a few places. With this array for RBS storage, that structure
- * is a bit over 21k. It looks like maybe we're blowing the stack
- * and causing rather random looking failures on a couple systems.
- * Remove since we're not actually using it for now.
- */
-
+ /*
+ * The rbs is intended to be the image of the stacked registers still
+ * in the cpu (not yet stored in memory). It is laid out as if it
+ * were written in memory at an 512 (64*8) * aligned address + offset.
+ * The offset is IA64_RBS_OFFSET % 512.
+ * rbs_nat contains NaT bits for the remaining rbs registers.
+ */
/* Note: loadrs is 2**14 bytes == 2**11 slots. */
+#define IA64_GUEST_CONTEXT_RBS_OFFSET 448
unsigned long rbs[2048];
-#endif
+ unsigned long rbs_nat;
};
struct vcpu_guest_context {
diff -r fd0103b55504 -r 65956e1d1aec xen/include/public/foreign/reference.size
--- a/xen/include/public/foreign/reference.size Fri Jun 15 11:34:34 2007 -0600
+++ b/xen/include/public/foreign/reference.size Fri Jun 15 12:36:04 2007 -0600
@@ -8,8 +8,8 @@ xen_ia64_boot_param | -
xen_ia64_boot_param | - - 96
ia64_tr_entry | - - 32
vcpu_tr_regs | - - 512
-vcpu_guest_context_regs | - - 5488
-vcpu_guest_context | 2800 5168 5520
+vcpu_guest_context_regs | - - 21872
+vcpu_guest_context | 2800 5168 21904
arch_vcpu_info | 24 16 0
vcpu_time_info | 32 32 32
vcpu_info | 64 64 48
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|