direct-io.hg

changeset 4478:1081b873c010

bitkeeper revision 1.1236.59.1 (4252adc5cfdr_zYEiMj6H6F9DIrq4A)

privify tool
Signed-off by: Dan Magenheimer (dan.magenheimer@hp.com)
author djm@djmnc4000.(none)
date Tue Apr 05 15:24:53 2005 +0000 (2005-04-05)
parents 281cdf5f5f64
children 47a052edfe9f
files .rootkeys xen/arch/ia64/tools/privify/Makefile xen/arch/ia64/tools/privify/README.privify xen/arch/ia64/tools/privify/privify.c xen/arch/ia64/tools/privify/privify.h xen/arch/ia64/tools/privify/privify_elf64.c
line diff
     1.1 --- a/.rootkeys	Fri Apr 01 20:56:01 2005 +0000
     1.2 +++ b/.rootkeys	Tue Apr 05 15:24:53 2005 +0000
     1.3 @@ -1053,6 +1053,11 @@ 421098b6_ToSGrf6Pk1Uwg5aMAIBxg xen/arch/
     1.4  421098b6AUdbxR3wyn1ATcmNuTao_Q xen/arch/ia64/tools/README.xenia64
     1.5  42376c6dfyY0eq8MS2dK3BW2rFuEGg xen/arch/ia64/tools/README.xenia64linux
     1.6  421098b6rQ2BQ103qu1n1HNofbS2Og xen/arch/ia64/tools/mkbuildtree
     1.7 +4252ace7eQQmDdwOqsKWdHo8JpKqnQ xen/arch/ia64/tools/privify/Makefile
     1.8 +4252ace76fKAIizJRS6S84KbK6yXYw xen/arch/ia64/tools/privify/README.privify
     1.9 +4252ace7uR0Th8eEXiLyafNPTDYrOg xen/arch/ia64/tools/privify/privify.c
    1.10 +4252ace7H2dIMPFeFwczAVoP4yAHxA xen/arch/ia64/tools/privify/privify.h
    1.11 +4252ace74lKUPFnO8PmF0Dtpk7Xkng xen/arch/ia64/tools/privify/privify_elf64.c
    1.12  41a26ebc--sjlYZQxmIxyCx3jw70qA xen/arch/ia64/vcpu.c
    1.13  421098b6M2WhsJ_ZMzFamAQcdc5gzw xen/arch/ia64/vhpt.c
    1.14  41a26ebc4jSBGQOuyNIPDST58mNbBw xen/arch/ia64/xenasm.S
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/ia64/tools/privify/Makefile	Tue Apr 05 15:24:53 2005 +0000
     2.3 @@ -0,0 +1,9 @@
     2.4 +privify: privify_elf64.o privify.o
     2.5 +	gcc -g privify.o privify_elf64.o -o privify
     2.6 +
     2.7 +
     2.8 +privify_elf64.o: privify_elf64.c
     2.9 +	gcc -g -D__KERNEL__ -c privify_elf64.c
    2.10 +
    2.11 +privify.o: privify.c
    2.12 +	gcc -nostdinc -g -D__KERNEL__ -c privify.c
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/ia64/tools/privify/README.privify	Tue Apr 05 15:24:53 2005 +0000
     3.3 @@ -0,0 +1,8 @@
     3.4 +In this directory, just "make".
     3.5 +
     3.6 +Run the resulting program on a vmlinux that has been adjusted
     3.7 +to run on Xen (see arch/ia64/tools/README.xenia64linux):
     3.8 +
     3.9 +	./privify vmlinux xenlinux
    3.10 +
    3.11 +Use the resulting xenlinux file as domain0
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/arch/ia64/tools/privify/privify.c	Tue Apr 05 15:24:53 2005 +0000
     4.3 @@ -0,0 +1,360 @@
     4.4 +/*
     4.5 + * Binary translate privilege-sensitive ops to privileged
     4.6 + *
     4.7 + * Copyright (C) 2004 Hewlett-Packard Co.
     4.8 + *      Dan Magenheimer (dan.magenheimer@hp.com)
     4.9 + *
    4.10 + */
    4.11 +
    4.12 +#include "privify.h"
    4.13 +
    4.14 +typedef unsigned long long u64;
    4.15 +typedef unsigned long long IA64_INST;
    4.16 +
    4.17 +typedef union U_IA64_BUNDLE {
    4.18 +    u64 i64[2];
    4.19 +    struct { u64 template:5,slot0:41,slot1a:18,slot1b:23,slot2:41; };
    4.20 +    // NOTE: following doesn't work because bitfields can't cross natural
    4.21 +    // size boundaries
    4.22 +    //struct { u64 template:5, slot0:41, slot1:41, slot2:41; };
    4.23 +} IA64_BUNDLE;
    4.24 +
    4.25 +typedef enum E_IA64_SLOT_TYPE { I, M, F, B, L, ILLEGAL } IA64_SLOT_TYPE;
    4.26 +
    4.27 +typedef union U_INST64_A5 {
    4.28 +    IA64_INST inst;
    4.29 +    struct { u64 qp:6, r1:7, imm7b:7, r3:2, imm5c:5, imm9d:9, s:1, major:4; };
    4.30 +} INST64_A5;
    4.31 +
    4.32 +typedef union U_INST64_B4 {
    4.33 +    IA64_INST inst;
    4.34 +    struct { u64 qp:6, btype:3, un3:3, p:1, b2:3, un11:11, x6:6, wh:2, d:1, un1:1, major:4; };
    4.35 +} INST64_B4;
    4.36 +
    4.37 +typedef union U_INST64_B8 {
    4.38 +    IA64_INST inst;
    4.39 +    struct { u64 qp:6, un21:21, x6:6, un4:4, major:4; };
    4.40 +} INST64_B8;
    4.41 +
    4.42 +typedef union U_INST64_B9 {
    4.43 +    IA64_INST inst;
    4.44 +    struct { u64 qp:6, imm20:20, :1, x6:6, :3, i:1, major:4; };
    4.45 +} INST64_B9;
    4.46 +
    4.47 +typedef union U_INST64_I19 {
    4.48 +    IA64_INST inst;
    4.49 +    struct { u64 qp:6, imm20:20, :1, x6:6, x3:3, i:1, major:4; };
    4.50 +} INST64_I19;
    4.51 +
    4.52 +typedef union U_INST64_I26 {
    4.53 +    IA64_INST inst;
    4.54 +    struct { u64 qp:6, :7, r2:7, ar3:7, x6:6, x3:3, :1, major:4;};
    4.55 +} INST64_I26;
    4.56 +
    4.57 +typedef union U_INST64_I27 {
    4.58 +    IA64_INST inst;
    4.59 +    struct { u64 qp:6, :7, imm:7, ar3:7, x6:6, x3:3, s:1, major:4;};
    4.60 +} INST64_I27;
    4.61 +
    4.62 +typedef union U_INST64_I28 { // not privileged (mov from AR)
    4.63 +    IA64_INST inst;
    4.64 +    struct { u64 qp:6, r1:7, :7, ar3:7, x6:6, x3:3, :1, major:4;};
    4.65 +} INST64_I28;
    4.66 +
    4.67 +typedef union U_INST64_M28 {
    4.68 +    IA64_INST inst;
    4.69 +    struct { u64 qp:6, :14, r3:7, x6:6, x3:3, :1, major:4;};
    4.70 +} INST64_M28;
    4.71 +
    4.72 +typedef union U_INST64_M29 {
    4.73 +    IA64_INST inst;
    4.74 +    struct { u64 qp:6, :7, r2:7, ar3:7, x6:6, x3:3, :1, major:4;};
    4.75 +} INST64_M29;
    4.76 +
    4.77 +typedef union U_INST64_M30 {
    4.78 +    IA64_INST inst;
    4.79 +    struct { u64 qp:6, :7, imm:7, ar3:7,x4:4,x2:2,x3:3,s:1,major:4;};
    4.80 +} INST64_M30;
    4.81 +
    4.82 +typedef union U_INST64_M31 {
    4.83 +    IA64_INST inst;
    4.84 +    struct { u64 qp:6, r1:7, :7, ar3:7, x6:6, x3:3, :1, major:4;};
    4.85 +} INST64_M31;
    4.86 +
    4.87 +typedef union U_INST64_M32 {
    4.88 +    IA64_INST inst;
    4.89 +    struct { u64 qp:6, :7, r2:7, cr3:7, x6:6, x3:3, :1, major:4;};
    4.90 +} INST64_M32;
    4.91 +
    4.92 +typedef union U_INST64_M33 {
    4.93 +    IA64_INST inst;
    4.94 +    struct { u64 qp:6, r1:7, :7, cr3:7, x6:6, x3:3, :1, major:4; };
    4.95 +} INST64_M33;
    4.96 +
    4.97 +typedef union U_INST64_M35 {
    4.98 +    IA64_INST inst;
    4.99 +    struct { u64 qp:6, :7, r2:7, :7, x6:6, x3:3, :1, major:4; };
   4.100 +    	
   4.101 +} INST64_M35;
   4.102 +
   4.103 +typedef union U_INST64_M36 {
   4.104 +    IA64_INST inst;
   4.105 +    struct { u64 qp:6, r1:7, :14, x6:6, x3:3, :1, major:4; }; 
   4.106 +} INST64_M36;
   4.107 +
   4.108 +typedef union U_INST64_M41 {
   4.109 +    IA64_INST inst;
   4.110 +    struct { u64 qp:6, :7, r2:7, :7, x6:6, x3:3, :1, major:4; }; 
   4.111 +} INST64_M41;
   4.112 +
   4.113 +typedef union U_INST64_M42 {
   4.114 +    IA64_INST inst;
   4.115 +    struct { u64 qp:6, :7, r2:7, r3:7, x6:6, x3:3, :1, major:4; };
   4.116 +} INST64_M42;
   4.117 +
   4.118 +typedef union U_INST64_M43 {
   4.119 +    IA64_INST inst;
   4.120 +    struct { u64 qp:6, r1:7, :7, r3:7, x6:6, x3:3, :1, major:4; };
   4.121 +} INST64_M43;
   4.122 +
   4.123 +typedef union U_INST64_M44 {
   4.124 +    IA64_INST inst;
   4.125 +    struct { u64 qp:6, imm:21, x4:4, i2:2, x3:3, i:1, major:4; };
   4.126 +} INST64_M44;
   4.127 +
   4.128 +typedef union U_INST64_M45 {
   4.129 +    IA64_INST inst;
   4.130 +    struct { u64 qp:6, :7, r2:7, r3:7, x6:6, x3:3, :1, major:4; };
   4.131 +} INST64_M45;
   4.132 +
   4.133 +typedef union U_INST64_M46 {
   4.134 +    IA64_INST inst;
   4.135 +    struct { u64 qp:6, r1:7, un7:7, r3:7, x6:6, x3:3, un1:1, major:4; };
   4.136 +} INST64_M46;
   4.137 +
   4.138 +typedef union U_INST64 {
   4.139 +    IA64_INST inst;
   4.140 +    struct { u64 :37, major:4; } generic;
   4.141 +    INST64_A5 A5;	// used in build_hypercall_bundle only
   4.142 +    INST64_B4 B4;	// used in build_hypercall_bundle only
   4.143 +    INST64_B8 B8;	// rfi, bsw.[01]
   4.144 +    INST64_B9 B9;	// break.b
   4.145 +    INST64_I19 I19;	// used in build_hypercall_bundle only
   4.146 +    INST64_I26 I26;	// mov register to ar (I unit)
   4.147 +    INST64_I27 I27;	// mov immediate to ar (I unit)
   4.148 +    INST64_I28 I28;	// mov from ar (I unit)
   4.149 +    INST64_M28 M28;	// purge translation cache entry
   4.150 +    INST64_M29 M29;	// mov register to ar (M unit)
   4.151 +    INST64_M30 M30;	// mov immediate to ar (M unit)
   4.152 +    INST64_M31 M31;	// mov from ar (M unit)
   4.153 +    INST64_M32 M32;	// mov reg to cr
   4.154 +    INST64_M33 M33;	// mov from cr
   4.155 +    INST64_M35 M35;	// mov to psr
   4.156 +    INST64_M36 M36;	// mov from psr
   4.157 +    INST64_M41 M41;	// translation cache insert
   4.158 +    INST64_M42 M42;	// mov to indirect reg/translation reg insert
   4.159 +    INST64_M43 M43;	// mov from indirect reg
   4.160 +    INST64_M44 M44;	// set/reset system mask
   4.161 +    INST64_M45 M45;	// translation purge
   4.162 +    INST64_M46 M46;	// translation access (tpa,tak)
   4.163 +} INST64;
   4.164 +
   4.165 +#define MASK_41 ((u64)0x1ffffffffff)
   4.166 +
   4.167 +long priv_verbose = 0;
   4.168 +#define verbose(a...) do { if (priv_verbose) printf(a); } while(0)
   4.169 +
   4.170 +/*
   4.171 + * privify_inst
   4.172 + *
   4.173 + * Replaces privilege-sensitive instructions (and reads from write-trapping
   4.174 + * registers) with privileged/trapping instructions as follows:
   4.175 + *	mov rx=ar.cflg -> mov ar.cflg=r(x+64) [**]
   4.176 + *	mov rx=ar.ky -> mov ar.ky=r(x+64)
   4.177 + *	fc rx -> ptc r(x+64)
   4.178 + *	thash rx=ry -> tak rx=r(y+64)
   4.179 + *	ttag rx=ry -> tpa rx=r(y+64)
   4.180 + *	mov rx=cpuid[ry] -> mov r(x+64)=rr[ry]
   4.181 + *	mov rx=pmd[ry] -> mov r(x+64)=pmc[ry] [**]
   4.182 + *	cover -> break.b 0x1fffff
   4.183 + *
   4.184 + * [**] not currently implemented
   4.185 + */
   4.186 +IA64_INST privify_inst(IA64_INST inst_val,
   4.187 +		IA64_SLOT_TYPE slot_type, IA64_BUNDLE *bp, char **msg)
   4.188 +{
   4.189 +	INST64 inst = *(INST64 *)&inst_val;
   4.190 +
   4.191 +	*msg = 0;
   4.192 +	switch (slot_type) {
   4.193 +	    case M:
   4.194 +		// FIXME: Also use for mov_to/from_ar.cflag (M29/M30) (IA32 only)
   4.195 +		if (inst.generic.major != 1) break;
   4.196 +		if (inst.M46.x3 != 0) break;
   4.197 +		if (inst.M31.x6 == 0x22 && inst.M31.ar3 < 8) {
   4.198 +			// mov r1=kr -> mov kr=r1+64
   4.199 +			verbose("privify_inst: privified mov r1=kr @%p\n",bp);
   4.200 +			if (inst.M31.r1 >= 64) *msg = "mov r1=kr w/r1>63";
   4.201 +			else privify_mov_from_kr_m(inst);
   4.202 +			break;
   4.203 +		}
   4.204 +		if (inst.M29.x6 == 0x2a && inst.M29.ar3 < 8)  {// mov kr=r1
   4.205 +			if (inst.M29.r2 >= 64) *msg = "mov kr=r2 w/r2>63";
   4.206 +			break;
   4.207 +		}
   4.208 +		if (inst.M28.x6 == 0x30) {
   4.209 +			// fc r3-> ptc r3+64
   4.210 +			verbose("privify_inst: privified fc r3 @%p\n",bp);
   4.211 +			if (inst.M28.r3 >= 64) *msg = "fc r3 w/r3>63";
   4.212 +			else privify_fc(inst);
   4.213 +			break;
   4.214 +		}
   4.215 +		if (inst.M28.x6 == 0x34) {
   4.216 +			if (inst.M28.r3 >= 64) *msg = "ptc.e w/r3>63";
   4.217 +			break;
   4.218 +		}
   4.219 +		if (inst.M46.un7 != 0) break;
   4.220 +		if (inst.M46.un1 != 0) break;
   4.221 +		if (inst.M46.x6 == 0x1a)  { // thash -> tak r1=r3+64
   4.222 +			verbose("privify_inst: privified thash @%p\n",bp);
   4.223 +			if (inst.M46.r3 >= 64) *msg = "thash w/r3>63";
   4.224 +			else privify_thash(inst);
   4.225 +		}
   4.226 +		else if (inst.M46.x6 == 0x1b)  { // ttag -> tpa r1=r3+64
   4.227 +			verbose("privify_inst: privified ttag @%p\n",bp);
   4.228 +			if (inst.M46.r3 >= 64) *msg = "ttag w/r3>63";
   4.229 +			else privify_ttag(inst);
   4.230 +		}
   4.231 +		else if (inst.M43.x6 == 0x17) {
   4.232 +			verbose("privify_inst: privified mov_from_cpuid @%p\n",bp);
   4.233 +			if (inst.M43.r1 >= 64) *msg = "mov_from_cpuid w/r1>63";
   4.234 +			else privify_mov_from_cpuid(inst);
   4.235 +		}
   4.236 +		else if (inst.M46.x6 == 0x1e)  { // tpa
   4.237 +			if (inst.M46.r3 >= 64) *msg = "tpa w/r3>63";
   4.238 +		}
   4.239 +		else if (inst.M46.x6 == 0x1f)  { // tak
   4.240 +			if (inst.M46.r3 >= 64) *msg = "tak w/r3>63";
   4.241 +		}
   4.242 +		else if (inst.M43.x6 == 0x10) {
   4.243 +			if (inst.M43.r1 >= 64) *msg = "mov_to_rr w/r1>63";
   4.244 +		}
   4.245 +		break;
   4.246 +	    case B:
   4.247 +		if (inst.generic.major != 0) break;
   4.248 +		if (inst.B8.x6 == 0x2) { // cover -> break.b 0x1fffff
   4.249 +			if (inst.B8.un21 != 0) break;
   4.250 +			if (inst.B8.un4 != 0) break;
   4.251 +			privify_cover(inst);
   4.252 +			verbose("privify_inst: privified cover @%p\n",bp);
   4.253 +		}
   4.254 +		if (inst.B9.x6 == 0x0) { // (p15) break.b 0x1fffff -> cover
   4.255 +			if (inst.B9.qp != 15) break;
   4.256 +			if (inst.B9.imm20 != 0xfffff) break;
   4.257 +			if (inst.B9.i != 1) break;
   4.258 +			inst.B8.x6 = 0x2;
   4.259 +			inst.B8.un21 = 0;
   4.260 +			inst.B8.un4 = 0;
   4.261 +			inst.B8.qp = 0;
   4.262 +			verbose("privify_inst: unprivified pseudo-cover @%p\n",
   4.263 +					bp);
   4.264 +		}
   4.265 +		break;
   4.266 +	    case I:	// only used for privifying mov_from_ar
   4.267 +		// FIXME: Also use for mov_to/from_ar.cflag (I26/I27) (IA32 only)
   4.268 +		if (inst.generic.major != 0) break;
   4.269 +		if (inst.I28.x6 == 0x32 && !inst.I28.x3 && inst.I28.ar3 < 8) {
   4.270 +			// mov r1=kr -> mov kr=r1+64
   4.271 +			verbose("privify_inst: privified mov r1=kr @%p\n",bp);
   4.272 +			if (inst.I28.r1 >= 64) *msg = "mov r1=kr w/r1>63";
   4.273 +			else privify_mov_from_kr_i(inst);
   4.274 +		}
   4.275 +		else if (inst.I26.x6 == 0x2a && !inst.I26.x3 &&
   4.276 +		    inst.I26.ar3 < 8)  {// mov kr=r1
   4.277 +			if (inst.I26.r2 >= 64) *msg = "mov kr=r2 w/r2>63";
   4.278 +		}
   4.279 +		break;
   4.280 +	    case F: case L: case ILLEGAL:
   4.281 +		break;
   4.282 +	}
   4.283 +	return *(IA64_INST *)&inst;
   4.284 +}
   4.285 +
   4.286 +#define read_slot1(b)	    (((b.i64[0]>>46L) | (b.i64[1]<<18UL)) & MASK_41)
   4.287 +// Not sure why, but this more obvious definition of read_slot1 doesn't work
   4.288 +// because the compiler treats (b.slot1b<<18UL) as a signed 32-bit integer
   4.289 +// so not enough bits get used and it gets sign extended to boot!
   4.290 +//#define read_slot1(b)	    ((b.slot1a | (b.slot1b<<18UL)) & MASK_41)
   4.291 +#define write_slot1(b,inst) do { b.slot1a=inst;b.slot1b=inst>>18UL;} while (0)
   4.292 +
   4.293 +
   4.294 +void privify_memory(void *start, unsigned long len)
   4.295 +{
   4.296 +	IA64_BUNDLE bundle, *bp = (IA64_BUNDLE *)start;
   4.297 +	IA64_INST tmp;
   4.298 +	char *msg;
   4.299 +
   4.300 +printf("privifying %ld bytes of memory at %p\n",len,start);
   4.301 +	if ((unsigned long)start & 0xfL) {
   4.302 +		printf("unaligned memory block in privify_memory\n");
   4.303 +	}
   4.304 +	len &= ~0xf;
   4.305 +	for (bundle = *bp; len; len -= 16) {
   4.306 +	    switch(bundle.template) {
   4.307 +		case 0x06: case 0x07: case 0x14: case 0x15:
   4.308 +		case 0x1a: case 0x1b: case 0x1e: case 0x1f:
   4.309 +			break;
   4.310 +		case 0x16: case 0x17:
   4.311 +			// may be B in slot0/1 but cover can only be slot2
   4.312 +			bundle.slot2 = privify_inst(bundle.slot2,B,bp,&msg);
   4.313 +			break;
   4.314 +		case 0x00: case 0x01: case 0x02: case 0x03:
   4.315 +			tmp = privify_inst(read_slot1(bundle),I,bp,&msg);
   4.316 +			write_slot1(bundle,tmp);
   4.317 +		case 0x0c: case 0x0d:
   4.318 +			bundle.slot2 = privify_inst(bundle.slot2,I,bp,&msg);
   4.319 +		case 0x04: case 0x05:
   4.320 +			// could a privified cover be in slot2 here?
   4.321 +			bundle.slot0 = privify_inst(bundle.slot0,M,bp,&msg);
   4.322 +			break;
   4.323 +		case 0x08: case 0x09: case 0x0a: case 0x0b:
   4.324 +			bundle.slot2 = privify_inst(bundle.slot2,I,bp,&msg);
   4.325 +		case 0x0e: case 0x0f:
   4.326 +			bundle.slot0 = privify_inst(bundle.slot0,M,bp,&msg);
   4.327 +			if (msg) break;
   4.328 +			tmp = privify_inst(read_slot1(bundle),M,bp,&msg);
   4.329 +			write_slot1(bundle,tmp);
   4.330 +			break;
   4.331 +		case 0x10: case 0x11:
   4.332 +			tmp = privify_inst(read_slot1(bundle),I,bp,&msg);
   4.333 +			write_slot1(bundle,tmp);
   4.334 +		case 0x12: case 0x13:
   4.335 +			// may be B in slot1 but cover can only be slot2
   4.336 +		case 0x1c: case 0x1d:
   4.337 +			bundle.slot0 = privify_inst(bundle.slot0,M,bp,&msg);
   4.338 +			if (msg) break;
   4.339 +			bundle.slot2 = privify_inst(bundle.slot2,B,bp,&msg);
   4.340 +			break;
   4.341 +		case 0x18: case 0x19:
   4.342 +			bundle.slot0 = privify_inst(bundle.slot0,M,bp,&msg);
   4.343 +			if (msg) break;
   4.344 +			tmp = privify_inst(read_slot1(bundle),M,bp,&msg);
   4.345 +			write_slot1(bundle,tmp);
   4.346 +			if (msg) break;
   4.347 +			bundle.slot2 = privify_inst(bundle.slot2,B,bp,&msg);
   4.348 +			break;
   4.349 +	    }
   4.350 +	    if (msg) {
   4.351 +		if (bundle.slot2)
   4.352 +			printf("privify_memory: %s @%p\n",msg,bp);
   4.353 +		else
   4.354 +			printf("privify_memory: %s @%p probably not insts\n",
   4.355 +				msg,bp);
   4.356 +		printf("privify_memory: bundle=%p,%p\n",
   4.357 +			bundle.i64[1],bundle.i64[0]);
   4.358 +	    }
   4.359 +	    *bp = bundle;
   4.360 +	    bundle = *++bp;
   4.361 +	}
   4.362 +
   4.363 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/arch/ia64/tools/privify/privify.h	Tue Apr 05 15:24:53 2005 +0000
     5.3 @@ -0,0 +1,34 @@
     5.4 +/*
     5.5 + * Binary translate privilege-sensitive ops to privileged
     5.6 + *
     5.7 + * Copyright (C) 2004 Hewlett-Packard Co.
     5.8 + *      Dan Magenheimer (dan.magenheimer@hp.com)
     5.9 + *
    5.10 + */
    5.11 +
    5.12 +/*
    5.13 + * Macros to replace privilege-sensitive instructions (and reads from
    5.14 + * write-trapping registers) with privileged/trapping instructions as follows:
    5.15 + *	mov rx=ar.cflg -> mov ar.cflg=r(x+64) [**]
    5.16 + *	mov rx=ar.ky -> mov ar.ky=r(x+64)
    5.17 + *	fc rx -> ptc r(x+64)
    5.18 + *	thash rx=ry -> tak rx=r(y+64)
    5.19 + *	ttag rx=ry -> tpa rx=r(y+64)
    5.20 + *	mov rx=cpuid[ry] -> mov r(x+64)=rr[ry]
    5.21 + *	mov rx=pmd[ry] -> mov r(x+64)=pmc[ry] [**]
    5.22 + *	cover -> break.b 0x1fffff
    5.23 + *  [**] not implemented yet
    5.24 + */
    5.25 +
    5.26 +#define notimpl(s) printk(s##" not implemented");
    5.27 +#define privify_mov_from_cflg_m(i) do { notimpl("mov from ar.cflg"); } while(0)
    5.28 +#define privify_mov_from_cflg_i(i) do { notimpl("mov from ar.cflg"); } while(0)
    5.29 +#define privify_mov_from_kr_m(i) do { i.M31.x6 = 0x2a; i.M29.r2 = i.M31.r1 + 64; } while(0)
    5.30 +#define privify_mov_from_kr_i(i) do { i.I28.x6 = 0x2a; i.I26.r2 = i.I28.r1 + 64; } while(0)
    5.31 +#define privify_fc(i) do { i.M28.x6 = 0x34; i.M28.r3 = i.M28.r3 + 64; } while(0)
    5.32 +#define privify_thash(i) do { i.M46.x6 = 0x1f; i.M46.r3 += 64; } while(0)
    5.33 +#define privify_ttag(i) do { i.M46.x6 = 0x1f; i.M46.r3 += 64; } while(0)
    5.34 +#define privify_mov_from_cpuid(i) do { i.M43.x6 = 0x10; i.M43.r1 += 64; } while(0)
    5.35 +#define privify_mov_from_pmd(i) do { notimpl("mov from pmd"); } while(0)
    5.36 +#define privify_cover(x) do { x.B8.x6 = 0x0; x.B9.imm20 = 0xfffff; x.B9.i = 0x1; } while(0)
    5.37 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/arch/ia64/tools/privify/privify_elf64.c	Tue Apr 05 15:24:53 2005 +0000
     6.3 @@ -0,0 +1,120 @@
     6.4 +/*
     6.5 + * Binary translate privilege-sensitive ops to privileged
     6.6 + *
     6.7 + * Copyright (C) 2004 Hewlett-Packard Co.
     6.8 + *      Dan Magenheimer (dan.magenheimer@hp.com)
     6.9 + *
    6.10 + */
    6.11 +
    6.12 +#include <fcntl.h>
    6.13 +#include <stdio.h>
    6.14 +#include <stdlib.h>
    6.15 +#define ELFSIZE 64
    6.16 +#include <linux/elf.h>
    6.17 +
    6.18 +#define MAX_FILSIZ (32*1024*1024)
    6.19 +unsigned long buf[MAX_FILSIZ/sizeof(unsigned long)];
    6.20 +
    6.21 +static void
    6.22 +usage (FILE *fp)
    6.23 +{
    6.24 +	fprintf(fp, "Usage: privify elf64filein elf64fileout\n");
    6.25 +}
    6.26 +
    6.27 +static void
    6.28 +panic (char *s)
    6.29 +{
    6.30 +	fprintf(stderr, "panic: %s\n",s);
    6.31 +	exit(1);
    6.32 +}
    6.33 +
    6.34 +static int
    6.35 +read_file(const char *in_path, char *buf, int maxsize)
    6.36 +{
    6.37 +	ssize_t nread, totread = 0, ssize_inc = 8192;
    6.38 +	int from;
    6.39 +
    6.40 +	if ((from = open (in_path, O_RDONLY)) < 0) return -1;
    6.41 +	maxsize -= ssize_inc; // create safety zone
    6.42 +	if (maxsize < 0) panic("input file exceeds max size");
    6.43 +	while ((nread = read(from, buf, ssize_inc)) > 0) {
    6.44 +		if (nread < 0) return -1; // problem
    6.45 +		totread += nread;
    6.46 +		if (nread < ssize_inc) return totread; // done
    6.47 +		buf += ssize_inc;
    6.48 +		if (totread > maxsize) // buffer too small
    6.49 +			panic("file exceeds max size\n");
    6.50 +	}
    6.51 +	return totread;
    6.52 +}
    6.53 +
    6.54 +static int
    6.55 +write_file(const char *out_path, char *buf, int size)
    6.56 +{
    6.57 +	int to;
    6.58 +
    6.59 +	if ((to = open(out_path, O_WRONLY|O_CREAT|O_EXCL,0644)) < 0)
    6.60 +		return -1;
    6.61 +
    6.62 +	if (write(to,buf,size) < 0) return -1;
    6.63 +
    6.64 +	return 0;
    6.65 +}
    6.66 +
    6.67 +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
    6.68 +                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
    6.69 +                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
    6.70 +                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)
    6.71 +
    6.72 +
    6.73 +static void
    6.74 +privify_elf(char *elfbase)
    6.75 +{
    6.76 +	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)elfbase;
    6.77 +	Elf64_Phdr *phdr;
    6.78 +	Elf64_Shdr *shdr;
    6.79 +	char *elfaddr;
    6.80 +	unsigned long size;
    6.81 +	int h;
    6.82 +
    6.83 +	if ( !IS_ELF(*ehdr) )
    6.84 +		panic("Kernel image does not have an ELF header.\n");
    6.85 +	for ( h = 0; h < ehdr->e_phnum; h++ ) {
    6.86 +		phdr = (Elf64_Phdr *)(elfbase +
    6.87 +			ehdr->e_phoff + (h*ehdr->e_phentsize));
    6.88 +		printf("h=%d, phdr=%p,phdr->p_type=%lx",h,phdr,phdr->p_type);
    6.89 +		if ((phdr->p_type != PT_LOAD)) {
    6.90 +			printf("\n");
    6.91 +			continue;
    6.92 +		}
    6.93 +		size = phdr->p_filesz;
    6.94 +		elfaddr = elfbase + phdr->p_offset;
    6.95 +		printf(",elfaddr=%p,size=%d,phdr->p_flags=%lx\n",
    6.96 +			elfaddr,size,phdr->p_flags);
    6.97 +		if (phdr->p_flags & PF_X) privify_memory(elfaddr,size);
    6.98 +    	}
    6.99 +}
   6.100 +
   6.101 +int
   6.102 +main(int argc, char **argv)
   6.103 +{
   6.104 +	char *in_path, *out_path;
   6.105 +	int fsize;
   6.106 +
   6.107 +	if (argc != 3) {
   6.108 +		usage(stdout);
   6.109 +		exit(1);
   6.110 +	}
   6.111 +	in_path = argv[1];
   6.112 +	out_path = argv[2];
   6.113 +	if ((fsize = read_file(in_path,(char *)buf,MAX_FILSIZ)) < 0) {
   6.114 +		perror("read_file");
   6.115 +		panic("failed");
   6.116 +	}
   6.117 +	privify_elf((char *)buf);
   6.118 +	fflush(stdout);
   6.119 +	if (write_file(out_path,(char *)buf,fsize) < 0) {
   6.120 +		perror("write_file");
   6.121 +		panic("failed");
   6.122 +	}
   6.123 +}