ChangeSet 1.1305.1.7, 2005/03/17 17:48:21-07:00, djm@xxxxxxxxxxxxxxx
Fix timer tick before its due problem (again)
Split out hypercall code into separate module
First step implementation of domain creation via hypercall
arch/ia64/Makefile | 2
arch/ia64/domain.c | 488 ++++++++++++++++++++++++++++-----------------
arch/ia64/hypercall.c | 98 +++++++++
arch/ia64/process.c | 69 ------
arch/ia64/vcpu.c | 13 +
arch/ia64/xensetup.c | 4
include/public/arch-ia64.h | 2
7 files changed, 421 insertions(+), 255 deletions(-)
diff -Nru a/xen/arch/ia64/Makefile b/xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile 2005-03-25 19:04:38 -05:00
+++ b/xen/arch/ia64/Makefile 2005-03-25 19:04:38 -05:00
@@ -3,7 +3,7 @@
# libs-y += arch/ia64/lib/lib.a
OBJS = xensetup.o setup.o time.o irq.o ia64_ksyms.o process.o smp.o \
- xenmisc.o pdb-stub.o acpi.o \
+ xenmisc.o pdb-stub.o acpi.o hypercall.o \
machvec.o dom0_ops.o domain.o \
idle0_task.o pal.o hpsim.o efi.o efi_stub.o ivt.o mm_contig.o \
mm_bootmem.o sal.o cmdline.o mm_init.o tlb.o page_alloc.o slab.o \
diff -Nru a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c
--- a/xen/arch/ia64/domain.c 2005-03-25 19:04:38 -05:00
+++ b/xen/arch/ia64/domain.c 2005-03-25 19:04:38 -05:00
@@ -44,9 +44,11 @@
// initialized by arch/ia64/setup.c:find_initrd()
unsigned long initrd_start = 0, initrd_end = 0;
+#define IS_XEN_ADDRESS(d,a) ((a >= d->xen_vastart) && (a <= d->xen_vaend))
+
extern int loadelfimage(char *);
extern int readelfimage_base_and_size(char *, unsigned long,
- unsigned long *, unsigned long *, unsigned long *);
+ unsigned long *, unsigned long *, unsigned long *);
unsigned long map_domain_page0(struct domain *);
extern unsigned long dom_fw_setup(struct domain *, char *, int);
@@ -54,63 +56,63 @@
/* this belongs in include/asm, but there doesn't seem to be a suitable place
*/
void free_perdomain_pt(struct domain *d)
{
- dummy();
- //free_page((unsigned long)d->mm.perdomain_pt);
+ dummy();
+ //free_page((unsigned long)d->mm.perdomain_pt);
}
int hlt_counter;
void disable_hlt(void)
{
- hlt_counter++;
+ hlt_counter++;
}
void enable_hlt(void)
{
- hlt_counter--;
+ hlt_counter--;
}
static void default_idle(void)
{
- if ( hlt_counter == 0 )
- {
+ if ( hlt_counter == 0 )
+ {
local_irq_disable();
- if ( !softirq_pending(smp_processor_id()) )
- safe_halt();
- //else
+ if ( !softirq_pending(smp_processor_id()) )
+ safe_halt();
+ //else
local_irq_enable();
- }
+ }
}
void continue_cpu_idle_loop(void)
{
- int cpu = smp_processor_id();
- for ( ; ; )
- {
+ int cpu = smp_processor_id();
+ for ( ; ; )
+ {
#ifdef IA64
// __IRQ_STAT(cpu, idle_timestamp) = jiffies
#else
- irq_stat[cpu].idle_timestamp = jiffies;
+ irq_stat[cpu].idle_timestamp = jiffies;
#endif
- while ( !softirq_pending(cpu) )
- default_idle();
- do_softirq();
- }
+ while ( !softirq_pending(cpu) )
+ default_idle();
+ do_softirq();
+ }
}
void startup_cpu_idle_loop(void)
{
- /* Just some sanity to ensure that the scheduler is set up okay. */
- ASSERT(current->domain == IDLE_DOMAIN_ID);
- domain_unpause_by_systemcontroller(current->domain);
- __enter_scheduler();
-
- /*
- * Declares CPU setup done to the boot processor.
- * Therefore memory barrier to ensure state is visible.
- */
- smp_mb();
- init_idle();
+ /* Just some sanity to ensure that the scheduler is set up okay. */
+ ASSERT(current->domain == IDLE_DOMAIN_ID);
+ domain_unpause_by_systemcontroller(current->domain);
+ __enter_scheduler();
+
+ /*
+ * Declares CPU setup done to the boot processor.
+ * Therefore memory barrier to ensure state is visible.
+ */
+ smp_mb();
+ init_idle();
#if 0
//do we have to ensure the idle task has a shared page so that, for example,
//region registers can be loaded from it. Apparently not...
@@ -129,7 +131,7 @@
}
#endif
- continue_cpu_idle_loop();
+ continue_cpu_idle_loop();
}
struct domain *arch_alloc_domain_struct(void)
@@ -214,9 +216,9 @@
// heavily leveraged from linux/arch/ia64/kernel/process.c:copy_thread()
// and linux/arch/ia64/kernel/process.c:kernel_thread()
void new_thread(struct exec_domain *ed,
- unsigned long start_pc,
- unsigned long start_stack,
- unsigned long start_info)
+ unsigned long start_pc,
+ unsigned long start_stack,
+ unsigned long start_info)
{
struct domain *d = ed->domain;
struct switch_stack *sw;
@@ -393,24 +395,38 @@
return (IS_ELF(*ehdr));
}
+static void copy_memory(void *dst, void *src, int size)
+{
+ if (IS_XEN_ADDRESS(dom0,src)) {
+ memcpy(dst,src,size);
+ }
+ else {
+ if (__copy_from_user(dst,src,size))
+ printf("incomplete user copy\n");
+ }
+}
+
void loaddomainelfimage(struct domain *d, unsigned long image_start)
{
- char *elfbase = image_start;
- Elf_Ehdr *ehdr = (Elf_Ehdr *)image_start;
- Elf_Phdr *phdr;
- int h, filesz, memsz, paddr;
- unsigned long elfaddr, dom_mpaddr, dom_imva;
- struct page *p;
+ char *elfbase = image_start;
+ //Elf_Ehdr *ehdr = (Elf_Ehdr *)image_start;
+ Elf_Ehdr ehdr;
+ Elf_Phdr phdr;
+ int h, filesz, memsz, paddr;
+ unsigned long elfaddr, dom_mpaddr, dom_imva;
+ struct page *p;
- for ( h = 0; h < ehdr->e_phnum; h++ ) {
- phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
- //if ( !is_loadable_phdr(phdr) )
- if ((phdr->p_type != PT_LOAD)) {
- continue;
- }
- filesz = phdr->p_filesz; memsz = phdr->p_memsz;
- elfaddr = elfbase + phdr->p_offset;
- dom_mpaddr = phdr->p_paddr;
+ copy_memory(&ehdr,image_start,sizeof(Elf_Ehdr));
+ for ( h = 0; h < ehdr.e_phnum; h++ ) {
+ copy_memory(&phdr,elfbase + ehdr.e_phoff + (h*ehdr.e_phentsize),
+ sizeof(Elf_Phdr));
+ //if ( !is_loadable_phdr(phdr) )
+ if ((phdr.p_type != PT_LOAD)) {
+ continue;
+ }
+ filesz = phdr.p_filesz; memsz = phdr.p_memsz;
+ elfaddr = elfbase + phdr.p_offset;
+ dom_mpaddr = phdr.p_paddr;
//printf("p_offset: %x, size=%x\n",elfaddr,filesz);
#ifdef CONFIG_DOMAIN0_CONTIGUOUS
if (d == dom0) {
@@ -419,10 +435,10 @@
while(1);
}
dom_imva = __va(dom_mpaddr + dom0_start);
- memcpy(dom_imva,elfaddr,filesz);
+ copy_memory(dom_imva,elfaddr,filesz);
if (memsz > filesz) memset(dom_imva+filesz,0,memsz-filesz);
//FIXME: This test for code seems to find a lot more than objdump -x does
- if (phdr->p_flags & PF_X) privify_memory(dom_imva,filesz);
+ if (phdr.p_flags & PF_X) privify_memory(dom_imva,filesz);
}
else
#endif
@@ -432,13 +448,13 @@
dom_imva = __va(page_to_phys(p));
if (filesz > 0) {
if (filesz >= PAGE_SIZE)
- memcpy(dom_imva,elfaddr,PAGE_SIZE);
+ copy_memory(dom_imva,elfaddr,PAGE_SIZE);
else { // copy partial page, zero the rest of page
- memcpy(dom_imva,elfaddr,filesz);
+ copy_memory(dom_imva,elfaddr,filesz);
memset(dom_imva+filesz,0,PAGE_SIZE-filesz);
}
//FIXME: This test for code seems to find a lot more than objdump -x does
- if (phdr->p_flags & PF_X)
+ if (phdr.p_flags & PF_X)
privify_memory(dom_imva,PAGE_SIZE);
}
else if (memsz > 0) // always zero out entire page
@@ -446,66 +462,102 @@
memsz -= PAGE_SIZE; filesz -= PAGE_SIZE;
elfaddr += PAGE_SIZE; dom_mpaddr += PAGE_SIZE;
}
- }
+ }
+}
+
+int
+parsedomainelfimage(char *elfbase, unsigned long elfsize, unsigned long *entry)
+{
+ Elf_Ehdr ehdr;
+
+ copy_memory(&ehdr,elfbase,sizeof(Elf_Ehdr));
+
+ if ( !elf_sanity_check(&ehdr) ) {
+ printk("ELF sanity check failed.\n");
+ return -EINVAL;
+ }
+
+ if ( (ehdr.e_phoff + (ehdr.e_phnum * ehdr.e_phentsize)) > elfsize )
+ {
+ printk("ELF program headers extend beyond end of image.\n");
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/xen-changelog
|