ChangeSet 1.1709.1.3, 2005/06/13 16:03:21-06:00, djm@xxxxxxxxxxxxxxxxxx
Various fixes for multi-domain prep
Signed-off-by: Matthew Chapman <matthewc@xxxxxx>
arch/ia64/dom0_ops.c | 58 ++++++--
arch/ia64/domain.c | 220 ++++++++++++++-------------------
arch/ia64/hypercall.c | 24 +++
arch/ia64/patch/linux-2.6.11/uaccess.h | 15 ++
arch/ia64/tools/mkbuildtree | 2
arch/ia64/vcpu.c | 6
arch/ia64/xenmisc.c | 8 -
include/asm-ia64/config.h | 5
include/asm-ia64/domain.h | 3
include/public/arch-ia64.h | 11 +
10 files changed, 196 insertions(+), 156 deletions(-)
diff -Nru a/xen/arch/ia64/dom0_ops.c b/xen/arch/ia64/dom0_ops.c
--- a/xen/arch/ia64/dom0_ops.c 2005-06-19 14:03:47 -04:00
+++ b/xen/arch/ia64/dom0_ops.c 2005-06-19 14:03:47 -04:00
@@ -18,14 +18,6 @@
#include <xen/console.h>
#include <public/sched_ctl.h>
-#define TRC_DOM0OP_ENTER_BASE 0x00020000
-#define TRC_DOM0OP_LEAVE_BASE 0x00030000
-
-static int msr_cpu_mask;
-static unsigned long msr_addr;
-static unsigned long msr_lo;
-static unsigned long msr_hi;
-
long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
{
long ret = 0;
@@ -35,6 +27,49 @@
switch ( op->cmd )
{
+ /*
+ * NOTE: DOM0_GETMEMLIST has somewhat different semantics on IA64 -
+ * it actually allocates and maps pages.
+ */
+ case DOM0_GETMEMLIST:
+ {
+ unsigned long i;
+ struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
+ unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
+ unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
+ unsigned long pfn;
+ unsigned long *buffer = op->u.getmemlist.buffer;
+ struct page *page;
+
+ ret = -EINVAL;
+ if ( d != NULL )
+ {
+ ret = 0;
+
+ for ( i = start_page; i < (start_page + nr_pages); i++ )
+ {
+ page = map_new_domain_page(d, i << PAGE_SHIFT);
+ if ( page == NULL )
+ {
+ ret = -ENOMEM;
+ break;
+ }
+ pfn = page_to_pfn(page);
+ if ( put_user(pfn, buffer) )
+ {
+ ret = -EFAULT;
+ break;
+ }
+ buffer++;
+ }
+
+ op->u.getmemlist.num_pfns = i - start_page;
+ copy_to_user(u_dom0_op, op, sizeof(*op));
+
+ put_domain(d);
+ }
+ }
+ break;
default:
ret = -ENOSYS;
@@ -42,11 +77,4 @@
}
return ret;
-}
-
-void arch_getdomaininfo_ctxt(struct domain *d, struct vcpu_guest_context *c)
-{
- int i;
-
- dummy();
}
diff -Nru a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c
--- a/xen/arch/ia64/domain.c 2005-06-19 14:03:47 -04:00
+++ b/xen/arch/ia64/domain.c 2005-06-19 14:03:47 -04:00
@@ -76,7 +76,7 @@
/* this belongs in include/asm, but there doesn't seem to be a suitable place
*/
void free_perdomain_pt(struct domain *d)
{
- dummy();
+ printf("free_perdomain_pt: not implemented\n");
//free_page((unsigned long)d->mm.perdomain_pt);
}
@@ -166,12 +166,34 @@
free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
}
+static void init_switch_stack(struct vcpu *v)
+{
+ struct pt_regs *regs = (struct pt_regs *) ((unsigned long) v +
IA64_STK_OFFSET) - 1;
+ struct switch_stack *sw = (struct switch_stack *) regs - 1;
+ extern void ia64_ret_from_clone;
+
+ memset(sw, 0, sizeof(struct switch_stack) + sizeof(struct pt_regs));
+ sw->ar_bspstore = (unsigned long)v + IA64_RBS_OFFSET;
+ sw->b0 = (unsigned long) &ia64_ret_from_clone;
+ sw->ar_fpsr = FPSR_DEFAULT;
+ v->arch._thread.ksp = (unsigned long) sw - 16;
+ // stay on kernel stack because may get interrupts!
+ // ia64_ret_from_clone (which b0 gets in new_thread) switches
+ // to user stack
+ v->arch._thread.on_ustack = 0;
+ memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
+}
+
#ifdef CONFIG_VTI
void arch_do_createdomain(struct vcpu *v)
{
struct domain *d = v->domain;
struct thread_info *ti = alloc_thread_info(v);
+ /* Clear thread_info to clear some important fields, like preempt_count
*/
+ memset(ti, 0, sizeof(struct thread_info));
+ init_switch_stack(v);
+
/* If domain is VMX domain, shared info area is created
* by domain and then domain notifies HV by specific hypercall.
* If domain is xenolinux, shared info area is created by
@@ -194,9 +216,6 @@
}
memset(v->vcpu_info, 0, PAGE_SIZE);
- /* Clear thread_info to clear some important fields, like preempt_count
*/
- memset(ti, 0, sizeof(struct thread_info));
-
/* Allocate per-domain vTLB and vhpt */
v->arch.vtlb = init_domain_tlb(v);
@@ -212,37 +231,37 @@
d->xen_vaend = 0xf300000000000000;
d->arch.breakimm = 0x1000;
- // stay on kernel stack because may get interrupts!
- // ia64_ret_from_clone (which b0 gets in new_thread) switches
- // to user stack
- v->arch._thread.on_ustack = 0;
+ d->arch.mm = xmalloc(struct mm_struct);
+ if (unlikely(!d->arch.mm)) {
+ printk("Can't allocate mm_struct for domain %d\n",d->domain_id);
+ return -ENOMEM;
+ }
+ memset(d->arch.mm, 0, sizeof(*d->arch.mm));
+ d->arch.mm->pgd = pgd_alloc(d->arch.mm);
+ if (unlikely(!d->arch.mm->pgd)) {
+ printk("Can't allocate pgd for domain %d\n",d->domain_id);
+ return -ENOMEM;
+ }
+}
}
#else // CONFIG_VTI
void arch_do_createdomain(struct vcpu *v)
{
struct domain *d = v->domain;
+ struct thread_info *ti = alloc_thread_info(v);
+
+ /* Clear thread_info to clear some important fields, like preempt_count
*/
+ memset(ti, 0, sizeof(struct thread_info));
+ init_switch_stack(v);
d->shared_info = (void *)alloc_xenheap_page();
- v->vcpu_info = (void *)alloc_xenheap_page();
- if (!v->vcpu_info) {
+ if (!d->shared_info) {
printk("ERROR/HALTING: CAN'T ALLOC PAGE\n");
while (1);
}
- memset(v->vcpu_info, 0, PAGE_SIZE);
- /* pin mapping */
- // FIXME: Does this belong here? Or do only at domain switch time?
-#if 0
- // this is now done in ia64_new_rr7
- {
- /* WARNING: following must be inlined to avoid nested fault */
- unsigned long psr = ia64_clear_ic();
- ia64_itr(0x2, IA64_TR_SHARED_INFO, SHAREDINFO_ADDR,
- pte_val(pfn_pte(ia64_tpa(d->shared_info) >> PAGE_SHIFT,
PAGE_KERNEL)),
- PAGE_SHIFT);
- ia64_set_psr(psr);
- ia64_srlz_i();
- }
-#endif
+ memset(d->shared_info, 0, PAGE_SIZE);
+ v->vcpu_info = &(d->shared_info->vcpu_data[0]);
+
d->max_pages = (128*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
if ((d->arch.metaphysical_rr0 = allocate_metaphysical_rr0()) == -1UL)
BUG();
@@ -258,33 +277,63 @@
d->shared_info_va = 0xf100000000000000;
d->arch.breakimm = 0x1000;
v->arch.breakimm = d->arch.breakimm;
- // stay on kernel stack because may get interrupts!
- // ia64_ret_from_clone (which b0 gets in new_thread) switches
- // to user stack
- v->arch._thread.on_ustack = 0;
+
+ d->arch.mm = xmalloc(struct mm_struct);
+ if (unlikely(!d->arch.mm)) {
+ printk("Can't allocate mm_struct for domain %d\n",d->domain_id);
+ return -ENOMEM;
+ }
+ memset(d->arch.mm, 0, sizeof(*d->arch.mm));
+ d->arch.mm->pgd = pgd_alloc(d->arch.mm);
+ if (unlikely(!d->arch.mm->pgd)) {
+ printk("Can't allocate pgd for domain %d\n",d->domain_id);
+ return -ENOMEM;
+ }
}
#endif // CONFIG_VTI
-void arch_do_boot_vcpu(struct vcpu *v)
+void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
{
- return;
+ struct pt_regs *regs = (struct pt_regs *) ((unsigned long) v +
IA64_STK_OFFSET) - 1;
+
+ printf("arch_getdomaininfo_ctxt\n");
+ c->regs = *regs;
+ c->vcpu = v->vcpu_info->arch;
+ c->shared = v->domain->shared_info->arch;
}
int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c)
{
- dummy();
- return 1;
+ struct pt_regs *regs = (struct pt_regs *) ((unsigned long) v +
IA64_STK_OFFSET) - 1;
+
+ printf("arch_set_info_guest\n");
+ *regs = c->regs;
+ regs->cr_ipsr =
IA64_PSR_IT|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IC|IA64_PSR_I|IA64_PSR_DFH|IA64_PSR_BN|IA64_PSR_SP|IA64_PSR_DI;
+ regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT;
+ regs->ar_rsc |= (2 << 2); /* force PL2/3 */
+
+ v->vcpu_info->arch = c->vcpu;
+ init_all_rr(v);
+
+ // this should be in userspace
+ regs->r28 = dom_fw_setup(v->domain,"nomca nosmp xencons=ttyS
console=ttyS0",256L); //FIXME
+ v->vcpu_info->arch.banknum = 1;
+ v->vcpu_info->arch.metaphysical_mode = 1;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|