# HG changeset patch # User gingold@virtu10 # Node ID 111af84f1267e8a87da3780a9b14445fc3ccc486 # Parent 85958f34f18314f50a63662eaa1a186cf726531b Implement and use DOM0_DOMAIN_STEUP. DOM0_GETMEMLIST now reads ptes and use gpfn. Domain builder reworked: calls DOMAIN_SETUP, setup start_info page. SAL data are now in domain memory. is_vti field added in domain.arch. Many cleanups (indentation, static, warnings). Signed-off-by: Tristan Gingold diff -r 85958f34f183 -r 111af84f1267 linux-2.6-xen-sparse/arch/ia64/kernel/setup.c --- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Mon Jun 26 14:41:54 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Wed Jun 28 08:50:58 2006 +0200 @@ -523,15 +523,14 @@ setup_arch (char **cmdline_p) shared_info_t *s = HYPERVISOR_shared_info; xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT); - xen_start_info->flags = s->arch.flags; printk("Running on Xen! start_info_pfn=0x%lx nr_pages=%ld " "flags=0x%x\n", s->arch.start_info_pfn, xen_start_info->nr_pages, xen_start_info->flags); /* xen_start_info isn't setup yet, get the flags manually */ - if (s->arch.flags & SIF_INITDOMAIN) { - if (!(s->arch.flags & SIF_PRIVILEGED)) + if (xen_start_info->flags & SIF_INITDOMAIN) { + if (!(xen_start_info->flags & SIF_PRIVILEGED)) panic("Xen granted us console access " "but not privileged status"); } else { diff -r 85958f34f183 -r 111af84f1267 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Mon Jun 26 14:41:54 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Wed Jun 28 08:50:58 2006 +0200 @@ -547,8 +547,10 @@ xen_ia64_privcmd_entry_mmap(struct vm_ar unsigned long gpfn; unsigned long flags; - BUG_ON((addr & ~PAGE_MASK) != 0); - BUG_ON(mfn == INVALID_MFN); + if ((addr & ~PAGE_MASK) != 0 || mfn == INVALID_MFN) { + error = -EINVAL; + goto out; + } if (entry->gpfn != INVALID_GPFN) { error = -EBUSY; diff -r 85958f34f183 -r 111af84f1267 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Mon Jun 26 14:41:54 2006 -0600 +++ b/tools/ioemu/vl.c Wed Jun 28 08:50:58 2006 +0200 @@ -3198,6 +3198,9 @@ int main(int argc, char **argv) PROT_READ|PROT_WRITE, page_array[nr_pages - 1]); + fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", (nr_pages-1), + (uint64_t)(page_array[nr_pages - 1])); + #elif defined(__ia64__) if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, nr_pages) != nr_pages) @@ -3217,7 +3220,7 @@ int main(int argc, char **argv) if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, - nr_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 ) + IO_PAGE_START >> PAGE_SHIFT, 1) != 1 ) { fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno); exit(-1); @@ -3226,10 +3229,10 @@ int main(int argc, char **argv) shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]); -#endif - - fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", (nr_pages-1), - (uint64_t)(page_array[nr_pages - 1])); + + fprintf(logfile, "shared page at pfn:%lx, mfn: %l016x\n", + IO_PAGE_START >> PAGE_SHIFT, page_array[0]); +#endif /* we always create the cdrom drive, even if no disk is there */ bdrv_init(); diff -r 85958f34f183 -r 111af84f1267 tools/libxc/xc_ia64_stubs.c --- a/tools/libxc/xc_ia64_stubs.c Mon Jun 26 14:41:54 2006 -0600 +++ b/tools/libxc/xc_ia64_stubs.c Wed Jun 28 08:50:58 2006 +0200 @@ -48,13 +48,13 @@ xc_plan9_build(int xc_handle, PERROR("xc_plan9_build not implemented\n"); return -1; } + /* VMM uses put_user to copy pfn_list to guest buffer, this maybe fail, VMM doesn't handle this now. This method will touch guest buffer to make sure the buffer's mapping is tracked by VMM, - */ - +*/ int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, @@ -152,15 +152,6 @@ error_out: #define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64" #define GFW_HOB_START ((4UL<<30)-(14UL<<20)) // 4G - 14M #define GFW_HOB_SIZE (1UL<<20) // 1M -#define RAW_GFW_START_NR(s) ((s) >> PAGE_SHIFT) -#define RAW_GFW_HOB_START_NR(s) \ - (RAW_GFW_START_NR(s) + ((GFW_HOB_START - GFW_START) >> PAGE_SHIFT)) -#define RAW_GFW_IMAGE_START_NR(s,i) \ - (RAW_GFW_START_NR(s) + (((GFW_SIZE - (i))) >> PAGE_SHIFT)) -#define RAW_IO_PAGE_START_NR(s) \ - (RAW_GFW_START_NR(s) + (GFW_SIZE >> PAGE_SHIFT)) -#define RAW_STORE_PAGE_START_NR(s) \ - (RAW_IO_PAGE_START_NR(s) + (IO_PAGE_SIZE >> PAGE_SHFIT)) typedef struct { unsigned long signature; @@ -382,7 +373,7 @@ load_hob(int xc_handle, uint32_t dom, vo nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT; return xc_ia64_copy_to_domain_pages(xc_handle, dom, - hob_buf, RAW_GFW_HOB_START_NR(dom_mem_size), nr_pages ); + hob_buf, GFW_HOB_START>>PAGE_SHIFT, nr_pages ); } #define MIN(x, y) ((x) < (y)) ? (x) : (y) @@ -629,16 +620,27 @@ static int setup_guest( int xc_handle, shared_iopage_t *sp; int i; unsigned long dom_memsize = (memsize << 20); + DECLARE_DOM0_OP; if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { PERROR("Guest firmware size is incorrect [%ld]?", image_size); return -1; } + /* This will creates the physmap. */ + op.u.domain_setup.flags = XEN_DOMAINSETUP_hvm_guest; + op.u.domain_setup.domain = (domid_t)dom; + op.u.domain_setup.bp = 0; + op.u.domain_setup.maxmem = 0; + + op.cmd = DOM0_DOMAIN_SETUP; + if ( xc_dom0_op(xc_handle, &op) ) + goto error_out; + /* Load guest firmware */ - if( xc_ia64_copy_to_domain_pages( xc_handle, dom, - image, RAW_GFW_IMAGE_START_NR(dom_memsize, image_size), - image_size>>PAGE_SHIFT)) { + if( xc_ia64_copy_to_domain_pages + (xc_handle, dom, image, (GFW_START+GFW_SIZE-image_size)>>PAGE_SHIFT, + image_size>>PAGE_SHIFT)) { PERROR("Could not load guest firmware into domain"); goto error_out; } @@ -651,7 +653,7 @@ static int setup_guest( int xc_handle, /* Retrieve special pages like io, xenstore, etc. */ if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, - RAW_IO_PAGE_START_NR(dom_memsize), 2) != 2 ) + IO_PAGE_START>>PAGE_SHIFT, 2) != 2 ) { PERROR("Could not get the page frame list"); goto error_out; @@ -737,9 +739,7 @@ int xc_hvm_build(int xc_handle, free(image); - ctxt->flags = VGCF_VMX_GUEST; ctxt->user_regs.cr_iip = 0x80000000ffffffb0UL; - ctxt->privregs = 0; memset( &launch_op, 0, sizeof(launch_op) ); diff -r 85958f34f183 -r 111af84f1267 tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c Mon Jun 26 14:41:54 2006 -0600 +++ b/tools/libxc/xc_linux_build.c Wed Jun 28 08:50:58 2006 +0200 @@ -2,6 +2,7 @@ * xc_linux_build.c */ +#include #include "xg_private.h" #include "xc_private.h" #include @@ -476,6 +477,11 @@ static int setup_guest(int xc_handle, unsigned long v_end; unsigned long start_page, pgnr; start_info_t *start_info; + unsigned long start_info_mpa; + struct xen_ia64_boot_param *bp; + shared_info_t *shared_info; + int i; + DECLARE_DOM0_OP; int rc; rc = probeimageformat(image, image_size, &load_funcs); @@ -492,6 +498,17 @@ static int setup_guest(int xc_handle, vinitrd_start = round_pgup(dsi.v_end); vinitrd_end = vinitrd_start + initrd->len; v_end = round_pgup(vinitrd_end); + start_info_mpa = (nr_pages - 3) << PAGE_SHIFT; + + /* Build firmware. */ + op.u.domain_setup.flags = 0; + op.u.domain_setup.domain = (domid_t)dom; + op.u.domain_setup.bp = start_info_mpa + sizeof (start_info_t); + op.u.domain_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT; + + op.cmd = DOM0_DOMAIN_SETUP; + if ( xc_dom0_op(xc_handle, &op) ) + goto error_out; start_page = dsi.v_start >> PAGE_SHIFT; pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT; @@ -544,7 +561,7 @@ static int setup_guest(int xc_handle, IPRINTF("start_info: 0x%lx at 0x%lx, " "store_mfn: 0x%lx at 0x%lx, " "console_mfn: 0x%lx at 0x%lx\n", - page_array[0], nr_pages, + page_array[0], nr_pages - 3, *store_mfn, nr_pages - 2, *console_mfn, nr_pages - 1); @@ -559,22 +576,34 @@ static int setup_guest(int xc_handle, start_info->console_mfn = nr_pages - 1; start_info->console_evtchn = console_evtchn; start_info->nr_pages = nr_pages; // FIXME?: nr_pages - 2 ???? + + bp = (struct xen_ia64_boot_param *)(start_info + 1); + bp->command_line = start_info_mpa + offsetof(start_info_t, cmd_line); + if ( cmdline != NULL ) + { + strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE); + start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = 0; + } if ( initrd->len != 0 ) { - ctxt->initrd.start = vinitrd_start; - ctxt->initrd.size = initrd->len; - } - else - { - ctxt->initrd.start = 0; - ctxt->initrd.size = 0; - } - if ( cmdline != NULL ) - { - strncpy((char *)ctxt->cmdline, cmdline, IA64_COMMAND_LINE_SIZE); - ctxt->cmdline[IA64_COMMAND_LINE_SIZE-1] = '\0'; - } + bp->initrd_start = vinitrd_start; + bp->initrd_size = initrd->len; + } + ctxt->user_regs.r28 = start_info_mpa + sizeof (start_info_t); munmap(start_info, PAGE_SIZE); + + /* shared_info page starts its life empty. */ + shared_info = xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame); + printf ("shared_info = %p, err=%s frame=%lx\n", + shared_info, strerror (errno), shared_info_frame); + //memset(shared_info, 0, sizeof(shared_info_t)); + /* Mask all upcalls... */ + for ( i = 0; i < MAX_VIRT_CPUS; i++ ) + shared_info->vcpu_info[i].evtchn_upcall_mask = 1; + shared_info->arch.start_info_pfn = nr_pages - 3; + + munmap(shared_info, PAGE_SIZE); free(page_array); return 0; @@ -1156,16 +1185,10 @@ static int xc_linux_build_internal(int x #ifdef __ia64__ /* based on new_thread in xen/arch/ia64/domain.c */ ctxt->flags = 0; - ctxt->shared.flags = flags; - ctxt->shared.start_info_pfn = nr_pages - 3; /* metaphysical */ ctxt->user_regs.cr_ipsr = 0; /* all necessary bits filled by hypervisor */ ctxt->user_regs.cr_iip = vkern_entry; ctxt->user_regs.cr_ifs = 1UL << 63; ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default(); - /* currently done by hypervisor, should move here */ - /* ctxt->regs.r28 = dom_fw_setup(); */ - ctxt->privregs = 0; - ctxt->sys_pgnr = 3; i = 0; /* silence unused variable warning */ #else /* x86 */ /* diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/linux-xen/entry.S --- a/xen/arch/ia64/linux-xen/entry.S Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/linux-xen/entry.S Wed Jun 28 08:50:58 2006 +0200 @@ -652,17 +652,8 @@ GLOBAL_ENTRY(ia64_ret_from_clone) ld8 r16 = [r16] ;; cmp.ne p6,p7 = r16, r0 - (p6) br.cond.spnt ia64_leave_hypervisor - (p7) br.cond.spnt ia64_leave_kernel - ;; -// adds r16 = IA64_VCPU_FLAGS_OFFSET, r13 -// ;; -// ld8 r16 = [r16] -// ;; -// cmp.ne p6,p7 = r16, r0 -// (p6) br.cond.spnt ia64_leave_hypervisor -// (p7) br.cond.spnt ia64_leave_kernel -// ;; + (p6) br.cond.spnt ia64_leave_hypervisor /* VTi */ + (p7) br.cond.spnt ia64_leave_kernel /* !VTi */ #else .ret8: adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/vmx/mmio.c --- a/xen/arch/ia64/vmx/mmio.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/vmx/mmio.c Wed Jun 28 08:50:58 2006 +0200 @@ -386,20 +386,16 @@ static void write_ipi (VCPU *vcpu, uint6 struct pt_regs *targ_regs = vcpu_regs (targ); struct vcpu_guest_context c; - printf ("arch_boot_vcpu: %p %p\n", - (void *)d->arch.boot_rdv_ip, - (void *)d->arch.boot_rdv_r1); memset (&c, 0, sizeof (c)); - c.flags = VGCF_VMX_GUEST; if (arch_set_info_guest (targ, &c) != 0) { printf ("arch_boot_vcpu: failure\n"); return; } /* First or next rendez-vous: set registers. */ vcpu_init_regs (targ); - targ_regs->cr_iip = d->arch.boot_rdv_ip; - targ_regs->r1 = d->arch.boot_rdv_r1; + targ_regs->cr_iip = d->arch.sal_data->boot_rdv_ip; + targ_regs->r1 = d->arch.sal_data->boot_rdv_r1; if (test_and_clear_bit(_VCPUF_down,&targ->vcpu_flags)) { vcpu_wake(targ); diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/vmx/vmmu.c --- a/xen/arch/ia64/vmx/vmmu.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/vmx/vmmu.c Wed Jun 28 08:50:58 2006 +0200 @@ -290,6 +290,7 @@ int vhpt_enabled(VCPU *vcpu, uint64_t va int unimplemented_gva(VCPU *vcpu,u64 vadr) { +#if 0 int bit=vcpu->domain->arch.imp_va_msb; u64 ladr =(vadr<<3)>>(3+bit); if(!ladr||ladr==(1U<<(61-bit))-1){ @@ -297,6 +298,9 @@ int unimplemented_gva(VCPU *vcpu,u64 vad }else{ return 1; } +#else + return 0; +#endif } diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/vmx/vmx_init.c --- a/xen/arch/ia64/vmx/vmx_init.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/vmx/vmx_init.c Wed Jun 28 08:50:58 2006 +0200 @@ -271,8 +271,6 @@ vmx_final_setup_guest(struct vcpu *v) { vpd_t *vpd; - free_xenheap_pages(v->arch.privregs, get_order(sizeof(mapped_regs_t))); - vpd = alloc_vpd(); ASSERT(vpd); @@ -317,7 +315,7 @@ typedef struct io_range { unsigned long type; } io_range_t; -io_range_t io_ranges[] = { +static const io_range_t io_ranges[] = { {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER}, {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO}, {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO}, @@ -325,25 +323,25 @@ io_range_t io_ranges[] = { {PIB_START, PIB_SIZE, GPFN_PIB}, }; +/* Reseve 1 page for shared I/O and 1 page for xenstore. */ #define VMX_SYS_PAGES (2 + (GFW_SIZE >> PAGE_SHIFT)) #define VMX_CONFIG_PAGES(d) ((d)->max_pages - VMX_SYS_PAGES) -int vmx_build_physmap_table(struct domain *d) +static void vmx_build_physmap_table(struct domain *d) { unsigned long i, j, start, tmp, end, mfn; struct vcpu *v = d->vcpu[0]; struct list_head *list_ent = d->page_list.next; - ASSERT(!d->arch.physmap_built); ASSERT(!test_bit(ARCH_VMX_CONTIG_MEM, &v->arch.arch_vmx.flags)); ASSERT(d->max_pages == d->tot_pages); /* Mark I/O ranges */ for (i = 0; i < (sizeof(io_ranges) / sizeof(io_range_t)); i++) { for (j = io_ranges[i].start; - j < io_ranges[i].start + io_ranges[i].size; - j += PAGE_SIZE) - __assign_domain_page(d, j, io_ranges[i].type, ASSIGN_writable); + j < io_ranges[i].start + io_ranges[i].size; + j += PAGE_SIZE) + __assign_domain_page(d, j, io_ranges[i].type, ASSIGN_writable); } /* Map normal memory below 3G */ @@ -353,7 +351,7 @@ int vmx_build_physmap_table(struct domai mfn = page_to_mfn(list_entry(list_ent, struct page_info, list)); list_ent = mfn_to_page(mfn)->list.next; if (VGA_IO_START <= i && i < VGA_IO_START + VGA_IO_SIZE) - continue; + continue; assign_domain_page(d, i, mfn << PAGE_SHIFT); } ASSERT(list_ent != &d->page_list); @@ -362,21 +360,19 @@ int vmx_build_physmap_table(struct domai if (unlikely(end > MMIO_START)) { start = 4 * MEM_G; end = start + (end - 3 * MEM_G); - for (i = start; (i < end) && - (list_ent != &d->page_list); i += PAGE_SIZE) { - mfn = page_to_mfn(list_entry( - list_ent, struct page_info, list)); - assign_domain_page(d, i, mfn << PAGE_SHIFT); - list_ent = mfn_to_page(mfn)->list.next; + for (i = start; + (i < end) && (list_ent != &d->page_list); i += PAGE_SIZE) { + mfn = page_to_mfn(list_entry(list_ent, struct page_info, list)); + assign_domain_page(d, i, mfn << PAGE_SHIFT); + list_ent = mfn_to_page(mfn)->list.next; } ASSERT(list_ent != &d->page_list); - } + } /* Map guest firmware */ for (i = GFW_START; (i < GFW_START + GFW_SIZE) && (list_ent != &d->page_list); i += PAGE_SIZE) { - mfn = page_to_mfn(list_entry( - list_ent, struct page_info, list)); + mfn = page_to_mfn(list_entry(list_ent, struct page_info, list)); assign_domain_page(d, i, mfn << PAGE_SHIFT); list_ent = mfn_to_page(mfn)->list.next; } @@ -393,24 +389,22 @@ int vmx_build_physmap_table(struct domai list_ent = mfn_to_page(mfn)->list.next; ASSERT(list_ent == &d->page_list); - d->arch.max_pfn = end >> PAGE_SHIFT; - d->arch.physmap_built = 1; set_bit(ARCH_VMX_CONTIG_MEM, &v->arch.arch_vmx.flags); - return 0; -} - -void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c) +} + +void vmx_setup_platform(struct domain *d) { ASSERT(d != dom0); /* only for non-privileged vti domain */ - if (!d->arch.physmap_built) - vmx_build_physmap_table(d); + vmx_build_physmap_table(d); d->arch.vmx_platform.shared_page_va = (unsigned long)__va(__gpa_to_mpa(d, IO_PAGE_START)); /* TEMP */ d->arch.vmx_platform.pib_base = 0xfee00000UL; + d->arch.sal_data = xmalloc(struct xen_sal_data); + /* Only open one port for I/O and interrupt emulation */ memset(&d->shared_info->evtchn_mask[0], 0xff, sizeof(d->shared_info->evtchn_mask)); @@ -426,12 +420,11 @@ void vmx_do_launch(struct vcpu *v) { if (evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0) { printk("VMX domain bind port %d to vcpu %d failed!\n", - iopacket_port(v), v->vcpu_id); + iopacket_port(v), v->vcpu_id); domain_crash_synchronous(); } - clear_bit(iopacket_port(v), - &v->domain->shared_info->evtchn_mask[0]); + clear_bit(iopacket_port(v), &v->domain->shared_info->evtchn_mask[0]); vmx_load_all_rr(v); } diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/xen/dom0_ops.c Wed Jun 28 08:50:58 2006 +0200 @@ -19,6 +19,10 @@ #include #include #include +#include + +void build_physmap_table(struct domain *d); + extern unsigned long total_pages; long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) { @@ -154,52 +158,37 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_ case DOM0_GETMEMLIST: { - unsigned long i = 0; + 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 mfn; - struct list_head *list_ent; ret = -EINVAL; - if ( d != NULL ) - { - ret = 0; - - list_ent = d->page_list.next; - while ( (i != start_page) && (list_ent != &d->page_list)) { - mfn = page_to_mfn(list_entry( - list_ent, struct page_info, list)); - i++; - list_ent = mfn_to_page(mfn)->list.next; - } - - if (i == start_page) - { - while((i < (start_page + nr_pages)) && - (list_ent != &d->page_list)) - { - mfn = page_to_mfn(list_entry( - list_ent, struct page_info, list)); - - if ( copy_to_guest_offset(op->u.getmemlist.buffer, - i - start_page, &mfn, 1) ) - { - ret = -EFAULT; - break; - } - i++; - list_ent = mfn_to_page(mfn)->list.next; - } - } else - ret = -ENOMEM; - - op->u.getmemlist.num_pfns = i - start_page; - if (copy_to_guest(u_dom0_op, op, 1)) - ret = -EFAULT; - - put_domain(d); - } + if ( d == NULL ) + break; + for (i = 0; i < nr_pages; i++) { + pte_t *pte; + + pte = lookup_noalloc_domain_pte + (d, (start_page + i) << PAGE_SHIFT); + if (pte && pte_present (*pte)) + mfn = pte_pfn (*pte); + else + mfn = INVALID_MFN; + + if ( copy_to_guest_offset(op->u.getmemlist.buffer, i, &mfn, 1) ) + { + ret = -EFAULT; + break; + } + } + + op->u.getmemlist.num_pfns = i; + if (copy_to_guest(u_dom0_op, op, 1)) + ret = -EFAULT; + + put_domain(d); } break; @@ -225,6 +214,33 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_ } break; + case DOM0_DOMAIN_SETUP: + { + dom0_domain_setup_t *ds = &op->u.domain_setup; + struct domain *d = find_domain_by_id(ds->domain); + + if ( d == NULL) { + ret = -EINVAL; + break; + } + + if (ds->flags & XEN_DOMAINSETUP_hvm_guest) { + if (!vmx_enabled) { + printk("No VMX hardware feature for vmx domain.\n"); + ret = -EINVAL; + break; + } + d->arch.is_vti = 1; + vmx_setup_platform(d); + } + else { + build_physmap_table(d); + dom_fw_setup (d, ds->bp, ds->maxmem); + } + put_domain(d); + } + break; + default: printf("arch_do_dom0_op: unrecognized dom0 op: %d!!!\n",op->cmd); ret = -ENOSYS; diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/xen/dom_fw.c --- a/xen/arch/ia64/xen/dom_fw.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/xen/dom_fw.c Wed Jun 28 08:50:58 2006 +0200 @@ -24,14 +24,16 @@ #include -static struct ia64_boot_param *dom_fw_init(struct domain *, const char *,int,char *,int); +static void dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char *fw_mem, int fw_mem_size, unsigned long maxmem); + extern struct domain *dom0; extern unsigned long dom0_start; extern unsigned long running_on_sim; -unsigned long dom_fw_base_mpa = -1; -unsigned long imva_fw_base = -1; +/* Note: two domains cannot be created simulteanously! */ +static unsigned long dom_fw_base_mpa = -1; +static unsigned long imva_fw_base = -1; #define FW_VENDOR "X\0e\0n\0/\0i\0a\0\066\0\064\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" @@ -138,21 +140,20 @@ static void dom_fw_pal_hypercall_patch(s } -// FIXME: This is really a hack: Forcing the boot parameter block -// at domain mpaddr 0 page, then grabbing only the low bits of the -// Xen imva, which is the offset into the page -unsigned long dom_fw_setup(struct domain *d, const char *args, int arglen) +void dom_fw_setup(struct domain *d, unsigned long bp_mpa, unsigned long maxmem) { struct ia64_boot_param *bp; dom_fw_base_mpa = 0; #ifndef CONFIG_XEN_IA64_DOM0_VP if (d == dom0) dom_fw_base_mpa += dom0_start; + if (d == dom0) bp_mpa += dom0_start; #endif ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, dom_fw_base_mpa); imva_fw_base = (unsigned long) domain_mpa_to_imva(d, dom_fw_base_mpa); - bp = dom_fw_init(d, args, arglen, (char *) imva_fw_base, PAGE_SIZE); - return dom_pa((unsigned long) bp); + ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, bp_mpa); + bp = domain_mpa_to_imva(d, bp_mpa); + dom_fw_init(d, bp, (char *) imva_fw_base, PAGE_SIZE, maxmem); } @@ -525,8 +526,8 @@ efi_mdt_cmp(const void *a, const void *b return 0; } -static struct ia64_boot_param * -dom_fw_init (struct domain *d, const char *args, int arglen, char *fw_mem, int fw_mem_size) +static void +dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char *fw_mem, int fw_mem_size, unsigned long maxmem) { efi_system_table_t *efi_systab; efi_runtime_services_t *efi_runtime; @@ -536,12 +537,11 @@ dom_fw_init (struct domain *d, const cha struct ia64_sal_desc_ap_wakeup *sal_wakeup; fpswa_interface_t *fpswa_inf; efi_memory_desc_t *efi_memmap, *md; - struct ia64_boot_param *bp; + struct xen_sal_data *sal_data; unsigned long *pfn; unsigned char checksum = 0; - char *cp, *cmd_line, *fw_vendor; + char *cp, *fw_vendor; int num_mds, j, i = 0; - unsigned long maxmem = (d->max_pages - d->arch.sys_pgnr) * PAGE_SIZE; #ifdef CONFIG_XEN_IA64_DOM0_VP const unsigned long start_mpaddr = 0; #else @@ -566,33 +566,23 @@ dom_fw_init (struct domain *d, const cha sal_wakeup = (void *) cp; cp += sizeof(*sal_wakeup); fpswa_inf = (void *) cp; cp += sizeof(*fpswa_inf); efi_memmap = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap); - bp = (void *) cp; cp += sizeof(*bp); pfn = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn); - cmd_line = (void *) cp; + sal_data = (void *) cp; cp += sizeof (*sal_data); /* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */ d->arch.efi_runtime = efi_runtime; d->arch.fpswa_inf = fpswa_inf; - - if (args) { - if (arglen >= 1024) - arglen = 1023; - memcpy(cmd_line, args, arglen); - } else { - arglen = 0; - } - cmd_line[arglen] = '\0'; + d->arch.sal_data = sal_data; memset(efi_systab, 0, sizeof(efi_systab)); efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE; efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION; efi_systab->hdr.headersize = sizeof(efi_systab->hdr); - cp = fw_vendor = &cmd_line[arglen] + (2-(arglen&1)); // round to 16-bit boundary + fw_vendor = cp; cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to 64-bit boundary memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR)); efi_systab->fw_vendor = dom_pa((unsigned long) fw_vendor); - efi_systab->fw_revision = 1; efi_systab->runtime = (void *) dom_pa((unsigned long) efi_runtime); efi_systab->nr_tables = NUM_EFI_SYS_TABLES; @@ -694,20 +684,20 @@ dom_fw_init (struct domain *d, const cha dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1); sal_ed->gp = 0; // will be ignored + /* Fill an AP wakeup descriptor. */ + sal_wakeup->type = SAL_DESC_AP_WAKEUP; + sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT; + sal_wakeup->vector = XEN_SAL_BOOT_RENDEZ_VEC; + + /* Compute checksum. */ + for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp) + checksum += *cp; + sal_systab->checksum = -checksum; + /* SAL return point. */ d->arch.sal_return_addr = FW_HYPERCALL_SAL_RETURN_PADDR + start_mpaddr; dom_fw_hypercall_patch (d, d->arch.sal_return_addr, FW_HYPERCALL_SAL_RETURN, 0); - - /* Fill an AP wakeup descriptor. */ - sal_wakeup->type = SAL_DESC_AP_WAKEUP; - sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT; - sal_wakeup->vector = XEN_SAL_BOOT_RENDEZ_VEC; - - for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp) - checksum += *cp; - - sal_systab->checksum = -checksum; /* Fill in the FPSWA interface: */ fpswa_inf->revision = fpswa_interface->revision; @@ -784,6 +774,7 @@ dom_fw_init (struct domain *d, const cha else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0); } else { #ifndef CONFIG_XEN_IA64_DOM0_VP + /* Dom0 maps legacy mmio in first MB. */ MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 1); MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1); #endif @@ -848,7 +839,7 @@ dom_fw_init (struct domain *d, const cha bp->efi_memmap_size = i * sizeof(efi_memory_desc_t); bp->efi_memdesc_size = sizeof(efi_memory_desc_t); bp->efi_memdesc_version = EFI_MEMDESC_VERSION; - bp->command_line = dom_pa((unsigned long) cmd_line); + bp->command_line = 0; bp->console_info.num_cols = 80; bp->console_info.num_rows = 25; bp->console_info.orig_x = 0; @@ -858,12 +849,6 @@ dom_fw_init (struct domain *d, const cha int j; u64 addr; - // XXX CONFIG_XEN_IA64_DOM0_VP - // initrd_start address is hard coded in construct_dom0() - bp->initrd_start = (dom0_start+dom0_size) - - (PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024); - bp->initrd_size = ia64_boot_param->initrd_size; - // dom0 doesn't need build_physmap_table() // see arch_set_info_guest() // instead we allocate pages manually. @@ -899,17 +884,9 @@ dom_fw_init (struct domain *d, const cha if (efi_mmio(addr, PAGE_SIZE)) assign_domain_mmio_page(d, addr, PAGE_SIZE); } - d->arch.physmap_built = 1; - } - else { - bp->initrd_start = d->arch.initrd_start; - bp->initrd_size = d->arch.initrd_len; } for (i = 0 ; i < bp->efi_memmap_size/sizeof(efi_memory_desc_t) ; i++) { md = efi_memmap + i; print_md(md); } - printf(" initrd start 0x%lx", bp->initrd_start); - printf(" initrd size 0x%lx\n", bp->initrd_size); - return bp; -} +} diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/xen/domain.c Wed Jun 28 08:50:58 2006 +0200 @@ -79,7 +79,6 @@ extern void serial_input_init(void); extern void serial_input_init(void); static void init_switch_stack(struct vcpu *v); extern void vmx_do_launch(struct vcpu *); -void build_physmap_table(struct domain *d); /* this belongs in include/asm, but there doesn't seem to be a suitable place */ unsigned long context_switch_count = 0; @@ -246,14 +245,15 @@ struct vcpu *alloc_vcpu_struct(struct do } if (!is_idle_domain(d)) { - v->arch.privregs = - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); - BUG_ON(v->arch.privregs == NULL); - memset(v->arch.privregs, 0, PAGE_SIZE); - - if (!vcpu_id) - memset(&d->shared_info->evtchn_mask[0], 0xff, - sizeof(d->shared_info->evtchn_mask)); + if (!d->arch.is_vti) { + /* Create privregs page only if not VTi. */ + v->arch.privregs = + alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); + BUG_ON(v->arch.privregs == NULL); + memset(v->arch.privregs, 0, PAGE_SIZE); + share_xen_page_with_guest + (virt_to_page(v->arch.privregs), d, XENSHARE_writable); + } v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0; v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4; @@ -320,6 +320,8 @@ int arch_domain_create(struct domain *d) if ((d->shared_info = (void *)alloc_xenheap_page()) == NULL) goto fail_nomem; memset(d->shared_info, 0, PAGE_SIZE); + share_xen_page_with_guest + (virt_to_page(d->shared_info), d, XENSHARE_writable); d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME /* We may also need emulation rid for region4, though it's unlikely @@ -328,11 +330,9 @@ int arch_domain_create(struct domain *d) */ if (!allocate_rid_range(d,0)) goto fail_nomem; - d->arch.sys_pgnr = 0; memset(&d->arch.mm, 0, sizeof(d->arch.mm)); - d->arch.physmap_built = 0; if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL) goto fail_nomem; @@ -361,70 +361,31 @@ void arch_getdomaininfo_ctxt(struct vcpu void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) { c->user_regs = *vcpu_regs (v); - c->shared = v->domain->shared_info->arch; + c->privregs_pfn = virt_to_maddr (v->arch.privregs) >> PAGE_SHIFT; } int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) { struct pt_regs *regs = vcpu_regs (v); struct domain *d = v->domain; - unsigned long cmdline_addr; - - if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) - return 0; - if (c->flags & VGCF_VMX_GUEST) { - if (!vmx_enabled) { - printk("No VMX hardware feature for vmx domain.\n"); - return -EINVAL; - } - - if (v == d->vcpu[0]) - vmx_setup_platform(d, c); - - vmx_final_setup_guest(v); - } else if (!d->arch.physmap_built) - build_physmap_table(d); - + *regs = c->user_regs; - cmdline_addr = 0; - if (v == d->vcpu[0]) { - /* Only for first vcpu. */ - d->arch.sys_pgnr = c->sys_pgnr; - d->arch.initrd_start = c->initrd.start; - d->arch.initrd_len = c->initrd.size; - d->arch.cmdline = c->cmdline; - d->shared_info->arch = c->shared; - - if (!VMX_DOMAIN(v)) { - const char *cmdline = d->arch.cmdline; - int len; - - if (*cmdline == 0) { -#define DEFAULT_CMDLINE "nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1" - cmdline = DEFAULT_CMDLINE; - len = sizeof (DEFAULT_CMDLINE); - printf("domU command line defaulted to" - DEFAULT_CMDLINE "\n"); - } - else - len = IA64_COMMAND_LINE_SIZE; - cmdline_addr = dom_fw_setup (d, cmdline, len); - } - - /* Cache synchronization seems to be done by the linux kernel - during mmap/unmap operation. However be conservative. */ - domain_cache_flush (d, 1); - } - vcpu_init_regs (v); - regs->r28 = cmdline_addr; - - if ( c->privregs && copy_from_user(v->arch.privregs, - c->privregs, sizeof(mapped_regs_t))) { - printk("Bad ctxt address in arch_set_info_guest: %p\n", - c->privregs); - return -EFAULT; - } - + + if (!d->arch.is_vti) { + /* domain runs at PL2/3 */ + regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; + regs->ar_rsc |= (2 << 2); /* force PL2/3 */ + } + + if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + return 0; + if (d->arch.is_vti) { + vmx_final_setup_guest(v); + } + + /* This overrides some registers. */ + vcpu_init_regs (v); + /* Don't redo final setup */ set_bit(_VCPUF_initialised, &v->vcpu_flags); return 0; @@ -502,6 +463,9 @@ void domain_relinquish_resources(struct relinquish_memory(d, &d->xenpage_list); relinquish_memory(d, &d->page_list); + + if (d->arch.is_vti && d->arch.sal_data) + xfree (d->arch.sal_data); } void build_physmap_table(struct domain *d) @@ -509,7 +473,6 @@ void build_physmap_table(struct domain * struct list_head *list_ent = d->page_list.next; unsigned long mfn, i = 0; - ASSERT(!d->arch.physmap_built); while(list_ent != &d->page_list) { mfn = page_to_mfn(list_entry( list_ent, struct page_info, list)); @@ -518,7 +481,6 @@ void build_physmap_table(struct domain * i++; list_ent = mfn_to_page(mfn)->list.next; } - d->arch.physmap_built = 1; } unsigned long @@ -733,8 +695,9 @@ int construct_dom0(struct domain *d, unsigned long pkern_end; unsigned long pinitrd_start = 0; unsigned long pstart_info; - unsigned long cmdline_addr; struct page_info *start_info_page; + unsigned long bp_mpa; + struct ia64_boot_param *bp; #ifdef VALIDATE_VT unsigned int vmx_dom0 = 0; @@ -884,8 +847,6 @@ int construct_dom0(struct domain *d, //if ( initrd_len != 0 ) // memcpy((void *)vinitrd_start, initrd_start, initrd_len); - d->shared_info->arch.flags = SIF_INITDOMAIN|SIF_PRIVILEGED; - /* Set up start info area. */ d->shared_info->arch.start_info_pfn = pstart_info >> PAGE_SHIFT; start_info_page = assign_new_domain_page(d, pstart_info); @@ -895,6 +856,7 @@ int construct_dom0(struct domain *d, memset(si, 0, PAGE_SIZE); sprintf(si->magic, "xen-%i.%i-ia64", XEN_VERSION, XEN_SUBVERSION); si->nr_pages = max_pages; + si->flags = SIF_INITDOMAIN|SIF_PRIVILEGED; console_endboot(); @@ -910,15 +872,39 @@ int construct_dom0(struct domain *d, set_bit(_VCPUF_initialised, &v->vcpu_flags); - cmdline_addr = dom_fw_setup(d, dom0_command_line, COMMAND_LINE_SIZE); + /* Build firmware. + Note: Linux kernel reserve memory used by start_info, so there is + no need to remove it from MDT. */ + bp_mpa = pstart_info + sizeof (struct start_info); + dom_fw_setup (d, bp_mpa, max_pages * PAGE_SIZE); + + /* Fill boot param. */ + strncpy ((char *)si->cmd_line, + dom0_command_line, sizeof (si->cmd_line)); + si->cmd_line[sizeof(si->cmd_line)-1] = 0; + + bp = (struct ia64_boot_param *)(si + 1); + bp->command_line = pstart_info + offsetof (start_info_t, cmd_line); + + /* We assume console has reached the last line! */ + bp->console_info.num_cols = ia64_boot_param->console_info.num_cols; + bp->console_info.num_rows = ia64_boot_param->console_info.num_rows; + bp->console_info.orig_x = 0; + bp->console_info.orig_y = bp->console_info.num_rows == 0 ? 0 : + bp->console_info.num_rows - 1; + + bp->initrd_start = (dom0_start+dom0_size) - + (PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024); + bp->initrd_size = ia64_boot_param->initrd_size; vcpu_init_regs (v); + + vcpu_regs(v)->r28 = bp_mpa; #ifdef CONFIG_DOMAIN0_CONTIGUOUS pkern_entry += dom0_start; #endif vcpu_regs (v)->cr_iip = pkern_entry; - vcpu_regs (v)->r28 = cmdline_addr; physdev_init_dom0(d); diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/xen/fw_emul.c --- a/xen/arch/ia64/xen/fw_emul.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/xen/fw_emul.c Wed Jun 28 08:50:58 2006 +0200 @@ -95,8 +95,8 @@ sal_emulator (long index, unsigned long } else { struct domain *d = current->domain; - d->arch.boot_rdv_ip = in2; - d->arch.boot_rdv_r1 = in3; + d->arch.sal_data->boot_rdv_ip = in2; + d->arch.sal_data->boot_rdv_r1 = in3; } } else @@ -368,7 +368,7 @@ efi_translate_domain_addr(unsigned long *fault = IA64_NO_FAULT; again: - if (v->domain->arch.efi_virt_mode) { + if (v->domain->arch.sal_data->efi_virt_mode) { *fault = vcpu_tpa(v, domain_addr, &mpaddr); if (*fault != IA64_NO_FAULT) return 0; } @@ -432,7 +432,7 @@ efi_emulate_set_virtual_address_map( fpswa_interface_t *fpswa_inf = d->arch.fpswa_inf; if (descriptor_version != EFI_MEMDESC_VERSION) { - printf ("efi_emulate_set_virtual_address_map: memory descriptor version unmatched\n"); + printf ("efi_emulate_set_virtual_address_map: memory descriptor version unmatched (%d vs %d)\n", (int)descriptor_version, EFI_MEMDESC_VERSION); return EFI_INVALID_PARAMETER; } @@ -441,7 +441,8 @@ efi_emulate_set_virtual_address_map( return EFI_INVALID_PARAMETER; } - if (d->arch.efi_virt_mode) return EFI_UNSUPPORTED; + if (d->arch.sal_data->efi_virt_mode) + return EFI_UNSUPPORTED; efi_map_start = virtual_map; efi_map_end = efi_map_start + memory_map_size; @@ -483,7 +484,7 @@ efi_emulate_set_virtual_address_map( } /* The virtual address map has been applied. */ - d->arch.efi_virt_mode = 1; + d->arch.sal_data->efi_virt_mode = 1; return EFI_SUCCESS; } diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/xen/hypercall.c Wed Jun 28 08:50:58 2006 +0200 @@ -159,8 +159,8 @@ fw_hypercall_ipi (struct pt_regs *regs) /* First or next rendez-vous: set registers. */ vcpu_init_regs (targ); - vcpu_regs (targ)->cr_iip = d->arch.boot_rdv_ip; - vcpu_regs (targ)->r1 = d->arch.boot_rdv_r1; + vcpu_regs (targ)->cr_iip = d->arch.sal_data->boot_rdv_ip; + vcpu_regs (targ)->r1 = d->arch.sal_data->boot_rdv_r1; vcpu_regs (targ)->b0 = d->arch.sal_return_addr; if (test_and_clear_bit(_VCPUF_down, diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/xen/mm.c Wed Jun 28 08:50:58 2006 +0200 @@ -583,7 +583,7 @@ lookup_alloc_domain_pte(struct domain* d } //XXX xxx_none() should be used instread of !xxx_present()? -static volatile pte_t* +volatile pte_t* lookup_noalloc_domain_pte(struct domain* d, unsigned long mpaddr) { struct mm_struct *mm = &d->arch.mm; @@ -1155,11 +1155,10 @@ dom0vp_add_physmap(struct domain* d, uns get_knownalive_domain(rd); } - if (unlikely(rd == d)) { + if (unlikely(rd == d) || unlikely(!mfn_valid(mfn))) { error = -EINVAL; goto out1; } - BUG_ON(!mfn_valid(mfn)); if (unlikely(get_page(mfn_to_page(mfn), rd) == 0)) { error = -EINVAL; goto out1; diff -r 85958f34f183 -r 111af84f1267 xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/arch/ia64/xen/vcpu.c Wed Jun 28 08:50:58 2006 +0200 @@ -1386,7 +1386,7 @@ static TR_ENTRY* static TR_ENTRY* vcpu_tr_lookup(VCPU* vcpu, unsigned long va, UINT64 rid, BOOLEAN is_data) { - unsigned int* regions; + unsigned char* regions; TR_ENTRY *trp; int tr_max; int i; diff -r 85958f34f183 -r 111af84f1267 xen/include/asm-ia64/dom_fw.h --- a/xen/include/asm-ia64/dom_fw.h Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/include/asm-ia64/dom_fw.h Wed Jun 28 08:50:58 2006 +0200 @@ -166,7 +166,7 @@ extern struct ia64_pal_retval xen_pal_em extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64); extern struct sal_ret_values sal_emulator (long index, unsigned long in1, unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, unsigned long in6, unsigned long in7); extern struct ia64_pal_retval pal_emulator_static (unsigned long); -extern unsigned long dom_fw_setup (struct domain *, const char *, int); +extern void dom_fw_setup (struct domain *, unsigned long bp_mpa, unsigned long maxmem); extern efi_status_t efi_emulator (struct pt_regs *regs, unsigned long *fault); extern void build_pal_hypercall_bundles(unsigned long *imva, unsigned long brkimm, unsigned long hypnum); diff -r 85958f34f183 -r 111af84f1267 xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/include/asm-ia64/domain.h Wed Jun 28 08:50:58 2006 +0200 @@ -58,10 +58,26 @@ struct mm_struct { // atomic_t mm_users; /* How many users with user space? */ }; +/* These are data in domain memory for SAL emulator. */ +struct xen_sal_data { + /* OS boot rendez vous. */ + unsigned long boot_rdv_ip; + unsigned long boot_rdv_r1; + + /* There are these for EFI_SET_VIRTUAL_ADDRESS_MAP emulation. */ + int efi_virt_mode; /* phys : 0 , virt : 1 */ +}; + struct arch_domain { struct mm_struct mm; - unsigned long metaphysical_rr0; - unsigned long metaphysical_rr4; + + /* Flags. */ + union { + unsigned long flags; + struct { + unsigned int is_vti : 1; + }; + }; /* There are two ranges of RID for a domain: one big range, used to virtualize domain RID, @@ -69,37 +85,31 @@ struct arch_domain { /* Big range. */ int starting_rid; /* first RID assigned to domain */ int ending_rid; /* one beyond highest RID assigned to domain */ - int rid_bits; /* number of virtual rid bits (default: 18) */ /* Metaphysical range. */ int starting_mp_rid; int ending_mp_rid; - + /* RID for metaphysical mode. */ + unsigned long metaphysical_rr0; + unsigned long metaphysical_rr4; + + int rid_bits; /* number of virtual rid bits (default: 18) */ int breakimm; /* The imm value for hypercalls. */ - int physmap_built; /* Whether is physmap built or not */ - int imp_va_msb; - /* System pages out of guest memory, like for xenstore/console */ - unsigned long sys_pgnr; - unsigned long max_pfn; /* Max pfn including I/O holes */ struct virtual_platform_def vmx_platform; #define hvm_domain vmx_platform /* platform defs are not vmx specific */ - /* OS boot rendez vous. */ - unsigned long boot_rdv_ip; - unsigned long boot_rdv_r1; - + u64 xen_vastart; + u64 xen_vaend; + u64 shared_info_va; + + /* Address of SAL emulator data */ + struct xen_sal_data *sal_data; /* SAL return point. */ unsigned long sal_return_addr; - u64 shared_info_va; - unsigned long initrd_start; - unsigned long initrd_len; - char *cmdline; - /* There are these for EFI_SET_VIRTUAL_ADDRESS_MAP emulation. */ - int efi_virt_mode; /* phys : 0 , virt : 1 */ - /* Metaphysical address to efi_runtime_services_t in domain firmware memory is set. */ + /* Address of efi_runtime_services_t (placed in domain memory) */ void *efi_runtime; - /* Metaphysical address to fpswa_interface_t in domain firmware memory is set. */ + /* Address of fpswa_interface_t (placed in domain memory) */ void *fpswa_inf; }; #define INT_ENABLE_OFFSET(v) \ @@ -107,23 +117,28 @@ struct arch_domain { offsetof(vcpu_info_t, evtchn_upcall_mask)) struct arch_vcpu { + /* Save the state of vcpu. + This is the first entry to speed up accesses. */ + mapped_regs_t *privregs; + + /* TR and TC. */ TR_ENTRY itrs[NITRS]; TR_ENTRY dtrs[NDTRS]; TR_ENTRY itlb; TR_ENTRY dtlb; - unsigned int itr_regions; - unsigned int dtr_regions; - unsigned long irr[4]; - unsigned long insvc[4]; - unsigned long tc_regions; + + /* Bit is set if there is a tr/tc for the region. */ + unsigned char itr_regions; + unsigned char dtr_regions; + unsigned char tc_regions; + + unsigned long irr[4]; /* Interrupt request register. */ + unsigned long insvc[4]; /* Interrupt in service. */ unsigned long iva; unsigned long dcr; - unsigned long itc; unsigned long domain_itm; unsigned long domain_itm_last; - unsigned long xen_itm; - mapped_regs_t *privregs; /* save the state of vcpu */ unsigned long event_callback_ip; // event callback handler unsigned long failsafe_callback_ip; // Do we need it? diff -r 85958f34f183 -r 111af84f1267 xen/include/asm-ia64/mm.h --- a/xen/include/asm-ia64/mm.h Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/include/asm-ia64/mm.h Wed Jun 28 08:50:58 2006 +0200 @@ -429,7 +429,7 @@ struct p2m_entry; struct p2m_entry; extern unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr, struct p2m_entry* entry); extern void *domain_mpa_to_imva(struct domain *d, unsigned long mpaddr); - +extern volatile pte_t *lookup_noalloc_domain_pte(struct domain* d, unsigned long mpaddr); #ifdef CONFIG_XEN_IA64_DOM0_VP extern unsigned long assign_domain_mmio_page(struct domain *d, unsigned long mpaddr, unsigned long size); extern unsigned long assign_domain_mach_page(struct domain *d, unsigned long mpaddr, unsigned long size, unsigned long flags); diff -r 85958f34f183 -r 111af84f1267 xen/include/asm-ia64/vmx.h --- a/xen/include/asm-ia64/vmx.h Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/include/asm-ia64/vmx.h Wed Jun 28 08:50:58 2006 +0200 @@ -34,7 +34,7 @@ extern void vmx_final_setup_guest(struct extern void vmx_final_setup_guest(struct vcpu *v); extern void vmx_save_state(struct vcpu *v); extern void vmx_load_state(struct vcpu *v); -extern void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c); +extern void vmx_setup_platform(struct domain *d); extern void vmx_wait_io(void); extern void vmx_io_assist(struct vcpu *v); extern void panic_domain(struct pt_regs *regs, const char *fmt, ...); @@ -43,7 +43,6 @@ extern void vmx_load_state(struct vcpu * extern void vmx_load_state(struct vcpu *v); extern void show_registers(struct pt_regs *regs); #define show_execution_state show_registers -extern int vmx_build_physmap_table(struct domain *d); extern unsigned long __gpfn_to_mfn_foreign(struct domain *d, unsigned long gpfn); extern void sync_split_caches(void); extern void vmx_virq_line_assist(struct vcpu *v); diff -r 85958f34f183 -r 111af84f1267 xen/include/public/arch-ia64.h --- a/xen/include/public/arch-ia64.h Mon Jun 26 14:41:54 2006 -0600 +++ b/xen/include/public/arch-ia64.h Wed Jun 28 08:50:58 2006 +0200 @@ -302,15 +302,14 @@ struct mapped_regs { unsigned long reserved7[4096]; }; typedef struct mapped_regs mapped_regs_t; +typedef mapped_regs_t vpd_t; struct arch_vcpu_info { }; typedef struct arch_vcpu_info arch_vcpu_info_t; -typedef mapped_regs_t vpd_t; - struct arch_shared_info { - unsigned int flags; + /* PFN of the start_info page. */ unsigned long start_info_pfn; /* Interrupt vector for event channel. */ @@ -318,30 +317,13 @@ struct arch_shared_info { }; typedef struct arch_shared_info arch_shared_info_t; -struct arch_initrd_info { - unsigned long start; - unsigned long size; -}; -typedef struct arch_initrd_info arch_initrd_info_t; - typedef unsigned long xen_callback_t; -#define IA64_COMMAND_LINE_SIZE 512 struct vcpu_guest_context { -#define VGCF_FPU_VALID (1<<0) -#define VGCF_VMX_GUEST (1<<1) -#define VGCF_IN_KERNEL (1<<2) unsigned long flags; /* VGCF_* flags */ - unsigned long pt_base; /* PMT table base */ - unsigned long share_io_pg; /* Shared page for I/O emulation */ - unsigned long sys_pgnr; /* System pages out of domain memory */ - unsigned long vm_assist; /* VMASST_TYPE_* bitmap, now none on IPF */ struct cpu_user_regs user_regs; - struct mapped_regs *privregs; - struct arch_shared_info shared; - struct arch_initrd_info initrd; - char cmdline[IA64_COMMAND_LINE_SIZE]; + unsigned long privregs_pfn; }; typedef struct vcpu_guest_context vcpu_guest_context_t; DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); @@ -378,6 +360,28 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte #define ASSIGN_readonly (1UL << _ASSIGN_readonly) #define ASSIGN_writable (0UL << _ASSIGN_readonly) // dummy flag +/* This structure has the same layout of struct ia64_boot_param, defined in + . It is redefined here to ease use. */ +struct xen_ia64_boot_param { + unsigned long command_line; /* physical address of cmd line args */ + unsigned long efi_systab; /* physical address of EFI system table */ + unsigned long efi_memmap; /* physical address of EFI memory map */ + unsigned long efi_memmap_size; /* size of EFI memory map */ + unsigned long efi_memdesc_size; /* size of an EFI memory map descriptor */ + unsigned int efi_memdesc_version; /* memory descriptor version */ + struct { + unsigned short num_cols; /* number of columns on console. */ + unsigned short num_rows; /* number of rows on console. */ + unsigned short orig_x; /* cursor's x position */ + unsigned short orig_y; /* cursor's y position */ + } console_info; + unsigned long fpswa; /* physical address of the fpswa interface */ + unsigned long initrd_start; + unsigned long initrd_size; + unsigned long domain_start; /* va where the boot time domain begins */ + unsigned long domain_size; /* how big is the boot domain */ +}; + #endif /* !__ASSEMBLY__ */ /* Address of shared_info in domain virtual space.