📄 domain_build.c
字号:
page = mfn_to_page(mfn); if ( (page->u.inuse.type_info == 0) && !get_page_and_type(page, d, PGT_writable_page) ) BUG(); mfn++; } if ( is_pv_32on64_domain(d) ) { /* Ensure the first four L3 entries are all populated. */ for ( i = 0, l3tab = l3start; i < 4; ++i, ++l3tab ) { if ( !l3e_get_intpte(*l3tab) ) { maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l2_page_table; l2tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; clear_page(l2tab); *l3tab = l3e_from_paddr(__pa(l2tab), L3_PROT); } if ( i == 3 ) l3e_get_page(*l3tab)->u.inuse.type_info |= PGT_pae_xen_l2; } /* Install read-only guest visible MPT mapping. */ l2tab = l3e_to_l2e(l3start[3]); memcpy(&l2tab[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*l2tab)); } /* Pages that are part of page tables must be read only. */ l4tab = l4start + l4_table_offset(vpt_start); l3start = l3tab = l4e_to_l3e(*l4tab); l3tab += l3_table_offset(vpt_start); l2start = l2tab = l3e_to_l2e(*l3tab); l2tab += l2_table_offset(vpt_start); l1start = l1tab = l2e_to_l1e(*l2tab); l1tab += l1_table_offset(vpt_start); for ( count = 0; count < nr_pt_pages; count++ ) { l1e_remove_flags(*l1tab, _PAGE_RW); page = mfn_to_page(l1e_get_pfn(*l1tab)); /* Read-only mapping + PGC_allocated + page-table page. */ page->count_info = PGC_allocated | 3; page->u.inuse.type_info |= PGT_validated | 1; /* Top-level p.t. is pinned. */ if ( (page->u.inuse.type_info & PGT_type_mask) == (!is_pv_32on64_domain(d) ? PGT_l4_page_table : PGT_l3_page_table) ) { page->count_info += 1; page->u.inuse.type_info += 1 | PGT_pinned; } /* Iterate. */ if ( !((unsigned long)++l1tab & (PAGE_SIZE - 1)) ) { if ( !((unsigned long)++l2tab & (PAGE_SIZE - 1)) ) { if ( !((unsigned long)++l3tab & (PAGE_SIZE - 1)) ) l3start = l3tab = l4e_to_l3e(*++l4tab); l2start = l2tab = l3e_to_l2e(*l3tab); } l1start = l1tab = l2e_to_l1e(*l2tab); } }#endif /* __x86_64__ */ /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) shared_info(d, vcpu_info[i].evtchn_upcall_mask) = 1; if ( opt_dom0_max_vcpus == 0 ) opt_dom0_max_vcpus = num_online_cpus(); if ( opt_dom0_max_vcpus > MAX_VIRT_CPUS ) opt_dom0_max_vcpus = MAX_VIRT_CPUS; printk("Dom0 has maximum %u VCPUs\n", opt_dom0_max_vcpus); for ( i = 1; i < opt_dom0_max_vcpus; i++ ) (void)alloc_vcpu(d, i, i % num_online_cpus()); /* Set up CR3 value for write_ptbase */ if ( paging_mode_enabled(v->domain) ) paging_update_paging_modes(v); else update_cr3(v); /* Install the new page tables. */ local_irq_disable(); write_ptbase(v); /* Copy the OS image and free temporary buffer. */ elf.dest = (void*)vkern_start; elf_load_binary(&elf); if ( UNSET_ADDR != parms.virt_hypercall ) { if ( (parms.virt_hypercall < v_start) || (parms.virt_hypercall >= v_end) ) { write_ptbase(current); local_irq_enable(); printk("Invalid HYPERCALL_PAGE field in ELF notes.\n"); return -1; } hypercall_page_initialise(d, (void *)(unsigned long)parms.virt_hypercall); } /* Copy the initial ramdisk. */ if ( initrd_len != 0 ) memcpy((void *)vinitrd_start, initrd_start, initrd_len); /* Free temporary buffers. */ discard_initial_images(); /* Set up start info area. */ si = (start_info_t *)vstartinfo_start; clear_page(si); si->nr_pages = nr_pages; si->shared_info = virt_to_maddr(d->shared_info); si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; si->flags |= (xen_processor_pmbits << 8) & SIF_PM_MASK; si->pt_base = vpt_start + 2 * PAGE_SIZE * !!is_pv_32on64_domain(d); si->nr_pt_frames = nr_pt_pages; si->mfn_list = vphysmap_start; snprintf(si->magic, sizeof(si->magic), "xen-3.0-x86_%d%s", elf_64bit(&elf) ? 64 : 32, parms.pae ? "p" : ""); /* Write the phys->machine and machine->phys table entries. */ for ( pfn = 0; pfn < d->tot_pages; pfn++ ) { mfn = pfn + alloc_spfn;#ifndef NDEBUG#define REVERSE_START ((v_end - v_start) >> PAGE_SHIFT) if ( pfn > REVERSE_START ) mfn = alloc_epfn - (pfn - REVERSE_START);#endif if ( !is_pv_32on64_domain(d) ) ((unsigned long *)vphysmap_start)[pfn] = mfn; else ((unsigned int *)vphysmap_start)[pfn] = mfn; set_gpfn_from_mfn(mfn, pfn); } while ( pfn < nr_pages ) { if ( (page = alloc_chunk(d, nr_pages - d->tot_pages)) == NULL ) panic("Not enough RAM for DOM0 reservation.\n"); while ( pfn < d->tot_pages ) { mfn = page_to_mfn(page);#ifndef NDEBUG#define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn)))#endif if ( !is_pv_32on64_domain(d) ) ((unsigned long *)vphysmap_start)[pfn] = mfn; else ((unsigned int *)vphysmap_start)[pfn] = mfn; set_gpfn_from_mfn(mfn, pfn);#undef pfn page++; pfn++; } } if ( initrd_len != 0 ) { si->mod_start = vinitrd_start; si->mod_len = initrd_len; } memset(si->cmd_line, 0, sizeof(si->cmd_line)); if ( cmdline != NULL ) strlcpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line)); if ( fill_console_start_info((void *)(si + 1)) ) { si->console.dom0.info_off = sizeof(struct start_info); si->console.dom0.info_size = sizeof(struct dom0_vga_console_info); }#if defined(__x86_64__) if ( is_pv_32on64_domain(d) ) xlat_start_info(si, XLAT_start_info_console_dom0);#endif /* Reinstate the caller's page tables. */ write_ptbase(current); local_irq_enable();#if defined(__i386__) /* Destroy low mappings - they were only for our convenience. */ zap_low_mappings(l2start);#endif update_domain_wallclock_time(d); v->is_initialised = 1; clear_bit(_VPF_down, &v->pause_flags); /* * Initial register values: * DS,ES,FS,GS = FLAT_KERNEL_DS * CS:EIP = FLAT_KERNEL_CS:start_pc * SS:ESP = FLAT_KERNEL_SS:start_stack * ESI = start_info * [EAX,EBX,ECX,EDX,EDI,EBP are zero] */ regs = &v->arch.guest_context.user_regs; regs->ds = regs->es = regs->fs = regs->gs = !is_pv_32on64_domain(d) ? FLAT_KERNEL_DS : FLAT_COMPAT_KERNEL_DS; regs->ss = (!is_pv_32on64_domain(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS); regs->cs = (!is_pv_32on64_domain(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS); regs->eip = parms.virt_entry; regs->esp = vstack_end; regs->esi = vstartinfo_start; regs->eflags = X86_EFLAGS_IF; if ( opt_dom0_shadow ) if ( paging_enable(d, PG_SH_enable) == 0 ) paging_update_paging_modes(v); if ( supervisor_mode_kernel ) { v->arch.guest_context.kernel_ss &= ~3; v->arch.guest_context.user_regs.ss &= ~3; v->arch.guest_context.user_regs.es &= ~3; v->arch.guest_context.user_regs.ds &= ~3; v->arch.guest_context.user_regs.fs &= ~3; v->arch.guest_context.user_regs.gs &= ~3; printk("Dom0 runs in ring 0 (supervisor mode)\n"); if ( !test_bit(XENFEAT_supervisor_mode_kernel, parms.f_supported) ) panic("Dom0 does not support supervisor-mode execution\n"); } else { if ( test_bit(XENFEAT_supervisor_mode_kernel, parms.f_required) ) panic("Dom0 requires supervisor-mode execution\n"); } rc = 0; /* DOM0 is permitted full I/O capabilities. */ rc |= ioports_permit_access(dom0, 0, 0xFFFF); rc |= iomem_permit_access(dom0, 0UL, ~0UL); rc |= irqs_permit_access(dom0, 0, NR_IRQS-1); /* * Modify I/O port access permissions. */ /* Master Interrupt Controller (PIC). */ rc |= ioports_deny_access(dom0, 0x20, 0x21); /* Slave Interrupt Controller (PIC). */ rc |= ioports_deny_access(dom0, 0xA0, 0xA1); /* Interval Timer (PIT). */ rc |= ioports_deny_access(dom0, 0x40, 0x43); /* PIT Channel 2 / PC Speaker Control. */ rc |= ioports_deny_access(dom0, 0x61, 0x61); /* PCI configuration space (NB. 0xcf8 has special treatment). */ rc |= ioports_deny_access(dom0, 0xcfc, 0xcff); /* Command-line I/O ranges. */ process_dom0_ioports_disable(); /* * Modify I/O memory access permissions. */ /* Local APIC. */ if ( mp_lapic_addr != 0 ) { mfn = paddr_to_pfn(mp_lapic_addr); rc |= iomem_deny_access(dom0, mfn, mfn); } /* I/O APICs. */ for ( i = 0; i < nr_ioapics; i++ ) { mfn = paddr_to_pfn(mp_ioapics[i].mpc_apicaddr); if ( smp_found_config ) rc |= iomem_deny_access(dom0, mfn, mfn); } /* Remove access to E820_UNUSABLE I/O regions above 1MB. */ for ( i = 0; i < e820.nr_map; i++ ) { unsigned long sfn, efn; sfn = max_t(unsigned long, paddr_to_pfn(e820.map[i].addr), 0x100ul); efn = paddr_to_pfn(e820.map[i].addr + e820.map[i].size - 1); if ( (e820.map[i].type == E820_UNUSABLE) && (e820.map[i].size != 0) && (sfn <= efn) ) rc |= iomem_deny_access(dom0, sfn, efn); } BUG_ON(rc != 0); return 0;}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -