aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxen-ia64.adm@bkbits.net <xen-ia64.adm@bkbits.net>2005-03-07 17:31:43 +0000
committerxen-ia64.adm@bkbits.net <xen-ia64.adm@bkbits.net>2005-03-07 17:31:43 +0000
commit1cc05252d378a0fff39f6e13bec30615b4669f5e (patch)
tree3a3f43909e80c149c8ee1ee3281877c86d94823d
parentaa4b616c673527e14e7729c571b37de35daee7bf (diff)
parent45dd7ca4d6a4879e08a810ebda6724ebcce9bf10 (diff)
downloadxen-1cc05252d378a0fff39f6e13bec30615b4669f5e.tar.gz
xen-1cc05252d378a0fff39f6e13bec30615b4669f5e.tar.bz2
xen-1cc05252d378a0fff39f6e13bec30615b4669f5e.zip
bitkeeper revision 1.1236.11.1 (422c8fffPd62_3ejA06WBfNou1MZyg)
Merge bk://xen.bkbits.net/xeno-unstable.bk into bkbits.net:/repos/x/xen-ia64/xeno-unstable-ia64.bk
-rw-r--r--BitKeeper/etc/logging_ok1
-rw-r--r--xen/arch/ia64/Makefile1
-rw-r--r--xen/arch/ia64/privop.c90
-rw-r--r--xen/arch/ia64/process.c39
-rw-r--r--xen/arch/ia64/tools/mkbuildtree5
-rw-r--r--xen/arch/ia64/xenasm.S19
-rw-r--r--xen/arch/ia64/xenmisc.c12
-rw-r--r--xen/arch/ia64/xensetup.c2
-rw-r--r--xen/include/asm-ia64/config.h17
9 files changed, 151 insertions, 35 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index a20c296edf..b8ea3df1eb 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -76,4 +76,5 @@ tlh20@elite.cl.cam.ac.uk
tlh20@labyrinth.cl.cam.ac.uk
tw275@labyrinth.cl.cam.ac.uk
tw275@striker.cl.cam.ac.uk
+xen-ia64.adm@bkbits.net
xenbk@gandalf.hpl.hp.com
diff --git a/xen/arch/ia64/Makefile b/xen/arch/ia64/Makefile
index e6f2c26af2..fb0511ffe2 100644
--- a/xen/arch/ia64/Makefile
+++ b/xen/arch/ia64/Makefile
@@ -7,6 +7,7 @@ OBJS = xensetup.o setup.o time.o irq.o ia64_ksyms.o process.o smp.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 \
+ extable.o linuxextable.o \
regionreg.o entry.o unaligned.o privop.o vcpu.o \
irq_ia64.o irq_lsapic.o hpsim_irq.o vhpt.o xenasm.o dom_fw.o
# perfmon.o
diff --git a/xen/arch/ia64/privop.c b/xen/arch/ia64/privop.c
index d3540462d3..85c839103d 100644
--- a/xen/arch/ia64/privop.c
+++ b/xen/arch/ia64/privop.c
@@ -538,7 +538,8 @@ unsigned long privop_trace = 0;
IA64FAULT
priv_handle_op(VCPU *vcpu, REGS *regs, int privlvl)
{
- IA64_BUNDLE bundle, __get_domain_bundle(UINT64);
+ IA64_BUNDLE bundle;
+ IA64_BUNDLE __get_domain_bundle(UINT64);
int slot;
IA64_SLOT_TYPE slot_type;
INST64 inst;
@@ -550,19 +551,14 @@ priv_handle_op(VCPU *vcpu, REGS *regs, int privlvl)
// make a local copy of the bundle containing the privop
#if 1
bundle = __get_domain_bundle(iip);
- if (!bundle.i64[0] && !bundle.i64[1]) return IA64_RETRY;
-#else
-#ifdef AVOIDING_POSSIBLE_DOMAIN_TLB_MISS
- //TODO: this needs to check for faults and behave accordingly
- if (!vcpu_get_iip_bundle(&bundle)) return IA64_DTLB_FAULT;
+ if (!bundle.i64[0] && !bundle.i64[1])
#else
-if (iip < 0x10000) {
- printf("priv_handle_op: unlikely iip=%p,b0=%p\n",iip,regs->b0);
- dummy();
-}
- bundle = *(IA64_BUNDLE *)iip;
-#endif
+ if (__copy_from_user(&bundle,iip,sizeof(bundle)))
#endif
+ {
+//printf("*** priv_handle_op: privop bundle @%p not mapped, retrying\n",iip);
+ return IA64_RETRY;
+ }
#if 0
if (iip==0xa000000100001820) {
static int firstpagefault = 1;
@@ -783,10 +779,12 @@ char *cr_str[128] = {
RS,RS,RS,RS,RS,RS,RS,RS
};
-void dump_privop_counts(void)
+// FIXME: should use snprintf to ensure no buffer overflow
+int dump_privop_counts(char *buf)
{
int i, j;
UINT64 sum = 0;
+ char *s = buf;
// this is ugly and should probably produce sorted output
// but it will have to do for now
@@ -795,63 +793,64 @@ void dump_privop_counts(void)
sum += privcnt.rfi; sum += privcnt.bsw0;
sum += privcnt.bsw1; sum += privcnt.cover;
for (i=0; i < 64; i++) sum += privcnt.Mpriv_cnt[i];
- printf("Privop statistics: (Total privops: %ld)\r\n",sum);
+ s += sprintf(s,"Privop statistics: (Total privops: %ld)\r\n",sum);
if (privcnt.mov_to_ar_imm)
- printf("%10d %s [%d%%]\r\n", privcnt.mov_to_ar_imm,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.mov_to_ar_imm,
"mov_to_ar_imm", (privcnt.mov_to_ar_imm*100L)/sum);
if (privcnt.mov_to_ar_reg)
- printf("%10d %s [%d%%]\r\n", privcnt.mov_to_ar_reg,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.mov_to_ar_reg,
"mov_to_ar_reg", (privcnt.mov_to_ar_reg*100L)/sum);
if (privcnt.ssm)
- printf("%10d %s [%d%%]\r\n", privcnt.ssm,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.ssm,
"ssm", (privcnt.ssm*100L)/sum);
if (privcnt.rsm)
- printf("%10d %s [%d%%]\r\n", privcnt.rsm,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.rsm,
"rsm", (privcnt.rsm*100L)/sum);
if (privcnt.rfi)
- printf("%10d %s [%d%%]\r\n", privcnt.rfi,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.rfi,
"rfi", (privcnt.rfi*100L)/sum);
if (privcnt.bsw0)
- printf("%10d %s [%d%%]\r\n", privcnt.bsw0,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.bsw0,
"bsw0", (privcnt.bsw0*100L)/sum);
if (privcnt.bsw1)
- printf("%10d %s [%d%%]\r\n", privcnt.bsw1,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.bsw1,
"bsw1", (privcnt.bsw1*100L)/sum);
if (privcnt.cover)
- printf("%10d %s [%d%%]\r\n", privcnt.cover,
+ s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.cover,
"cover", (privcnt.cover*100L)/sum);
for (i=0; i < 64; i++) if (privcnt.Mpriv_cnt[i]) {
- if (!Mpriv_str[i]) printf("PRIVSTRING NULL!!\r\n");
- else printf("%10d %s [%d%%]\r\n", privcnt.Mpriv_cnt[i],
+ if (!Mpriv_str[i]) s += sprintf(s,"PRIVSTRING NULL!!\r\n");
+ else s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.Mpriv_cnt[i],
Mpriv_str[i], (privcnt.Mpriv_cnt[i]*100L)/sum);
if (i == 0x24) { // mov from CR
- printf(" [");
+ s += sprintf(s," [");
for (j=0; j < 128; j++) if (from_cr_cnt[j]) {
if (!cr_str[j])
- printf("PRIVSTRING NULL!!\r\n");
- printf("%s(%d),",cr_str[j],from_cr_cnt[j]);
+ s += sprintf(s,"PRIVSTRING NULL!!\r\n");
+ s += sprintf(s,"%s(%d),",cr_str[j],from_cr_cnt[j]);
}
- printf("]\r\n");
+ s += sprintf(s,"]\r\n");
}
else if (i == 0x2c) { // mov to CR
- printf(" [");
+ s += sprintf(s," [");
for (j=0; j < 128; j++) if (to_cr_cnt[j]) {
if (!cr_str[j])
- printf("PRIVSTRING NULL!!\r\n");
- printf("%s(%d),",cr_str[j],to_cr_cnt[j]);
+ s += sprintf(s,"PRIVSTRING NULL!!\r\n");
+ s += sprintf(s,"%s(%d),",cr_str[j],to_cr_cnt[j]);
}
- printf("]\r\n");
+ s += sprintf(s,"]\r\n");
}
}
+ return s - buf;
}
-void zero_privop_counts(void)
+int zero_privop_counts(char *buf)
{
int i, j;
+ char *s = buf;
// this is ugly and should probably produce sorted output
// but it will have to do for now
- printf("Zeroing privop statistics\r\n");
privcnt.mov_to_ar_imm = 0; privcnt.mov_to_ar_reg = 0;
privcnt.ssm = 0; privcnt.rsm = 0;
privcnt.rfi = 0; privcnt.bsw0 = 0;
@@ -859,4 +858,27 @@ void zero_privop_counts(void)
for (i=0; i < 64; i++) privcnt.Mpriv_cnt[i] = 0;
for (j=0; j < 128; j++) from_cr_cnt[j] = 0;
for (j=0; j < 128; j++) to_cr_cnt[j] = 0;
+ s += sprintf(s,"All privop statistics zeroed\r\n");
+ return s - buf;
+}
+
+#define TMPBUFLEN 8*1024
+int dump_privop_counts_to_user(char __user *ubuf, int len)
+{
+ char buf[TMPBUFLEN];
+ int n = dump_privop_counts(buf);
+
+ if (len < TMPBUFLEN) return -1;
+ if (__copy_to_user(ubuf,buf,n)) return -1;
+ return n;
+}
+
+int zero_privop_counts_to_user(char __user *ubuf, int len)
+{
+ char buf[TMPBUFLEN];
+ int n = zero_privop_counts(buf);
+
+ if (len < TMPBUFLEN) return -1;
+ if (__copy_to_user(ubuf,buf,n)) return -1;
+ return n;
}
diff --git a/xen/arch/ia64/process.c b/xen/arch/ia64/process.c
index 029ec803c7..8baacbc816 100644
--- a/xen/arch/ia64/process.c
+++ b/xen/arch/ia64/process.c
@@ -242,7 +242,9 @@ void xen_handle_domain_access(unsigned long address, unsigned long isr, struct p
unsigned long pteval, mpaddr;
unsigned long lookup_domain_mpa(struct domain *,unsigned long);
IA64FAULT fault;
+#ifndef USER_ACCESS
extern void __get_domain_bundle(void);
+#endif
// NEED TO HANDLE THREE CASES:
// 1) domain is in metaphysical mode
@@ -265,20 +267,41 @@ void xen_handle_domain_access(unsigned long address, unsigned long isr, struct p
vcpu_itc_no_srlz(ed,2,address,pteval,PAGE_SHIFT);
return;
}
-if (address < 0x4000) printf("WARNING: page_fault @%p, iip=%p\n",address,iip);
+#ifndef USER_ACCESS
if (*(unsigned long *)__get_domain_bundle != iip) {
printf("Bad user space access @%p ",address);
printf("iip=%p, ipsr=%p, b0=%p\n",iip,psr,regs->b0);
while(1);
}
+#endif
+if (address < 0x4000) printf("WARNING: page_fault @%p, iip=%p\n",address,iip);
fault = vcpu_tpa(ed,address,&mpaddr);
if (fault != IA64_NO_FAULT) {
+#ifndef USER_ACCESS
// this is hardcoded to handle __get_domain_bundle only
regs->r8 = 0; regs->r9 = 0;
regs->cr_iip += 0x20;
//regs->cr_iip |= (2UL << IA64_PSR_RI_BIT);
return;
+#else /* USER_ACCESS */
+ static int uacnt = 0;
+ // can't translate it, just fail (poor man's exception)
+ // which results in retrying execution
+//printk("*** xen_handle_domain_access: poor man's exception cnt=%i iip=%p, addr=%p...\n",uacnt++,iip,address);
+ if (ia64_done_with_exception(regs)) {
+//if (!(uacnt++ & 0x3ff)) printk("*** xen_handle_domain_access: successfully handled cnt=%d iip=%p, addr=%p...\n",uacnt,iip,address);
+ return;
+ }
+ else {
+ // should never happen. If it does, region 0 addr may
+ // indicate a bad xen pointer
+ printk("*** xen_handle_domain_access: exception table"
+ " lookup failed, iip=%p, addr=%p, spinning...\n",
+ iip,address);
+ while(1);
+ }
+#endif /* USER_ACCESS */
}
if (d == dom0) {
if (mpaddr < dom0_start || mpaddr >= dom0_start + dom0_size) {
@@ -286,6 +309,7 @@ if (address < 0x4000) printf("WARNING: page_fault @%p, iip=%p\n",address,iip);
tdpfoo();
}
}
+//printk("*** xen_handle_domain_access: tpa resolved miss @%p...\n",address);
pteval = lookup_domain_mpa(d,mpaddr);
// would be nice to have a counter here
//printf("Handling privop data TLB miss\n");
@@ -755,6 +779,16 @@ ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, u
// FIXME: need fixes in efi.h from 2.6.9
regs->r8 = EFI_UNSUPPORTED;
break;
+ case 0xffff: // test dummy hypercall
+ regs->r8 = dump_privop_counts_to_user(
+ vcpu_get_gr(ed,32),
+ vcpu_get_gr(ed,33));
+ break;
+ case 0xfffe: // test dummy hypercall
+ regs->r8 = zero_privop_counts_to_user(
+ vcpu_get_gr(ed,32),
+ vcpu_get_gr(ed,33));
+ break;
}
vcpu_increment_iip(current);
}
@@ -809,6 +843,9 @@ ia64_handle_reflection (unsigned long ifa, struct pt_regs *regs, unsigned long i
case 10:
check_lazy_cover = 1;
vector = IA64_DATA_ACCESS_BIT_VECTOR; break;
+ case 20:
+ check_lazy_cover = 1;
+ vector = IA64_PAGE_NOT_PRESENT_VECTOR; break;
case 22:
vector = IA64_INST_ACCESS_RIGHTS_VECTOR; break;
case 23:
diff --git a/xen/arch/ia64/tools/mkbuildtree b/xen/arch/ia64/tools/mkbuildtree
index 883dd91b8a..35c3e926a9 100644
--- a/xen/arch/ia64/tools/mkbuildtree
+++ b/xen/arch/ia64/tools/mkbuildtree
@@ -98,6 +98,9 @@ cp_patch mm/bootmem.c arch/ia64/mm_bootmem.c mm_bootmem.c
cp_patch mm/page_alloc.c arch/ia64/page_alloc.c page_alloc.c
cp_patch mm/slab.c arch/ia64/slab.c slab.c
+# following renamed to avoid conflict
+softlink kernel/extable.c arch/ia64/linuxextable.c
+
cp_patch arch/ia64/mm/contig.c arch/ia64/mm_contig.c mm_contig.c
cp_patch arch/ia64/mm/tlb.c arch/ia64/tlb.c tlb.c
@@ -108,6 +111,7 @@ softlink arch/ia64/kernel/entry.h arch/ia64/entry.h
softlink arch/ia64/kernel/ia64_ksyms.c arch/ia64/ia64_ksyms.c
softlink arch/ia64/kernel/irq_lsapic.c arch/ia64/irq_lsapic.c
softlink arch/ia64/kernel/machvec.c arch/ia64/machvec.c
+softlink arch/ia64/mm/extable.c arch/ia64/extable.c
softlink arch/ia64/kernel/pal.S arch/ia64/pal.S
softlink arch/ia64/kernel/patch.c arch/ia64/patch.c
softlink arch/ia64/kernel/sal.c arch/ia64/sal.c
@@ -182,6 +186,7 @@ null include/asm-ia64/domain_page.h
null include/asm-ia64/flushtlb.h
null include/asm-ia64/io_apic.h
null include/asm-ia64/pdb.h
+null include/asm-ia64/module.h
softlink include/asm-ia64/acpi.h include/asm-ia64/acpi.h
softlink include/asm-ia64/asmmacro.h include/asm-ia64/asmmacro.h
diff --git a/xen/arch/ia64/xenasm.S b/xen/arch/ia64/xenasm.S
index 3be0b9b2a8..998a3d87d1 100644
--- a/xen/arch/ia64/xenasm.S
+++ b/xen/arch/ia64/xenasm.S
@@ -261,6 +261,8 @@ GLOBAL_ENTRY(ia64_prepare_handle_reflection)
br.cond.sptk.many rp // goes to ia64_leave_kernel
END(ia64_prepare_handle_reflection)
+#ifndef USER_ACCESS
+// REMOVE: replaced with get_user
// NOTE: instruction spacing must be explicit for recovery on miss
GLOBAL_ENTRY(__get_domain_bundle)
ld8 r8=[r32],8
@@ -276,6 +278,23 @@ GLOBAL_ENTRY(__get_domain_bundle)
nop 0
;;
END(__get_domain_bundle)
+#else
+GLOBAL_ENTRY(__get_domain_bundle)
+ EX(.failure_in_get_bundle,ld8 r8=[r32],8)
+ ;;
+ EX(.failure_in_get_bundle,ld8 r9=[r32])
+ ;;
+ br.ret.sptk.many rp
+ ;;
+.failure_in_get_bundle:
+ mov r8=0
+ ;;
+ mov r9=0
+ ;;
+ br.ret.sptk.many rp
+ ;;
+END(__get_domain_bundle)
+#endif
GLOBAL_ENTRY(dorfirfi)
#define SI_CR_IIP_OFFSET 0x10
diff --git a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c
index 663319de3c..425aed9894 100644
--- a/xen/arch/ia64/xenmisc.c
+++ b/xen/arch/ia64/xenmisc.c
@@ -216,3 +216,15 @@ physdev_pci_access_modify(domid_t id, int bus, int dev, int func, int enable)
{
return -EINVAL;
}
+
+// accomodate linux extable.c
+//const struct exception_table_entry *
+void *search_module_extables(unsigned long addr)
+{
+ return NULL;
+}
+
+void *module_text_address(unsigned long addr)
+{
+ return NULL;
+}
diff --git a/xen/arch/ia64/xensetup.c b/xen/arch/ia64/xensetup.c
index 713dd5761a..59ba8a4c49 100644
--- a/xen/arch/ia64/xensetup.c
+++ b/xen/arch/ia64/xensetup.c
@@ -288,6 +288,8 @@ printk("About to call ac_timer_init()\n");
// init_xen_time(); ???
// schedulers_start(); ???
// do_initcalls(); ???
+printk("About to call sort_main_extable()\n");
+ sort_main_extable();
#else
start_of_day();
diff --git a/xen/include/asm-ia64/config.h b/xen/include/asm-ia64/config.h
index 80a80c0eb0..3d1c4fc500 100644
--- a/xen/include/asm-ia64/config.h
+++ b/xen/include/asm-ia64/config.h
@@ -1,4 +1,7 @@
+// control flags for turning on/off features under test
#undef CLONE_DOMAIN0
+#define USER_ACCESS
+
// manufactured from component pieces
// defined in linux/arch/ia64/defconfig
@@ -160,6 +163,20 @@ struct pci_bus_region {
unsigned long end;
};
+// from linux/include/linux/module.h
+
+// warning: unless search_extable is declared, the return value gets
+// truncated to 32-bits, causing a very strange error in privop handling
+struct exception_table_entry;
+
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value);
+void sort_extable(struct exception_table_entry *start,
+ struct exception_table_entry *finish);
+void sort_main_extable(void);
+
// defined (why?) in include/asm-i386/processor.h
// used in common/physdev.c
#define IO_BITMAP_SIZE 32