debuggers.hg

changeset 646:9339f3942f4e

bitkeeper revision 1.339.1.1 (3f108aff8cNSEyxZFIWHZ-zZtSTT2w)

Many files:
new file
Clean up dom0 proc interfaces. Implemented ioremap and /dev/mem.
.del-dom0_block.c~63815c1974691c1c:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c
.del-sched_ops.c~20807e5c2ed6b51:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c
.del-xi_list~49abab167156959:
Delete: tools/internal/xi_list
.del-xl_physdisk_proc.c~49451bc26a40fcb2:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c
.del-mmu.h~6bc56547519b6f96:
Delete: xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h
.del-dom0.h~6fb656bb4a0c52e1:
Delete: xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h
.del-dom0_ops.h~fb19960d77217740:
Delete: tools/internal/dom0_ops.h
.del-dom0_ops.h~5c52b016e619bd2d:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h
.del-dom0_memory.c~c72c6e5f7fd65d38:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c
.del-direct_map.c~d2fedc686b334f2a:
Delete: xenolinux-2.4.21-sparse/arch/xeno/mm/direct_map.c
direct_map.c:
Rename: xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c -> xenolinux-2.4.21-sparse/arch/xeno/mm/direct_map.c
author kaf24@scramble.cl.cam.ac.uk
date Sat Jul 12 22:26:07 2003 +0000 (2003-07-12)
parents 5e169da77286
children f36f032527a0
files .rootkeys tools/control/src/org/xenoserver/control/CommandVbdCreate.java tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java tools/control/src/org/xenoserver/control/CommandVbdList.java tools/internal/Makefile tools/internal/dom0_defs.h tools/internal/dom0_ops.h tools/internal/mem_defs.h tools/internal/xi_build.c tools/internal/xi_create.c tools/internal/xi_destroy.c tools/internal/xi_list tools/internal/xi_list.c tools/internal/xi_phys_grant.c tools/internal/xi_phys_probe.c tools/internal/xi_phys_revoke.c tools/internal/xi_sched_domain.c tools/internal/xi_sched_global.c tools/internal/xi_start.c tools/internal/xi_stop.c tools/internal/xi_usage.c tools/internal/xi_vifinit xen/common/dom0_ops.c xen/common/domain.c xen/common/kernel.c xen/common/network.c xen/include/hypervisor-ifs/dom0_ops.h xen/include/hypervisor-ifs/network.h xen/include/xeno/sched.h xenolinux-2.4.21-sparse/arch/xeno/Makefile xenolinux-2.4.21-sparse/arch/xeno/config.in xenolinux-2.4.21-sparse/arch/xeno/defconfig xenolinux-2.4.21-sparse/arch/xeno/drivers/block/Makefile xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.h xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/Makefile xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/vfr.c xenolinux-2.4.21-sparse/arch/xeno/kernel/process.c xenolinux-2.4.21-sparse/arch/xeno/mm/Makefile xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c xenolinux-2.4.21-sparse/drivers/char/mem.c xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h xenolinux-2.4.21-sparse/include/asm-xeno/hypervisor.h xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h xenolinux-2.4.21-sparse/include/asm-xeno/mmu_context.h xenolinux-2.4.21-sparse/include/asm-xeno/multicall.h xenolinux-2.4.21-sparse/include/asm-xeno/pgalloc.h xenolinux-2.4.21-sparse/include/asm-xeno/pgtable.h xenolinux-2.4.21-sparse/include/asm-xeno/proc_cmd.h xenolinux-2.4.21-sparse/include/asm-xeno/segment.h xenolinux-2.4.21-sparse/mkbuildtree xenolinux-2.4.21-sparse/mm/memory.c xenolinux-2.4.21-sparse/mm/mprotect.c xenolinux-2.4.21-sparse/mm/mremap.c xenolinux-2.4.21-sparse/mm/vmalloc.c
line diff
     1.1 --- a/.rootkeys	Thu Jul 10 13:42:56 2003 +0000
     1.2 +++ b/.rootkeys	Sat Jul 12 22:26:07 2003 +0000
     1.3 @@ -122,19 +122,21 @@ 3eb781fc6vgq5yhkJRGDLY9gWWRY2A tools/con
     1.4  3eb781fcabCKRogwxJA3-jJKstw9Vg tools/control/xenctl.xml
     1.5  3eb781fdl4lXWYZzmqDDUAYhAThRqQ tools/internal/Makefile
     1.6  3eb781fdc539MQQm47rYRCCR3N5i-Q tools/internal/dom0_defs.h
     1.7 -3ee609b3Yr4aggmLSKmhiIzT8-nURA tools/internal/dom0_ops.h
     1.8  3eb781fdKiQbgozBsgs_zzJQ9ubehw tools/internal/mem_defs.h
     1.9  3ec61e1bJCeJJu0SsptmDpA1xKvwvw tools/internal/rpm.spec
    1.10  3eb781fdgbSkh2O6JQS-65Dz4n0ItQ tools/internal/xi_build.c
    1.11  3eb781fdW1SAyiaC4mTsXq_9fRHh-A tools/internal/xi_create.c
    1.12  3eb781fdcJ0fF7rWfzAOArW-x4-gwA tools/internal/xi_destroy.c
    1.13  3ec43c5dmQxGDvgJJXbV1yLxT30Y1A tools/internal/xi_helper
    1.14 -3eb83c3bZeECmphOKOJxSu4Lo1LpBw tools/internal/xi_list
    1.15 +3f108ad5wQm0ZaQ4GXFoUhH1W1aW9w tools/internal/xi_list.c
    1.16  3f0458aaXhD8BQAggO81gv30RQ-ifA tools/internal/xi_phys_grant.c
    1.17  3f0458aaJHmlzkDwf0qxEzAcjX55sg tools/internal/xi_phys_probe.c
    1.18  3f0458aaVAbFSwptQbQAnDOiZlwQ3w tools/internal/xi_phys_revoke.c
    1.19 +3f108adb2b5OkKL6-faG3lMiOYDf_w tools/internal/xi_sched_domain.c
    1.20 +3f108ade1v8weyh1sKx890VTd240Hw tools/internal/xi_sched_global.c
    1.21  3eb781fd8oRfPgH7qTh7xvgmwD6NgA tools/internal/xi_start.c
    1.22  3eb781fd0Eo9K1jEFCSAVzO51i_ngg tools/internal/xi_stop.c
    1.23 +3f108ae2to5nHRRXfvUK7oxgjcW_yA tools/internal/xi_usage.c
    1.24  3eb781fd7211MZsLxJSiuy7W4KnJXg tools/internal/xi_vifinit
    1.25  3ddb79bcbOVHh38VJzc97-JEGD4dJQ xen/Makefile
    1.26  3ddb79bcCa2VbsMp7mWKlhgwLQUQGA xen/README
    1.27 @@ -516,18 +518,13 @@ 3e5a4e65iHEuC5sjFhj42XALYbLVRw xenolinux
    1.28  3e5a4e65pP5spJErBW69pJxSSdK9RA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c
    1.29  3e67f822FOPwqHiaRKbrskgWgoNL5g xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.h
    1.30  3e677190SjkzJIvFifRVeYpIZOCtYA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_ide.c
    1.31 -3f045897EIYU5l5jxFBpeF1Z0ZOTwA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c
    1.32  3e677193nOKKTLJzcAu4SYdbZaia8g xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_scsi.c
    1.33  3e676eb5RXnHzSHgA1BvM0B1aIm4qg xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment.c
    1.34  3e5d129aDldt6geU2-2SzBae34sQzg xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c
    1.35  3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ xenolinux-2.4.21-sparse/arch/xeno/drivers/console/Makefile
    1.36  3e5a4e651TH-SXHoufurnWjgl5bfOA xenolinux-2.4.21-sparse/arch/xeno/drivers/console/console.c
    1.37  3e5a4e656nfFISThfbyXQOA6HN6YHw xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/Makefile
    1.38 -3e5a4e65Cc7io-vynYob10SlqXTjAQ xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c
    1.39  3e5a4e65BXtftInNHUC2PjDfPhdZZA xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c
    1.40 -3e5a4e65uXAx05p6B1-HU2tijuw8qA xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c
    1.41 -3e5a4e65EOOLlPwXnhSuX-iVdWLmnA xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h
    1.42 -3e6dba59C8o0kBks7UZ4IW_FY853Aw xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c
    1.43  3e5a4e65gfn_ltB8ujHMVFApnTTNRQ xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/vfr.c
    1.44  3e5a4e65gZBRBB6RsSVg1c9iahigAw xenolinux-2.4.21-sparse/arch/xeno/drivers/network/Makefile
    1.45  3e5a4e65ZxKrbFetVB84JhrTyZ1YuQ xenolinux-2.4.21-sparse/arch/xeno/drivers/network/network.c
    1.46 @@ -548,13 +545,13 @@ 3e5a4e66-9_NczrVMbuQkoSLyXckIw xenolinux
    1.47  3e5a4e6637ZDk0BvFEC-aFQs599-ng xenolinux-2.4.21-sparse/arch/xeno/lib/delay.c
    1.48  3e5a4e66croVgpcJyJuF2ycQw0HuJw xenolinux-2.4.21-sparse/arch/xeno/mm/Makefile
    1.49  3e5a4e66l8Q5Tv-6B3lQIRmaVbFPzg xenolinux-2.4.21-sparse/arch/xeno/mm/fault.c
    1.50 -3e5a4e66TyNNUEXkr5RxqvQhXK1MQA xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c
    1.51  3e5a4e668SE9rixq4ahho9rNhLUUFQ xenolinux-2.4.21-sparse/arch/xeno/mm/hypervisor.c
    1.52  3e5a4e661gLzzff25pJooKIIWe7IWg xenolinux-2.4.21-sparse/arch/xeno/mm/init.c
    1.53  3f0bed43UUdQichXAiVNrjV-y2Kzcg xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c
    1.54  3e5a4e66qRlSTcjafidMB6ulECADvg xenolinux-2.4.21-sparse/arch/xeno/vmlinux.lds
    1.55  3ea53c6em6uzVHSiGqrbbAVofyRY_g xenolinux-2.4.21-sparse/drivers/block/genhd.c
    1.56  3e5a4e66mrtlmV75L1tjKDg8RaM5gA xenolinux-2.4.21-sparse/drivers/block/ll_rw_blk.c
    1.57 +3f108aeaLcGDgQdFAANLTUEid0a05w xenolinux-2.4.21-sparse/drivers/char/mem.c
    1.58  3e5a4e66rw65CxyolW9PKz4GG42RcA xenolinux-2.4.21-sparse/drivers/char/tty_io.c
    1.59  3e5a4e669uzIE54VwucPYtGwXLAbzA xenolinux-2.4.21-sparse/fs/exec.c
    1.60  3f05a939l8s0eQb_fpMvYiI06cTGlA xenolinux-2.4.21-sparse/fs/partitions/Config.in
    1.61 @@ -564,20 +561,19 @@ 3f05a939ZSKN7gX2sfTLzPcYJvPkcQ xenolinux
    1.62  3f05a939_I9vPADPgyVBwUDUxtoeOQ xenolinux-2.4.21-sparse/fs/partitions/xeno.h
    1.63  3e5a4e66wbeCpsJgVf_U8Jde-CNcsA xenolinux-2.4.21-sparse/include/asm-xeno/bugs.h
    1.64  3e5a4e66HdSkvIV6SJ1evG_xmTmXHA xenolinux-2.4.21-sparse/include/asm-xeno/desc.h
    1.65 -3f0c3721E5WAnbeoPp7PE35J_Ndxaw xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h
    1.66  3e5a4e66SYp_UpAVcF8Lc1wa3Qtgzw xenolinux-2.4.21-sparse/include/asm-xeno/fixmap.h
    1.67  3e5a4e67w_DWgjIJ17Tlossu1LGujQ xenolinux-2.4.21-sparse/include/asm-xeno/highmem.h
    1.68  3e5a4e67YtcyDLQsShhCfQwPSELfvA xenolinux-2.4.21-sparse/include/asm-xeno/hw_irq.h
    1.69  3e5a4e677VBavzM1UZIEcH1B-RlXMA xenolinux-2.4.21-sparse/include/asm-xeno/hypervisor.h
    1.70  3e5a4e673p7PEOyHFm3nHkYX6HQYBg xenolinux-2.4.21-sparse/include/asm-xeno/irq.h
    1.71  3ead095db_LRUXnxaqs0dA1DWhPoQQ xenolinux-2.4.21-sparse/include/asm-xeno/keyboard.h
    1.72 -3e5a4e67zoNch27qYhEBpr2k6SABOg xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h
    1.73  3e5a4e678ddsQOpbSiRdy1GRcDc9WA xenolinux-2.4.21-sparse/include/asm-xeno/mmu_context.h
    1.74  3e7270deQqtGPSnFxcW4AvJZuTUWfg xenolinux-2.4.21-sparse/include/asm-xeno/multicall.h
    1.75  3e5a4e67mnQfh-R8KcQCaVo2Oho6yg xenolinux-2.4.21-sparse/include/asm-xeno/page.h
    1.76  3e5a4e67uTYU5oEnIDjxuaez8njjqg xenolinux-2.4.21-sparse/include/asm-xeno/pgalloc.h
    1.77  3e5a4e67X7JyupgdYkgDX19Huj2sAw xenolinux-2.4.21-sparse/include/asm-xeno/pgtable-2level.h
    1.78  3e5a4e67gr4NLGtQ5CvSLimMYZlkOA xenolinux-2.4.21-sparse/include/asm-xeno/pgtable.h
    1.79 +3f108af1qNv8DVSGPv4zpqIU1txCkg xenolinux-2.4.21-sparse/include/asm-xeno/proc_cmd.h
    1.80  3e5a4e676uK4xErTBDH6XJREn9LSyg xenolinux-2.4.21-sparse/include/asm-xeno/processor.h
    1.81  3e5a4e67AJPjW-zL7p-xWuA6IVeH1g xenolinux-2.4.21-sparse/include/asm-xeno/ptrace.h
    1.82  3e5a4e68uJz-xI0IBVMD7xRLQKJDFg xenolinux-2.4.21-sparse/include/asm-xeno/segment.h
    1.83 @@ -591,5 +587,7 @@ 3e5a4e68TJJavrunYwTAnLRSBxSYqQ xenolinux
    1.84  3eba8f878XjouY21EkQBXwYBsPsipQ xenolinux-2.4.21-sparse/lndir-rel
    1.85  3e6e7c1efbQe93xCvOpOVCnXTMmQ5w xenolinux-2.4.21-sparse/mkbuildtree
    1.86  3e5a4e68GxCIaFH4sy01v1wjapetaA xenolinux-2.4.21-sparse/mm/memory.c
    1.87 +3f108af5VxPkLv13tXpXgoRKALQtXQ xenolinux-2.4.21-sparse/mm/mprotect.c
    1.88  3e5a4e681xMPdF9xCMwpyfuYMySU5g xenolinux-2.4.21-sparse/mm/mremap.c
    1.89  3e5a4e683HKVU-sxtagrDasRB8eBVw xenolinux-2.4.21-sparse/mm/swapfile.c
    1.90 +3f108af81Thhb242EmKjGCYkjx-GJA xenolinux-2.4.21-sparse/mm/vmalloc.c
     2.1 --- a/tools/control/src/org/xenoserver/control/CommandVbdCreate.java	Thu Jul 10 13:42:56 2003 +0000
     2.2 +++ b/tools/control/src/org/xenoserver/control/CommandVbdCreate.java	Sat Jul 12 22:26:07 2003 +0000
     2.3 @@ -53,12 +53,12 @@ public class CommandVbdCreate extends Co
     2.4          String command = vd.dumpForXen(vbd);
     2.5  
     2.6          try {
     2.7 -            FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd");
     2.8 +            FileWriter fw = new FileWriter("/proc/xeno/vhd");
     2.9              fw.write(command);
    2.10              fw.flush();
    2.11              fw.close();
    2.12          } catch (IOException e) {
    2.13 -            throw new CommandFailedException("Could not write VBD details to /proc/xeno/dom0/vhd", e);
    2.14 +            throw new CommandFailedException("Could not write VBD details to /proc/xeno/vhd", e);
    2.15          }
    2.16  
    2.17          return "Created virtual block device "
     3.1 --- a/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java	Thu Jul 10 13:42:56 2003 +0000
     3.2 +++ b/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java	Sat Jul 12 22:26:07 2003 +0000
     3.3 @@ -53,13 +53,13 @@ public class CommandVbdCreatePhysical ex
     3.4          String command = vd.dumpForXen(vbd);
     3.5  
     3.6          try {
     3.7 -            FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd");
     3.8 +            FileWriter fw = new FileWriter("/proc/xeno/vhd");
     3.9              fw.write(command);
    3.10              fw.flush();
    3.11              fw.close();
    3.12          } catch (IOException e) {
    3.13              throw new CommandFailedException(
    3.14 -                "Could not write VBD details to /proc/xeno/dom0/vhd",
    3.15 +                "Could not write VBD details to /proc/xeno/vhd",
    3.16                  e);
    3.17          }
    3.18  
     4.1 --- a/tools/control/src/org/xenoserver/control/CommandVbdList.java	Thu Jul 10 13:42:56 2003 +0000
     4.2 +++ b/tools/control/src/org/xenoserver/control/CommandVbdList.java	Sat Jul 12 22:26:07 2003 +0000
     4.3 @@ -16,7 +16,7 @@ public class CommandVbdList extends Comm
     4.4          String line;
     4.5  
     4.6          try {
     4.7 -            in = new BufferedReader(new FileReader("/proc/xeno/dom0/vhd"));
     4.8 +            in = new BufferedReader(new FileReader("/proc/xeno/vhd"));
     4.9              line = in.readLine();
    4.10              while (line != null) {
    4.11                  int domain = -1;
     5.1 --- a/tools/internal/Makefile	Thu Jul 10 13:42:56 2003 +0000
     5.2 +++ b/tools/internal/Makefile	Sat Jul 12 22:26:07 2003 +0000
     5.3 @@ -1,55 +1,27 @@
     5.4 -CC = gcc
     5.5 -CFLAGS = -Wall -I../../xen/include -I../../xenolinux-2.4.21-sparse/include
     5.6 -XI_CREATE = xi_create
     5.7 -XI_START = xi_start
     5.8 -XI_STOP = xi_stop
     5.9 -XI_DESTROY = xi_destroy
    5.10 -XI_BUILD = xi_build
    5.11 -XI_PHYS_GRANT = xi_phys_grant
    5.12 -XI_PHYS_REVOKE = xi_phys_revoke
    5.13 -XI_PHYS_PROBE = xi_phys_probe
    5.14  
    5.15 -all: $(XI_CREATE).o $(XI_START).o $(XI_STOP).o $(XI_DESTROY).o $(XI_BUILD).o \
    5.16 -	$(XI_PHYS_GRANT).o $(XI_PHYS_REVOKE).o $(XI_PHYS_PROBE).o
    5.17 -	$(CC) -o $(XI_CREATE) $(XI_CREATE).o
    5.18 -	$(CC) -o $(XI_BUILD) $(XI_BUILD).o
    5.19 -	$(CC) -o $(XI_START) $(XI_START).o
    5.20 -	$(CC) -o $(XI_STOP) $(XI_STOP).o
    5.21 -	$(CC) -o $(XI_DESTROY) $(XI_DESTROY).o
    5.22 -	$(CC) -o $(XI_PHYS_GRANT) $(XI_PHYS_GRANT).o
    5.23 -	$(CC) -o $(XI_PHYS_REVOKE) $(XI_PHYS_REVOKE).o
    5.24 -	$(CC) -o $(XI_PHYS_PROBE) $(XI_PHYS_PROBE).o
    5.25 +CC       = gcc
    5.26 +CFLAGS   = -Wall -O3 
    5.27 +CFLAGS  += -I../../xen/include -I../../xenolinux-2.4.21-sparse/include
    5.28  
    5.29 -$(XI_CREATE).o: $(XI_CREATE).c dom0_defs.h dom0_ops.h mem_defs.h
    5.30 -	$(CC) $(CFLAGS) -c $(XI_CREATE).c 
    5.31 -
    5.32 -internal_domain_build.o: internal_domain_build.c dom0_defs.h dom0_ops.h mem_defs.h
    5.33 -	$(CC) $(CFLAGS) -c internal_domain_build.c 
    5.34 -
    5.35 -$(XI_START).o: $(XI_START).c dom0_defs.h dom0_ops.h mem_defs.h
    5.36 -	$(CC) $(CFLAGS) -c $(XI_START).c 
    5.37 -
    5.38 -$(XI_STOP).o: $(XI_STOP).c dom0_defs.h dom0_ops.h mem_defs.h
    5.39 -	$(CC) $(CFLAGS) -c $(XI_STOP).c 
    5.40 +HDRS     = $(wildcard *.h)
    5.41 +SRCS     = $(wildcard *.c)
    5.42 +OBJS     = $(patsubst %.c,%.o,$(SRCS))
    5.43  
    5.44 -$(XI_DESTROY).o: $(XI_DESTROY).c dom0_ops.h dom0_defs.h
    5.45 -	$(CC) $(CFLAGS) -c $(XI_DESTROY).c 
    5.46 -
    5.47 -$(XI_PHYS_GRANT).o: $(XI_PHYS_GRANT).c 
    5.48 -	$(CC) $(CFLAGS) -c $(XI_PHYS_GRANT).c 
    5.49 +TARGETS  = xi_create xi_start xi_stop xi_destroy xi_build 
    5.50 +TARGETS += xi_phys_grant xi_phys_revoke xi_phys_probe xi_list 
    5.51 +TARGETS += xi_sched_global xi_sched_domain xi_usage
    5.52 +INSTALL  = $(TARGETS) xi_vifinit xi_helper
    5.53  
    5.54 -$(XI_PHYS_REVOKE).o: $(XI_PHYS_REVOKE).c
    5.55 -	$(CC) $(CFLAGS) -c $(XI_PHYS_REVOKE).c 
    5.56 -
    5.57 -$(XI_PHYS_PROBE).o: $(XI_PHYS_PROBE).c
    5.58 -	$(CC) $(CFLAGS) -c $(XI_PHYS_PROBE).c 
    5.59 +all: $(TARGETS)
    5.60  
    5.61  install: all
    5.62 -	cp -a xi_list xi_vifinit xi_helper $(XI_CREATE) $(XI_BUILD) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_PHYSDEV_GRANT) $(XI_PHYS_REVOKE) $(XI_PHYS_PROBE).o../../../install/bin
    5.63 -	chmod 755 ../../../install/bin/xi_list
    5.64 +	cp -a $(INSTALL) ../../../install/bin
    5.65  	chmod 755 ../../../install/bin/xi_vifinit
    5.66  	chmod 755 ../../../install/bin/xi_helper
    5.67  
    5.68 +clean:
    5.69 +	$(RM) *.o *.rpm $(TARGETS)
    5.70 +
    5.71  rpm: all
    5.72  	rm -rf staging
    5.73  	mkdir staging
    5.74 @@ -58,6 +30,6 @@ rpm: all
    5.75  	mv staging/i386/*.rpm .
    5.76  	rm -rf staging
    5.77  
    5.78 -clean:
    5.79 -	$(RM) *.o *.rpm $(XI_CREATE) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_BUILD) $(XI_PHYS_GRANT) $(XI_PHYS_REVOKE) $(XI_PHYS_PROBE)
    5.80 +%: %.c $(HDRS) Makefile
    5.81 +	$(CC) $(CFLAGS) -o $@ $<
    5.82  
     6.1 --- a/tools/internal/dom0_defs.h	Thu Jul 10 13:42:56 2003 +0000
     6.2 +++ b/tools/internal/dom0_defs.h	Sat Jul 12 22:26:07 2003 +0000
     6.3 @@ -1,9 +1,121 @@
     6.4 -#define PROC_XENO_ROOT  "xeno"
     6.5 -#define PROC_CMD        "dom0_cmd"
     6.6 -#define PROC_DOM_PREFIX "dom"
     6.7 -#define PROC_DOM_MEM    "mem"
     6.8 -#define PROC_DOM_DATA   "new_dom_data"
     6.9 -#define PROC_DOMAINS    "domains"
    6.10 +
    6.11 +#ifndef __DOM0_DEFS_H__
    6.12 +#define __DOM0_DEFS_H__
    6.13 +
    6.14 +#include <unistd.h>
    6.15 +#include <stdio.h>
    6.16 +#include <errno.h>
    6.17 +#include <fcntl.h>
    6.18 +#include <sys/mman.h>
    6.19 +#include <sys/types.h>
    6.20 +#include <sys/stat.h>
    6.21 +#include <stdlib.h>
    6.22 +#include <sys/ioctl.h>
    6.23 +#include <errno.h>
    6.24 +#include <string.h>
    6.25 +
    6.26 +#include <asm/types.h>
    6.27 +
    6.28 +#include "mem_defs.h"
    6.29 +#include <asm-xeno/proc_cmd.h>
    6.30 +#include <hypervisor-ifs/hypervisor-if.h>
    6.31 +#include <hypervisor-ifs/dom0_ops.h>
    6.32 +
    6.33 +#define ERROR(_m)  \
    6.34 +    fprintf(stderr, "ERROR: %s\n", (_m))
    6.35 +
    6.36 +#define PERROR(_m) \
    6.37 +    fprintf(stderr, "ERROR: %s (%d = %s)\n", (_m), errno, strerror(errno))
    6.38 +
    6.39 +static inline int do_privcmd(unsigned int cmd, unsigned long data)
    6.40 +{
    6.41 +    int fd;
    6.42 +
    6.43 +    if ( (fd = open("/proc/xeno/privcmd", O_RDWR)) < 0 )
    6.44 +    {
    6.45 +        PERROR("Could not open proc interface");
    6.46 +        return -1;
    6.47 +    }
    6.48 +
    6.49 +    if ( ioctl(fd, cmd, data) < 0 )
    6.50 +    {
    6.51 +#ifndef SILENT_ERRORS_FROM_XEN
    6.52 +        PERROR("Error when executing privileged control ioctl");
    6.53 +#endif
    6.54 +        close(fd);
    6.55 +        return -1;
    6.56 +    }
    6.57 +
    6.58 +    close(fd);
    6.59 +    return 0;
    6.60 +}
    6.61 +
    6.62 +static inline int xldev_to_physdev(int xldev)
    6.63 +{
    6.64 +    return do_privcmd(IOCTL_PRIVCMD_LINDEV_TO_XENDEV, 
    6.65 +                      (unsigned long)xldev);
    6.66 +}
    6.67  
    6.68 -#define MAX_PATH        256
    6.69 +static inline int physdev_to_xldev(int physdev)
    6.70 +{
    6.71 +    return do_privcmd(IOCTL_PRIVCMD_XENDEV_TO_LINDEV, 
    6.72 +                      (unsigned long)physdev);
    6.73 +}
    6.74 +
    6.75 +static inline int do_xen_blkmsg(privcmd_blkmsg_t *blkmsg)
    6.76 +{
    6.77 +    return do_privcmd(IOCTL_PRIVCMD_BLKMSG, (unsigned long)blkmsg);
    6.78 +}
    6.79 +
    6.80 +static inline int do_xen_hypercall(privcmd_hypercall_t *hypercall)
    6.81 +{
    6.82 +    return do_privcmd(IOCTL_PRIVCMD_HYPERCALL, (unsigned long)hypercall);
    6.83 +}
    6.84 +
    6.85 +static inline int do_dom0_op(dom0_op_t *op)
    6.86 +{
    6.87 +    int ret = -1;
    6.88 +    privcmd_hypercall_t hypercall;
    6.89 +
    6.90 +    hypercall.op     = __HYPERVISOR_dom0_op;
    6.91 +    hypercall.arg[0] = (unsigned long)op;
    6.92 +
    6.93 +    if ( mlock(op, sizeof(*op)) != 0 )
    6.94 +    {
    6.95 +        PERROR("Could not lock memory for Xen hypercall");
    6.96 +        goto out1;
    6.97 +    }
    6.98  
    6.99 +    if ( do_xen_hypercall(&hypercall) < 0 )
   6.100 +        goto out2;
   6.101 +
   6.102 +    ret = 0;
   6.103 +
   6.104 + out2: (void)munlock(op, sizeof(*op));
   6.105 + out1: return ret;
   6.106 +}
   6.107 +
   6.108 +static inline int do_network_op(network_op_t *op)
   6.109 +{
   6.110 +    int ret = -1;
   6.111 +    privcmd_hypercall_t hypercall;
   6.112 +
   6.113 +    hypercall.op     = __HYPERVISOR_network_op;
   6.114 +    hypercall.arg[0] = (unsigned long)op;
   6.115 +
   6.116 +    if ( mlock(op, sizeof(*op)) != 0 )
   6.117 +    {
   6.118 +        PERROR("Could not lock memory for Xen hypercall");
   6.119 +        goto out1;
   6.120 +    }
   6.121 +
   6.122 +    if ( do_xen_hypercall(&hypercall) < 0 )
   6.123 +        goto out2;
   6.124 +
   6.125 +    ret = 0;
   6.126 +
   6.127 + out2: (void)munlock(op, sizeof(*op));
   6.128 + out1: return ret;
   6.129 +}
   6.130 +
   6.131 +#endif /* __DOM0_DEFS_H__ */
     7.1 --- a/tools/internal/dom0_ops.h	Thu Jul 10 13:42:56 2003 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,5 +0,0 @@
     7.4 -
     7.5 -#define NO_DOM0_OP_T
     7.6 -#include "../../xen/include/hypervisor-ifs/dom0_ops.h"
     7.7 -#undef  NO_DOM0_OP_T
     7.8 -#include "../../xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h"
     8.1 --- a/tools/internal/mem_defs.h	Thu Jul 10 13:42:56 2003 +0000
     8.2 +++ b/tools/internal/mem_defs.h	Sat Jul 12 22:26:07 2003 +0000
     8.3 @@ -1,24 +1,16 @@
     8.4 -/*
     8.5 - * memory related definitions needed for userspace domain builder dom0 application. these _need_ to
     8.6 - * be kept in sync with the kernel .h files they were copied over from or something horrible will
     8.7 - * happen. remmember: god kills a kitten every time you forget to keep these in sync.
     8.8 - * 
     8.9 - * KAF: Boris, these constants are all fixed by x86 hardware. So the kittens are safe for now :-)
    8.10 - * 
    8.11 - * Copyright 2002 by B Dragovic
    8.12 - */
    8.13  
    8.14 -/* copied over from hypervisor: include/asm-i386/page.h */
    8.15 +#ifndef __MEM_DEFS_H__
    8.16 +#define __MEM_DEFS_H__
    8.17  
    8.18  #define _PAGE_PRESENT   0x001
    8.19 -#define _PAGE_RW    0x002
    8.20 -#define _PAGE_USER  0x004
    8.21 -#define _PAGE_PWT   0x008
    8.22 -#define _PAGE_PCD   0x010
    8.23 +#define _PAGE_RW        0x002
    8.24 +#define _PAGE_USER      0x004
    8.25 +#define _PAGE_PWT       0x008
    8.26 +#define _PAGE_PCD       0x010
    8.27  #define _PAGE_ACCESSED  0x020
    8.28 -#define _PAGE_DIRTY 0x040
    8.29 +#define _PAGE_DIRTY     0x040
    8.30  #define _PAGE_PAT       0x080
    8.31 -#define _PAGE_PSE   0x080
    8.32 +#define _PAGE_PSE       0x080
    8.33  #define _PAGE_GLOBAL    0x100
    8.34  
    8.35  
    8.36 @@ -40,6 +32,4 @@ typedef struct { unsigned long l2_lo; } 
    8.37  #define l2_table_offset(_a) \
    8.38            ((_a) >> L2_PAGETABLE_SHIFT)
    8.39  
    8.40 -/* local definitions */
    8.41 -
    8.42 -#define nr_2_page(x) ((x) << PAGE_SHIFT)
    8.43 +#endif /* __MEM_DEFS_H__ */
     9.1 --- a/tools/internal/xi_build.c	Thu Jul 10 13:42:56 2003 +0000
     9.2 +++ b/tools/internal/xi_build.c	Sat Jul 12 22:26:07 2003 +0000
     9.3 @@ -1,131 +1,95 @@
     9.4 -/* 
     9.5 - * XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk
     9.6 - * This code is released under terms and conditions of GNU GPL :).
     9.7 - * Usage: <executable> <mem_kb> <os image> <num_vifs> 
     9.8 - */
     9.9  
    9.10 -#include <unistd.h>
    9.11 -#include <stdio.h>
    9.12 -#include <errno.h>
    9.13 -#include <fcntl.h>
    9.14 -#include <sys/stat.h>
    9.15 -#include <sys/ioctl.h>
    9.16 -#include <string.h>
    9.17 -#include <stdlib.h>
    9.18 -
    9.19 -#include "asm-xeno/dom0.h"
    9.20 -#include "hypervisor-ifs/hypervisor-if.h"
    9.21 -#include "dom0_ops.h"
    9.22 +#include "hypervisor-ifs/dom0_ops.h"
    9.23  #include "dom0_defs.h"
    9.24  #include "mem_defs.h"
    9.25  
    9.26 -#define PERR_STRING "Xeno Domain Builder"
    9.27 -
    9.28  #define GUEST_SIG   "XenoGues"
    9.29  #define SIG_LEN    8
    9.30  
    9.31 -/* Watch for precedence when using thses ones... */
    9.32 -#define PROC_XENO_DOM0_CMD "/proc/" PROC_XENO_ROOT "/" PROC_CMD
    9.33 -#define PROC_XENO_DOMAINS "/proc" PROC_XENO_ROOT "/" PROC_DOMAINS
    9.34 -
    9.35 -/*
    9.36 - * NB. No ring-3 access in initial guestOS pagetables. Note that we allow
    9.37 - * ring-3 privileges in the page directories, so that the guestOS may later
    9.38 - * decide to share a 4MB region with applications.
    9.39 - */
    9.40  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    9.41  #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    9.42  
    9.43 -/* standardized error reporting function */
    9.44 -static void dberr(char *msg)
    9.45 +static long get_tot_pages(int domain_id)
    9.46  {
    9.47 -    printf("%s: %s\n", PERR_STRING, msg);
    9.48 -}
    9.49 -
    9.50 -/* status reporting function */
    9.51 -static void dbstatus(char * msg)
    9.52 -{
    9.53 -    printf("Domain Builder: %s\n", msg);
    9.54 +    dom0_op_t op;
    9.55 +    op.cmd = DOM0_GETDOMAININFO;
    9.56 +    op.u.getdominfo.domain = domain_id;
    9.57 +    return (do_dom0_op(&op) < 0) ? -1 : op.u.getdominfo.tot_pages;
    9.58  }
    9.59  
    9.60 -
    9.61 -/* clean up domain's memory allocations */
    9.62 -static void dom_mem_cleanup(dom_mem_t * dom_mem)
    9.63 +static int get_pfn_list(
    9.64 +    int domain_id, unsigned long *pfn_buf, unsigned long max_pfns)
    9.65  {
    9.66 -    int fd;
    9.67 -    struct dom0_unmapdommem_args argbuf;
    9.68 -	    
    9.69 -    fd = open("/proc/xeno/dom0_cmd", O_WRONLY);
    9.70 -    if(fd < 0){
    9.71 -        perror("openning /proc/xeno/dom0_cmd");
    9.72 -	return;
    9.73 -    }
    9.74 -    
    9.75 -    argbuf.vaddr = dom_mem->vaddr;
    9.76 -    argbuf.start_pfn = dom_mem->start_pfn;
    9.77 -    argbuf.tot_pages = dom_mem->tot_pages;
    9.78 +    dom0_op_t op;
    9.79 +    int ret;
    9.80 +    op.cmd = DOM0_GETMEMLIST;
    9.81 +    op.u.getmemlist.domain   = domain_id;
    9.82 +    op.u.getmemlist.max_pfns = max_pfns;
    9.83 +    op.u.getmemlist.buffer   = pfn_buf;
    9.84 +
    9.85 +    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
    9.86 +    {
    9.87 +        PERROR("Could not lock pfn list buffer");
    9.88 +        return -1;
    9.89 +    }    
    9.90 +
    9.91 +    ret = do_dom0_op(&op);
    9.92 +
    9.93 +    (void)munlock(pfn_buf, max_pfns * sizeof(unsigned long));
    9.94  
    9.95 -    if (ioctl(fd, IOCTL_DOM0_UNMAPDOMMEM, &argbuf) < 0) {
    9.96 -        dbstatus("Error unmapping domain's memory.\n");
    9.97 +    return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
    9.98 +}
    9.99 +
   9.100 +static int send_pgupdates(page_update_request_t *updates, int nr_updates)
   9.101 +{
   9.102 +    int ret = -1;
   9.103 +    privcmd_hypercall_t hypercall;
   9.104 +
   9.105 +    hypercall.op     = __HYPERVISOR_pt_update;
   9.106 +    hypercall.arg[0] = (unsigned long)updates;
   9.107 +    hypercall.arg[1] = (unsigned long)nr_updates;
   9.108 +
   9.109 +    if ( mlock(updates, nr_updates * sizeof(*updates)) != 0 )
   9.110 +    {
   9.111 +        PERROR("Could not lock pagetable update array");
   9.112 +        goto out1;
   9.113      }
   9.114  
   9.115 -    close(fd);
   9.116 +    if ( do_xen_hypercall(&hypercall) < 0 )
   9.117 +        goto out2;
   9.118 +
   9.119 +    ret = 0;
   9.120 +
   9.121 + out2: (void)munlock(updates, nr_updates * sizeof(*updates));
   9.122 + out1: return ret;
   9.123  }
   9.124  
   9.125 -static int map_dom_mem(unsigned long pfn, int pages, int dom, 
   9.126 -                       dom_mem_t * dom_mem)
   9.127 -{
   9.128 -    struct dom0_mapdommem_args argbuf;
   9.129 -    int fd;
   9.130 -
   9.131 -    argbuf.domain = dom;
   9.132 -    argbuf.start_pfn = pfn;
   9.133 -    argbuf.tot_pages = pages;
   9.134 -  
   9.135 -    fd = open("/proc/xeno/dom0_cmd", O_RDWR);
   9.136 -    if (fd < 0) {
   9.137 -        perror("openning /proc/xeno/dom0_cmd");
   9.138 -        return -1;
   9.139 -    }
   9.140 -  
   9.141 -    dom_mem->domain = dom;
   9.142 -    dom_mem->start_pfn = pfn;
   9.143 -    dom_mem->tot_pages = pages;
   9.144 -    dom_mem->vaddr = ioctl(fd, IOCTL_DOM0_MAPDOMMEM, &argbuf);
   9.145 -    
   9.146 -    if (dom_mem->vaddr == -1) {
   9.147 -        perror("mapping domain memory");
   9.148 -	close(fd);
   9.149 -	return -1;
   9.150 -    }
   9.151 -    close(fd);
   9.152 -
   9.153 -    return 0;
   9.154 -}
   9.155 -
   9.156 -/* read the kernel header, extracting the image size and load address. */
   9.157 +/* Read the kernel header, extracting the image size and load address. */
   9.158  static int read_kernel_header(int fd, long dom_size, 
   9.159  			      unsigned long * load_addr, size_t * ksize)
   9.160  {
   9.161      char signature[8];
   9.162 -    char status[MAX_PATH];
   9.163 +    char status[1024];
   9.164      struct stat stat;
   9.165      
   9.166 -    if(fstat(fd, &stat) < 0){
   9.167 -        perror(PERR_STRING);
   9.168 +    if ( fstat(fd, &stat) < 0 )
   9.169 +    {
   9.170 +        PERROR("Cannot stat the kernel image");
   9.171  	return -1;
   9.172      }
   9.173  
   9.174 -    if(stat.st_size > (dom_size << 10)){
   9.175 +    if ( (stat.st_size * 2) > (dom_size << 10) )
   9.176 +    {
   9.177          sprintf(status, "Kernel image size %ld larger than requested "
   9.178                  "domain size %ld\n Terminated.\n", stat.st_size, dom_size);
   9.179 -        dberr(status);
   9.180 +        ERROR(status);
   9.181  	return -1;
   9.182      }
   9.183      
   9.184      read(fd, signature, SIG_LEN);
   9.185 -    if(strncmp(signature, GUEST_SIG, SIG_LEN)){
   9.186 -        dberr("Kernel image does not contain required signature. "
   9.187 +    if ( strncmp(signature, GUEST_SIG, SIG_LEN) )
   9.188 +    {
   9.189 +        ERROR("Kernel image does not contain required signature. "
   9.190                "Terminating.\n");
   9.191  	return -1;
   9.192      }
   9.193 @@ -137,62 +101,165 @@ static int read_kernel_header(int fd, lo
   9.194      return 0;
   9.195  }
   9.196  
   9.197 -/* this is the main guestos setup function,
   9.198 - * returnes domain descriptor structure to be used when launching
   9.199 - * the domain by hypervisor to do some last minute initialization.
   9.200 - * page table initialization is done by making a list of page table
   9.201 - * requests that are handeled by the hypervisor in the ordinary
   9.202 - * manner. this way, many potentially messy things are avoided...
   9.203 - */ 
   9.204 -#define PAGE_TO_VADDR(_pfn) ((void *)(dom_mem->vaddr + ((_pfn) * PAGE_SIZE)))
   9.205 -static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
   9.206 -                                    unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem)
   9.207 +static int devmem_fd;
   9.208 +
   9.209 +static int init_pfn_mapper(void)
   9.210 +{
   9.211 +    if ( (devmem_fd = open("/dev/mem", O_RDWR)) < 0 )
   9.212 +    {
   9.213 +        PERROR("Could not open /dev/mem");
   9.214 +        return -1;
   9.215 +    }
   9.216 +    return 0;
   9.217 +}
   9.218 +
   9.219 +static void *map_pfn(unsigned long pfn)
   9.220 +{
   9.221 +    void *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
   9.222 +                       MAP_SHARED, devmem_fd, pfn << PAGE_SHIFT);
   9.223 +    if ( vaddr == MAP_FAILED )
   9.224 +    {
   9.225 +        PERROR("Could not mmap a domain pfn using /dev/mem");
   9.226 +        return NULL;
   9.227 +    }
   9.228 +    return vaddr;
   9.229 +}
   9.230 +
   9.231 +static void unmap_pfn(void *vaddr)
   9.232  {
   9.233 -    dom_meminfo_t *meminfo = NULL;
   9.234 +    (void)munmap(vaddr, PAGE_SIZE);
   9.235 +}
   9.236 +
   9.237 +static int clear_domain_page(unsigned long pfn)
   9.238 +{
   9.239 +    void *vaddr = map_pfn(pfn);
   9.240 +    if ( vaddr == NULL )
   9.241 +        return -1;
   9.242 +    memset(vaddr, 0, PAGE_SIZE);
   9.243 +    unmap_pfn(vaddr);
   9.244 +    return 0;
   9.245 +}
   9.246 +
   9.247 +static int copy_to_domain_page(unsigned long dst_pfn, void *src_page)
   9.248 +{
   9.249 +    void *vaddr = map_pfn(dst_pfn);
   9.250 +    if ( vaddr == NULL )
   9.251 +        return -1;
   9.252 +    memcpy(vaddr, src_page, PAGE_SIZE);
   9.253 +    unmap_pfn(vaddr);
   9.254 +    return 0;
   9.255 +}
   9.256 +
   9.257 +static int setup_guestos(
   9.258 +    int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages,
   9.259 +    unsigned long virt_load_addr, size_t ksize, dom_meminfo_t *meminfo)
   9.260 +{
   9.261      unsigned long *page_array = NULL;
   9.262 -    page_update_request_t *pgt_updates = NULL;
   9.263 +    page_update_request_t *pgt_update_arr = NULL, *pgt_updates = NULL;
   9.264      int alloc_index, num_pt_pages;
   9.265      unsigned long l2tab;
   9.266      unsigned long l1tab = 0;
   9.267      unsigned long num_pgt_updates = 0;
   9.268 -    unsigned long count, pt_start;
   9.269 -    struct dom0_dopgupdates_args pgupdate_req;
   9.270 -    int cmd_fd;
   9.271 -    int result;
   9.272 -
   9.273 -    meminfo     = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t));
   9.274 -    page_array  = malloc(dom_mem->tot_pages * 4);
   9.275 -    if (!meminfo || !page_array) {
   9.276 -	dberr ("Could not allocate memory");
   9.277 -	goto error_out;
   9.278 -    }
   9.279 -    pgt_updates = (page_update_request_t *)dom_mem->vaddr;
   9.280 -    alloc_index = dom_mem->tot_pages - 1;
   9.281 +    unsigned long count, pt_start, i, j;
   9.282  
   9.283      memset(meminfo, 0, sizeof(*meminfo));
   9.284  
   9.285 -    memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4);
   9.286 +    if ( init_pfn_mapper() < 0 )
   9.287 +        goto error_out;
   9.288 +
   9.289 +    pgt_updates = malloc((tot_pages + 1024) * 3
   9.290 +                         * sizeof(page_update_request_t));
   9.291 +    page_array = malloc(tot_pages * sizeof(unsigned long));
   9.292 +    pgt_update_arr = pgt_updates;
   9.293 +    if ( (pgt_update_arr == NULL) || (page_array == NULL) )
   9.294 +    {
   9.295 +	PERROR("Could not allocate memory");
   9.296 +	goto error_out;
   9.297 +    }
   9.298 +
   9.299 +    if ( get_pfn_list(dom, page_array, tot_pages) != tot_pages )
   9.300 +    {
   9.301 +	PERROR("Could not get the page frame list");
   9.302 +	goto error_out;
   9.303 +    }
   9.304 +
   9.305 +    /* Load the guest OS image. */
   9.306 +    for ( i = 0; i < ksize; i += PAGE_SIZE )
   9.307 +    {
   9.308 +        char page[PAGE_SIZE];
   9.309 +        int size = ((ksize-i) < PAGE_SIZE) ? (ksize-i) : PAGE_SIZE;
   9.310 +        if ( read(kernel_fd, page, size) != size )
   9.311 +        {
   9.312 +            PERROR("Error reading kernel image, could not"
   9.313 +                   " read the whole image.");
   9.314 +            goto error_out;
   9.315 +        } 
   9.316 +        copy_to_domain_page(page_array[i>>PAGE_SHIFT], page);
   9.317 +    }
   9.318  
   9.319 -    /* Count bottom-level PTs, rounding up. Include one PTE for shared info. */
   9.320 +    /* Load the initial ramdisk image. */
   9.321 +    if ( initrd_fd >= 0 )
   9.322 +    {
   9.323 +	struct stat stat;
   9.324 +	unsigned long isize;
   9.325 +
   9.326 +	if ( fstat(initrd_fd, &stat) < 0 )
   9.327 +        {
   9.328 +            PERROR("Could not stat the initrd image");
   9.329 +            goto error_out;
   9.330 +	}
   9.331 +	isize = stat.st_size;
   9.332 +        if ( ((isize + ksize) * 2) > (tot_pages << PAGE_SHIFT) )
   9.333 +        {
   9.334 +            ERROR("Kernel + initrd too big to safely fit in domain memory");
   9.335 +            goto error_out;
   9.336 +        }
   9.337 +
   9.338 +        meminfo->virt_mod_addr = virt_load_addr + i;
   9.339 +        meminfo->virt_mod_len  = isize;
   9.340 +
   9.341 +        for ( j = 0; j < isize; j += PAGE_SIZE, i += PAGE_SIZE )
   9.342 +        {
   9.343 +            char page[PAGE_SIZE];
   9.344 +            int size = ((isize-j) < PAGE_SIZE) ? (isize-j) : PAGE_SIZE;
   9.345 +            if ( read(initrd_fd, page, size) != size )
   9.346 +            {
   9.347 +                PERROR("Error reading initrd image, could not"
   9.348 +                       " read the whole image.");
   9.349 +                goto error_out;
   9.350 +            } 
   9.351 +            copy_to_domain_page(page_array[i>>PAGE_SHIFT], page);
   9.352 +        }
   9.353 +    }
   9.354 +
   9.355 +    alloc_index = tot_pages - 1;
   9.356 +
   9.357 +    /*
   9.358 +     * Count bottom-level PTs, rounding up. Include one PTE for shared info. We
   9.359 +     * therefore add 1024 because 1 is for shared_info, 1023 is to round up.
   9.360 +     */
   9.361      num_pt_pages = 
   9.362 -        (l1_table_offset(virt_load_addr) + dom_mem->tot_pages + 1024) / 1024;
   9.363 +        (l1_table_offset(virt_load_addr) + tot_pages + 1024) / 1024;
   9.364  
   9.365      /* We must also count the page directory. */
   9.366      num_pt_pages++;
   9.367  
   9.368      /* Index of first PT page. */
   9.369 -    pt_start = dom_mem->tot_pages - num_pt_pages;
   9.370 +    pt_start = tot_pages - num_pt_pages;
   9.371  
   9.372 -    /* first allocate page for page dir. allocation goes backwards from the
   9.373 -     * end of the allocated physical address space.
   9.374 +    /*
   9.375 +     * First allocate page for page dir. Allocation goes backwards from the end
   9.376 +     * of the allocated physical address space.
   9.377       */
   9.378 -    l2tab = *(page_array + alloc_index) << PAGE_SHIFT; 
   9.379 -    memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
   9.380 +    l2tab = page_array[alloc_index] << PAGE_SHIFT;
   9.381 +    if ( clear_domain_page(page_array[alloc_index]) < 0 )
   9.382 +        goto error_out;
   9.383      alloc_index--;
   9.384      meminfo->l2_pgt_addr = l2tab;
   9.385 -    meminfo->virt_shinfo_addr = virt_load_addr + nr_2_page(dom_mem->tot_pages);
   9.386 +    meminfo->virt_shinfo_addr = virt_load_addr + (tot_pages << PAGE_SHIFT);
   9.387  
   9.388 -    /* pin down l2tab addr as page dir page - causes hypervisor to provide
   9.389 +    /*
   9.390 +     * Pin down l2tab addr as page dir page - causes hypervisor to provide
   9.391       * correct protection for the page
   9.392       */ 
   9.393      pgt_updates->ptr = l2tab | PGREQ_EXTENDED_COMMAND;
   9.394 @@ -206,15 +273,16 @@ static dom_meminfo_t *setup_guestos(int 
   9.395       * Xen during final setup.
   9.396       */
   9.397      l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t);
   9.398 -    for ( count = 0; count < (dom_mem->tot_pages + 1); count++ )
   9.399 +    for ( count = 0; count < (tot_pages + 1); count++ )
   9.400      {    
   9.401          if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) 
   9.402          {
   9.403 -            l1tab = *(page_array + alloc_index) << PAGE_SHIFT;
   9.404 -            memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
   9.405 +            l1tab = page_array[alloc_index] << PAGE_SHIFT;
   9.406 +            if ( clear_domain_page(page_array[alloc_index]) < 0 )
   9.407 +                goto error_out;
   9.408              alloc_index--;
   9.409  			
   9.410 -            l1tab += l1_table_offset(virt_load_addr + nr_2_page(count)) 
   9.411 +            l1tab += l1_table_offset(virt_load_addr + (count << PAGE_SHIFT)) 
   9.412                  * sizeof(l1_pgentry_t);
   9.413  
   9.414              /* make apropriate entry in the page directory */
   9.415 @@ -226,12 +294,14 @@ static dom_meminfo_t *setup_guestos(int 
   9.416          }
   9.417  
   9.418          /* The last PTE we consider is filled in later by Xen. */
   9.419 -        if ( count == dom_mem->tot_pages ) break;
   9.420 +        if ( count == tot_pages ) break;
   9.421  		
   9.422 +        printf("%lu: %08lx\n", count, page_array[count]);
   9.423 +
   9.424          if ( count < pt_start )
   9.425          {
   9.426              pgt_updates->ptr = l1tab;
   9.427 -            pgt_updates->val = (*(page_array + count) << PAGE_SHIFT) | L1_PROT;
   9.428 +            pgt_updates->val = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   9.429              pgt_updates++;
   9.430              num_pgt_updates++;
   9.431              l1tab += sizeof(l1_pgentry_t);
   9.432 @@ -240,195 +310,82 @@ static dom_meminfo_t *setup_guestos(int 
   9.433          {
   9.434              pgt_updates->ptr = l1tab;
   9.435              pgt_updates->val = 
   9.436 -		((*(page_array + count) << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
   9.437 +		((page_array[count] << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
   9.438              pgt_updates++;
   9.439              num_pgt_updates++;
   9.440              l1tab += sizeof(l1_pgentry_t);
   9.441          }
   9.442  
   9.443          pgt_updates->ptr = 
   9.444 -	    (*(page_array + count) << PAGE_SHIFT) | PGREQ_MPT_UPDATE;
   9.445 +	    (page_array[count] << PAGE_SHIFT) | PGREQ_MPT_UPDATE;
   9.446          pgt_updates->val = count;
   9.447          pgt_updates++;
   9.448          num_pgt_updates++;
   9.449      }
   9.450  
   9.451 -    meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1);
   9.452 -    meminfo->domain = dom;
   9.453 +    printf("XHDHFDHGFGHFGXXX\n");
   9.454 +    sleep(4);
   9.455 +
   9.456 +    meminfo->virt_startinfo_addr =
   9.457 +        virt_load_addr + ((alloc_index-1)<<PAGE_SHIFT);
   9.458 +
   9.459 +    /* Send the page update requests down to the hypervisor. */
   9.460 +    if ( send_pgupdates(pgt_update_arr, num_pgt_updates) < 0 )
   9.461 +        goto error_out;
   9.462  
   9.463      free(page_array);
   9.464 -
   9.465 -    /*
   9.466 -     * Send the page update requests down to the hypervisor.
   9.467 -     * NB. We must do this before loading the guest OS image!
   9.468 -     */
   9.469 -    if ( (cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY)) < 0 )
   9.470 -    {
   9.471 -	dberr ("Could not open " PROC_XENO_DOM0_CMD);
   9.472 -	goto error_out;
   9.473 -    }
   9.474 -
   9.475 -    pgupdate_req.pgt_update_arr  = (unsigned long)dom_mem->vaddr;
   9.476 -    pgupdate_req.num_pgt_updates = num_pgt_updates;
   9.477 -    result = ioctl(cmd_fd, IOCTL_DOM0_DOPGUPDATES, &pgupdate_req);
   9.478 -    close(cmd_fd);
   9.479 -    if (result < 0) {
   9.480 -	dberr ("Could not build domain page tables.");
   9.481 -	goto error_out;
   9.482 -    }
   9.483 -
   9.484 -    /* Load the guest OS image. */
   9.485 -    if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize )
   9.486 -    {
   9.487 -        dberr("Error reading kernel image, could not"
   9.488 -              " read the whole image.");
   9.489 -	goto error_out;
   9.490 -    }
   9.491 -
   9.492 -    if( initrd_fd >= 0)
   9.493 -    {
   9.494 -	struct stat stat;
   9.495 -	unsigned long isize;
   9.496 -
   9.497 -	if(fstat(initrd_fd, &stat) < 0){
   9.498 -            perror(PERR_STRING);
   9.499 -            goto error_out;
   9.500 -	}
   9.501 -	isize = stat.st_size;
   9.502 -
   9.503 -	if( read(initrd_fd, ((char *)dom_mem->vaddr)+ksize, isize) != isize )
   9.504 -        {
   9.505 -	    dberr("Error reading initrd image, could not"
   9.506 -		  " read the whole image. Terminating.");
   9.507 -	    goto error_out;
   9.508 -        }
   9.509 -
   9.510 -	meminfo->virt_mod_addr = virt_load_addr + ksize;
   9.511 -	meminfo->virt_mod_len  = isize;
   9.512 -
   9.513 -    }
   9.514 -
   9.515 -
   9.516 -    return meminfo;
   9.517 +    free(pgt_update_arr);
   9.518 +    return 0;
   9.519  
   9.520   error_out:
   9.521 -    if (meminfo)
   9.522 -	free(meminfo);
   9.523 -    if (page_array)
   9.524 +    if ( page_array == NULL )
   9.525  	free(page_array);
   9.526 -
   9.527 -    return NULL;
   9.528 -}
   9.529 -
   9.530 -static int launch_domain(dom_meminfo_t  * meminfo)
   9.531 -{
   9.532 -    dom0_op_t dop;
   9.533 -    int cmd_fd;
   9.534 -
   9.535 -    cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY);
   9.536 -    if(cmd_fd < 0){
   9.537 -        perror(PERR_STRING);
   9.538 -        return -1;
   9.539 -    }
   9.540 -
   9.541 -    dop.cmd = DOM0_BUILDDOMAIN;
   9.542 -    memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
   9.543 -    write(cmd_fd, &dop, sizeof(dom0_op_t));
   9.544 -    close(cmd_fd);
   9.545 -
   9.546 -    return 0;
   9.547 +    if ( pgt_update_arr == NULL )
   9.548 +	free(pgt_update_arr);
   9.549 +    return -1;
   9.550  }
   9.551  
   9.552 -static int get_domain_info (int domain_id,
   9.553 -                            int *pg_head,
   9.554 -                            int *tot_pages)
   9.555 -{
   9.556 -    FILE *f; 
   9.557 -    char domains_line[256];
   9.558 -    int read_id;
   9.559 -
   9.560 -    f = fopen (PROC_XENO_DOMAINS, "r");
   9.561 -    if (f == NULL) return -1;
   9.562 -
   9.563 -    read_id = -1;
   9.564 -    while (fgets (domains_line, 256, f) != 0)
   9.565 -    { 
   9.566 -        int trans;
   9.567 -	read_id = -1;
   9.568 -        trans = sscanf (domains_line, "%d %*d %*d %*d %*d %*d %x %d %*s", &read_id
   9.569 -                        , pg_head, tot_pages);
   9.570 -	if (trans != 3) {
   9.571 -	    dberr ("format of " PROC_XENO_DOMAINS " changed -- wrong kernel version?");
   9.572 -	    read_id = -1;
   9.573 -	    break;
   9.574 -	}
   9.575 -
   9.576 -        if (read_id == domain_id) {
   9.577 -	    break;
   9.578 -        }
   9.579 -    }
   9.580 -
   9.581 -    fclose (f);
   9.582 -
   9.583 -    if (read_id == -1) {
   9.584 -        errno = ESRCH;
   9.585 -    }
   9.586 -
   9.587 -    return 0;
   9.588 -}
   9.589 -
   9.590 -
   9.591  int main(int argc, char **argv)
   9.592  {
   9.593 -
   9.594 -    dom_mem_t dom_os_image;
   9.595 -    dom_meminfo_t * meminfo;
   9.596 +    dom0_op_t launch_op;
   9.597      size_t ksize;
   9.598      unsigned long load_addr;
   9.599 +    long tot_pages;
   9.600      int kernel_fd, initrd_fd = -1;
   9.601      int count;
   9.602      int cmd_len;
   9.603      int args_start = 4;
   9.604      char initrd_name[1024];
   9.605      int domain_id;
   9.606 -    int pg_head;
   9.607 -    int tot_pages;
   9.608      int rc;
   9.609  
   9.610 -    /**** this argument parsing code is really _gross_. rewrite me! ****/
   9.611 -
   9.612 -    if(argc < 4) {
   9.613 -        dberr("Usage: dom_builder <domain_id> <image> <num_vifs> "
   9.614 -	      "[<initrd=initrd_name>] <boot_params>\n");
   9.615 -        return -1;
   9.616 +    if ( argc < 4 )
   9.617 +    {
   9.618 +        fprintf(stderr, "Usage: dom_builder <domain_id> <image> <num_vifs> "
   9.619 +                "[<initrd=initrd_name>] <boot_params>\n");
   9.620 +        return 1;
   9.621      }
   9.622  
   9.623 -    /* Look up information about the domain */
   9.624      domain_id = atol(argv[1]);
   9.625 -    if ( get_domain_info (domain_id, &pg_head, &tot_pages) != 0 ) 
   9.626 +    if ( (tot_pages = get_tot_pages(domain_id)) < 0 )
   9.627      {
   9.628 -        perror ("Could not find domain information");
   9.629 -	return -1;
   9.630 +        PERROR("Could not find total pages for domain");
   9.631 +	return 1;
   9.632      }
   9.633 -	     
   9.634 +
   9.635      kernel_fd = open(argv[2], O_RDONLY);
   9.636 -    if (kernel_fd < 0) {
   9.637 -        perror ("Could not open kernel image");
   9.638 -	return -1;
   9.639 +    if ( kernel_fd < 0 )
   9.640 +    {
   9.641 +        PERROR("Could not open kernel image");
   9.642 +	return 1;
   9.643      }
   9.644  
   9.645      rc = read_kernel_header(kernel_fd,
   9.646  			    tot_pages << (PAGE_SHIFT - 10), 
   9.647  			    &load_addr, &ksize);
   9.648      if ( rc < 0 )
   9.649 -	return -1;
   9.650 +	return 1;
   9.651      
   9.652 -
   9.653 -    /* map domain's memory */
   9.654 -    if ( map_dom_mem(pg_head, tot_pages,
   9.655 -                     domain_id, &dom_os_image) )
   9.656 -	return -1;
   9.657 -
   9.658      if( (argc > args_start) && 
   9.659          (strncmp("initrd=", argv[args_start], 7) == 0) )
   9.660      {
   9.661 @@ -438,41 +395,40 @@ int main(int argc, char **argv)
   9.662  	args_start++;
   9.663          
   9.664  	initrd_fd = open(initrd_name, O_RDONLY);
   9.665 -	if(initrd_fd < 0){
   9.666 -            perror(PERR_STRING);
   9.667 -	    return -1;
   9.668 +	if ( initrd_fd < 0 )
   9.669 +        {
   9.670 +            PERROR("Could not open the initial ramdisk image");
   9.671 +	    return 1;
   9.672  	}
   9.673      }
   9.674  
   9.675 -    /* the following code does the actual domain building */
   9.676 -    meminfo = setup_guestos(domain_id, kernel_fd, initrd_fd, load_addr, 
   9.677 -			    ksize, &dom_os_image); 
   9.678 -    if (!meminfo)
   9.679 -	return -1;
   9.680 +    if ( setup_guestos(domain_id, kernel_fd, initrd_fd, tot_pages,
   9.681 +                       load_addr, ksize, &launch_op.u.meminfo) < 0 )
   9.682 +        return 1;
   9.683  
   9.684 -    if (initrd_fd >= 0)
   9.685 +    if ( initrd_fd >= 0 )
   9.686  	close(initrd_fd);
   9.687      close(kernel_fd);
   9.688  
   9.689 -    /* and unmap the new domain's memory image since we no longer need it */
   9.690 -    dom_mem_cleanup(&dom_os_image);
   9.691 -
   9.692 -    meminfo->virt_load_addr = load_addr;
   9.693 -    meminfo->num_vifs = atoi(argv[3]);
   9.694 -    meminfo->cmd_line[0] = '\0';
   9.695 +    launch_op.u.meminfo.domain         = domain_id;
   9.696 +    launch_op.u.meminfo.virt_load_addr = load_addr;
   9.697 +    launch_op.u.meminfo.num_vifs       = atoi(argv[3]);
   9.698 +    launch_op.u.meminfo.cmd_line[0]    = '\0';
   9.699      cmd_len = 0;
   9.700 -    for(count = args_start; count < argc; count++){
   9.701 -        if(cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1){
   9.702 -            dberr("Size of image boot params too big!\n");
   9.703 +    for ( count = args_start; count < argc; count++ )
   9.704 +    {
   9.705 +        if ( cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1 ) 
   9.706 +        {
   9.707 +            ERROR("Size of image boot params too big!\n");
   9.708              break;
   9.709          }
   9.710 -        strcat(meminfo->cmd_line, argv[count]);
   9.711 -        strcat(meminfo->cmd_line, " ");
   9.712 +        strcat(launch_op.u.meminfo.cmd_line, argv[count]);
   9.713 +        strcat(launch_op.u.meminfo.cmd_line, " ");
   9.714          cmd_len += strlen(argv[count] + 1);
   9.715      }
   9.716  
   9.717 -    /* and launch the domain */
   9.718 -    rc = launch_domain(meminfo); 
   9.719 +    launch_op.cmd = DOM0_BUILDDOMAIN;
   9.720 +    rc = do_dom0_op(&launch_op);
   9.721      
   9.722 -    return 0;
   9.723 +    return (rc != 0) ? 1 : 0;
   9.724  }
    10.1 --- a/tools/internal/xi_create.c	Thu Jul 10 13:42:56 2003 +0000
    10.2 +++ b/tools/internal/xi_create.c	Sat Jul 12 22:26:07 2003 +0000
    10.3 @@ -4,90 +4,44 @@
    10.4   * Usage: <executable> <mem_kb> <os image> <num_vifs> 
    10.5   */
    10.6  
    10.7 -#include <unistd.h>
    10.8 -#include <stdio.h>
    10.9 -#include <errno.h>
   10.10 -#include <fcntl.h>
   10.11 -#include <sys/mman.h>
   10.12 -#include <sys/types.h>
   10.13 -#include <sys/stat.h>
   10.14 -#include <stdlib.h>
   10.15 -#include <sys/ioctl.h>
   10.16 -#include <errno.h>
   10.17 -#include <string.h>
   10.18 -
   10.19 -#include "dom0_ops.h"
   10.20 +#include <hypervisor-ifs/dom0_ops.h>
   10.21  #include "dom0_defs.h"
   10.22  #include "mem_defs.h"
   10.23 -#include "asm-xeno/dom0.h"
   10.24 -
   10.25 -/***********************************************************************/
   10.26  
   10.27  static char *argv0 = "internal_domain_create";
   10.28  
   10.29 -static void ERROR (char *message)
   10.30 -{
   10.31 -  fprintf (stderr, "%s: %s\n", argv0, message);
   10.32 -  exit (-1);
   10.33 -}
   10.34 -
   10.35 -static void PERROR (char *message)
   10.36 -{
   10.37 -  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
   10.38 -  exit (-1);
   10.39 -}
   10.40 -
   10.41 -/***********************************************************************/
   10.42 -
   10.43  static int create_new_domain(long req_mem, char *name)
   10.44  {
   10.45 -    char cmd_path[MAX_PATH];
   10.46 -    int cmd_fd;
   10.47 -    int dom_id;
   10.48 -    struct dom0_createdomain_args argbuf;
   10.49 +    int err;
   10.50 +    dom0_op_t op;
   10.51  
   10.52 -    /* open the /proc command interface */
   10.53 -    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
   10.54 -    cmd_fd = open(cmd_path, O_RDWR);
   10.55 -    if(cmd_fd < 0){
   10.56 -        PERROR ("Could not open PROC_CMD interface");
   10.57 -        return -1;
   10.58 -    }
   10.59 +    op.cmd = DOM0_CREATEDOMAIN;
   10.60 +    op.u.newdomain.memory_kb = req_mem;
   10.61 +    strncpy(op.u.newdomain.name, name, MAX_DOMAIN_NAME);
   10.62 +    op.u.newdomain.name[MAX_DOMAIN_NAME-1] = '\0';
   10.63  
   10.64 -    argbuf.kb_mem = req_mem;
   10.65 -    argbuf.name = name;
   10.66 -    dom_id = ioctl(cmd_fd, IOCTL_DOM0_CREATEDOMAIN, &argbuf);
   10.67 -    if (dom_id < 0) {
   10.68 -      PERROR("creating new domain");
   10.69 -    }
   10.70 -    close(cmd_fd);
   10.71 -    return dom_id;
   10.72 +    err = do_dom0_op(&op);
   10.73 +
   10.74 +    return (err < 0) ? err : op.u.newdomain.domain;
   10.75  }    
   10.76  
   10.77 -/***********************************************************************/
   10.78 -
   10.79  int main(int argc, char **argv)
   10.80  {
   10.81 -  int dom_id;
   10.82 -
   10.83 -  if (argv[0] != NULL) 
   10.84 +    int dom_id;
   10.85 +    
   10.86 +    if ( argv[0] != NULL ) 
   10.87 +        argv0 = argv[0];
   10.88 +    
   10.89 +    if ( argc != 3 ) 
   10.90      {
   10.91 -      argv0 = argv[0];
   10.92 -    }
   10.93 -
   10.94 -  if(argc != 3) 
   10.95 -    {
   10.96 -      fprintf (stderr, "Usage: %s <kbytes-mem> <domain-name>\n", argv0);
   10.97 -      return -1;
   10.98 +        fprintf(stderr, "Usage: %s <kbytes-mem> <domain-name>\n", argv0);
   10.99 +        return 1;
  10.100      }
  10.101 -
  10.102 -  dom_id = create_new_domain(atol(argv[1]), argv[2]);
  10.103 -
  10.104 -  if(dom_id < 0)
  10.105 -    {
  10.106 -      return -1;
  10.107 -    }
  10.108 -
  10.109 -  fprintf (stdout, "%d\n", dom_id);
  10.110 -  return 0;
  10.111 +    
  10.112 +    dom_id = create_new_domain(atol(argv[1]), argv[2]);
  10.113 +    if ( dom_id < 0 )
  10.114 +        return 1;
  10.115 +    
  10.116 +    printf("%d\n", dom_id);
  10.117 +    return 0;
  10.118  }
    11.1 --- a/tools/internal/xi_destroy.c	Thu Jul 10 13:42:56 2003 +0000
    11.2 +++ b/tools/internal/xi_destroy.c	Sat Jul 12 22:26:07 2003 +0000
    11.3 @@ -1,81 +1,43 @@
    11.4 -/* 
    11.5 - * A very(!) simple program to kill a domain. (c) Boris Dragovic
    11.6 - * Usage: <executable> <mem_kb> <os image> <num_vifs> 
    11.7 - */
    11.8  
    11.9 -#include <unistd.h>
   11.10 -#include <stdio.h>
   11.11 -#include <errno.h>
   11.12 -#include <fcntl.h>
   11.13 -#include <sys/stat.h>
   11.14 -#include <sys/types.h>
   11.15 -
   11.16 -#include "dom0_ops.h"
   11.17 +#include "hypervisor-ifs/dom0_ops.h"
   11.18  #include "dom0_defs.h"
   11.19 -
   11.20 -/***********************************************************************/
   11.21 +#include "mem_defs.h"
   11.22  
   11.23  static char *argv0 = "internal_domain_stop";
   11.24  
   11.25 -static void ERROR (char *message)
   11.26 -{
   11.27 -  fprintf (stderr, "%s: %s\n", argv0, message);
   11.28 -  exit (-1);
   11.29 -}
   11.30 -
   11.31 -static void PERROR (char *message)
   11.32 -{
   11.33 -  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
   11.34 -  exit (-1);
   11.35 -}
   11.36 -
   11.37 -/***********************************************************************/
   11.38 -
   11.39 -static int do_kill_domain(int dom_id, int force)
   11.40 +static int kill_domain(int dom_id, int force)
   11.41  {
   11.42 -    char cmd_path[MAX_PATH];
   11.43 -    dom0_op_t dop;
   11.44 -    int cmd_fd;
   11.45 -
   11.46 -    dop.cmd = DOM0_DESTROYDOMAIN;
   11.47 -    dop.u.killdomain.domain = dom_id;
   11.48 -    dop.u.killdomain.force  = force;
   11.49 +    int err;
   11.50 +    dom0_op_t op;
   11.51  
   11.52 -    /* open the /proc command interface */
   11.53 -    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
   11.54 -    cmd_fd = open(cmd_path, O_WRONLY);
   11.55 -    if(cmd_fd < 0){
   11.56 -        PERROR ("Count not open PROC_CMD interface");
   11.57 -    }
   11.58 +    op.cmd = DOM0_DESTROYDOMAIN;
   11.59 +    op.u.killdomain.domain = dom_id;
   11.60 +    op.u.killdomain.force  = force;
   11.61  
   11.62 -    write(cmd_fd, &dop, sizeof(dom0_op_t));
   11.63 -    close(cmd_fd);
   11.64 +    err = do_dom0_op(&op);
   11.65  
   11.66 -    return 0;
   11.67 +    return (err < 0) ? -1 : 0;
   11.68  }
   11.69  
   11.70  int main(int argc, char **argv)
   11.71  {
   11.72 -  int ret;
   11.73 -
   11.74 -  if (argv[0] != NULL) 
   11.75 -    {
   11.76 -      argv0 = argv[0];
   11.77 -    }
   11.78 -
   11.79 -  if ( (argc < 2) || (argc > 3) )
   11.80 +    int ret;
   11.81 +    
   11.82 +    if ( argv[0] != NULL ) 
   11.83 +        argv0 = argv[0];
   11.84 +    
   11.85 +    if ( (argc < 2) || (argc > 3) )
   11.86      {
   11.87      usage:
   11.88          fprintf(stderr, "Usage: %s [-f] <domain_id>\n", argv0);
   11.89 -        fprintf(stderr, " -f: Forces immediate destruction of specified domain\n");
   11.90 -        ret = -1;
   11.91 -        goto out;
   11.92 +        fprintf(stderr, " -f: Forces immediate destruction of <domain_id>\n");
   11.93 +        return 1;
   11.94      }
   11.95 -
   11.96 -    if ( (argc == 3) && strcmp("-f", argv[1]) ) goto usage;
   11.97 -
   11.98 -    ret = do_kill_domain(atoi(argv[argc-1]), argc == 3);
   11.99 -
  11.100 -out:
  11.101 -    return ret;
  11.102 +    
  11.103 +    if ( (argc == 3) && strcmp("-f", argv[1]) )
  11.104 +        goto usage;
  11.105 +    
  11.106 +    ret = kill_domain(atoi(argv[argc-1]), argc == 3);
  11.107 +    
  11.108 +    return (ret != 0) ? 1 : 0;
  11.109  }
    12.1 --- a/tools/internal/xi_list	Thu Jul 10 13:42:56 2003 +0000
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,46 +0,0 @@
    12.4 -#!/bin/bash
    12.5 -#
    12.6 -# xi_list
    12.7 -#
    12.8 -# This is a silly little script to dump the currently running domains.
    12.9 -# The output format is a series of space-separate fields for each domain:
   12.10 -#
   12.11 -#  1. Domain id
   12.12 -#  2. Processor
   12.13 -#  3. Has CPU (1 => true, 0 => false)
   12.14 -#  4. State (integer)
   12.15 -#  5. State (RUNNING, INTERRUPTABLE, UNINTERRUPTABLE, WAIT, SUSPENDED, DYING)
   12.16 -#  6. MCU advance
   12.17 -#  7. Total pages
   12.18 -#  8. Name
   12.19 -
   12.20 -INPUT_FILE=/proc/xeno/domains
   12.21 -
   12.22 -awk -f - $INPUT_FILE <<EOF
   12.23 -{
   12.24 -  dom_id = \$1;
   12.25 -
   12.26 -  processor = \$2;
   12.27 -
   12.28 -  has_cpu = \$3;
   12.29 -
   12.30 -  state = "UNKNOWN";
   12.31 -
   12.32 -  if (\$4 == 0)  state = "RUNNING";
   12.33 -  if (\$4 == 1)  state = "INTERRUPTIBLE";
   12.34 -  if (\$4 == 2)  state = "UNINTERRUPTABLE";
   12.35 -  if (\$4 == 4)  state = "WAIT";
   12.36 -  if (\$4 == 8)  state = "SUSPENDED";
   12.37 -  if (\$4 == 16) state = "DYING";
   12.38 -
   12.39 -  mcu_advance = \$6;
   12.40 -
   12.41 -  tot_pages = \$8;
   12.42 -
   12.43 -  printf "%d %d %d %d %s %d %d %s", dom_id, processor, has_cpu, \$4, state, mcu_advance, tot_pages, \$9;
   12.44 -  for (i = 10; i < NF; i ++) {
   12.45 -    printf " %s", \$i;
   12.46 -  }
   12.47 -  printf "\n";
   12.48 -}
   12.49 -EOF 
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/internal/xi_list.c	Sat Jul 12 22:26:07 2003 +0000
    13.3 @@ -0,0 +1,76 @@
    13.4 +/******************************************************************************
    13.5 + * xi_list.c
    13.6 + * 
    13.7 + * This is a silly little program to dump the currently running domains.
    13.8 + * The output format is a series of space-separate fields for each domain:
    13.9 + * 
   13.10 + *  1. Domain id
   13.11 + *  2. Processor
   13.12 + *  3. Has CPU (1 => true, 0 => false)
   13.13 + *  4. State (integer)
   13.14 + *  5. State (RUNNING, INTERRUPTIBLE, UNINTERRUPTIBLE, WAIT, SUSPENDED, DYING)
   13.15 + *  6. Pending events (hex value)
   13.16 + *  7. MCU advance
   13.17 + *  8. Total pages
   13.18 + *  9. Name
   13.19 + */
   13.20 +
   13.21 +/*
   13.22 + * Xen indicates when we've read info on all domains by returning error ESRCH. 
   13.23 + * We don't want the helper functiosn to interpret this as a real error!
   13.24 + */
   13.25 +#define SILENT_ERRORS_FROM_XEN
   13.26 +
   13.27 +#include "hypervisor-ifs/dom0_ops.h"
   13.28 +#include "dom0_defs.h"
   13.29 +#include "mem_defs.h"
   13.30 +
   13.31 +static char *argv0 = "internal_domain_list";
   13.32 +
   13.33 +static char *statestr(int state)
   13.34 +{
   13.35 +    switch ( state )
   13.36 +    {
   13.37 +    case  0: return "RUNNING";
   13.38 +    case  1: return "INTERRUPTIBLE";
   13.39 +    case  2: return "UNINTERRUPTIBLE";
   13.40 +    case  4: return "WAIT";
   13.41 +    case  8: return "SUSPENDED";
   13.42 +    case 16: return "DYING";
   13.43 +    default: return "UNKNOWN";
   13.44 +    }
   13.45 +    return NULL;
   13.46 +}
   13.47 +
   13.48 +int main(int argc, char **argv)
   13.49 +{
   13.50 +    dom0_op_t op;
   13.51 +
   13.52 +    if ( argv[0] != NULL ) 
   13.53 +        argv0 = argv[0];
   13.54 +
   13.55 +    if ( argc != 1 ) 
   13.56 +    {
   13.57 +        fprintf(stderr, "Usage: %s\n", argv0);
   13.58 +        return 1;
   13.59 +    }
   13.60 +
   13.61 +    op.cmd = DOM0_GETDOMAININFO;
   13.62 +    op.u.getdominfo.domain = 0;
   13.63 +    while ( do_dom0_op(&op) >= 0 )
   13.64 +    {
   13.65 +        printf("%8d %2d %1d %2d %s %08x %8ld %8d %s\n",
   13.66 +               op.u.getdominfo.domain, 
   13.67 +               op.u.getdominfo.processor,
   13.68 +               op.u.getdominfo.has_cpu,
   13.69 +               op.u.getdominfo.state,
   13.70 +               statestr(op.u.getdominfo.state),
   13.71 +               op.u.getdominfo.hyp_events,
   13.72 +               op.u.getdominfo.mcu_advance,
   13.73 +               op.u.getdominfo.tot_pages,
   13.74 +               op.u.getdominfo.name);
   13.75 +        op.u.getdominfo.domain++;
   13.76 +    }
   13.77 +
   13.78 +    return 0;
   13.79 +}
    14.1 --- a/tools/internal/xi_phys_grant.c	Thu Jul 10 13:42:56 2003 +0000
    14.2 +++ b/tools/internal/xi_phys_grant.c	Sat Jul 12 22:26:07 2003 +0000
    14.3 @@ -1,50 +1,43 @@
    14.4 +
    14.5  #define _GNU_SOURCE
    14.6 -#include <unistd.h>
    14.7 -#include <stdio.h>
    14.8 -#include <errno.h>
    14.9 -#include <sys/fcntl.h>
   14.10 -#include <string.h>
   14.11 -#include <stdlib.h>
   14.12 -
   14.13 -#include "hypervisor-ifs/block.h"
   14.14 +#include "dom0_defs.h"
   14.15  
   14.16  int main(int argc, char *argv[])
   14.17  {
   14.18 -    xp_disk_t buf;
   14.19 -    int fd;
   14.20 -    char *strbuf;
   14.21 +    privcmd_blkmsg_t blkmsg;
   14.22 +    xp_disk_t        xpd;
   14.23  
   14.24 -    if (argc != 7) {
   14.25 -	fprintf(stderr,
   14.26 -		"Usage: xi_physdev_grant <r/rw> <domain> <device> <start sector> <n_sectors> <partition>\n");
   14.27 +    if ( argc != 7 )
   14.28 +    {
   14.29 +	fprintf(stderr, "Usage: xi_physdev_grant <r/rw> <domain> "
   14.30 +                "<device> <start sector> <n_sectors> <partition>\n");
   14.31  	return 1;
   14.32      }
   14.33  
   14.34 -    buf.mode = 0;
   14.35 -    if (argv[1][0] == 'r')
   14.36 -	buf.mode |= 1;
   14.37 -    else if (argv[1][0] == 'w')
   14.38 -	buf.mode |= 2;
   14.39 -    if (argv[1][1] == 'r')
   14.40 -	buf.mode |= 1;
   14.41 -    else if (argv[1][1] == 'w')
   14.42 -	buf.mode |= 2;
   14.43 +    xpd.mode = 0;
   14.44 +    if ( strchr(argv[1], 'r') )
   14.45 +	xpd.mode |= PHYSDISK_MODE_R;
   14.46 +    if ( strchr(argv[1], 'w') )
   14.47 +        xpd.mode |= PHYSDISK_MODE_W;
   14.48 +
   14.49 +    xpd.domain     = atol(argv[2]);
   14.50 +    xpd.device     = xldev_to_physdev(atol(argv[3]));
   14.51 +    xpd.start_sect = atol(argv[4]);
   14.52 +    xpd.n_sectors  = atol(argv[5]);
   14.53 +    xpd.partition  = atol(argv[6]);
   14.54  
   14.55 -    buf.device = atol(argv[3]);
   14.56 -    buf.start_sect = atol(argv[4]);
   14.57 -    buf.n_sectors = atol(argv[5]);
   14.58 -    buf.partition = atol(argv[6]);
   14.59 +    if ( xpd.device == 0 )
   14.60 +    {
   14.61 +        ERROR("Unrecognised device");
   14.62 +        return 1;
   14.63 +    }
   14.64  
   14.65 -    asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[2]);
   14.66 -    fd = open(strbuf, O_WRONLY);
   14.67 -    if (fd < 0) {
   14.68 -	fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno));
   14.69 -	return 1;
   14.70 -    }
   14.71 -    free(strbuf);
   14.72 +    blkmsg.op       = XEN_BLOCK_PHYSDEV_GRANT;
   14.73 +    blkmsg.buf      = &xpd;
   14.74 +    blkmsg.buf_size = sizeof(xpd);
   14.75  
   14.76 -    write(fd, &buf, sizeof(buf));
   14.77 -    close(fd);
   14.78 +    if ( do_xen_blkmsg(&blkmsg) < 0 )
   14.79 +        return 1;
   14.80  
   14.81      return 0;
   14.82  }
    15.1 --- a/tools/internal/xi_phys_probe.c	Thu Jul 10 13:42:56 2003 +0000
    15.2 +++ b/tools/internal/xi_phys_probe.c	Sat Jul 12 22:26:07 2003 +0000
    15.3 @@ -1,50 +1,46 @@
    15.4 +
    15.5  #define _GNU_SOURCE
    15.6 -#include <stdio.h>
    15.7 -#include <sys/fcntl.h>
    15.8 -#include <errno.h>
    15.9 -#include <unistd.h>
   15.10 -#include <string.h>
   15.11 -#include <stdlib.h>
   15.12 -
   15.13 -#include "hypervisor-ifs/block.h"
   15.14 +#include "dom0_defs.h"
   15.15  
   15.16  int main(int argc, char *argv[])
   15.17  {
   15.18 +    privcmd_blkmsg_t    blkmsg;
   15.19      physdisk_probebuf_t buf;
   15.20 -    int fd;
   15.21 -    int x;
   15.22 -    char *strbuf;
   15.23 +    int                 i;
   15.24  
   15.25 -    if (argc != 2) {
   15.26 +    if ( argc != 2 )
   15.27 +    {
   15.28  	fprintf(stderr, "Usage: xi_phys_probe <domain_nr>\n");
   15.29  	return 1;
   15.30      }
   15.31  
   15.32 -    asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[1]);
   15.33 -    fd = open(strbuf, O_RDONLY);
   15.34 -    if (fd < 0) {
   15.35 -	fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno));
   15.36 -	return 1;
   15.37 -    }
   15.38 -    free(strbuf);
   15.39 +    memset(&buf, 0, sizeof(buf));
   15.40  
   15.41 -    memset(&buf, 0, sizeof(buf));
   15.42 -    buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST;
   15.43      do {
   15.44 -	buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST;
   15.45 -	read(fd, &buf, sizeof(buf));
   15.46 -	if (!buf.n_aces)
   15.47 -	    break;
   15.48 +        buf.domain      = atol(argv[1]);
   15.49 +	buf.n_aces      = PHYSDISK_MAX_ACES_PER_REQUEST;
   15.50 +
   15.51 +        blkmsg.op       = XEN_BLOCK_PHYSDEV_PROBE;
   15.52 +        blkmsg.buf      = &buf;
   15.53 +        blkmsg.buf_size = sizeof(buf);
   15.54  
   15.55 -	for (x = 0; x < buf.n_aces; x++) {
   15.56 -	    char read = (buf.entries[x].mode & 1 ? 'r' : ' ');
   15.57 -	    char write = (buf.entries[x].mode & 2 ? 'w' : ' ');
   15.58 -	    printf("%x %x %lx %lx %c%c\n", buf.entries[x].device,
   15.59 -		   buf.entries[x].partition,
   15.60 -		   buf.entries[x].start_sect,
   15.61 -		   buf.entries[x].n_sectors, read, write);
   15.62 +        if ( do_xen_blkmsg(&blkmsg) < 0 )
   15.63 +            return 1;
   15.64 +        
   15.65 +	for ( i = 0; i < buf.n_aces; i++ )
   15.66 +        {
   15.67 +	    char read = (buf.entries[i].mode & 1 ? 'r' : ' ');
   15.68 +	    char write = (buf.entries[i].mode & 2 ? 'w' : ' ');
   15.69 +	    printf("%x %x %lx %lx %c%c\n", 
   15.70 +                   physdev_to_xldev(buf.entries[i].device),
   15.71 +		   buf.entries[i].partition,
   15.72 +		   buf.entries[i].start_sect,
   15.73 +		   buf.entries[i].n_sectors, read, write);
   15.74  	}
   15.75 +
   15.76  	buf.start_ind += buf.n_aces;
   15.77 -    } while (buf.n_aces == PHYSDISK_MAX_ACES_PER_REQUEST);
   15.78 +    } 
   15.79 +    while ( buf.n_aces == PHYSDISK_MAX_ACES_PER_REQUEST );
   15.80 +
   15.81      return 0;
   15.82  }
    16.1 --- a/tools/internal/xi_phys_revoke.c	Thu Jul 10 13:42:56 2003 +0000
    16.2 +++ b/tools/internal/xi_phys_revoke.c	Sat Jul 12 22:26:07 2003 +0000
    16.3 @@ -1,40 +1,37 @@
    16.4 +
    16.5  #define _GNU_SOURCE
    16.6 -#include <unistd.h>
    16.7 -#include <errno.h>
    16.8 -#include <stdio.h>
    16.9 -#include <sys/fcntl.h>
   16.10 -#include <string.h>
   16.11 -#include <stdlib.h>
   16.12 -
   16.13 -#include "hypervisor-ifs/block.h"
   16.14 +#include "dom0_defs.h"
   16.15  
   16.16  int main(int argc, char *argv[])
   16.17  {
   16.18 -    xp_disk_t buf;
   16.19 -    int fd;
   16.20 -    char *strbuf;
   16.21 +    privcmd_blkmsg_t blkmsg;
   16.22 +    xp_disk_t        xpd;
   16.23  
   16.24 -    if (argc != 5) {
   16.25 -	fprintf(stderr,
   16.26 -		"Usage: xi_physdev_revoke <domain> <device> <start sector> <n_sectors>\n");
   16.27 +    if ( argc != 5 )
   16.28 +    {
   16.29 +	fprintf(stderr, "Usage: xi_physdev_revoke <domain> "
   16.30 +                "<device> <start sector> <n_sectors>\n");
   16.31  	return 1;
   16.32      }
   16.33  
   16.34 -    buf.device = atol(argv[2]);
   16.35 -    buf.mode = 0;
   16.36 -    buf.start_sect = atol(argv[3]);
   16.37 -    buf.n_sectors = atol(argv[4]);
   16.38 +    xpd.mode       = 0;
   16.39 +    xpd.domain     = atol(argv[1]);
   16.40 +    xpd.device     = xldev_to_physdev(atol(argv[2]));
   16.41 +    xpd.start_sect = atol(argv[3]);
   16.42 +    xpd.n_sectors  = atol(argv[4]);
   16.43  
   16.44 -    asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[1]);
   16.45 -    fd = open(strbuf, O_WRONLY);
   16.46 -    if (fd < 0) {
   16.47 -	fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno));
   16.48 -	return 1;
   16.49 +    if ( xpd.device == 0 )
   16.50 +    {
   16.51 +        ERROR("Unrecognised device");
   16.52 +        return 1;
   16.53      }
   16.54 -    free(strbuf);
   16.55  
   16.56 -    write(fd, &buf, sizeof(buf));
   16.57 -    close(fd);
   16.58 +    blkmsg.op       = XEN_BLOCK_PHYSDEV_GRANT;
   16.59 +    blkmsg.buf      = &xpd;
   16.60 +    blkmsg.buf_size = sizeof(xpd);
   16.61 +
   16.62 +    if ( do_xen_blkmsg(&blkmsg) < 0 )
   16.63 +        return 1;
   16.64  
   16.65      return 0;
   16.66  }
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/internal/xi_sched_domain.c	Sat Jul 12 22:26:07 2003 +0000
    17.3 @@ -0,0 +1,32 @@
    17.4 +
    17.5 +#include "hypervisor-ifs/dom0_ops.h"
    17.6 +#include "dom0_defs.h"
    17.7 +#include "mem_defs.h"
    17.8 +
    17.9 +static char *argv0 = "internal_domain_sched_domain";
   17.10 +
   17.11 +int main(int argc, char **argv)
   17.12 +{
   17.13 +    dom0_op_t op;
   17.14 +
   17.15 +    if ( argv[0] != NULL ) 
   17.16 +        argv0 = argv[0];
   17.17 +
   17.18 +    if ( argc != 6 ) 
   17.19 +    {
   17.20 +        fprintf(stderr, "Usage: %s <domain> <mcu_adv> "
   17.21 +                "<warp> <warpl> <warpu>\n", argv0);
   17.22 +        return 1;
   17.23 +    }
   17.24 +
   17.25 +    op.cmd = DOM0_ADJUSTDOM;
   17.26 +    op.u.adjustdom.domain  = atoi(argv[1]);
   17.27 +    op.u.adjustdom.mcu_adv = atol(argv[1]);
   17.28 +    op.u.adjustdom.warp    = atol(argv[1]);
   17.29 +    op.u.adjustdom.warpl   = atol(argv[1]);
   17.30 +    op.u.adjustdom.warpu   = atol(argv[1]);
   17.31 +    if ( do_dom0_op(&op) < 0 )
   17.32 +        return 1;
   17.33 +
   17.34 +    return 0;
   17.35 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/internal/xi_sched_global.c	Sat Jul 12 22:26:07 2003 +0000
    18.3 @@ -0,0 +1,27 @@
    18.4 +
    18.5 +#include "hypervisor-ifs/dom0_ops.h"
    18.6 +#include "dom0_defs.h"
    18.7 +#include "mem_defs.h"
    18.8 +
    18.9 +static char *argv0 = "internal_domain_sched_global";
   18.10 +
   18.11 +int main(int argc, char **argv)
   18.12 +{
   18.13 +    dom0_op_t op;
   18.14 +
   18.15 +    if ( argv[0] != NULL ) 
   18.16 +        argv0 = argv[0];
   18.17 +
   18.18 +    if ( argc != 2 ) 
   18.19 +    {
   18.20 +        fprintf(stderr, "Usage: %s <ctxt allowance>\n", argv0);
   18.21 +        return 1;
   18.22 +    }
   18.23 +
   18.24 +    op.cmd = DOM0_BVTCTL;
   18.25 +    op.u.bvtctl.ctx_allow = atol(argv[1]);
   18.26 +    if ( do_dom0_op(&op) < 0 )
   18.27 +        return 1;
   18.28 +
   18.29 +    return 0;
   18.30 +}
    19.1 --- a/tools/internal/xi_start.c	Thu Jul 10 13:42:56 2003 +0000
    19.2 +++ b/tools/internal/xi_start.c	Sat Jul 12 22:26:07 2003 +0000
    19.3 @@ -1,77 +1,37 @@
    19.4 -#include <unistd.h>
    19.5 -#include <stdio.h>
    19.6 -#include <errno.h>
    19.7 -#include <fcntl.h>
    19.8 -#include <sys/mman.h>
    19.9 -#include <sys/types.h>
   19.10 -#include <sys/stat.h>
   19.11 -#include <stdlib.h>
   19.12 -#include <string.h>
   19.13  
   19.14 -#include "dom0_ops.h"
   19.15 +#include "hypervisor-ifs/dom0_ops.h"
   19.16  #include "dom0_defs.h"
   19.17  #include "mem_defs.h"
   19.18  
   19.19 -/***********************************************************************/
   19.20 -
   19.21  static char *argv0 = "internal_domain_start";
   19.22  
   19.23 -static void ERROR (char *message)
   19.24 -{
   19.25 -  fprintf (stderr, "%s: %s\n", argv0, message);
   19.26 -  exit (-1);
   19.27 -}
   19.28 -
   19.29 -static void PERROR (char *message)
   19.30 -{
   19.31 -  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
   19.32 -  exit (-1);
   19.33 -}
   19.34 -
   19.35 -/***********************************************************************/
   19.36 -
   19.37  static int start_domain(int id)
   19.38  {
   19.39 -    char cmd_path[MAX_PATH];
   19.40 -    dom0_op_t dop;
   19.41 -    int cmd_fd;
   19.42 -
   19.43 -    /* Set up the DOM0_STARTDOMAIN command */
   19.44 -    dop.cmd = DOM0_STARTDOMAIN;
   19.45 -    dop.u.meminfo.domain = id;
   19.46 +    int err;
   19.47 +    dom0_op_t op;
   19.48  
   19.49 -    /* open the /proc command interface */
   19.50 -    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
   19.51 -    cmd_fd = open(cmd_path, O_WRONLY);
   19.52 -    if(cmd_fd < 0){
   19.53 -        PERROR ("Count not open PROC_CMD interface");
   19.54 -    }
   19.55 +    op.cmd = DOM0_STARTDOMAIN;
   19.56 +    op.u.meminfo.domain = id;
   19.57  
   19.58 -    /* Issue the command */
   19.59 -    write(cmd_fd, &dop, sizeof(dom0_op_t));
   19.60 -    close(cmd_fd);
   19.61 +    err = do_dom0_op(&op);
   19.62  
   19.63 -    return 0;
   19.64 +    return (err < 0) ? -1 : 0;
   19.65  }    
   19.66  
   19.67 -/***********************************************************************/
   19.68 -
   19.69  int main(int argc, char **argv)
   19.70  {
   19.71 -  int rc;
   19.72 +    int rc;
   19.73 +
   19.74 +    if ( argv[0] != NULL ) 
   19.75 +        argv0 = argv[0];
   19.76  
   19.77 -  if (argv[0] != NULL) 
   19.78 +    if ( argc != 2 ) 
   19.79      {
   19.80 -      argv0 = argv[0];
   19.81 +        fprintf(stderr, "Usage: %s <domain-id>\n", argv0);
   19.82 +        return 1;
   19.83      }
   19.84  
   19.85 -  if(argc != 2) 
   19.86 -    {
   19.87 -      fprintf (stderr, "Usage: %s <domain-id>\n", argv0);
   19.88 -      return -1;
   19.89 -    }
   19.90 +    rc = start_domain(atol(argv[1]));
   19.91  
   19.92 -  rc = start_domain(atol(argv[1]));
   19.93 -
   19.94 -  return rc;
   19.95 +    return (rc != 0) ? 1 : 0;
   19.96  }
    20.1 --- a/tools/internal/xi_stop.c	Thu Jul 10 13:42:56 2003 +0000
    20.2 +++ b/tools/internal/xi_stop.c	Sat Jul 12 22:26:07 2003 +0000
    20.3 @@ -1,79 +1,36 @@
    20.4 -#include <unistd.h>
    20.5 -#include <stdio.h>
    20.6 -#include <errno.h>
    20.7 -#include <fcntl.h>
    20.8 -#include <sys/mman.h>
    20.9 -#include <sys/types.h>
   20.10 -#include <sys/stat.h>
   20.11 -#include <stdlib.h>
   20.12 -
   20.13 -#include "dom0_ops.h"
   20.14 +#include "hypervisor-ifs/dom0_ops.h"
   20.15  #include "dom0_defs.h"
   20.16  #include "mem_defs.h"
   20.17  
   20.18 -/***********************************************************************/
   20.19 -
   20.20  static char *argv0 = "internal_domain_stop";
   20.21  
   20.22 -static void ERROR (char *message)
   20.23 -{
   20.24 -  fprintf (stderr, "%s: %s\n", argv0, message);
   20.25 -  exit (-1);
   20.26 -}
   20.27 -
   20.28 -static void PERROR (char *message)
   20.29 -{
   20.30 -  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
   20.31 -  exit (-1);
   20.32 -}
   20.33 -
   20.34 -/***********************************************************************/
   20.35 -
   20.36  static int stop_domain(int id)
   20.37  {
   20.38 -    dom0_newdomain_t * dom_data;
   20.39 -    char cmd_path[MAX_PATH];
   20.40 -    char dom_id_path[MAX_PATH];
   20.41 -    dom0_op_t dop;
   20.42 -    int cmd_fd;
   20.43 -    int id_fd;
   20.44 -
   20.45 -    /* Set up the DOM0_STOPDOMAIN command */
   20.46 -    dop.cmd = DOM0_STOPDOMAIN;
   20.47 -    dop.u.meminfo.domain = id;
   20.48 +    int err;
   20.49 +    dom0_op_t op;
   20.50  
   20.51 -    /* open the /proc command interface */
   20.52 -    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
   20.53 -    cmd_fd = open(cmd_path, O_WRONLY);
   20.54 -    if(cmd_fd < 0){
   20.55 -        PERROR ("Count not open PROC_CMD interface");
   20.56 -    }
   20.57 +    op.cmd = DOM0_STOPDOMAIN;
   20.58 +    op.u.meminfo.domain = id;
   20.59  
   20.60 -    /* Issue the command */
   20.61 -    write(cmd_fd, &dop, sizeof(dom0_op_t));
   20.62 -    close(cmd_fd);
   20.63 +    err = do_dom0_op(&op);
   20.64  
   20.65 -    return 0;
   20.66 +    return (err < 0) ? -1 : 0;
   20.67  }    
   20.68  
   20.69 -/***********************************************************************/
   20.70 -
   20.71  int main(int argc, char **argv)
   20.72  {
   20.73 -  int rc;
   20.74 +    int rc;
   20.75 +
   20.76 +    if ( argv[0] != NULL ) 
   20.77 +        argv0 = argv[0];
   20.78  
   20.79 -  if (argv[0] != NULL) 
   20.80 +    if ( argc != 2 ) 
   20.81      {
   20.82 -      argv0 = argv[0];
   20.83 +        fprintf(stderr, "Usage: %s <domain-id>\n", argv0);
   20.84 +        return 1;
   20.85      }
   20.86  
   20.87 -  if(argc != 2) 
   20.88 -    {
   20.89 -      fprintf (stderr, "Usage: %s <domain-id>\n", argv0);
   20.90 -      return -1;
   20.91 -    }
   20.92 +    rc = stop_domain(atol(argv[1]));
   20.93  
   20.94 -  rc = stop_domain(atol(argv[1]));
   20.95 -
   20.96 -  return rc;
   20.97 +    return (rc != 0) ? 1 : 0;
   20.98  }
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/internal/xi_usage.c	Sat Jul 12 22:26:07 2003 +0000
    21.3 @@ -0,0 +1,64 @@
    21.4 +
    21.5 +#include "hypervisor-ifs/dom0_ops.h"
    21.6 +#include "dom0_defs.h"
    21.7 +#include "mem_defs.h"
    21.8 +
    21.9 +static char *argv0 = "internal_domain_usage";
   21.10 +
   21.11 +int main(int argc, char **argv)
   21.12 +{
   21.13 +    dom0_op_t    op;
   21.14 +    network_op_t netop;
   21.15 +    int          i, domain, vifs[32];
   21.16 +
   21.17 +    if ( argv[0] != NULL ) 
   21.18 +        argv0 = argv[0];
   21.19 +
   21.20 +    if ( argc != 2 ) 
   21.21 +    {
   21.22 +        fprintf(stderr, "Usage: %s <domain-id>\n", argv0);
   21.23 +        return 1;
   21.24 +    }
   21.25 +
   21.26 +    domain = atol(argv[1]);
   21.27 +
   21.28 +    op.cmd                 = DOM0_GETDOMAININFO;
   21.29 +    op.u.getdominfo.domain = domain;
   21.30 +    if ( do_dom0_op(&op) < 0 )
   21.31 +        return 1;
   21.32 +
   21.33 +    printf("cpu%d: %lld\n", 
   21.34 +           op.u.getdominfo.processor,
   21.35 +           op.u.getdominfo.cpu_time);
   21.36 +
   21.37 +    if ( mlock(vifs, sizeof(vifs)) != 0 )
   21.38 +    {
   21.39 +        PERROR("Could not lock memory for network query buffer");
   21.40 +        return 1;
   21.41 +    }
   21.42 +
   21.43 +    netop.cmd = NETWORK_OP_VIFQUERY;
   21.44 +    netop.u.vif_query.domain = domain;
   21.45 +    netop.u.vif_query.buf    = vifs;
   21.46 +    if ( do_network_op(&netop) < 0 )
   21.47 +        return 1;
   21.48 +
   21.49 +    for ( i = 1; i <= vifs[0]; i++ )
   21.50 +    {
   21.51 +        netop.cmd = NETWORK_OP_VIFGETINFO;
   21.52 +        netop.u.vif_getinfo.domain = domain;
   21.53 +        netop.u.vif_getinfo.vif    = vifs[i];
   21.54 +        if ( do_network_op(&netop) < 0 )
   21.55 +            return 1;
   21.56 +
   21.57 +        printf("vif%d: sent %lld bytes (%lld packets) "
   21.58 +               "received %lld bytes (%lld packets)\n",
   21.59 +               vifs[i],
   21.60 +               netop.u.vif_getinfo.total_bytes_sent,
   21.61 +               netop.u.vif_getinfo.total_packets_sent,
   21.62 +               netop.u.vif_getinfo.total_bytes_received,
   21.63 +               netop.u.vif_getinfo.total_packets_received);
   21.64 +    }
   21.65 +
   21.66 +    return 0;
   21.67 +}
    22.1 --- a/tools/internal/xi_vifinit	Thu Jul 10 13:42:56 2003 +0000
    22.2 +++ b/tools/internal/xi_vifinit	Sat Jul 12 22:26:07 2003 +0000
    22.3 @@ -16,10 +16,10 @@ then
    22.4  fi
    22.5  
    22.6  #outbound rule:
    22.7 -echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/vfr
    22.8 +echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/xeno/vfr
    22.9  
   22.10  #inbound rule:
   22.11 -echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/vfr
   22.12 +echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/xeno/vfr
   22.13  
   22.14  #----] done.
   22.15  
    23.1 --- a/xen/common/dom0_ops.c	Thu Jul 10 13:42:56 2003 +0000
    23.2 +++ b/xen/common/dom0_ops.c	Sat Jul 12 22:26:07 2003 +0000
    23.3 @@ -146,9 +146,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    23.4          ret = p->domain;
    23.5          
    23.6          op.u.newdomain.domain = ret;
    23.7 -        op.u.newdomain.pg_head = 
    23.8 -            list_entry(p->pg_head.next, struct pfn_info, list) -
    23.9 -            frame_table;
   23.10          copy_to_user(u_dom0_op, &op, sizeof(op));
   23.11  
   23.12      exit_create:
   23.13 @@ -189,16 +186,38 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   23.14      case DOM0_GETMEMLIST:
   23.15      {
   23.16          int i;
   23.17 -        unsigned long pfn = op.u.getmemlist.start_pfn;
   23.18 +        struct task_struct * p = find_domain_by_id(op.u.getmemlist.domain);
   23.19 +        unsigned long max_pfns = op.u.getmemlist.max_pfns;
   23.20 +        unsigned long pfn;
   23.21          unsigned long *buffer = op.u.getmemlist.buffer;
   23.22          struct list_head *list_ent;
   23.23  
   23.24 -        for ( i = 0; i < op.u.getmemlist.num_pfns; i++ )
   23.25 +        ret = -EINVAL;
   23.26 +        if ( p != NULL )
   23.27          {
   23.28 -            /* XXX We trust DOM0 to give us a safe buffer. XXX */
   23.29 -            *buffer++ = pfn;
   23.30 -            list_ent = frame_table[pfn].list.next;
   23.31 +            list_ent = p->pg_head.next;
   23.32              pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
   23.33 +            
   23.34 +            for ( i = 0; (i < max_pfns) && (list_ent != &p->pg_head); i++ )
   23.35 +            {
   23.36 +                if ( put_user(pfn, buffer) )
   23.37 +                {
   23.38 +                    ret = -EFAULT;
   23.39 +                    goto out_getmemlist;
   23.40 +                }
   23.41 +                buffer++;
   23.42 +                list_ent = frame_table[pfn].list.next;
   23.43 +                pfn = list_entry(list_ent, struct pfn_info, list) - 
   23.44 +                    frame_table;
   23.45 +            }
   23.46 +
   23.47 +            op.u.getmemlist.num_pfns = i;
   23.48 +            copy_to_user(u_dom0_op, &op, sizeof(op));
   23.49 +
   23.50 +            ret = 0;
   23.51 +
   23.52 +        out_getmemlist:
   23.53 +            put_task_struct(p);
   23.54          }
   23.55      }
   23.56      break;
   23.57 @@ -227,9 +246,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   23.58              op.u.getdominfo.state       = p->state;
   23.59              op.u.getdominfo.hyp_events  = p->hyp_events;
   23.60              op.u.getdominfo.mcu_advance = p->mcu_advance;
   23.61 -            op.u.getdominfo.pg_head     = 
   23.62 -                list_entry(p->pg_head.next, struct pfn_info, list) -
   23.63 -                frame_table;
   23.64              op.u.getdominfo.tot_pages   = p->tot_pages;
   23.65              op.u.getdominfo.cpu_time    = p->cpu_time;
   23.66          }
    24.1 --- a/xen/common/domain.c	Thu Jul 10 13:42:56 2003 +0000
    24.2 +++ b/xen/common/domain.c	Sat Jul 12 22:26:07 2003 +0000
    24.3 @@ -462,6 +462,7 @@ static unsigned long alloc_page_from_dom
    24.4   * userspace dom0 and final setup is being done by final_setup_guestos.
    24.5   */
    24.6  int setup_guestos(struct task_struct *p, dom0_newdomain_t *params, 
    24.7 +                  unsigned int num_vifs,
    24.8                    char *phy_data_start, unsigned long data_len, 
    24.9  		  char *cmdline, unsigned long initrd_len)
   24.10  {
   24.11 @@ -689,7 +690,7 @@ int setup_guestos(struct task_struct *p,
   24.12      }
   24.13  
   24.14      /* Add virtual network interfaces and point to them in startinfo. */
   24.15 -    while (params->num_vifs-- > 0) {
   24.16 +    while (num_vifs-- > 0) {
   24.17          net_vif = create_net_vif(dom);
   24.18          shared_rings = net_vif->shared_rings;
   24.19          if (!shared_rings) panic("no network ring!\n");
    25.1 --- a/xen/common/kernel.c	Thu Jul 10 13:42:56 2003 +0000
    25.2 +++ b/xen/common/kernel.c	Sat Jul 12 22:26:07 2003 +0000
    25.3 @@ -197,9 +197,7 @@ void cmain (unsigned long magic, multibo
    25.4      start_of_day();
    25.5  
    25.6      /* Create initial domain 0. */
    25.7 -    dom0_params.num_vifs  = 1;
    25.8      dom0_params.memory_kb = opt_dom0_mem;
    25.9 -
   25.10      new_dom = do_newdomain(0, 0);
   25.11      if ( new_dom == NULL ) panic("Error creating domain 0\n");
   25.12  
   25.13 @@ -209,7 +207,7 @@ void cmain (unsigned long magic, multibo
   25.14       * present, is an initrd ramdisk
   25.15       */
   25.16      if ( setup_guestos(new_dom, 
   25.17 -                       &dom0_params, 
   25.18 +                       &dom0_params, 1,
   25.19                         (char *)MAX_DIRECTMAP_ADDRESS, 
   25.20                         mod[mbi->mods_count-1].mod_end - mod[0].mod_start,
   25.21                         __va(mod[0].string),
    26.1 --- a/xen/common/network.c	Thu Jul 10 13:42:56 2003 +0000
    26.2 +++ b/xen/common/network.c	Sat Jul 12 22:26:07 2003 +0000
    26.3 @@ -8,7 +8,6 @@
    26.4   * Copyright (c) 2002-2003, A K Warfield and K A Fraser
    26.5   */
    26.6  
    26.7 -#include <hypervisor-ifs/network.h>
    26.8  #include <xeno/sched.h>
    26.9  #include <xeno/errno.h>
   26.10  #include <xeno/init.h>
   26.11 @@ -20,6 +19,7 @@
   26.12  #include <xeno/in.h>
   26.13  #include <asm/domain_page.h>
   26.14  #include <asm/io.h>
   26.15 +#include <hypervisor-ifs/network.h>
   26.16  
   26.17  net_rule_ent_t *net_rule_list;                      /* global list of rules */
   26.18  kmem_cache_t *net_vif_cache;                        
   26.19 @@ -222,7 +222,7 @@ int vif_query(vif_query_t *vq)
   26.20      if ( !(p = find_domain_by_id(vq->domain)) ) {
   26.21          buf[0] = -1;
   26.22          copy_to_user(vq->buf, buf, sizeof(int));
   26.23 -        return -ENOSYS;
   26.24 +        return -ESRCH;
   26.25      }
   26.26  
   26.27      for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
   26.28 @@ -524,12 +524,13 @@ long do_network_op(network_op_t *u_netwo
   26.29  {
   26.30      long ret=0;
   26.31      network_op_t op;
   26.32 -    
   26.33 +
   26.34      if ( current->domain != 0 )
   26.35          return -EPERM;
   26.36  
   26.37      if ( copy_from_user(&op, u_network_op, sizeof(op)) )
   26.38          return -EFAULT;
   26.39 +
   26.40      switch ( op.cmd )
   26.41      {
   26.42  
   26.43 @@ -566,6 +567,7 @@ long do_network_op(network_op_t *u_netwo
   26.44      {
   26.45          ret = vif_query(&op.u.vif_query);
   26.46      }
   26.47 +    break;
   26.48      
   26.49      default:
   26.50          ret = -ENOSYS;
    27.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h	Thu Jul 10 13:42:56 2003 +0000
    27.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h	Sat Jul 12 22:26:07 2003 +0000
    27.3 @@ -26,11 +26,11 @@
    27.4  
    27.5  typedef struct dom0_newdomain_st 
    27.6  {
    27.7 -    unsigned int domain;    // return parameter
    27.8 +    /* IN parameters. */
    27.9      unsigned int memory_kb; 
   27.10 -    unsigned int num_vifs;  // temporary
   27.11 -    unsigned long pg_head;  // return parameter
   27.12      char name[MAX_DOMAIN_NAME];
   27.13 +    /* OUT parameters. */
   27.14 +    unsigned int domain; 
   27.15  } dom0_newdomain_t;
   27.16  
   27.17  typedef struct dom0_killdomain_st
   27.18 @@ -41,14 +41,17 @@ typedef struct dom0_killdomain_st
   27.19  
   27.20  typedef struct dom0_getmemlist_st
   27.21  {
   27.22 -    unsigned long start_pfn;
   27.23 +    /* IN variables. */
   27.24 +    unsigned int  domain;
   27.25 +    unsigned long max_pfns;
   27.26 +    void         *buffer;
   27.27 +    /* OUT variables. */
   27.28      unsigned long num_pfns;
   27.29 -    void *buffer;
   27.30  } dom0_getmemlist_t;
   27.31  
   27.32  typedef struct domain_launch
   27.33  {
   27.34 -    unsigned int domain;
   27.35 +    unsigned int  domain;
   27.36      unsigned long l2_pgt_addr;
   27.37      unsigned long virt_load_addr;
   27.38      unsigned long virt_shinfo_addr;
   27.39 @@ -75,14 +78,15 @@ typedef struct dom0_adjustdom_st
   27.40  
   27.41  typedef struct dom0_getdominfo_st
   27.42  {
   27.43 -    unsigned int domain;          /* All returns except domain */
   27.44 +    /* IN variables. */
   27.45 +    unsigned int domain;
   27.46 +    /* OUT variables. */
   27.47      char name[MAX_DOMAIN_NAME];
   27.48      int processor;
   27.49      int has_cpu;
   27.50      int state;
   27.51      int hyp_events;
   27.52      unsigned long mcu_advance;
   27.53 -    unsigned long pg_head;
   27.54      unsigned int tot_pages;
   27.55      long long cpu_time;
   27.56  } dom0_getdominfo_t;
   27.57 @@ -93,7 +97,6 @@ typedef struct dom0_iopl_st
   27.58      unsigned int iopl;
   27.59  } dom0_iopl_t;
   27.60  
   27.61 -#ifndef NO_DOM0_OP_T
   27.62  typedef struct dom0_op_st
   27.63  {
   27.64      unsigned long cmd;
   27.65 @@ -110,6 +113,5 @@ typedef struct dom0_op_st
   27.66      }
   27.67      u;
   27.68  } dom0_op_t;
   27.69 -#endif
   27.70  
   27.71  #endif
    28.1 --- a/xen/include/hypervisor-ifs/network.h	Thu Jul 10 13:42:56 2003 +0000
    28.2 +++ b/xen/include/hypervisor-ifs/network.h	Sat Jul 12 22:26:07 2003 +0000
    28.3 @@ -12,9 +12,6 @@
    28.4  #ifndef __RING_H__
    28.5  #define __RING_H__
    28.6  
    28.7 -#include <linux/types.h>
    28.8 -
    28.9 -
   28.10  typedef struct tx_req_entry_st
   28.11  {
   28.12      unsigned short id;
    29.1 --- a/xen/include/xeno/sched.h	Thu Jul 10 13:42:56 2003 +0000
    29.2 +++ b/xen/include/xeno/sched.h	Sat Jul 12 22:26:07 2003 +0000
    29.3 @@ -226,7 +226,7 @@ extern struct task_struct first_task_str
    29.4  
    29.5  extern struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu);
    29.6  extern int setup_guestos(
    29.7 -    struct task_struct *p, dom0_newdomain_t *params,
    29.8 +    struct task_struct *p, dom0_newdomain_t *params, unsigned int num_vifs,
    29.9      char *data_start, unsigned long data_len, 
   29.10      char *cmdline, unsigned long initrd_len);
   29.11  extern int final_setup_guestos(struct task_struct *p, dom_meminfo_t *);
    30.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/Makefile	Thu Jul 10 13:42:56 2003 +0000
    30.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/Makefile	Sat Jul 12 22:26:07 2003 +0000
    30.3 @@ -48,14 +48,18 @@ HEAD := arch/xeno/kernel/head.o arch/xen
    30.4  
    30.5  SUBDIRS += arch/xeno/kernel arch/xeno/mm arch/xeno/lib
    30.6  SUBDIRS += arch/xeno/drivers/console arch/xeno/drivers/network
    30.7 -SUBDIRS += arch/xeno/drivers/dom0 arch/xeno/drivers/block
    30.8 -SUBDIRS += arch/xeno/drivers/balloon
    30.9 +SUBDIRS += arch/xeno/drivers/block arch/xeno/drivers/balloon
   30.10 +ifdef CONFIG_XENO_PRIV
   30.11 +SUBDIRS += arch/xeno/drivers/dom0 
   30.12 +endif
   30.13  
   30.14  CORE_FILES += arch/xeno/kernel/kernel.o arch/xeno/mm/mm.o
   30.15  CORE_FILES += arch/xeno/drivers/console/con.o
   30.16  CORE_FILES += arch/xeno/drivers/block/blk.o
   30.17  CORE_FILES += arch/xeno/drivers/network/net.o
   30.18 +ifdef CONFIG_XENO_PRIV
   30.19  CORE_FILES += arch/xeno/drivers/dom0/dom0.o
   30.20 +endif
   30.21  CORE_FILES += arch/xeno/drivers/balloon/balloon_driver.o
   30.22  LIBS := $(TOPDIR)/arch/xeno/lib/lib.a $(LIBS) $(TOPDIR)/arch/xeno/lib/lib.a
   30.23  
    31.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/config.in	Thu Jul 10 13:42:56 2003 +0000
    31.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/config.in	Sat Jul 12 22:26:07 2003 +0000
    31.3 @@ -13,6 +13,11 @@ define_bool CONFIG_SBUS n
    31.4  define_bool CONFIG_UID16 y
    31.5  
    31.6  mainmenu_option next_comment
    31.7 +comment 'Privileged guest OS'
    31.8 +bool 'Support for privileged operations (domain 0)' CONFIG_XENO_PRIV
    31.9 +endmenu
   31.10 +
   31.11 +mainmenu_option next_comment
   31.12  comment 'Code maturity level options'
   31.13  bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
   31.14  endmenu
    32.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/defconfig	Thu Jul 10 13:42:56 2003 +0000
    32.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/defconfig	Sat Jul 12 22:26:07 2003 +0000
    32.3 @@ -8,6 +8,11 @@ CONFIG_ISA=y
    32.4  CONFIG_UID16=y
    32.5  
    32.6  #
    32.7 +# Privileged guest OS
    32.8 +#
    32.9 +CONFIG_XENO_PRIV=y
   32.10 +
   32.11 +#
   32.12  # Code maturity level options
   32.13  #
   32.14  # CONFIG_EXPERIMENTAL is not set
    33.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/Makefile	Thu Jul 10 13:42:56 2003 +0000
    33.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/Makefile	Sat Jul 12 22:26:07 2003 +0000
    33.3 @@ -1,3 +1,3 @@
    33.4  O_TARGET := blk.o
    33.5 -obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o xl_segment_proc.o xl_physdisk_proc.o
    33.6 +obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o xl_segment_proc.o
    33.7  include $(TOPDIR)/Rules.make
    34.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c	Thu Jul 10 13:42:56 2003 +0000
    34.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c	Sat Jul 12 22:26:07 2003 +0000
    34.3 @@ -43,6 +43,31 @@ static inline void signal_requests_to_xe
    34.4      HYPERVISOR_block_io_op();
    34.5  }
    34.6  
    34.7 +
    34.8 +inline kdev_t physdev_to_xldev(unsigned short physdev)
    34.9 +{
   34.10 +    switch (physdev & XENDEV_TYPE_MASK) {
   34.11 +    case XENDEV_IDE:
   34.12 +        if ( (physdev & XENDEV_IDX_MASK) < XLIDE_DEVS_PER_MAJOR) {
   34.13 +	    return MKDEV(XLIDE_MAJOR_0,
   34.14 +			 (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
   34.15 +	} else if ( (physdev & XENDEV_IDX_MASK) < (XLIDE_DEVS_PER_MAJOR * 2)) {
   34.16 +	    return MKDEV(XLIDE_MAJOR_1,
   34.17 +			 (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
   34.18 +	}
   34.19 +	break;
   34.20 +    case XENDEV_SCSI:
   34.21 +	return MKDEV(XLSCSI_MAJOR,
   34.22 +		     (physdev & XENDEV_IDX_MASK) << XLSCSI_PARTN_SHIFT);
   34.23 +    case XENDEV_VIRTUAL:
   34.24 +	return MKDEV(XLVIRT_MAJOR,
   34.25 +		     (physdev & XENDEV_IDX_MASK) << XLVIRT_PARTN_SHIFT);
   34.26 +    }
   34.27 +
   34.28 +    return 0;
   34.29 +}
   34.30 +
   34.31 +
   34.32  /* Convert from a XenoLinux major device to the Xen-level 'physical' device */
   34.33  inline unsigned short xldev_to_physdev(kdev_t xldev) 
   34.34  {
   34.35 @@ -69,8 +94,6 @@ inline unsigned short xldev_to_physdev(k
   34.36          break;
   34.37      } 
   34.38  
   34.39 -    if ( physdev == 0 ) BUG();
   34.40 -
   34.41      return physdev;
   34.42  }
   34.43  
    35.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.h	Thu Jul 10 13:42:56 2003 +0000
    35.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.h	Sat Jul 12 22:26:07 2003 +0000
    35.3 @@ -104,4 +104,7 @@ extern struct gendisk *xlscsi_gendisk;
    35.4  extern int  xlsegment_hwsect(int minor); 
    35.5  extern struct gendisk *xlsegment_gendisk;
    35.6  
    35.7 +extern unsigned short xldev_to_physdev(kdev_t xldev);
    35.8 +extern kdev_t physdev_to_xldev(unsigned short physdev);
    35.9 +
   35.10  #endif /* __XL_BLOCK_H__ */
    36.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c	Thu Jul 10 13:42:56 2003 +0000
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,119 +0,0 @@
    36.4 -/* We stuff the domain number into the proc_dir_entry data pointer. */
    36.5 -#include <linux/kernel.h>
    36.6 -#include <linux/module.h>
    36.7 -#include <linux/fs.h>
    36.8 -#include <asm/errno.h>
    36.9 -#include <linux/slab.h>
   36.10 -#include <asm/hypervisor-ifs/block.h>
   36.11 -#include <asm/uaccess.h>
   36.12 -#include <linux/proc_fs.h>
   36.13 -
   36.14 -#include "xl_block.h"
   36.15 -
   36.16 -extern int xenolinux_control_msg(int operration, char *buffer, int size);
   36.17 -extern unsigned short xldev_to_physdev(kdev_t xldev);
   36.18 -
   36.19 -dev_t physdev_to_xldev(unsigned short physdev)
   36.20 -{
   36.21 -    switch (physdev & XENDEV_TYPE_MASK) {
   36.22 -    case XENDEV_IDE:
   36.23 -        if ( (physdev & XENDEV_IDX_MASK) < XLIDE_DEVS_PER_MAJOR) {
   36.24 -	    return MKDEV(XLIDE_MAJOR_0,
   36.25 -			 (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
   36.26 -	} else if ( (physdev & XENDEV_IDX_MASK) < (XLIDE_DEVS_PER_MAJOR * 2)) {
   36.27 -	    return MKDEV(XLIDE_MAJOR_1,
   36.28 -			 (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
   36.29 -	}
   36.30 -	break;
   36.31 -    case XENDEV_SCSI:
   36.32 -	return MKDEV(XLSCSI_MAJOR,
   36.33 -		     (physdev & XENDEV_IDX_MASK) << XLSCSI_PARTN_SHIFT);
   36.34 -    case XENDEV_VIRTUAL:
   36.35 -	return MKDEV(XLVIRT_MAJOR,
   36.36 -		     (physdev & XENDEV_IDX_MASK) << XLVIRT_PARTN_SHIFT);
   36.37 -    }
   36.38 -    printk(KERN_ALERT "Unrecognised xl device: %x\n", physdev);
   36.39 -    BUG();
   36.40 -    return -1;
   36.41 -}
   36.42 -
   36.43 -static ssize_t proc_read_phd(struct file *file, char *buff, size_t size,
   36.44 -			     loff_t * off)
   36.45 -{
   36.46 -    physdisk_probebuf_t *buf;
   36.47 -    int res;
   36.48 -    struct proc_dir_entry *pde;
   36.49 -    int x;
   36.50 -
   36.51 -    if (size != sizeof(physdisk_probebuf_t))
   36.52 -	return -EINVAL;
   36.53 -
   36.54 -    buf = kmalloc(sizeof(physdisk_probebuf_t), GFP_KERNEL);
   36.55 -    if (!buf)
   36.56 -	return -ENOMEM;
   36.57 -
   36.58 -    pde = file->f_dentry->d_inode->u.generic_ip;
   36.59 -    buf->domain = (int) pde->data;
   36.60 -
   36.61 -    /* The offset reported by lseek and friends doesn't have to be in
   36.62 -       bytes, and it's marginally easier to say that it's in records, so
   36.63 -       that's what we do. */
   36.64 -    buf->start_ind = *off;
   36.65 -    res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_PROBE, (void *) buf,
   36.66 -				sizeof(physdisk_probebuf_t));
   36.67 -    *off += buf->n_aces;
   36.68 -
   36.69 -    if (res)
   36.70 -	res = -EINVAL;
   36.71 -    else {
   36.72 -	for (x = 0; x < buf->n_aces; x++)
   36.73 -	    buf->entries[x].device =
   36.74 -		physdev_to_xldev(buf->entries[x].device);
   36.75 -	res = sizeof(physdisk_probebuf_t);
   36.76 -	if (copy_to_user(buff, buf, sizeof(physdisk_probebuf_t))) {
   36.77 -	    res = -EFAULT;
   36.78 -	}
   36.79 -    }
   36.80 -    kfree(buf);
   36.81 -    return res;
   36.82 -}
   36.83 -
   36.84 -static int proc_write_phd(struct file *file, const char *buffer,
   36.85 -			  size_t count, loff_t * ignore)
   36.86 -{
   36.87 -    char *local;
   36.88 -    int res;
   36.89 -    xp_disk_t *xpd;
   36.90 -    struct proc_dir_entry *pde;
   36.91 -
   36.92 -    if (count != sizeof(xp_disk_t))
   36.93 -	return -EINVAL;
   36.94 -
   36.95 -    local = kmalloc(count + 1, GFP_KERNEL);
   36.96 -    if (!local)
   36.97 -	return -ENOMEM;
   36.98 -    if (copy_from_user(local, buffer, count)) {
   36.99 -	res = -EFAULT;
  36.100 -	goto out;
  36.101 -    }
  36.102 -
  36.103 -    xpd = (xp_disk_t *) local;
  36.104 -
  36.105 -    pde = file->f_dentry->d_inode->u.generic_ip;
  36.106 -    xpd->domain = (int) pde->data;
  36.107 -    xpd->device = xldev_to_physdev(xpd->device);
  36.108 -
  36.109 -    res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_GRANT, local, count);
  36.110 -    if (res == 0)
  36.111 -	res = count;
  36.112 -    else
  36.113 -	res = -EINVAL;
  36.114 -  out:
  36.115 -    kfree(local);
  36.116 -    return res;
  36.117 -}
  36.118 -
  36.119 -struct file_operations dom0_phd_fops = {
  36.120 -  read:proc_read_phd,
  36.121 -  write:proc_write_phd
  36.122 -};
    37.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c	Thu Jul 10 13:42:56 2003 +0000
    37.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c	Sat Jul 12 22:26:07 2003 +0000
    37.3 @@ -12,9 +12,6 @@
    37.4  
    37.5  static struct proc_dir_entry *vhd;
    37.6  
    37.7 -extern unsigned short xldev_to_physdev(kdev_t xldev);
    37.8 -extern dev_t physdev_to_xldev(unsigned short physdev);
    37.9 -
   37.10  static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos)
   37.11  {
   37.12      xen_segment_info_t *data;
   37.13 @@ -310,11 +307,13 @@ static struct file_operations proc_vhd_o
   37.14  
   37.15  int __init xlseg_proc_init(void)
   37.16  {
   37.17 -    vhd = create_proc_entry("xeno/dom0/vhd", 0600, NULL);
   37.18 -    if (vhd == NULL)
   37.19 -    {
   37.20 +    if ( !(start_info.flags & SIF_PRIVILEGED) )
   37.21 +        return 0;
   37.22 +
   37.23 +    vhd = create_proc_entry("xeno/vhd", 0600, NULL);
   37.24 +    if ( vhd == NULL )
   37.25          panic ("xlseg_init: unable to create vhd proc entry\n");
   37.26 -    }
   37.27 +
   37.28      vhd->data       = NULL;
   37.29      vhd->proc_fops  = &proc_vhd_operations;
   37.30      vhd->owner      = THIS_MODULE;
    38.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/Makefile	Thu Jul 10 13:42:56 2003 +0000
    38.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/Makefile	Sat Jul 12 22:26:07 2003 +0000
    38.3 @@ -1,3 +1,3 @@
    38.4  O_TARGET := dom0.o
    38.5 -obj-y := dom0_memory.o dom0_core.o vfr.o sched_ops.o
    38.6 +obj-y := dom0_core.o vfr.o
    38.7  include $(TOPDIR)/Rules.make
    39.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c	Thu Jul 10 13:42:56 2003 +0000
    39.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.3 @@ -1,27 +0,0 @@
    39.4 -/*
    39.5 - * domain 0 block driver interface
    39.6 - *
    39.7 - */
    39.8 -
    39.9 -#include <linux/config.h>
   39.10 -#include <linux/module.h>
   39.11 -#include <linux/kernel.h>
   39.12 -#include <linux/sched.h>
   39.13 -
   39.14 -static int __init init_module(void)
   39.15 -{
   39.16 -  request_module("xl_block");
   39.17 -  printk("Successfully installed domain 0 block interface\n");
   39.18 -
   39.19 -
   39.20 -  return 0;
   39.21 -}
   39.22 -
   39.23 -static void __exit cleanup_module(void)
   39.24 -{
   39.25 -  printk("Successfully de-installed domain-0 block interface\n");
   39.26 -  return 0;
   39.27 -}
   39.28 -
   39.29 -module_init(init_module);
   39.30 -module_exit(cleanup_module);
    40.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c	Thu Jul 10 13:42:56 2003 +0000
    40.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c	Sat Jul 12 22:26:07 2003 +0000
    40.3 @@ -3,7 +3,7 @@
    40.4   * 
    40.5   * Interface to privileged domain-0 commands.
    40.6   * 
    40.7 - * Copyright (c) 2002, K A Fraser, B Dragovic
    40.8 + * Copyright (c) 2002-2003, K A Fraser, B Dragovic
    40.9   */
   40.10  
   40.11  #include <linux/config.h>
   40.12 @@ -14,7 +14,6 @@
   40.13  #include <linux/string.h>
   40.14  #include <linux/errno.h>
   40.15  #include <linux/proc_fs.h>
   40.16 -
   40.17  #include <linux/mm.h>
   40.18  #include <linux/mman.h>
   40.19  #include <linux/swap.h>
   40.20 @@ -29,392 +28,117 @@
   40.21  #include <asm/pgtable.h>
   40.22  #include <asm/uaccess.h>
   40.23  #include <asm/tlb.h>
   40.24 -#include <asm/dom0.h>
   40.25 -
   40.26 -#include "dom0_ops.h"
   40.27 -
   40.28 -#define MAP_DISCONT 1
   40.29 +#include <asm/proc_cmd.h>
   40.30 +#include <asm/hypervisor-ifs/dom0_ops.h>
   40.31  
   40.32 -/* Private proc-file data structures. */
   40.33 -typedef struct proc_data {
   40.34 -    unsigned int domain;
   40.35 -    unsigned long map_size;
   40.36 -} dom_procdata_t;
   40.37 -
   40.38 -/* XXX this certainly shouldn't be here. */
   40.39 -extern struct file_operations dom0_phd_fops;
   40.40 +#include "../block/xl_block.h"
   40.41  
   40.42  struct proc_dir_entry *xeno_base;
   40.43 -static struct proc_dir_entry *dom0_cmd_intf;
   40.44 -static struct proc_dir_entry *dom_list_intf;
   40.45 +static struct proc_dir_entry *privcmd_intf;
   40.46 +
   40.47  
   40.48 -int direct_unmap(struct mm_struct *, unsigned long, unsigned long);
   40.49 -unsigned long direct_mmap(unsigned long phys_addr, unsigned long size, 
   40.50 -			  pgprot_t prot, int flag, int tot_pages);
   40.51 -struct list_head * find_direct(struct list_head *, unsigned long);
   40.52 -
   40.53 -static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff_t * off)
   40.54 +static int privcmd_ioctl(struct inode *inode, struct file *file,
   40.55 +                         unsigned int cmd, unsigned long data)
   40.56  {
   40.57 -    char str[256];
   40.58 -    int vifs[32];
   40.59 -    dom0_op_t op;
   40.60 -    network_op_t netop;
   40.61 -    int i, end;
   40.62 -    unsigned int domain;
   40.63 -    static int finished = 0;
   40.64 +    int ret = 0;
   40.65 +
   40.66 +    switch ( cmd )
   40.67 +    {
   40.68 +    case IOCTL_PRIVCMD_HYPERCALL:
   40.69 +    {
   40.70 +        privcmd_hypercall_t hypercall;
   40.71 +        if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
   40.72 +            return -EFAULT;
   40.73 +        __asm__ __volatile__ (
   40.74 +            "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
   40.75 +            "movl  4(%%eax),%%ebx ;"
   40.76 +            "movl  8(%%eax),%%ecx ;"
   40.77 +            "movl 12(%%eax),%%edx ;"
   40.78 +            "movl 16(%%eax),%%esi ;"
   40.79 +            "movl 20(%%eax),%%edi ;"
   40.80 +            "movl   (%%eax),%%eax ;"
   40.81 +            TRAP_INSTR "; "
   40.82 +            "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
   40.83 +            : "=a" (ret) : "0" (&hypercall) : "memory" );
   40.84 +    }
   40.85 +    break;
   40.86  
   40.87 -    if ( finished )
   40.88 +    case IOCTL_PRIVCMD_BLKMSG:
   40.89      {
   40.90 -        finished = 0;
   40.91 -        return 0;
   40.92 +        privcmd_blkmsg_t blkmsg;
   40.93 +        char            *kbuf;
   40.94 +        int              ret;
   40.95 +        if ( copy_from_user(&blkmsg, (void *)data, sizeof(blkmsg)) )
   40.96 +            return -EFAULT;
   40.97 +        if ( blkmsg.buf_size > PAGE_SIZE )
   40.98 +            return -EINVAL;
   40.99 +        if ( (kbuf = kmalloc(blkmsg.buf_size, GFP_KERNEL)) == NULL )
  40.100 +            return -ENOMEM;
  40.101 +        if ( copy_from_user(kbuf, blkmsg.buf, blkmsg.buf_size) ) {
  40.102 +            kfree(kbuf);
  40.103 +            return -EFAULT;
  40.104 +        }
  40.105 +        ret = xenolinux_control_msg((int)blkmsg.op, kbuf, blkmsg.buf_size);
  40.106 +        if ( ret != 0 ) {
  40.107 +            kfree(kbuf);
  40.108 +            return ret;
  40.109 +        }
  40.110 +        if ( copy_to_user(blkmsg.buf, kbuf, blkmsg.buf_size) ) {
  40.111 +            kfree(kbuf);
  40.112 +            return -EFAULT;
  40.113 +        }
  40.114 +        kfree(kbuf);
  40.115 +    }
  40.116 +    break;
  40.117 +    
  40.118 +    case IOCTL_PRIVCMD_LINDEV_TO_XENDEV:
  40.119 +        ret = (int)xldev_to_physdev((kdev_t)data);
  40.120 +
  40.121 +    case IOCTL_PRIVCMD_XENDEV_TO_LINDEV:
  40.122 +        ret = (int)physdev_to_xldev((unsigned short)data);
  40.123 +
  40.124 +    default:
  40.125 +    {
  40.126 +        ret = -EINVAL;
  40.127 +    }
  40.128 +    break;
  40.129      }
  40.130  
  40.131 -    domain = (unsigned int)
  40.132 -        ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
  40.133 -    op.cmd = DOM0_GETDOMAININFO;
  40.134 -
  40.135 -    op.u.getdominfo.domain = domain;
  40.136 -
  40.137 -    (void) HYPERVISOR_dom0_op(&op);
  40.138 -
  40.139 -    end = snprintf(str, 256, "cpu: %lld\n", op.u.getdominfo.cpu_time);
  40.140 -
  40.141 -    netop.cmd = NETWORK_OP_VIFQUERY;
  40.142 -    netop.u.vif_query.domain = domain;
  40.143 -    netop.u.vif_query.buf = vifs;
  40.144 -
  40.145 -    (void) HYPERVISOR_network_op(&netop);
  40.146 -
  40.147 -    for(i = 1; i <= vifs[0]; i++) {
  40.148 -        netop.cmd = NETWORK_OP_VIFGETINFO;
  40.149 -        netop.u.vif_getinfo.domain = domain;
  40.150 -        netop.u.vif_getinfo.vif = vifs[i];
  40.151 -
  40.152 -        (void) HYPERVISOR_network_op(&netop);
  40.153 -
  40.154 -        end += snprintf(str + end, 255 - end,
  40.155 -                        "vif%d: sent %lld bytes (%lld packets) "
  40.156 -                        "received %lld bytes (%lld packets)\n",
  40.157 -                        vifs[i],
  40.158 -                        netop.u.vif_getinfo.total_bytes_sent,
  40.159 -                        netop.u.vif_getinfo.total_packets_sent,
  40.160 -                        netop.u.vif_getinfo.total_bytes_received,
  40.161 -                        netop.u.vif_getinfo.total_packets_received);
  40.162 -    }
  40.163 -
  40.164 -    if (*off >= end + 1) return 0;
  40.165 -    
  40.166 -    copy_to_user(buff, str, end);
  40.167 -
  40.168 -    finished = 1;
  40.169 -
  40.170 -    return end + 1;
  40.171 +    return ret;
  40.172  }
  40.173  
  40.174 -static struct file_operations dom_usage_ops = {
  40.175 -    read:    dom_usage_read
  40.176 +
  40.177 +static struct file_operations privcmd_file_ops = {
  40.178 +  ioctl : privcmd_ioctl
  40.179  };
  40.180  
  40.181  
  40.182 -static void create_proc_dom_entries(int dom)
  40.183 -{
  40.184 -    struct proc_dir_entry * dir;
  40.185 -    dom_procdata_t * dom_data;
  40.186 -    char dir_name[16];
  40.187 -    struct proc_dir_entry * file;
  40.188 -
  40.189 -    sprintf(dir_name, "dom%d", dom);
  40.190 -
  40.191 -    dom_data = (dom_procdata_t *)kmalloc(sizeof(dom_procdata_t), GFP_KERNEL);
  40.192 -    dom_data->domain = dom;
  40.193 -
  40.194 -    dir = proc_mkdir(dir_name, xeno_base);
  40.195 -    dir->data = dom_data;
  40.196 -    
  40.197 -    file = create_proc_entry("usage", 0600, dir);
  40.198 -    if (file != NULL)
  40.199 -    {
  40.200 -        file->owner         = THIS_MODULE;
  40.201 -        file->nlink         = 1;
  40.202 -        file->proc_fops     = &dom_usage_ops;
  40.203 -        file->data          = (void *) dom;
  40.204 -    }
  40.205 -
  40.206 -    file = create_proc_entry("phd", 0600, dir);
  40.207 -    if (file != NULL)
  40.208 -    {
  40.209 -        file->owner         = THIS_MODULE;
  40.210 -        file->nlink         = 1;
  40.211 -        file->proc_fops     = &dom0_phd_fops;
  40.212 -        file->data          = (void *) dom;
  40.213 -    }
  40.214 -}
  40.215 -
  40.216 -/***********************************************************************
  40.217 - *
  40.218 - * Implementation of /proc/xeno/domains
  40.219 - */
  40.220 -
  40.221 -static dom0_op_t proc_domains_op;
  40.222 -static int proc_domains_finished;
  40.223 -static DECLARE_MUTEX(proc_xeno_domains_lock);
  40.224 -
  40.225 -static void *xeno_domains_next(struct seq_file *s, void *v, loff_t *pos)
  40.226 -{
  40.227 -    int ret;
  40.228 -
  40.229 -    if ( pos != NULL )
  40.230 -        ++(*pos); 
  40.231 -
  40.232 -    if ( !proc_domains_finished ) 
  40.233 -    {
  40.234 -        proc_domains_op.u.getdominfo.domain++;
  40.235 -        ret = HYPERVISOR_dom0_op(&proc_domains_op);
  40.236 -        if ( ret < 0 ) 
  40.237 -            proc_domains_finished = 1;
  40.238 -    }
  40.239 -  
  40.240 -    return (proc_domains_finished) ? NULL : &proc_domains_op;
  40.241 -}
  40.242 -
  40.243 -static void *xeno_domains_start(struct seq_file *s, loff_t *ppos)
  40.244 -{ 
  40.245 -    loff_t pos = *ppos;
  40.246 -  
  40.247 -    down (&proc_xeno_domains_lock);
  40.248 -    proc_domains_op.cmd = DOM0_GETDOMAININFO;
  40.249 -    proc_domains_op.u.getdominfo.domain = 0;
  40.250 -    (void)HYPERVISOR_dom0_op(&proc_domains_op);
  40.251 -    proc_domains_finished = 0;
  40.252 -  
  40.253 -    while (pos > 0) {
  40.254 -        pos --;
  40.255 -        xeno_domains_next (s, NULL, NULL);
  40.256 -    }
  40.257 -  
  40.258 -    return (proc_domains_finished) ? NULL : &proc_domains_op;
  40.259 -}
  40.260 -
  40.261 -static void xeno_domains_stop(struct seq_file *s, void *v)
  40.262 -{ 
  40.263 -    up(&proc_xeno_domains_lock);
  40.264 -}
  40.265 -
  40.266 -static int xeno_domains_show(struct seq_file *s, void *v)
  40.267 -{ 
  40.268 -    dom0_op_t *di = v;
  40.269 -  
  40.270 -    /*
  40.271 -     * Output one domain's details to dom0.
  40.272 -     *
  40.273 -     * If you update this format string then change xi_list to match.
  40.274 -     */
  40.275 -
  40.276 -    seq_printf (s, 
  40.277 -                "%8d %2d %1d %2d %8d %8ld %p %8d %s\n",
  40.278 -                di -> u.getdominfo.domain, 
  40.279 -                di -> u.getdominfo.processor,
  40.280 -                di -> u.getdominfo.has_cpu,
  40.281 -                di -> u.getdominfo.state,
  40.282 -                di -> u.getdominfo.hyp_events,
  40.283 -                di -> u.getdominfo.mcu_advance,
  40.284 -                (void *)di -> u.getdominfo.pg_head,
  40.285 -                di -> u.getdominfo.tot_pages,
  40.286 -                di -> u.getdominfo.name);
  40.287 -
  40.288 -    return 0;
  40.289 -}
  40.290 -
  40.291 -static struct seq_operations xeno_domains_op = {
  40.292 -    .start          = xeno_domains_start,
  40.293 -    .next           = xeno_domains_next,
  40.294 -    .stop           = xeno_domains_stop,
  40.295 -    .show           = xeno_domains_show,
  40.296 -};
  40.297 -
  40.298 -static int xeno_domains_open(struct inode *inode, struct file *file)
  40.299 -{
  40.300 -    return seq_open(file, &xeno_domains_op);
  40.301 -}
  40.302 -
  40.303 -static struct file_operations proc_xeno_domains_operations = {
  40.304 -    open:           xeno_domains_open,
  40.305 -    read:           seq_read,
  40.306 -    llseek:         seq_lseek,
  40.307 -    release:        seq_release,
  40.308 -};
  40.309 -
  40.310 -/***********************************************************************
  40.311 - *
  40.312 - * Implementation of /proc/xeno/dom0_cmd
  40.313 - */
  40.314 -
  40.315 -static int dom0_cmd_write(struct file *file, const char *buffer, size_t size,
  40.316 -			  loff_t *off)
  40.317 -{
  40.318 -    dom0_op_t op;
  40.319 -    
  40.320 -    copy_from_user(&op, buffer, sizeof(dom0_op_t));
  40.321 -
  40.322 -    return HYPERVISOR_dom0_op(&op);
  40.323 -}
  40.324 -
  40.325 -static int handle_dom0_cmd_createdomain(unsigned long data)
  40.326 -{
  40.327 -  struct dom0_createdomain_args argbuf;
  40.328 -  int namelen;
  40.329 -  dom0_op_t op;
  40.330 -  int ret;
  40.331 -
  40.332 -  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
  40.333 -    return -EFAULT;
  40.334 -
  40.335 -  op.cmd = DOM0_CREATEDOMAIN;
  40.336 -  op.u.newdomain.domain = -666;
  40.337 -  op.u.newdomain.memory_kb = argbuf.kb_mem;
  40.338 -  op.u.newdomain.num_vifs = 0; /* Not used anymore -- it's done in
  40.339 -				  BUILDDOMAIN. */
  40.340 -  namelen = strnlen_user(argbuf.name, MAX_DOMAIN_NAME);
  40.341 -  if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1))
  40.342 -    return -EFAULT;
  40.343 -
  40.344 -  /* Error checking?  The old code deosn't appear to do any, and I
  40.345 -     can't see where the return values are documented... */
  40.346 -  ret = HYPERVISOR_dom0_op(&op);
  40.347 -
  40.348 -  if (op.u.newdomain.domain == -666) {
  40.349 -    /* HACK: We use this to detect whether the create actually
  40.350 -       succeeded, because Xen doesn't appear to want to tell us... */
  40.351 -
  40.352 -    /* The only time I've actually got this to happen was when trying
  40.353 -       to create a domain with more memory than is actually in the
  40.354 -       machine, so we guess the error code is ENOMEM. */
  40.355 -    return -ENOMEM;
  40.356 -  }
  40.357 -
  40.358 -  /* Create proc entries */
  40.359 -  ret = op.u.newdomain.domain;
  40.360 -  create_proc_dom_entries(ret);
  40.361 -
  40.362 -  return ret;
  40.363 -}
  40.364 -
  40.365 -static unsigned long handle_dom0_cmd_mapdommem(unsigned long data)
  40.366 -{
  40.367 -  struct dom0_mapdommem_args argbuf;
  40.368 -
  40.369 -  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
  40.370 -    return -EFAULT;
  40.371 -
  40.372 -  return direct_mmap(argbuf.start_pfn << PAGE_SHIFT,
  40.373 -		     argbuf.tot_pages << PAGE_SHIFT,
  40.374 -		     PAGE_SHARED,
  40.375 -		     MAP_DISCONT,
  40.376 -		     argbuf.tot_pages);
  40.377 -}
  40.378 -
  40.379 -static int handle_dom0_cmd_unmapdommem(unsigned long data)
  40.380 -{
  40.381 -  struct dom0_unmapdommem_args argbuf;
  40.382 -
  40.383 -  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
  40.384 -    return -EFAULT;
  40.385 -
  40.386 -  return direct_unmap(current->mm, argbuf.vaddr,
  40.387 -		      argbuf.tot_pages << PAGE_SHIFT);
  40.388 -}
  40.389 -
  40.390 -static int handle_dom0_cmd_dopgupdates(unsigned long data)
  40.391 -{
  40.392 -    struct dom0_dopgupdates_args argbuf;
  40.393 -    struct list_head *entry;
  40.394 -    direct_mmap_node_t *node;
  40.395 -
  40.396 -    if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
  40.397 -	return -EFAULT;
  40.398 -
  40.399 -    /* argbuf.pgt_update_arr had better be direct mapped... */
  40.400 -    /* Actually, we only *really* need to make sure that all of it's
  40.401 -       pages are in memory and aren't going to get swapped out in the
  40.402 -       mean time, but this is slightly easier than checking all of
  40.403 -       that and is sufficient for the current userspace tools. */
  40.404 -    entry = find_direct(&current->mm->context.direct_list,
  40.405 -			argbuf.pgt_update_arr);
  40.406 -    if (entry == &current->mm->context.direct_list)
  40.407 -	return -EINVAL;
  40.408 -    node = list_entry(entry, direct_mmap_node_t, list);
  40.409 -    if (node->vm_start > argbuf.pgt_update_arr ||
  40.410 -	node->vm_end <= argbuf.pgt_update_arr * sizeof(page_update_request_t))
  40.411 -	return -EINVAL;
  40.412 -    
  40.413 -    return HYPERVISOR_pt_update((void *)argbuf.pgt_update_arr,
  40.414 -				argbuf.num_pgt_updates);
  40.415 -}
  40.416 -
  40.417 -static int dom0_cmd_ioctl(struct inode *inode, struct file *file,
  40.418 -			  unsigned int cmd, unsigned long data)
  40.419 -{
  40.420 -  switch (cmd) {
  40.421 -  case IOCTL_DOM0_CREATEDOMAIN:
  40.422 -    return handle_dom0_cmd_createdomain(data);
  40.423 -  case IOCTL_DOM0_MAPDOMMEM:
  40.424 -    return handle_dom0_cmd_mapdommem(data);
  40.425 -  case IOCTL_DOM0_UNMAPDOMMEM:
  40.426 -    return handle_dom0_cmd_unmapdommem(data);
  40.427 -  case IOCTL_DOM0_DOPGUPDATES:
  40.428 -    return handle_dom0_cmd_dopgupdates(data);
  40.429 -  default:
  40.430 -    return -ENOTTY; /* It isn't obvious why this is the correct error
  40.431 -		       code when an ioctl isn't recognised, but it
  40.432 -		       does appear to be what's used in the rest of
  40.433 -		       the kernel. */
  40.434 -  }
  40.435 -}
  40.436 -
  40.437 -/***********************************************************************/
  40.438 -
  40.439 -
  40.440 -static struct file_operations dom0_cmd_file_ops = {
  40.441 -  write : dom0_cmd_write,
  40.442 -  ioctl : dom0_cmd_ioctl
  40.443 -};
  40.444 -
  40.445  static int __init init_module(void)
  40.446  {
  40.447 +    if ( !(start_info.flags & SIF_PRIVILEGED) )
  40.448 +        return 0;
  40.449 +
  40.450      /* xeno proc root setup */
  40.451      xeno_base = proc_mkdir("xeno", &proc_root); 
  40.452  
  40.453      /* xeno control interface */
  40.454 -    dom0_cmd_intf = create_proc_entry("dom0_cmd", 0600, xeno_base);
  40.455 -
  40.456 -    if ( dom0_cmd_intf != NULL )
  40.457 +    privcmd_intf = create_proc_entry("privcmd", 0400, xeno_base);
  40.458 +    if ( privcmd_intf != NULL )
  40.459      {
  40.460 -        dom0_cmd_intf->owner      = THIS_MODULE;
  40.461 -        dom0_cmd_intf->nlink      = 1;
  40.462 -	dom0_cmd_intf->proc_fops  = &dom0_cmd_file_ops;
  40.463 +        privcmd_intf->owner      = THIS_MODULE;
  40.464 +        privcmd_intf->nlink      = 1;
  40.465 +	privcmd_intf->proc_fops  = &privcmd_file_ops;
  40.466      }
  40.467  
  40.468 -    /* domain list interface */
  40.469 -    dom_list_intf = create_proc_entry("domains", 0400, xeno_base);
  40.470 -    if ( dom_list_intf != NULL )
  40.471 -    {
  40.472 -        dom_list_intf->owner = THIS_MODULE;
  40.473 -        dom_list_intf->nlink = 1;
  40.474 -        dom_list_intf->proc_fops = &proc_xeno_domains_operations;
  40.475 -    }
  40.476 -
  40.477 -    /* set up /proc entries for dom 0 */
  40.478 -    create_proc_dom_entries(0);
  40.479 -
  40.480      return 0;
  40.481  }
  40.482  
  40.483  
  40.484  static void __exit cleanup_module(void)
  40.485  {
  40.486 -    if ( dom0_cmd_intf == NULL ) return;
  40.487 -    remove_proc_entry("dom0", &proc_root);
  40.488 -    dom0_cmd_intf = NULL;
  40.489 +    if ( privcmd_intf == NULL ) return;
  40.490 +    remove_proc_entry("xeno", &proc_root);
  40.491 +    privcmd_intf = NULL;
  40.492  }
  40.493  
  40.494  
    41.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c	Thu Jul 10 13:42:56 2003 +0000
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,151 +0,0 @@
    41.4 -#include <linux/slab.h>
    41.5 -#include <linux/mm.h>
    41.6 -#include <linux/mman.h>
    41.7 -#include <linux/swap.h>
    41.8 -#include <linux/smp_lock.h>
    41.9 -#include <linux/swapctl.h>
   41.10 -#include <linux/iobuf.h>
   41.11 -#include <linux/highmem.h>
   41.12 -#include <linux/pagemap.h>
   41.13 -#include <linux/list.h>
   41.14 -
   41.15 -#include <asm/pgalloc.h>
   41.16 -#include <asm/uaccess.h>
   41.17 -#include <asm/tlb.h>
   41.18 -#include <asm/mmu.h>
   41.19 -
   41.20 -#include "dom0_ops.h"
   41.21 -
   41.22 -#define MAP_CONT    0
   41.23 -#define MAP_DISCONT 1
   41.24 -
   41.25 -extern struct list_head * find_direct(struct list_head *, unsigned long);
   41.26 -extern int direct_remap_area_pages(struct mm_struct *, unsigned long, 
   41.27 -                                   unsigned long, unsigned long, pgprot_t);
   41.28 -extern void direct_zap_page_range(struct mm_struct *, unsigned long, 
   41.29 -                                  unsigned long);
   41.30 -
   41.31 -/* 
   41.32 - * used for remapping discontiguous bits of domain's memory, pages to map are
   41.33 - * found from frame table beginning at the given first_pg index
   41.34 - */ 
   41.35 -int direct_remap_disc_page_range(unsigned long from, 
   41.36 -                                 unsigned long first_pg, 
   41.37 -                                 int tot_pages, 
   41.38 -                                 pgprot_t prot)
   41.39 -{
   41.40 -    dom0_op_t dom0_op;
   41.41 -    unsigned long *pfns = (unsigned long *)get_free_page(GFP_KERNEL);
   41.42 -    unsigned long start = from;
   41.43 -    int pages, i;
   41.44 -
   41.45 -    while ( tot_pages != 0 )
   41.46 -    {
   41.47 -        dom0_op.cmd = DOM0_GETMEMLIST;
   41.48 -        dom0_op.u.getmemlist.start_pfn = first_pg;
   41.49 -        pages = 1023;
   41.50 -        dom0_op.u.getmemlist.num_pfns = 1024;
   41.51 -        if ( tot_pages < 1024 )
   41.52 -            dom0_op.u.getmemlist.num_pfns = pages = tot_pages;
   41.53 -        dom0_op.u.getmemlist.buffer = pfns;
   41.54 -        (void)HYPERVISOR_dom0_op(&dom0_op);
   41.55 -        first_pg = pfns[1023]; 
   41.56 -
   41.57 -        for ( i = 0; i < pages; i++ )
   41.58 -        {
   41.59 -            if(direct_remap_area_pages(current->mm,
   41.60 -                                       start, pfns[i] << PAGE_SHIFT, 
   41.61 -                                       PAGE_SIZE, prot))
   41.62 -                goto out;
   41.63 -            start += PAGE_SIZE;
   41.64 -            tot_pages--;
   41.65 -        }
   41.66 -    }
   41.67 -
   41.68 - out:
   41.69 -    free_page((unsigned long)pfns);
   41.70 -    return tot_pages;
   41.71 -} 
   41.72 -           
   41.73 -
   41.74 -unsigned long direct_mmap(unsigned long phys_addr, unsigned long size, 
   41.75 -                          pgprot_t prot, int flag, int tot_pages)
   41.76 -{
   41.77 -    direct_mmap_node_t * dmmap;
   41.78 -    struct list_head * entry;
   41.79 -    unsigned long addr;
   41.80 -    int ret = 0;
   41.81 -    
   41.82 -    if(!capable(CAP_SYS_ADMIN)){
   41.83 -        ret = -EPERM;
   41.84 -        goto out;
   41.85 -    }
   41.86 -
   41.87 -    /* get unmapped area invokes xen specific arch_get_unmapped_area */
   41.88 -    addr = get_unmapped_area(NULL, 0, size, 0, 0);
   41.89 -    if(addr & ~PAGE_MASK){
   41.90 -        ret = -ENOMEM;
   41.91 -        goto out;
   41.92 -    }
   41.93 -
   41.94 -    /* add node on the list of directly mapped areas, make sure the
   41.95 -     * list remains sorted.
   41.96 -     */ 
   41.97 -    dmmap = (direct_mmap_node_t *)kmalloc(sizeof(direct_mmap_node_t), GFP_KERNEL);
   41.98 -    dmmap->vm_start = addr;
   41.99 -    dmmap->vm_end = addr + size;
  41.100 -    entry = find_direct(&current->mm->context.direct_list, addr);
  41.101 -    if(entry != &current->mm->context.direct_list){
  41.102 -        list_add_tail(&dmmap->list, entry);
  41.103 -    } else {
  41.104 -    	list_add_tail(&dmmap->list, &current->mm->context.direct_list);
  41.105 -    }
  41.106 -
  41.107 -    /* and perform the mapping */
  41.108 -    if(flag == MAP_DISCONT){
  41.109 -        ret = direct_remap_disc_page_range(addr, phys_addr >> PAGE_SHIFT, 
  41.110 -                                           tot_pages, prot);
  41.111 -    } else {
  41.112 -        ret = direct_remap_area_pages(current->mm, 
  41.113 -                                      addr, phys_addr, size, prot);
  41.114 -    }
  41.115 -
  41.116 -    if(ret == 0)
  41.117 -        ret = addr;
  41.118 -
  41.119 - out: 
  41.120 -    return ret;
  41.121 -}
  41.122 -
  41.123 -
  41.124 -int direct_unmap(struct mm_struct *mm, unsigned long addr, unsigned long size)
  41.125 -{
  41.126 -    int count = 0, tot_pages = (size+PAGE_SIZE-1) >> PAGE_SHIFT;
  41.127 -    direct_mmap_node_t * node;
  41.128 -    struct list_head * curr;
  41.129 -    struct list_head * direct_list = &mm->context.direct_list;    
  41.130 -
  41.131 -    curr = direct_list->next;
  41.132 -    while ( curr != direct_list )
  41.133 -    {
  41.134 -        node = list_entry(curr, direct_mmap_node_t, list);
  41.135 -        if ( node->vm_start == addr )
  41.136 -            break;
  41.137 -        curr = curr->next;
  41.138 -    }
  41.139 -
  41.140 -    if ( curr == direct_list )
  41.141 -        return -1;
  41.142 -
  41.143 -    list_del(&node->list);
  41.144 -    kfree(node);
  41.145 -
  41.146 -    while ( count < tot_pages )
  41.147 -    {
  41.148 -        direct_zap_page_range(mm, addr, PAGE_SIZE);
  41.149 -        addr += PAGE_SIZE;
  41.150 -        count++;
  41.151 -    }
  41.152 -
  41.153 -    return 0;
  41.154 -} 
    42.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h	Thu Jul 10 13:42:56 2003 +0000
    42.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.3 @@ -1,56 +0,0 @@
    42.4 -/******************************************************************************
    42.5 - * dom0_ops.h
    42.6 - * 
    42.7 - * Process command requests from domain-0 guest OS.
    42.8 - * This file includes the Xen part of the interface, plus the extra stuff
    42.9 - * that is dealt with by Xenolinux without being handed down to Xen.
   42.10 - * 
   42.11 - * Copyright (c) 2002-2003, K A Fraser, B Dragovic
   42.12 - */
   42.13 -
   42.14 -#ifndef __DOM0_DOM0_OPS_H__
   42.15 -#define __DOM0_DOM0_OPS_H__
   42.16 -
   42.17 -/* External users of this header file will include Xen's version separately. */
   42.18 -#ifdef __KERNEL__
   42.19 -#define NO_DOM0_OP_T
   42.20 -#include <asm/hypervisor-ifs/dom0_ops.h>
   42.21 -#endif
   42.22 -
   42.23 -/* Extra commands dealt with by Xenolinux. */
   42.24 -#define MAP_DOM_MEM        1014
   42.25 -#define DO_PGUPDATES       1015
   42.26 -
   42.27 -typedef struct dom_mem 
   42.28 -{
   42.29 -    unsigned int domain;
   42.30 -    unsigned long vaddr;
   42.31 -    unsigned long start_pfn;
   42.32 -    int tot_pages;
   42.33 -} dom_mem_t;
   42.34 -
   42.35 -typedef struct dom_pgupdate
   42.36 -{
   42.37 -    unsigned long pgt_update_arr;
   42.38 -    unsigned long num_pgt_updates;
   42.39 -} dom_pgupdate_t;
   42.40 -
   42.41 -typedef struct dom0_op_st
   42.42 -{
   42.43 -    unsigned long cmd;
   42.44 -    union
   42.45 -    {
   42.46 -        dom0_newdomain_t newdomain;
   42.47 -        dom0_killdomain_t killdomain;
   42.48 -        dom0_getmemlist_t getmemlist;
   42.49 -        dom0_bvtctl_t bvtctl;
   42.50 -        dom0_adjustdom_t adjustdom;
   42.51 -        dom_mem_t dommem;
   42.52 -        dom_pgupdate_t pgupdate;
   42.53 -        dom_meminfo_t meminfo;
   42.54 -        dom0_getdominfo_t getdominfo;
   42.55 -        dom0_iopl_t iopl;
   42.56 -   } u;
   42.57 -} dom0_op_t;
   42.58 -
   42.59 -#endif /* __DOM0_DOM0_OPS_H__ */
    43.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c	Thu Jul 10 13:42:56 2003 +0000
    43.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.3 @@ -1,137 +0,0 @@
    43.4 -/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
    43.5 - ****************************************************************************
    43.6 - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
    43.7 - ****************************************************************************
    43.8 - *
    43.9 - *        File: sched_ops.c
   43.10 - *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
   43.11 - *     Changes: 
   43.12 - *              
   43.13 - *        Date: Mar 2003
   43.14 - * 
   43.15 - * Environment: XenoLinux
   43.16 - * Description: Dom0 Control interface to scheduler in Xen
   43.17 - *
   43.18 - * code based on Andy's vfr parsing code
   43.19 - *
   43.20 - * Commands understood by the interface:
   43.21 - *
   43.22 - * C <context swith allowance>
   43.23 - * S <did> <mcu advance> <warp> <warp limit> <unwarp limit>
   43.24 - *
   43.25 - ****************************************************************************
   43.26 - * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
   43.27 - ****************************************************************************
   43.28 - */
   43.29 -
   43.30 -#include <linux/config.h>
   43.31 -#include <linux/module.h>
   43.32 -#include <linux/kernel.h>
   43.33 -#include <linux/sched.h>
   43.34 -#include <linux/ctype.h>
   43.35 -#include <linux/string.h>
   43.36 -#include <linux/errno.h>
   43.37 -#include <linux/proc_fs.h>
   43.38 -
   43.39 -#include "dom0_ops.h"
   43.40 -
   43.41 -#define SCHED_ENTRY    "sched"
   43.42 -extern struct proc_dir_entry *xeno_base;
   43.43 -static struct proc_dir_entry *sched_pde;
   43.44 -
   43.45 -static unsigned char readbuf[1024];
   43.46 -
   43.47 -static int sched_read_proc(char *page, char **start, off_t off,
   43.48 -                           int count, int *eof, void *data)
   43.49 -{   
   43.50 -    strcpy(page, readbuf);
   43.51 -    *readbuf = '\0';
   43.52 -    *eof = 1;
   43.53 -    *start = page;
   43.54 -    return strlen(page);
   43.55 -}
   43.56 -
   43.57 -
   43.58 -static int sched_write_proc(struct file *file, const char *buffer,
   43.59 -                            u_long count, void *data)
   43.60 -{
   43.61 -    dom0_op_t op;
   43.62 -
   43.63 -    int ret, len;
   43.64 -    int ts, te, tl; /* token start, end, and length */
   43.65 -
   43.66 -    /* Only admin can adjust scheduling parameters */
   43.67 -    if ( !capable(CAP_SYS_ADMIN) )
   43.68 -        return -EPERM;
   43.69 -
   43.70 -    /* parse the commands  */
   43.71 -    len = count;
   43.72 -    ts = te = 0;
   43.73 -
   43.74 -    while ( count && isspace(buffer[ts]) ) { ts++; count--; } /*skip spaces*/
   43.75 -    te = ts;
   43.76 -    while ( count && !isspace(buffer[te]) ) { te++; count--; } /*command end*/
   43.77 -    if ( te <= ts ) goto bad;
   43.78 -    tl = te - ts;
   43.79 -
   43.80 -    if ( strncmp(&buffer[ts], "C", tl) == 0 ) {
   43.81 -        op.cmd = DOM0_BVTCTL;
   43.82 -    } else if ( strncmp(&buffer[ts], "S", tl) == 0 ) {
   43.83 -        op.cmd = DOM0_ADJUSTDOM;
   43.84 -    } else
   43.85 -        goto bad;
   43.86 -
   43.87 -    /* skip whitspaces and get first parameter */
   43.88 -    ts = te; while ( count &&  isspace(buffer[ts]) ) { ts++; count--; }
   43.89 -    te = ts; while ( count && !isspace(buffer[te]) ) { te++; count--; }
   43.90 -    if ( te <= ts ) goto bad;
   43.91 -    tl = te - ts;
   43.92 -    if ( !isdigit(buffer[ts]) ) goto bad;
   43.93 -
   43.94 -    if (op.cmd == DOM0_BVTCTL) {
   43.95 -        /* get context switch allowance  */
   43.96 -        sscanf(&buffer[ts], "%lu", &op.u.bvtctl.ctx_allow);
   43.97 -    } else if (op.cmd == DOM0_ADJUSTDOM) {
   43.98 -        sscanf(&buffer[ts], "%u %lu %lu %lu %lu",
   43.99 -               &op.u.adjustdom.domain,
  43.100 -               &op.u.adjustdom.mcu_adv,
  43.101 -               &op.u.adjustdom.warp,
  43.102 -               &op.u.adjustdom.warpl,
  43.103 -               &op.u.adjustdom.warpu);
  43.104 -    }
  43.105 -    ret = HYPERVISOR_dom0_op(&op);
  43.106 -    return sizeof(op);
  43.107 -    
  43.108 - bad:
  43.109 -    return -EINVAL;
  43.110 -
  43.111 -}
  43.112 -
  43.113 -
  43.114 -/*
  43.115 - * main scheduler interface driver driver initialization function.
  43.116 - */
  43.117 -static int __init init_module(void)
  43.118 -{
  43.119 -    printk(KERN_ALERT "Starting Domain Scheduler Control Interface\n");
  43.120 -
  43.121 -    sched_pde = create_proc_entry(SCHED_ENTRY, 0600, xeno_base);
  43.122 -    if ( sched_pde == NULL )
  43.123 -    {
  43.124 -        printk(KERN_ALERT "Unable to create dom scheduler proc entry!");
  43.125 -        return -1;
  43.126 -    }
  43.127 -
  43.128 -    sched_pde->read_proc  = sched_read_proc;
  43.129 -    sched_pde->write_proc = sched_write_proc;
  43.130 -
  43.131 -    return 0;
  43.132 -}
  43.133 -
  43.134 -static void __exit cleanup_module(void)
  43.135 -{
  43.136 -}
  43.137 -
  43.138 -module_init(init_module);
  43.139 -module_exit(cleanup_module);
  43.140 -
    44.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/vfr.c	Thu Jul 10 13:42:56 2003 +0000
    44.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/vfr.c	Sat Jul 12 22:26:07 2003 +0000
    44.3 @@ -224,7 +224,7 @@ static int vfr_write_proc(struct file *f
    44.4  static int __init init_module(void)
    44.5  {
    44.6      *readbuf = '\0';
    44.7 -    proc_vfr = create_proc_entry ("vfr", 0600, &proc_root);
    44.8 +    proc_vfr = create_proc_entry ("xeno/vfr", 0600, &proc_root);
    44.9      if ( proc_vfr != NULL )
   44.10      {
   44.11          proc_vfr->owner      = THIS_MODULE;
   44.12 @@ -239,7 +239,7 @@ static int __init init_module(void)
   44.13  static void __exit cleanup_module(void)
   44.14  {
   44.15      if ( proc_vfr == NULL ) return;
   44.16 -    remove_proc_entry("vfr", &proc_root);
   44.17 +    remove_proc_entry("xeno/vfr", &proc_root);
   44.18      proc_vfr = NULL;
   44.19  }
   44.20  
    45.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/kernel/process.c	Thu Jul 10 13:42:56 2003 +0000
    45.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/kernel/process.c	Sat Jul 12 22:26:07 2003 +0000
    45.3 @@ -145,9 +145,6 @@ void release_segments(struct mm_struct *
    45.4          flush_page_update_queue();
    45.5          vfree(ldt);
    45.6      }
    45.7 -
    45.8 -    /* YUK! We do this here because destroy_context() is too late. */
    45.9 -    destroy_direct_list(mm);
   45.10  }
   45.11  
   45.12  /*
    46.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/mm/Makefile	Thu Jul 10 13:42:56 2003 +0000
    46.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/mm/Makefile	Sat Jul 12 22:26:07 2003 +0000
    46.3 @@ -9,7 +9,7 @@
    46.4  
    46.5  O_TARGET := mm.o
    46.6  
    46.7 -obj-y	 := init.o fault.o extable.o pageattr.o hypervisor.o get_unmapped_area.o ioremap.o
    46.8 +obj-y	 := init.o fault.o extable.o pageattr.o hypervisor.o ioremap.o
    46.9  
   46.10  export-objs := pageattr.o
   46.11  
    47.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c	Thu Jul 10 13:42:56 2003 +0000
    47.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.3 @@ -1,114 +0,0 @@
    47.4 -
    47.5 -#include <linux/slab.h>
    47.6 -#include <linux/shm.h>
    47.7 -#include <linux/mman.h>
    47.8 -#include <linux/pagemap.h>
    47.9 -#include <linux/swap.h>
   47.10 -#include <linux/swapctl.h>
   47.11 -#include <linux/smp_lock.h>
   47.12 -#include <linux/init.h>
   47.13 -#include <linux/file.h>
   47.14 -#include <linux/fs.h>
   47.15 -#include <linux/personality.h>
   47.16 -
   47.17 -#include <asm/uaccess.h>
   47.18 -#include <asm/pgalloc.h>
   47.19 -
   47.20 -extern int direct_unmap(struct mm_struct *, unsigned long, unsigned long);
   47.21 -
   47.22 -int init_direct_list(struct mm_struct *mm)
   47.23 -{
   47.24 -    INIT_LIST_HEAD(&mm->context.direct_list);
   47.25 -    return 0;
   47.26 -}
   47.27 -
   47.28 -
   47.29 -void destroy_direct_list(struct mm_struct *mm)
   47.30 -{
   47.31 -    struct list_head *curr, *direct_list = &mm->context.direct_list;
   47.32 -    while ( (curr = direct_list->next) != direct_list )
   47.33 -    {
   47.34 -        direct_mmap_node_t *node = list_entry(curr, direct_mmap_node_t, list);
   47.35 -        if ( direct_unmap(mm, node->vm_start, node->vm_end - node->vm_start) )
   47.36 -            BUG();
   47.37 -    }
   47.38 -}
   47.39 -
   47.40 -
   47.41 -struct list_head *find_direct(struct list_head *list, unsigned long addr)
   47.42 -{
   47.43 -    struct list_head * curr;
   47.44 -    struct list_head * direct_list = &current->mm->context.direct_list;
   47.45 -    direct_mmap_node_t * node;
   47.46 -
   47.47 -    for ( curr = direct_list->next; curr != direct_list; curr = curr->next )
   47.48 -    {
   47.49 -        node = list_entry(curr, direct_mmap_node_t, list);
   47.50 -        if ( node->vm_start >= addr ) break;
   47.51 -    }
   47.52 -
   47.53 -    return curr;
   47.54 -}
   47.55 -
   47.56 -
   47.57 -unsigned long arch_get_unmapped_area(struct file *filp, 
   47.58 -                                     unsigned long addr, 
   47.59 -                                     unsigned long len, 
   47.60 -                                     unsigned long pgoff, 
   47.61 -                                     unsigned long flags)
   47.62 -{
   47.63 -    struct vm_area_struct *vma;
   47.64 -    direct_mmap_node_t * node;
   47.65 -    struct list_head * curr;
   47.66 -    struct list_head * direct_list = &current->mm->context.direct_list;
   47.67 -
   47.68 -    if ( len > TASK_SIZE )
   47.69 -        return -ENOMEM;
   47.70 -
   47.71 -    if ( addr )
   47.72 -    {
   47.73 -        addr = PAGE_ALIGN(addr);
   47.74 -        vma = find_vma(current->mm, addr);
   47.75 -        curr = find_direct(direct_list, addr);
   47.76 -        node = list_entry(curr, direct_mmap_node_t, list);
   47.77 -        if ( (TASK_SIZE - len >= addr) &&
   47.78 -             (!vma || addr + len <= vma->vm_start) &&
   47.79 -             ((curr == direct_list) || addr + len <= node->vm_start) )
   47.80 -            return addr;
   47.81 -    }
   47.82 -
   47.83 -    addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
   47.84 -
   47.85 -
   47.86 -    /* Find first VMA and direct_map nodes with vm_start > addr */
   47.87 -    vma  = find_vma(current->mm, addr);
   47.88 -    curr = find_direct(direct_list, addr);
   47.89 -    node = list_entry(curr, direct_mmap_node_t, list);
   47.90 -
   47.91 -    for ( ; ; )
   47.92 -    {
   47.93 -        if ( TASK_SIZE - len < addr ) return -ENOMEM;
   47.94 -
   47.95 -        if ( vma && ((curr == direct_list) || 
   47.96 -                     (vma->vm_start < node->vm_start)) )
   47.97 -        {
   47.98 -            /* Do we fit before VMA node? */
   47.99 -            if ( addr + len <= vma->vm_start ) return addr;
  47.100 -            addr = vma->vm_end;
  47.101 -            vma = vma->vm_next;
  47.102 -        }
  47.103 -        else if ( curr != direct_list )
  47.104 -        {
  47.105 -            /* Do we fit before direct_map node? */
  47.106 -            if ( addr + len <= node->vm_start) return addr;
  47.107 -            addr = node->vm_end;
  47.108 -            curr = curr->next;
  47.109 -            node = list_entry(curr, direct_mmap_node_t, list);
  47.110 -        }
  47.111 -        else
  47.112 -        {
  47.113 -            /* !vma && curr == direct_list */
  47.114 -            return addr;
  47.115 -        }
  47.116 -    }
  47.117 -}
    48.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c	Thu Jul 10 13:42:56 2003 +0000
    48.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c	Sat Jul 12 22:26:07 2003 +0000
    48.3 @@ -18,10 +18,10 @@
    48.4  #include <asm/tlb.h>
    48.5  #include <asm/mmu.h>
    48.6  
    48.7 +#if defined(CONFIG_XENO_PRIV)
    48.8 +
    48.9  #define direct_set_pte(pteptr, pteval) \
   48.10    queue_l1_entry_update(__pa(pteptr)|PGREQ_UNCHECKED_UPDATE, (pteval).pte_low)
   48.11 -#define direct_pte_clear(pteptr) \
   48.12 -  queue_l1_entry_update(__pa(pteptr)|PGREQ_UNCHECKED_UPDATE, 0)
   48.13  #define __direct_pte(x) ((pte_t) { (x) } )
   48.14  #define __direct_mk_pte(page_nr,pgprot) \
   48.15    __direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
   48.16 @@ -29,9 +29,6 @@
   48.17    __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
   48.18  
   48.19  
   48.20 -
   48.21 -/******************* Mapping a page range directly ************************/
   48.22 -
   48.23  static inline void direct_remap_area_pte(pte_t *pte, 
   48.24                                           unsigned long address, 
   48.25                                           unsigned long size,
   48.26 @@ -51,7 +48,7 @@ static inline void direct_remap_area_pte
   48.27              printk("direct_remap_area_pte: page already exists\n");
   48.28              BUG();
   48.29          }
   48.30 -        direct_set_pte(pte, direct_mk_pte_phys(machine_addr, prot)); 
   48.31 +        direct_set_pte(pte, pte_mkio(direct_mk_pte_phys(machine_addr, prot))); 
   48.32          address += PAGE_SIZE;
   48.33          machine_addr += PAGE_SIZE;
   48.34          pte++;
   48.35 @@ -119,104 +116,8 @@ int direct_remap_area_pages(struct mm_st
   48.36      return error;
   48.37  }
   48.38  
   48.39 -
   48.40 -
   48.41 -/************************ Zapping a page range directly *******************/
   48.42 -
   48.43 -static inline int direct_zap_pte_range(mmu_gather_t *tlb, 
   48.44 -                                       pmd_t * pmd, 
   48.45 -                                       unsigned long address, 
   48.46 -                                       unsigned long size)
   48.47 -{
   48.48 -    unsigned long offset;
   48.49 -    pte_t * ptep;
   48.50 -    int freed = 0;
   48.51 -
   48.52 -    if (pmd_none(*pmd))
   48.53 -        return 0;
   48.54 -    if (pmd_bad(*pmd)) {
   48.55 -        pmd_ERROR(*pmd);
   48.56 -        pmd_clear(pmd);
   48.57 -        return 0;
   48.58 -    }
   48.59 -    ptep = pte_offset(pmd, address);
   48.60 -    offset = address & ~PMD_MASK;
   48.61 -    if (offset + size > PMD_SIZE)
   48.62 -        size = PMD_SIZE - offset;
   48.63 -    size &= PAGE_MASK;
   48.64 -    for (offset=0; offset < size; ptep++, offset += PAGE_SIZE) {
   48.65 -        pte_t pte = *ptep;
   48.66 -        if (pte_none(pte))
   48.67 -            continue;
   48.68 -        freed++;
   48.69 -        direct_pte_clear(ptep);
   48.70 -    }
   48.71 -
   48.72 -    return freed;
   48.73 -}
   48.74 -
   48.75 -static inline int direct_zap_pmd_range(mmu_gather_t *tlb, 
   48.76 -                                       pgd_t * dir, 
   48.77 -                                       unsigned long address, 
   48.78 -                                       unsigned long size)
   48.79 -{
   48.80 -    pmd_t * pmd;
   48.81 -    unsigned long end;
   48.82 -    int freed;
   48.83 +#endif /* CONFIG_XENO_PRIV */
   48.84  
   48.85 -    if (pgd_none(*dir))
   48.86 -        return 0;
   48.87 -    if (pgd_bad(*dir)) {
   48.88 -        pgd_ERROR(*dir);
   48.89 -        pgd_clear(dir);
   48.90 -        return 0;
   48.91 -    }
   48.92 -    pmd = pmd_offset(dir, address);
   48.93 -    end = address + size;
   48.94 -    if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
   48.95 -        end = ((address + PGDIR_SIZE) & PGDIR_MASK);
   48.96 -    freed = 0;
   48.97 -    do {
   48.98 -        freed += direct_zap_pte_range(tlb, pmd, address, end - address);
   48.99 -        address = (address + PMD_SIZE) & PMD_MASK; 
  48.100 -        pmd++;
  48.101 -    } while (address < end);
  48.102 -    return freed;
  48.103 -}
  48.104 -
  48.105 -void direct_zap_page_range(struct mm_struct *mm, 
  48.106 -                           unsigned long address, 
  48.107 -                           unsigned long size)
  48.108 -{
  48.109 -    mmu_gather_t *tlb;
  48.110 -    pgd_t * dir;
  48.111 -    unsigned long start = address, end = address + size;
  48.112 -    int freed = 0;
  48.113 -
  48.114 -    dir = pgd_offset(mm, address);
  48.115 -
  48.116 -    if (address >= end)
  48.117 -        BUG();
  48.118 -    spin_lock(&mm->page_table_lock);
  48.119 -    flush_cache_range(mm, address, end);
  48.120 -    tlb = tlb_gather_mmu(mm);
  48.121 -
  48.122 -    do {
  48.123 -        freed += direct_zap_pmd_range(tlb, dir, address, end - address);
  48.124 -        address = (address + PGDIR_SIZE) & PGDIR_MASK;
  48.125 -        dir++;
  48.126 -    } while (address && (address < end));
  48.127 -
  48.128 -    /* this will flush any remaining tlb entries */
  48.129 -    tlb_finish_mmu(tlb, start, end);
  48.130 -
  48.131 -    /* decrementing rss removed */
  48.132 -    spin_unlock(&mm->page_table_lock);
  48.133 -}
  48.134 -
  48.135 -
  48.136 -
  48.137 -/****************** Generic public functions ****************************/
  48.138  
  48.139  /*
  48.140   * Remap an arbitrary machine address space into the kernel virtual
  48.141 @@ -231,6 +132,7 @@ void * __ioremap(unsigned long machine_a
  48.142                   unsigned long size, 
  48.143                   unsigned long flags)
  48.144  {
  48.145 +#if defined(CONFIG_XENO_PRIV)
  48.146      void * addr;
  48.147      struct vm_struct * area;
  48.148      unsigned long offset, last_addr;
  48.149 @@ -255,45 +157,22 @@ void * __ioremap(unsigned long machine_a
  48.150      if (!area)
  48.151          return NULL;
  48.152      addr = area->addr;
  48.153 -    prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | 
  48.154 -                    flags);
  48.155 +    prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | 
  48.156 +                    _PAGE_ACCESSED | flags);
  48.157      if (direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(addr), 
  48.158                                  machine_addr, size, prot)) {
  48.159          vfree(addr);
  48.160          return NULL;
  48.161      }
  48.162      return (void *) (offset + (char *)addr);
  48.163 +#else
  48.164 +    return NULL;
  48.165 +#endif
  48.166  }
  48.167  
  48.168 -/*
  48.169 - * 'vfree' is basically inlined here. This is because we use a different
  48.170 - * function to zap the associated page range.
  48.171 - */
  48.172  void iounmap(void *addr)
  48.173  {
  48.174 -    struct vm_struct **p, *tmp;
  48.175 -
  48.176 -    addr = (void *)((unsigned long)addr & PAGE_MASK);
  48.177 -    
  48.178 -    if (addr == NULL)
  48.179 -        return;
  48.180 -
  48.181 -    write_lock(&vmlist_lock);
  48.182 -
  48.183 -    for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
  48.184 -        if (tmp->addr == addr) {
  48.185 -            *p = tmp->next;
  48.186 -            direct_zap_page_range(&init_mm, 
  48.187 -                                  VMALLOC_VMADDR(tmp->addr), 
  48.188 -                                  tmp->size);
  48.189 -            write_unlock(&vmlist_lock);
  48.190 -            kfree(tmp);
  48.191 -            return;
  48.192 -        }
  48.193 -    }
  48.194 -
  48.195 -    write_unlock(&vmlist_lock);
  48.196 -    printk(KERN_ERR "Trying to iounmap() nonexistent vm area (%p)\n", addr);
  48.197 +    vfree((void *)((unsigned long)addr & PAGE_MASK));
  48.198  }
  48.199  
  48.200  
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/xenolinux-2.4.21-sparse/drivers/char/mem.c	Sat Jul 12 22:26:07 2003 +0000
    49.3 @@ -0,0 +1,807 @@
    49.4 +/*
    49.5 + *  linux/drivers/char/mem.c
    49.6 + *
    49.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
    49.8 + *
    49.9 + *  Added devfs support. 
   49.10 + *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
   49.11 + *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
   49.12 + *
   49.13 + *  MODIFIED FOR XENOLINUX by Keir Fraser, 10th July 2003.
   49.14 + *  Xenolinux has strange semantics for /dev/mem and /dev/kmem!!
   49.15 + *   1. mmap will not work on /dev/kmem
   49.16 + *   2. mmap on /dev/mem interprets the 'file offset' as a machine address
   49.17 + *      rather than a physical address.
   49.18 + *  I don't believe anyone sane mmaps /dev/kmem, but /dev/mem is mmapped
   49.19 + *  to get at memory-mapped I/O spaces (eg. the VESA X server does this).
   49.20 + *  For this to work at all we need to expect machine addresses.
   49.21 + *  Reading/writing of /dev/kmem expects kernel virtual addresses, as usual.
   49.22 + *  Reading/writing of /dev/mem expects 'physical addresses' as usual -- this
   49.23 + *  is because /dev/mem can only read/write existing kernel mappings, which
   49.24 + *  will be normal RAM, and we should present pseudo-physical layout for all
   49.25 + *  except I/O (which is the sticky case that mmap is hacked to deal with).
   49.26 + */
   49.27 +
   49.28 +#include <linux/config.h>
   49.29 +#include <linux/mm.h>
   49.30 +#include <linux/miscdevice.h>
   49.31 +#include <linux/tpqic02.h>
   49.32 +#include <linux/ftape.h>
   49.33 +#include <linux/slab.h>
   49.34 +#include <linux/vmalloc.h>
   49.35 +#include <linux/mman.h>
   49.36 +#include <linux/random.h>
   49.37 +#include <linux/init.h>
   49.38 +#include <linux/raw.h>
   49.39 +#include <linux/tty.h>
   49.40 +#include <linux/capability.h>
   49.41 +
   49.42 +#include <asm/uaccess.h>
   49.43 +#include <asm/io.h>
   49.44 +#include <asm/pgalloc.h>
   49.45 +
   49.46 +#ifdef CONFIG_I2C
   49.47 +extern int i2c_init_all(void);
   49.48 +#endif
   49.49 +#ifdef CONFIG_FB
   49.50 +extern void fbmem_init(void);
   49.51 +#endif
   49.52 +#ifdef CONFIG_PROM_CONSOLE
   49.53 +extern void prom_con_init(void);
   49.54 +#endif
   49.55 +#ifdef CONFIG_MDA_CONSOLE
   49.56 +extern void mda_console_init(void);
   49.57 +#endif
   49.58 +#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
   49.59 +extern void tapechar_init(void);
   49.60 +#endif
   49.61 +     
   49.62 +static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
   49.63 +			    const char * buf, size_t count, loff_t *ppos)
   49.64 +{
   49.65 +	ssize_t written;
   49.66 +
   49.67 +	written = 0;
   49.68 +#if defined(__sparc__) || defined(__mc68000__)
   49.69 +	/* we don't have page 0 mapped on sparc and m68k.. */
   49.70 +	if (realp < PAGE_SIZE) {
   49.71 +		unsigned long sz = PAGE_SIZE-realp;
   49.72 +		if (sz > count) sz = count; 
   49.73 +		/* Hmm. Do something? */
   49.74 +		buf+=sz;
   49.75 +		p+=sz;
   49.76 +		count-=sz;
   49.77 +		written+=sz;
   49.78 +	}
   49.79 +#endif
   49.80 +	if (copy_from_user(p, buf, count))
   49.81 +		return -EFAULT;
   49.82 +	written += count;
   49.83 +	*ppos += written;
   49.84 +	return written;
   49.85 +}
   49.86 +
   49.87 +
   49.88 +/*
   49.89 + * This funcion reads the *physical* memory. The f_pos points directly to the 
   49.90 + * memory location. 
   49.91 + */
   49.92 +static ssize_t read_mem(struct file * file, char * buf,
   49.93 +			size_t count, loff_t *ppos)
   49.94 +{
   49.95 +	unsigned long p = *ppos;
   49.96 +	unsigned long end_mem;
   49.97 +	ssize_t read;
   49.98 +	
   49.99 +	end_mem = __pa(high_memory);
  49.100 +	if (p >= end_mem)
  49.101 +		return 0;
  49.102 +	if (count > end_mem - p)
  49.103 +		count = end_mem - p;
  49.104 +	read = 0;
  49.105 +#if defined(__sparc__) || defined(__mc68000__)
  49.106 +	/* we don't have page 0 mapped on sparc and m68k.. */
  49.107 +	if (p < PAGE_SIZE) {
  49.108 +		unsigned long sz = PAGE_SIZE-p;
  49.109 +		if (sz > count) 
  49.110 +			sz = count; 
  49.111 +		if (sz > 0) {
  49.112 +			if (clear_user(buf, sz))
  49.113 +				return -EFAULT;
  49.114 +			buf += sz; 
  49.115 +			p += sz; 
  49.116 +			count -= sz; 
  49.117 +			read += sz; 
  49.118 +		}
  49.119 +	}
  49.120 +#endif
  49.121 +	if (copy_to_user(buf, __va(p), count))
  49.122 +		return -EFAULT;
  49.123 +	read += count;
  49.124 +	*ppos += read;
  49.125 +	return read;
  49.126 +}
  49.127 +
  49.128 +static ssize_t write_mem(struct file * file, const char * buf, 
  49.129 +			 size_t count, loff_t *ppos)
  49.130 +{
  49.131 +	unsigned long p = *ppos;
  49.132 +	unsigned long end_mem;
  49.133 +
  49.134 +	end_mem = __pa(high_memory);
  49.135 +	if (p >= end_mem)
  49.136 +		return 0;
  49.137 +	if (count > end_mem - p)
  49.138 +		count = end_mem - p;
  49.139 +	return do_write_mem(file, __va(p), p, buf, count, ppos);
  49.140 +}
  49.141 +
  49.142 +#ifndef pgprot_noncached
  49.143 +
  49.144 +/*
  49.145 + * This should probably be per-architecture in <asm/pgtable.h>
  49.146 + */
  49.147 +static inline pgprot_t pgprot_noncached(pgprot_t _prot)
  49.148 +{
  49.149 +	unsigned long prot = pgprot_val(_prot);
  49.150 +
  49.151 +#if defined(__i386__) || defined(__x86_64__)
  49.152 +	/* On PPro and successors, PCD alone doesn't always mean 
  49.153 +	    uncached because of interactions with the MTRRs. PCD | PWT
  49.154 +	    means definitely uncached. */ 
  49.155 +	if (boot_cpu_data.x86 > 3)
  49.156 +		prot |= _PAGE_PCD | _PAGE_PWT;
  49.157 +#elif defined(__powerpc__)
  49.158 +	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
  49.159 +#elif defined(__mc68000__)
  49.160 +#ifdef SUN3_PAGE_NOCACHE
  49.161 +	if (MMU_IS_SUN3)
  49.162 +		prot |= SUN3_PAGE_NOCACHE;
  49.163 +	else
  49.164 +#endif
  49.165 +	if (MMU_IS_851 || MMU_IS_030)
  49.166 +		prot |= _PAGE_NOCACHE030;
  49.167 +	/* Use no-cache mode, serialized */
  49.168 +	else if (MMU_IS_040 || MMU_IS_060)
  49.169 +		prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
  49.170 +#endif
  49.171 +
  49.172 +	return __pgprot(prot);
  49.173 +}
  49.174 +
  49.175 +#endif /* !pgprot_noncached */
  49.176 +
  49.177 +/*
  49.178 + * Architectures vary in how they handle caching for addresses 
  49.179 + * outside of main memory.
  49.180 + */
  49.181 +static inline int noncached_address(unsigned long addr)
  49.182 +{
  49.183 +#if defined(__i386__)
  49.184 +	/* 
  49.185 +	 * On the PPro and successors, the MTRRs are used to set
  49.186 +	 * memory types for physical addresses outside main memory, 
  49.187 +	 * so blindly setting PCD or PWT on those pages is wrong.
  49.188 +	 * For Pentiums and earlier, the surround logic should disable 
  49.189 +	 * caching for the high addresses through the KEN pin, but
  49.190 +	 * we maintain the tradition of paranoia in this code.
  49.191 +	 */
  49.192 + 	return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
  49.193 +		  test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
  49.194 +		  test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
  49.195 +		  test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
  49.196 +	  && addr >= __pa(high_memory);
  49.197 +#else
  49.198 +	return addr >= __pa(high_memory);
  49.199 +#endif
  49.200 +}
  49.201 +
  49.202 +static int mmap_mem(struct file * file, struct vm_area_struct * vma)
  49.203 +{
  49.204 +	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  49.205 +
  49.206 +#if defined(CONFIG_XENO) && defined(CONFIG_XENO_PRIV)
  49.207 +	if (!(start_info.flags & SIF_PRIVILEGED))
  49.208 +		return -ENXIO;
  49.209 +
  49.210 +	/* DONTCOPY is essential for Xenolinux as copy_page_range is broken. */
  49.211 +	vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
  49.212 +	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  49.213 +	if (direct_remap_area_pages(vma->vm_mm, vma->vm_start, offset, 
  49.214 +			     vma->vm_end-vma->vm_start, vma->vm_page_prot))
  49.215 +		return -EAGAIN;
  49.216 +	return 0;
  49.217 +#elif defined(CONFIG_XENO)
  49.218 +	return -ENXIO;
  49.219 +#else
  49.220 +	/*
  49.221 +	 * Accessing memory above the top the kernel knows about or
  49.222 +	 * through a file pointer that was marked O_SYNC will be
  49.223 +	 * done non-cached.
  49.224 +	 */
  49.225 +	if (noncached_address(offset) || (file->f_flags & O_SYNC))
  49.226 +		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  49.227 +
  49.228 +	/* Don't try to swap out physical pages.. */
  49.229 +	vma->vm_flags |= VM_RESERVED;
  49.230 +
  49.231 +	/*
  49.232 +	 * Don't dump addresses that are not real memory to a core file.
  49.233 +	 */
  49.234 +	if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
  49.235 +		vma->vm_flags |= VM_IO;
  49.236 +
  49.237 +	if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
  49.238 +			     vma->vm_page_prot))
  49.239 +		return -EAGAIN;
  49.240 +	return 0;
  49.241 +#endif
  49.242 +}
  49.243 +
  49.244 +/*
  49.245 + * This function reads the *virtual* memory as seen by the kernel.
  49.246 + */
  49.247 +static ssize_t read_kmem(struct file *file, char *buf, 
  49.248 +			 size_t count, loff_t *ppos)
  49.249 +{
  49.250 +	unsigned long p = *ppos;
  49.251 +	ssize_t read = 0;
  49.252 +	ssize_t virtr = 0;
  49.253 +	char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
  49.254 +		
  49.255 +	if (p < (unsigned long) high_memory) {
  49.256 +		read = count;
  49.257 +		if (count > (unsigned long) high_memory - p)
  49.258 +			read = (unsigned long) high_memory - p;
  49.259 +
  49.260 +#if defined(__sparc__) || defined(__mc68000__)
  49.261 +		/* we don't have page 0 mapped on sparc and m68k.. */
  49.262 +		if (p < PAGE_SIZE && read > 0) {
  49.263 +			size_t tmp = PAGE_SIZE - p;
  49.264 +			if (tmp > read) tmp = read;
  49.265 +			if (clear_user(buf, tmp))
  49.266 +				return -EFAULT;
  49.267 +			buf += tmp;
  49.268 +			p += tmp;
  49.269 +			read -= tmp;
  49.270 +			count -= tmp;
  49.271 +		}
  49.272 +#endif
  49.273 +		if (copy_to_user(buf, (char *)p, read))
  49.274 +			return -EFAULT;
  49.275 +		p += read;
  49.276 +		buf += read;
  49.277 +		count -= read;
  49.278 +	}
  49.279 +
  49.280 +	if (count > 0) {
  49.281 +		kbuf = (char *)__get_free_page(GFP_KERNEL);
  49.282 +		if (!kbuf)
  49.283 +			return -ENOMEM;
  49.284 +		while (count > 0) {
  49.285 +			int len = count;
  49.286 +
  49.287 +			if (len > PAGE_SIZE)
  49.288 +				len = PAGE_SIZE;
  49.289 +			len = vread(kbuf, (char *)p, len);
  49.290 +			if (!len)
  49.291 +				break;
  49.292 +			if (copy_to_user(buf, kbuf, len)) {
  49.293 +				free_page((unsigned long)kbuf);
  49.294 +				return -EFAULT;
  49.295 +			}
  49.296 +			count -= len;
  49.297 +			buf += len;
  49.298 +			virtr += len;
  49.299 +			p += len;
  49.300 +		}
  49.301 +		free_page((unsigned long)kbuf);
  49.302 +	}
  49.303 + 	*ppos = p;
  49.304 + 	return virtr + read;
  49.305 +}
  49.306 +
  49.307 +extern long vwrite(char *buf, char *addr, unsigned long count);
  49.308 +
  49.309 +/*
  49.310 + * This function writes to the *virtual* memory as seen by the kernel.
  49.311 + */
  49.312 +static ssize_t write_kmem(struct file * file, const char * buf, 
  49.313 +			  size_t count, loff_t *ppos)
  49.314 +{
  49.315 +	unsigned long p = *ppos;
  49.316 +	ssize_t wrote = 0;
  49.317 +	ssize_t virtr = 0;
  49.318 +	char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
  49.319 +
  49.320 +	if (p < (unsigned long) high_memory) {
  49.321 +		wrote = count;
  49.322 +		if (count > (unsigned long) high_memory - p)
  49.323 +			wrote = (unsigned long) high_memory - p;
  49.324 +
  49.325 +		wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
  49.326 +
  49.327 +		p += wrote;
  49.328 +		buf += wrote;
  49.329 +		count -= wrote;
  49.330 +	}
  49.331 +
  49.332 +	if (count > 0) {
  49.333 +		kbuf = (char *)__get_free_page(GFP_KERNEL);
  49.334 +		if (!kbuf)
  49.335 +			return -ENOMEM;
  49.336 +		while (count > 0) {
  49.337 +			int len = count;
  49.338 +
  49.339 +			if (len > PAGE_SIZE)
  49.340 +				len = PAGE_SIZE;
  49.341 +			if (len && copy_from_user(kbuf, buf, len)) {
  49.342 +				free_page((unsigned long)kbuf);
  49.343 +				return -EFAULT;
  49.344 +			}
  49.345 +			len = vwrite(kbuf, (char *)p, len);
  49.346 +			count -= len;
  49.347 +			buf += len;
  49.348 +			virtr += len;
  49.349 +			p += len;
  49.350 +		}
  49.351 +		free_page((unsigned long)kbuf);
  49.352 +	}
  49.353 +
  49.354 + 	*ppos = p;
  49.355 + 	return virtr + wrote;
  49.356 +}
  49.357 +
  49.358 +#if defined(CONFIG_ISA) || !defined(__mc68000__)
  49.359 +static ssize_t read_port(struct file * file, char * buf,
  49.360 +			 size_t count, loff_t *ppos)
  49.361 +{
  49.362 +	unsigned long i = *ppos;
  49.363 +	char *tmp = buf;
  49.364 +
  49.365 +	if (verify_area(VERIFY_WRITE,buf,count))
  49.366 +		return -EFAULT; 
  49.367 +	while (count-- > 0 && i < 65536) {
  49.368 +		if (__put_user(inb(i),tmp) < 0) 
  49.369 +			return -EFAULT;  
  49.370 +		i++;
  49.371 +		tmp++;
  49.372 +	}
  49.373 +	*ppos = i;
  49.374 +	return tmp-buf;
  49.375 +}
  49.376 +
  49.377 +static ssize_t write_port(struct file * file, const char * buf,
  49.378 +			  size_t count, loff_t *ppos)
  49.379 +{
  49.380 +	unsigned long i = *ppos;
  49.381 +	const char * tmp = buf;
  49.382 +
  49.383 +	if (verify_area(VERIFY_READ,buf,count))
  49.384 +		return -EFAULT;
  49.385 +	while (count-- > 0 && i < 65536) {
  49.386 +		char c;
  49.387 +		if (__get_user(c, tmp)) 
  49.388 +			return -EFAULT; 
  49.389 +		outb(c,i);
  49.390 +		i++;
  49.391 +		tmp++;
  49.392 +	}
  49.393 +	*ppos = i;
  49.394 +	return tmp-buf;
  49.395 +}
  49.396 +#endif
  49.397 +
  49.398 +static ssize_t read_null(struct file * file, char * buf,
  49.399 +			 size_t count, loff_t *ppos)
  49.400 +{
  49.401 +	return 0;
  49.402 +}
  49.403 +
  49.404 +static ssize_t write_null(struct file * file, const char * buf,
  49.405 +			  size_t count, loff_t *ppos)
  49.406 +{
  49.407 +	return count;
  49.408 +}
  49.409 +
  49.410 +/*
  49.411 + * For fun, we are using the MMU for this.
  49.412 + */
  49.413 +static inline size_t read_zero_pagealigned(char * buf, size_t size)
  49.414 +{
  49.415 +	struct mm_struct *mm;
  49.416 +	struct vm_area_struct * vma;
  49.417 +	unsigned long addr=(unsigned long)buf;
  49.418 +
  49.419 +	mm = current->mm;
  49.420 +	/* Oops, this was forgotten before. -ben */
  49.421 +	down_read(&mm->mmap_sem);
  49.422 +
  49.423 +	/* For private mappings, just map in zero pages. */
  49.424 +	for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
  49.425 +		unsigned long count;
  49.426 +
  49.427 +		if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
  49.428 +			goto out_up;
  49.429 +		if (vma->vm_flags & VM_SHARED)
  49.430 +			break;
  49.431 +#if defined(CONFIG_XENO_PRIV)
  49.432 +		if (vma->vm_flags & VM_IO)
  49.433 +			break;
  49.434 +#endif
  49.435 +		count = vma->vm_end - addr;
  49.436 +		if (count > size)
  49.437 +			count = size;
  49.438 +
  49.439 +		zap_page_range(mm, addr, count);
  49.440 +        	zeromap_page_range(addr, count, PAGE_COPY);
  49.441 +
  49.442 +		size -= count;
  49.443 +		buf += count;
  49.444 +		addr += count;
  49.445 +		if (size == 0)
  49.446 +			goto out_up;
  49.447 +	}
  49.448 +
  49.449 +	up_read(&mm->mmap_sem);
  49.450 +	
  49.451 +	/* The shared case is hard. Let's do the conventional zeroing. */ 
  49.452 +	do {
  49.453 +		unsigned long unwritten = clear_user(buf, PAGE_SIZE);
  49.454 +		if (unwritten)
  49.455 +			return size + unwritten - PAGE_SIZE;
  49.456 +		if (current->need_resched)
  49.457 +			schedule();
  49.458 +		buf += PAGE_SIZE;
  49.459 +		size -= PAGE_SIZE;
  49.460 +	} while (size);
  49.461 +
  49.462 +	return size;
  49.463 +out_up:
  49.464 +	up_read(&mm->mmap_sem);
  49.465 +	return size;
  49.466 +}
  49.467 +
  49.468 +static ssize_t read_zero(struct file * file, char * buf, 
  49.469 +			 size_t count, loff_t *ppos)
  49.470 +{
  49.471 +	unsigned long left, unwritten, written = 0;
  49.472 +
  49.473 +	if (!count)
  49.474 +		return 0;
  49.475 +
  49.476 +	if (!access_ok(VERIFY_WRITE, buf, count))
  49.477 +		return -EFAULT;
  49.478 +
  49.479 +	left = count;
  49.480 +
  49.481 +	/* do we want to be clever? Arbitrary cut-off */
  49.482 +	if (count >= PAGE_SIZE*4) {
  49.483 +		unsigned long partial;
  49.484 +
  49.485 +		/* How much left of the page? */
  49.486 +		partial = (PAGE_SIZE-1) & -(unsigned long) buf;
  49.487 +		unwritten = clear_user(buf, partial);
  49.488 +		written = partial - unwritten;
  49.489 +		if (unwritten)
  49.490 +			goto out;
  49.491 +		left -= partial;
  49.492 +		buf += partial;
  49.493 +		unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
  49.494 +		written += (left & PAGE_MASK) - unwritten;
  49.495 +		if (unwritten)
  49.496 +			goto out;
  49.497 +		buf += left & PAGE_MASK;
  49.498 +		left &= ~PAGE_MASK;
  49.499 +	}
  49.500 +	unwritten = clear_user(buf, left);
  49.501 +	written += left - unwritten;
  49.502 +out:
  49.503 +	return written ? written : -EFAULT;
  49.504 +}
  49.505 +
  49.506 +static int mmap_zero(struct file * file, struct vm_area_struct * vma)
  49.507 +{
  49.508 +	if (vma->vm_flags & VM_SHARED)
  49.509 +		return shmem_zero_setup(vma);
  49.510 +	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
  49.511 +		return -EAGAIN;
  49.512 +	return 0;
  49.513 +}
  49.514 +
  49.515 +static ssize_t write_full(struct file * file, const char * buf,
  49.516 +			  size_t count, loff_t *ppos)
  49.517 +{
  49.518 +	return -ENOSPC;
  49.519 +}
  49.520 +
  49.521 +/*
  49.522 + * Special lseek() function for /dev/null and /dev/zero.  Most notably, you
  49.523 + * can fopen() both devices with "a" now.  This was previously impossible.
  49.524 + * -- SRB.
  49.525 + */
  49.526 +
  49.527 +static loff_t null_lseek(struct file * file, loff_t offset, int orig)
  49.528 +{
  49.529 +	return file->f_pos = 0;
  49.530 +}
  49.531 +
  49.532 +/*
  49.533 + * The memory devices use the full 32/64 bits of the offset, and so we cannot
  49.534 + * check against negative addresses: they are ok. The return value is weird,
  49.535 + * though, in that case (0).
  49.536 + *
  49.537 + * also note that seeking relative to the "end of file" isn't supported:
  49.538 + * it has no meaning, so it returns -EINVAL.
  49.539 + */
  49.540 +static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
  49.541 +{
  49.542 +	switch (orig) {
  49.543 +		case 0:
  49.544 +			file->f_pos = offset;
  49.545 +			return file->f_pos;
  49.546 +		case 1:
  49.547 +			file->f_pos += offset;
  49.548 +			return file->f_pos;
  49.549 +		default:
  49.550 +			return -EINVAL;
  49.551 +	}
  49.552 +}
  49.553 +
  49.554 +static int open_port(struct inode * inode, struct file * filp)
  49.555 +{
  49.556 +	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
  49.557 +}
  49.558 +
  49.559 +struct page *kmem_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write)
  49.560 +{
  49.561 +	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  49.562 +	unsigned long kaddr;
  49.563 +	pgd_t *pgd;
  49.564 +	pmd_t *pmd;
  49.565 +	pte_t *ptep, pte;
  49.566 +	struct page *page = NULL;
  49.567 +
  49.568 +	/* address is user VA; convert to kernel VA of desired page */
  49.569 +	kaddr = (address - vma->vm_start) + offset;
  49.570 +	kaddr = VMALLOC_VMADDR(kaddr);
  49.571 +
  49.572 +	spin_lock(&init_mm.page_table_lock);
  49.573 +
  49.574 +	/* Lookup page structure for kernel VA */
  49.575 +	pgd = pgd_offset(&init_mm, kaddr);
  49.576 +	if (pgd_none(*pgd) || pgd_bad(*pgd))
  49.577 +		goto out;
  49.578 +	pmd = pmd_offset(pgd, kaddr);
  49.579 +	if (pmd_none(*pmd) || pmd_bad(*pmd))
  49.580 +		goto out;
  49.581 +	ptep = pte_offset(pmd, kaddr);
  49.582 +	if (!ptep)
  49.583 +		goto out;
  49.584 +	pte = *ptep;
  49.585 +	if (!pte_present(pte))
  49.586 +		goto out;
  49.587 +	if (write && !pte_write(pte))
  49.588 +		goto out;
  49.589 +	page = pte_page(pte);
  49.590 +	if (!VALID_PAGE(page)) {
  49.591 +		page = NULL;
  49.592 +		goto out;
  49.593 +	}
  49.594 +
  49.595 +	/* Increment reference count on page */
  49.596 +	get_page(page);
  49.597 +
  49.598 +out:
  49.599 +	spin_unlock(&init_mm.page_table_lock);
  49.600 +
  49.601 +	return page;
  49.602 +}
  49.603 +
  49.604 +struct vm_operations_struct kmem_vm_ops = {
  49.605 +	nopage:		kmem_vm_nopage,
  49.606 +};
  49.607 +
  49.608 +static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
  49.609 +{
  49.610 +	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  49.611 +	unsigned long size = vma->vm_end - vma->vm_start;
  49.612 +
  49.613 +#if defined(CONFIG_XENO)
  49.614 +	return -ENXIO;
  49.615 +#endif
  49.616 +
  49.617 +	/*
  49.618 +	 * If the user is not attempting to mmap a high memory address then
  49.619 +	 * the standard mmap_mem mechanism will work.  High memory addresses
  49.620 +	 * need special handling, as remap_page_range expects a physically-
  49.621 +	 * contiguous range of kernel addresses (such as obtained in kmalloc).
  49.622 +	 */
  49.623 +	if ((offset + size) < (unsigned long) high_memory)
  49.624 +		return mmap_mem(file, vma);
  49.625 +
  49.626 +	/*
  49.627 +	 * Accessing memory above the top the kernel knows about or
  49.628 +	 * through a file pointer that was marked O_SYNC will be
  49.629 +	 * done non-cached.
  49.630 +	 */
  49.631 +	if (noncached_address(offset) || (file->f_flags & O_SYNC))
  49.632 +		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  49.633 +
  49.634 +	/* Don't do anything here; "nopage" will fill the holes */
  49.635 +	vma->vm_ops = &kmem_vm_ops;
  49.636 +
  49.637 +	/* Don't try to swap out physical pages.. */
  49.638 +	vma->vm_flags |= VM_RESERVED;
  49.639 +
  49.640 +	/*
  49.641 +	 * Don't dump addresses that are not real memory to a core file.
  49.642 +	 */
  49.643 +	vma->vm_flags |= VM_IO;
  49.644 +
  49.645 +	return 0;
  49.646 +}
  49.647 +
  49.648 +#define zero_lseek	null_lseek
  49.649 +#define full_lseek      null_lseek
  49.650 +#define write_zero	write_null
  49.651 +#define read_full       read_zero
  49.652 +#define open_mem	open_port
  49.653 +#define open_kmem	open_mem
  49.654 +
  49.655 +static struct file_operations mem_fops = {
  49.656 +	llseek:		memory_lseek,
  49.657 +	read:		read_mem,
  49.658 +	write:		write_mem,
  49.659 +	mmap:		mmap_mem,
  49.660 +	open:		open_mem,
  49.661 +};
  49.662 +
  49.663 +static struct file_operations kmem_fops = {
  49.664 +	llseek:		memory_lseek,
  49.665 +	read:		read_kmem,
  49.666 +	write:		write_kmem,
  49.667 +	mmap:		mmap_kmem,
  49.668 +	open:		open_kmem,
  49.669 +};
  49.670 +
  49.671 +static struct file_operations null_fops = {
  49.672 +	llseek:		null_lseek,
  49.673 +	read:		read_null,
  49.674 +	write:		write_null,
  49.675 +};
  49.676 +
  49.677 +#if defined(CONFIG_ISA) || !defined(__mc68000__)
  49.678 +static struct file_operations port_fops = {
  49.679 +	llseek:		memory_lseek,
  49.680 +	read:		read_port,
  49.681 +	write:		write_port,
  49.682 +	open:		open_port,
  49.683 +};
  49.684 +#endif
  49.685 +
  49.686 +static struct file_operations zero_fops = {
  49.687 +	llseek:		zero_lseek,
  49.688 +	read:		read_zero,
  49.689 +	write:		write_zero,
  49.690 +	mmap:		mmap_zero,
  49.691 +};
  49.692 +
  49.693 +static struct file_operations full_fops = {
  49.694 +	llseek:		full_lseek,
  49.695 +	read:		read_full,
  49.696 +	write:		write_full,
  49.697 +};
  49.698 +
  49.699 +static int memory_open(struct inode * inode, struct file * filp)
  49.700 +{
  49.701 +	switch (MINOR(inode->i_rdev)) {
  49.702 +		case 1:
  49.703 +			filp->f_op = &mem_fops;
  49.704 +			break;
  49.705 +		case 2:
  49.706 +			filp->f_op = &kmem_fops;
  49.707 +			break;
  49.708 +		case 3:
  49.709 +			filp->f_op = &null_fops;
  49.710 +			break;
  49.711 +#if defined(CONFIG_ISA) || !defined(__mc68000__)
  49.712 +		case 4:
  49.713 +#if defined(CONFIG_XENO)
  49.714 +#if defined(CONFIG_XENO_PRIV)
  49.715 +			if (!(start_info.flags & SIF_PRIVILEGED))
  49.716 +#endif
  49.717 +				return -ENXIO;
  49.718 +#endif
  49.719 +			filp->f_op = &port_fops;
  49.720 +			break;
  49.721 +#endif
  49.722 +		case 5:
  49.723 +			filp->f_op = &zero_fops;
  49.724 +			break;
  49.725 +		case 7:
  49.726 +			filp->f_op = &full_fops;
  49.727 +			break;
  49.728 +		case 8:
  49.729 +			filp->f_op = &random_fops;
  49.730 +			break;
  49.731 +		case 9:
  49.732 +			filp->f_op = &urandom_fops;
  49.733 +			break;
  49.734 +		default:
  49.735 +			return -ENXIO;
  49.736 +	}
  49.737 +	if (filp->f_op && filp->f_op->open)
  49.738 +		return filp->f_op->open(inode,filp);
  49.739 +	return 0;
  49.740 +}
  49.741 +
  49.742 +void __init memory_devfs_register (void)
  49.743 +{
  49.744 +    /*  These are never unregistered  */
  49.745 +    static const struct {
  49.746 +	unsigned short minor;
  49.747 +	char *name;
  49.748 +	umode_t mode;
  49.749 +	struct file_operations *fops;
  49.750 +    } list[] = { /* list of minor devices */
  49.751 +	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
  49.752 +	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
  49.753 +	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
  49.754 +#if defined(CONFIG_ISA) || !defined(__mc68000__)
  49.755 +	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
  49.756 +#endif
  49.757 +	{5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
  49.758 +	{7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
  49.759 +	{8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
  49.760 +	{9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
  49.761 +    };
  49.762 +    int i;
  49.763 +
  49.764 +    for (i=0; i<(sizeof(list)/sizeof(*list)); i++)
  49.765 +	devfs_register (NULL, list[i].name, DEVFS_FL_NONE,
  49.766 +			MEM_MAJOR, list[i].minor,
  49.767 +			list[i].mode | S_IFCHR,
  49.768 +			list[i].fops, NULL);
  49.769 +}
  49.770 +
  49.771 +static struct file_operations memory_fops = {
  49.772 +	open:		memory_open,	/* just a selector for the real open */
  49.773 +};
  49.774 +
  49.775 +int __init chr_dev_init(void)
  49.776 +{
  49.777 +	if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))
  49.778 +		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
  49.779 +	memory_devfs_register();
  49.780 +	rand_initialize();
  49.781 +#ifdef CONFIG_I2C
  49.782 +	i2c_init_all();
  49.783 +#endif
  49.784 +#if defined (CONFIG_FB)
  49.785 +	fbmem_init();
  49.786 +#endif
  49.787 +#if defined (CONFIG_PROM_CONSOLE)
  49.788 +	prom_con_init();
  49.789 +#endif
  49.790 +#if defined (CONFIG_MDA_CONSOLE)
  49.791 +	mda_console_init();
  49.792 +#endif
  49.793 +	tty_init();
  49.794 +#ifdef CONFIG_M68K_PRINTER
  49.795 +	lp_m68k_init();
  49.796 +#endif
  49.797 +	misc_init();
  49.798 +#if CONFIG_QIC02_TAPE
  49.799 +	qic02_tape_init();
  49.800 +#endif
  49.801 +#ifdef CONFIG_FTAPE
  49.802 +	ftape_init();
  49.803 +#endif
  49.804 +#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
  49.805 +	tapechar_init();
  49.806 +#endif
  49.807 +	return 0;
  49.808 +}
  49.809 +
  49.810 +__initcall(chr_dev_init);
    50.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h	Thu Jul 10 13:42:56 2003 +0000
    50.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.3 @@ -1,36 +0,0 @@
    50.4 -/* IOCTLs used when access /proc/xeno/dom0_cmd. */
    50.5 -#ifndef __DOM0_H__
    50.6 -#define __DOM0_H__
    50.7 -
    50.8 -#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_READ, 'x', 0, sizeof(struct dom0_createdomain_args))
    50.9 -#define IOCTL_DOM0_MAPDOMMEM _IOC(_IOC_READ, 'x', 1, sizeof(struct dom0_mapdommem_args))
   50.10 -#define IOCTL_DOM0_UNMAPDOMMEM _IOC(_IOC_READ, 'x', 2, sizeof(struct dom0_unmapdommem_args))
   50.11 -#define IOCTL_DOM0_DOPGUPDATES _IOC(_IOC_READ, 'x', 3, sizeof(struct dom0_dopgupdates_args))
   50.12 -
   50.13 -struct dom0_createdomain_args
   50.14 -{
   50.15 -    unsigned int kb_mem;
   50.16 -    const char *name;
   50.17 -};
   50.18 -
   50.19 -struct dom0_mapdommem_args
   50.20 -{
   50.21 -    unsigned int domain;
   50.22 -    unsigned start_pfn;
   50.23 -    unsigned tot_pages;  
   50.24 -};
   50.25 -
   50.26 -struct dom0_unmapdommem_args
   50.27 -{
   50.28 -    unsigned long vaddr;
   50.29 -    unsigned long start_pfn;
   50.30 -    unsigned long tot_pages;
   50.31 -};
   50.32 -
   50.33 -struct dom0_dopgupdates_args
   50.34 -{
   50.35 -    unsigned long pgt_update_arr;
   50.36 -    unsigned long num_pgt_updates;
   50.37 -};
   50.38 -
   50.39 -#endif /* __DOM0_H__ */
    51.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/hypervisor.h	Thu Jul 10 13:42:56 2003 +0000
    51.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/hypervisor.h	Sat Jul 12 22:26:07 2003 +0000
    51.3 @@ -9,9 +9,9 @@
    51.4  #ifndef __HYPERVISOR_H__
    51.5  #define __HYPERVISOR_H__
    51.6  
    51.7 +#include <linux/types.h>
    51.8  #include <asm/hypervisor-ifs/hypervisor-if.h>
    51.9  #include <asm/ptrace.h>
   51.10 -//#include <asm/page.h>
   51.11  
   51.12  /* arch/xeno/kernel/setup.c */
   51.13  union start_info_union
    52.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h	Thu Jul 10 13:42:56 2003 +0000
    52.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.3 @@ -1,23 +0,0 @@
    52.4 -#ifndef __i386_MMU_H
    52.5 -#define __i386_MMU_H
    52.6 -
    52.7 -#include <linux/list.h>
    52.8 -
    52.9 -/* describes dirrectly mapped vma nodes */
   52.10 -typedef struct {
   52.11 -    struct list_head list;
   52.12 -    unsigned long vm_start;
   52.13 -	unsigned long vm_end;
   52.14 -} direct_mmap_node_t;
   52.15 -
   52.16 -/*
   52.17 - * The i386 doesn't have a mmu context, but
   52.18 - * we put the segment information here.
   52.19 - */
   52.20 -typedef struct { 
   52.21 -	void *segments;
   52.22 -	unsigned long cpuvalid;
   52.23 -    struct list_head direct_list;
   52.24 -} mm_context_t;
   52.25 -
   52.26 -#endif
    53.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/mmu_context.h	Thu Jul 10 13:42:56 2003 +0000
    53.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/mmu_context.h	Sat Jul 12 22:26:07 2003 +0000
    53.3 @@ -5,15 +5,12 @@
    53.4  #include <asm/desc.h>
    53.5  #include <asm/atomic.h>
    53.6  #include <asm/pgalloc.h>
    53.7 -#include <asm/multicall.h>
    53.8  
    53.9 -/* Hooked directly from 'init_new_context'. */
   53.10 -extern int init_direct_list(struct mm_struct *);
   53.11 -/* Called from 'release_segments'. */
   53.12 -extern void destroy_direct_list(struct mm_struct *);
   53.13 -
   53.14 +/*
   53.15 + * possibly do the LDT unload here?
   53.16 + */
   53.17  #define destroy_context(mm)		do { } while(0)
   53.18 -#define init_new_context(tsk,mm)	init_direct_list(mm)
   53.19 +#define init_new_context(tsk,mm)	0
   53.20  
   53.21  #ifdef CONFIG_SMP
   53.22  
    54.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/multicall.h	Thu Jul 10 13:42:56 2003 +0000
    54.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/multicall.h	Sat Jul 12 22:26:07 2003 +0000
    54.3 @@ -35,6 +35,45 @@ static inline void queue_multicall2(
    54.4      nr_multicall_ents = i+1;
    54.5  }
    54.6  
    54.7 +static inline void queue_multicall3(
    54.8 +    unsigned long op, unsigned long arg1, unsigned long arg2,
    54.9 +    unsigned long arg3)
   54.10 +{
   54.11 +    int i = nr_multicall_ents;
   54.12 +    multicall_list[i].op      = op;
   54.13 +    multicall_list[i].args[0] = arg1;
   54.14 +    multicall_list[i].args[1] = arg2;
   54.15 +    multicall_list[i].args[2] = arg3;
   54.16 +    nr_multicall_ents = i+1;
   54.17 +}
   54.18 +
   54.19 +static inline void queue_multicall4(
   54.20 +    unsigned long op, unsigned long arg1, unsigned long arg2,
   54.21 +    unsigned long arg3, unsigned long arg4)
   54.22 +{
   54.23 +    int i = nr_multicall_ents;
   54.24 +    multicall_list[i].op      = op;
   54.25 +    multicall_list[i].args[0] = arg1;
   54.26 +    multicall_list[i].args[1] = arg2;
   54.27 +    multicall_list[i].args[2] = arg3;
   54.28 +    multicall_list[i].args[3] = arg4;
   54.29 +    nr_multicall_ents = i+1;
   54.30 +}
   54.31 +
   54.32 +static inline void queue_multicall5(
   54.33 +    unsigned long op, unsigned long arg1, unsigned long arg2,
   54.34 +    unsigned long arg3, unsigned long arg4, unsigned long arg5)
   54.35 +{
   54.36 +    int i = nr_multicall_ents;
   54.37 +    multicall_list[i].op      = op;
   54.38 +    multicall_list[i].args[0] = arg1;
   54.39 +    multicall_list[i].args[1] = arg2;
   54.40 +    multicall_list[i].args[2] = arg3;
   54.41 +    multicall_list[i].args[3] = arg4;
   54.42 +    multicall_list[i].args[4] = arg5;
   54.43 +    nr_multicall_ents = i+1;
   54.44 +}
   54.45 +
   54.46  static inline void execute_multicall_list(void)
   54.47  {
   54.48      if ( unlikely(nr_multicall_ents == 0) ) return;
    55.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/pgalloc.h	Thu Jul 10 13:42:56 2003 +0000
    55.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/pgalloc.h	Sat Jul 12 22:26:07 2003 +0000
    55.3 @@ -265,4 +265,10 @@ static inline void flush_tlb_pgtables(st
    55.4      XENO_flush_page_update_queue();
    55.5  }
    55.6  
    55.7 +extern int direct_remap_area_pages(struct mm_struct *mm,
    55.8 +                                   unsigned long address, 
    55.9 +                                   unsigned long machine_addr,
   55.10 +                                   unsigned long size, 
   55.11 +                                   pgprot_t prot);
   55.12 +
   55.13  #endif /* _I386_PGALLOC_H */
    56.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/pgtable.h	Thu Jul 10 13:42:56 2003 +0000
    56.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/pgtable.h	Sat Jul 12 22:26:07 2003 +0000
    56.3 @@ -3,8 +3,6 @@
    56.4  
    56.5  #include <linux/config.h>
    56.6  
    56.7 -#define HAVE_ARCH_UNMAPPED_AREA
    56.8 -
    56.9  /*
   56.10   * The Linux memory management assumes a three-level page table setup. On
   56.11   * the i386, we use that, but "fold" the mid level into the top-level page
   56.12 @@ -114,6 +112,7 @@ extern void * high_memory;
   56.13  #define _PAGE_BIT_DIRTY		6
   56.14  #define _PAGE_BIT_PSE		7	/* 4 MB (or 2MB) page, Pentium+, if present.. */
   56.15  #define _PAGE_BIT_GLOBAL	8	/* Global TLB entry PPro+ */
   56.16 +#define _PAGE_BIT_IO            9
   56.17  
   56.18  #define _PAGE_PRESENT	0x001
   56.19  #define _PAGE_RW	0x002
   56.20 @@ -124,6 +123,7 @@ extern void * high_memory;
   56.21  #define _PAGE_DIRTY	0x040
   56.22  #define _PAGE_PSE	0x080	/* 4 MB (or 2MB) page, Pentium+, if present.. */
   56.23  #define _PAGE_GLOBAL	0x100	/* Global TLB entry PPro+ */
   56.24 +#define _PAGE_IO        0x200
   56.25  
   56.26  #define _PAGE_PROTNONE	0x080	/* If not present */
   56.27  
   56.28 @@ -196,6 +196,7 @@ static inline int pte_exec(pte_t pte)		{
   56.29  static inline int pte_dirty(pte_t pte)		{ return (pte).pte_low & _PAGE_DIRTY; }
   56.30  static inline int pte_young(pte_t pte)		{ return (pte).pte_low & _PAGE_ACCESSED; }
   56.31  static inline int pte_write(pte_t pte)		{ return (pte).pte_low & _PAGE_RW; }
   56.32 +static inline int pte_io(pte_t pte)		{ return (pte).pte_low & _PAGE_IO; }
   56.33  
   56.34  static inline pte_t pte_rdprotect(pte_t pte)	{ (pte).pte_low &= ~_PAGE_USER; return pte; }
   56.35  static inline pte_t pte_exprotect(pte_t pte)	{ (pte).pte_low &= ~_PAGE_USER; return pte; }
   56.36 @@ -207,6 +208,7 @@ static inline pte_t pte_mkexec(pte_t pte
   56.37  static inline pte_t pte_mkdirty(pte_t pte)	{ (pte).pte_low |= _PAGE_DIRTY; return pte; }
   56.38  static inline pte_t pte_mkyoung(pte_t pte)	{ (pte).pte_low |= _PAGE_ACCESSED; return pte; }
   56.39  static inline pte_t pte_mkwrite(pte_t pte)	{ (pte).pte_low |= _PAGE_RW; return pte; }
   56.40 +static inline pte_t pte_mkio(pte_t pte)		{ (pte).pte_low |= _PAGE_IO; return pte; }
   56.41  
   56.42  static inline int ptep_test_and_clear_dirty(pte_t *ptep)
   56.43  {
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/proc_cmd.h	Sat Jul 12 22:26:07 2003 +0000
    57.3 @@ -0,0 +1,28 @@
    57.4 +/******************************************************************************
    57.5 + * proc_cmd.h
    57.6 + * 
    57.7 + * Interface to /proc/cmd and /proc/xeno/privcmd.
    57.8 + */
    57.9 +
   57.10 +#ifndef __PROC_CMD_H__
   57.11 +#define __PROC_CMD_H__
   57.12 +
   57.13 +#define IOCTL_PRIVCMD_HYPERCALL        0
   57.14 +#define IOCTL_PRIVCMD_BLKMSG           1
   57.15 +#define IOCTL_PRIVCMD_LINDEV_TO_XENDEV 2
   57.16 +#define IOCTL_PRIVCMD_XENDEV_TO_LINDEV 3
   57.17 +
   57.18 +typedef struct privcmd_hypercall
   57.19 +{
   57.20 +    unsigned long op;
   57.21 +    unsigned long arg[5];
   57.22 +} privcmd_hypercall_t;
   57.23 +
   57.24 +typedef struct privcmd_blkmsg
   57.25 +{
   57.26 +    unsigned long op;
   57.27 +    void         *buf;
   57.28 +    int           buf_size;
   57.29 +} privcmd_blkmsg_t;
   57.30 +
   57.31 +#endif /* __PROC_CMD_H__ */
    58.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/segment.h	Thu Jul 10 13:42:56 2003 +0000
    58.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/segment.h	Sat Jul 12 22:26:07 2003 +0000
    58.3 @@ -1,6 +1,9 @@
    58.4  #ifndef _ASM_SEGMENT_H
    58.5  #define _ASM_SEGMENT_H
    58.6  
    58.7 +#ifndef __ASSEMBLY__
    58.8 +#include <linux/types.h>
    58.9 +#endif
   58.10  #include <asm/hypervisor-ifs/hypervisor-if.h>
   58.11  
   58.12  #define __KERNEL_CS	FLAT_RING1_CS
    59.1 --- a/xenolinux-2.4.21-sparse/mkbuildtree	Thu Jul 10 13:42:56 2003 +0000
    59.2 +++ b/xenolinux-2.4.21-sparse/mkbuildtree	Sat Jul 12 22:26:07 2003 +0000
    59.3 @@ -125,6 +125,7 @@ ln -sf ../asm-i386/math_emu.h
    59.4  ln -sf ../asm-i386/mc146818rtc.h
    59.5  ln -sf ../asm-i386/mca_dma.h 
    59.6  ln -sf ../asm-i386/mman.h 
    59.7 +ln -sf ../asm-i386/mmu.h 
    59.8  ln -sf ../asm-i386/mmx.h 
    59.9  ln -sf ../asm-i386/module.h 
   59.10  ln -sf ../asm-i386/mpspec.h 
    60.1 --- a/xenolinux-2.4.21-sparse/mm/memory.c	Thu Jul 10 13:42:56 2003 +0000
    60.2 +++ b/xenolinux-2.4.21-sparse/mm/memory.c	Sat Jul 12 22:26:07 2003 +0000
    60.3 @@ -318,6 +318,13 @@ static inline int zap_pte_range(mmu_gath
    60.4  			continue;
    60.5  		if (pte_present(pte)) {
    60.6  			struct page *page = pte_page(pte);
    60.7 +#if defined(CONFIG_XENO_PRIV)
    60.8 +			if (pte_io(pte)) {
    60.9 +				queue_l1_entry_update(
   60.10 +					__pa(ptep)|PGREQ_UNCHECKED_UPDATE, 0);
   60.11 +				continue;
   60.12 +			}
   60.13 +#endif
   60.14  			if (VALID_PAGE(page) && !PageReserved(page))
   60.15  				freed ++;
   60.16  			/* This will eventually call __free_pte on the pte. */
   60.17 @@ -1374,6 +1381,15 @@ int handle_mm_fault(struct mm_struct *mm
   60.18  	pgd_t *pgd;
   60.19  	pmd_t *pmd;
   60.20  
   60.21 +#if defined(CONFIG_XENO_PRIV)
   60.22 +	/* Take care of I/O mappings right here. */
   60.23 +	if (vma->vm_flags & VM_IO) {
   60.24 +		if (write_access && !(vma->vm_flags & VM_WRITE))
   60.25 +			return -1;
   60.26 +		return 1;
   60.27 +	}
   60.28 +#endif
   60.29 +
   60.30  	current->state = TASK_RUNNING;
   60.31  	pgd = pgd_offset(mm, address);
   60.32  
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/xenolinux-2.4.21-sparse/mm/mprotect.c	Sat Jul 12 22:26:07 2003 +0000
    61.3 @@ -0,0 +1,344 @@
    61.4 +/*
    61.5 + *	linux/mm/mprotect.c
    61.6 + *
    61.7 + *  (C) Copyright 1994 Linus Torvalds
    61.8 + */
    61.9 +#include <linux/slab.h>
   61.10 +#include <linux/smp_lock.h>
   61.11 +#include <linux/shm.h>
   61.12 +#include <linux/mman.h>
   61.13 +
   61.14 +#include <asm/uaccess.h>
   61.15 +#include <asm/pgalloc.h>
   61.16 +#include <asm/pgtable.h>
   61.17 +
   61.18 +static inline void change_pte_range(pmd_t * pmd, unsigned long address,
   61.19 +	unsigned long size, pgprot_t newprot)
   61.20 +{
   61.21 +	pte_t * pte;
   61.22 +	unsigned long end;
   61.23 +
   61.24 +	if (pmd_none(*pmd))
   61.25 +		return;
   61.26 +	if (pmd_bad(*pmd)) {
   61.27 +		pmd_ERROR(*pmd);
   61.28 +		pmd_clear(pmd);
   61.29 +		return;
   61.30 +	}
   61.31 +	pte = pte_offset(pmd, address);
   61.32 +	address &= ~PMD_MASK;
   61.33 +	end = address + size;
   61.34 +	if (end > PMD_SIZE)
   61.35 +		end = PMD_SIZE;
   61.36 +	do {
   61.37 +		if (pte_present(*pte)) {
   61.38 +			pte_t entry;
   61.39 +
   61.40 +			/* Avoid an SMP race with hardware updated dirty/clean
   61.41 +			 * bits by wiping the pte and then setting the new pte
   61.42 +			 * into place.
   61.43 +			 */
   61.44 +			entry = ptep_get_and_clear(pte);
   61.45 +			set_pte(pte, pte_modify(entry, newprot));
   61.46 +		}
   61.47 +		address += PAGE_SIZE;
   61.48 +		pte++;
   61.49 +	} while (address && (address < end));
   61.50 +}
   61.51 +
   61.52 +static inline void change_pmd_range(pgd_t * pgd, unsigned long address,
   61.53 +	unsigned long size, pgprot_t newprot)
   61.54 +{
   61.55 +	pmd_t * pmd;
   61.56 +	unsigned long end;
   61.57 +
   61.58 +	if (pgd_none(*pgd))
   61.59 +		return;
   61.60 +	if (pgd_bad(*pgd)) {
   61.61 +		pgd_ERROR(*pgd);
   61.62 +		pgd_clear(pgd);
   61.63 +		return;
   61.64 +	}
   61.65 +	pmd = pmd_offset(pgd, address);
   61.66 +	address &= ~PGDIR_MASK;
   61.67 +	end = address + size;
   61.68 +	if (end > PGDIR_SIZE)
   61.69 +		end = PGDIR_SIZE;
   61.70 +	do {
   61.71 +		change_pte_range(pmd, address, end - address, newprot);
   61.72 +		address = (address + PMD_SIZE) & PMD_MASK;
   61.73 +		pmd++;
   61.74 +	} while (address && (address < end));
   61.75 +}
   61.76 +
   61.77 +static void change_protection(unsigned long start, unsigned long end, pgprot_t newprot)
   61.78 +{
   61.79 +	pgd_t *dir;
   61.80 +	unsigned long beg = start;
   61.81 +
   61.82 +	dir = pgd_offset(current->mm, start);
   61.83 +	flush_cache_range(current->mm, beg, end);
   61.84 +	if (start >= end)
   61.85 +		BUG();
   61.86 +	spin_lock(&current->mm->page_table_lock);
   61.87 +	do {
   61.88 +		change_pmd_range(dir, start, end - start, newprot);
   61.89 +		start = (start + PGDIR_SIZE) & PGDIR_MASK;
   61.90 +		dir++;
   61.91 +	} while (start && (start < end));
   61.92 +	spin_unlock(&current->mm->page_table_lock);
   61.93 +	flush_tlb_range(current->mm, beg, end);
   61.94 +	return;
   61.95 +}
   61.96 +
   61.97 +static inline int mprotect_fixup_all(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
   61.98 +	int newflags, pgprot_t prot)
   61.99 +{
  61.100 +	struct vm_area_struct * prev = *pprev;
  61.101 +	struct mm_struct * mm = vma->vm_mm;
  61.102 +
  61.103 +	if (prev && prev->vm_end == vma->vm_start && can_vma_merge(prev, newflags) &&
  61.104 +	    !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
  61.105 +		spin_lock(&mm->page_table_lock);
  61.106 +		prev->vm_end = vma->vm_end;
  61.107 +		__vma_unlink(mm, vma, prev);
  61.108 +		spin_unlock(&mm->page_table_lock);
  61.109 +
  61.110 +		kmem_cache_free(vm_area_cachep, vma);
  61.111 +		mm->map_count--;
  61.112 +
  61.113 +		return 0;
  61.114 +	}
  61.115 +
  61.116 +	spin_lock(&mm->page_table_lock);
  61.117 +	vma->vm_flags = newflags;
  61.118 +	vma->vm_page_prot = prot;
  61.119 +	spin_unlock(&mm->page_table_lock);
  61.120 +
  61.121 +	*pprev = vma;
  61.122 +
  61.123 +	return 0;
  61.124 +}
  61.125 +
  61.126 +static inline int mprotect_fixup_start(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
  61.127 +	unsigned long end,
  61.128 +	int newflags, pgprot_t prot)
  61.129 +{
  61.130 +	struct vm_area_struct * n, * prev = *pprev;
  61.131 +
  61.132 +	*pprev = vma;
  61.133 +
  61.134 +	if (prev && prev->vm_end == vma->vm_start && can_vma_merge(prev, newflags) &&
  61.135 +	    !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
  61.136 +		spin_lock(&vma->vm_mm->page_table_lock);
  61.137 +		prev->vm_end = end;
  61.138 +		vma->vm_start = end;
  61.139 +		spin_unlock(&vma->vm_mm->page_table_lock);
  61.140 +
  61.141 +		return 0;
  61.142 +	}
  61.143 +	n = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
  61.144 +	if (!n)
  61.145 +		return -ENOMEM;
  61.146 +	*n = *vma;
  61.147 +	n->vm_end = end;
  61.148 +	n->vm_flags = newflags;
  61.149 +	n->vm_raend = 0;
  61.150 +	n->vm_page_prot = prot;
  61.151 +	if (n->vm_file)
  61.152 +		get_file(n->vm_file);
  61.153 +	if (n->vm_ops && n->vm_ops->open)
  61.154 +		n->vm_ops->open(n);
  61.155 +	vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT;
  61.156 +	lock_vma_mappings(vma);
  61.157 +	spin_lock(&vma->vm_mm->page_table_lock);
  61.158 +	vma->vm_start = end;
  61.159 +	__insert_vm_struct(current->mm, n);
  61.160 +	spin_unlock(&vma->vm_mm->page_table_lock);
  61.161 +	unlock_vma_mappings(vma);
  61.162 +
  61.163 +	return 0;
  61.164 +}
  61.165 +
  61.166 +static inline int mprotect_fixup_end(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
  61.167 +	unsigned long start,
  61.168 +	int newflags, pgprot_t prot)
  61.169 +{
  61.170 +	struct vm_area_struct * n;
  61.171 +
  61.172 +	n = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
  61.173 +	if (!n)
  61.174 +		return -ENOMEM;
  61.175 +	*n = *vma;
  61.176 +	n->vm_start = start;
  61.177 +	n->vm_pgoff += (n->vm_start - vma->vm_start) >> PAGE_SHIFT;
  61.178 +	n->vm_flags = newflags;
  61.179 +	n->vm_raend = 0;
  61.180 +	n->vm_page_prot = prot;
  61.181 +	if (n->vm_file)
  61.182 +		get_file(n->vm_file);
  61.183 +	if (n->vm_ops && n->vm_ops->open)
  61.184 +		n->vm_ops->open(n);
  61.185 +	lock_vma_mappings(vma);
  61.186 +	spin_lock(&vma->vm_mm->page_table_lock);
  61.187 +	vma->vm_end = start;
  61.188 +	__insert_vm_struct(current->mm, n);
  61.189 +	spin_unlock(&vma->vm_mm->page_table_lock);
  61.190 +	unlock_vma_mappings(vma);
  61.191 +
  61.192 +	*pprev = n;
  61.193 +
  61.194 +	return 0;
  61.195 +}
  61.196 +
  61.197 +static inline int mprotect_fixup_middle(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
  61.198 +	unsigned long start, unsigned long end,
  61.199 +	int newflags, pgprot_t prot)
  61.200 +{
  61.201 +	struct vm_area_struct * left, * right;
  61.202 +
  61.203 +	left = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
  61.204 +	if (!left)
  61.205 +		return -ENOMEM;
  61.206 +	right = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
  61.207 +	if (!right) {
  61.208 +		kmem_cache_free(vm_area_cachep, left);
  61.209 +		return -ENOMEM;
  61.210 +	}
  61.211 +	*left = *vma;
  61.212 +	*right = *vma;
  61.213 +	left->vm_end = start;
  61.214 +	right->vm_start = end;
  61.215 +	right->vm_pgoff += (right->vm_start - left->vm_start) >> PAGE_SHIFT;
  61.216 +	left->vm_raend = 0;
  61.217 +	right->vm_raend = 0;
  61.218 +	if (vma->vm_file)
  61.219 +		atomic_add(2,&vma->vm_file->f_count);
  61.220 +	if (vma->vm_ops && vma->vm_ops->open) {
  61.221 +		vma->vm_ops->open(left);
  61.222 +		vma->vm_ops->open(right);
  61.223 +	}
  61.224 +	vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT;
  61.225 +	vma->vm_raend = 0;
  61.226 +	vma->vm_page_prot = prot;
  61.227 +	lock_vma_mappings(vma);
  61.228 +	spin_lock(&vma->vm_mm->page_table_lock);
  61.229 +	vma->vm_start = start;
  61.230 +	vma->vm_end = end;
  61.231 +	vma->vm_flags = newflags;
  61.232 +	__insert_vm_struct(current->mm, left);
  61.233 +	__insert_vm_struct(current->mm, right);
  61.234 +	spin_unlock(&vma->vm_mm->page_table_lock);
  61.235 +	unlock_vma_mappings(vma);
  61.236 +
  61.237 +	*pprev = right;
  61.238 +
  61.239 +	return 0;
  61.240 +}
  61.241 +
  61.242 +static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
  61.243 +	unsigned long start, unsigned long end, unsigned int newflags)
  61.244 +{
  61.245 +	pgprot_t newprot;
  61.246 +	int error;
  61.247 +
  61.248 +	if (newflags == vma->vm_flags) {
  61.249 +		*pprev = vma;
  61.250 +		return 0;
  61.251 +	}
  61.252 +	newprot = protection_map[newflags & 0xf];
  61.253 +	if (start == vma->vm_start) {
  61.254 +		if (end == vma->vm_end)
  61.255 +			error = mprotect_fixup_all(vma, pprev, newflags, newprot);
  61.256 +		else
  61.257 +			error = mprotect_fixup_start(vma, pprev, end, newflags, newprot);
  61.258 +	} else if (end == vma->vm_end)
  61.259 +		error = mprotect_fixup_end(vma, pprev, start, newflags, newprot);
  61.260 +	else
  61.261 +		error = mprotect_fixup_middle(vma, pprev, start, end, newflags, newprot);
  61.262 +
  61.263 +	if (error)
  61.264 +		return error;
  61.265 +
  61.266 +	change_protection(start, end, newprot);
  61.267 +	return 0;
  61.268 +}
  61.269 +
  61.270 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
  61.271 +{
  61.272 +	unsigned long nstart, end, tmp;
  61.273 +	struct vm_area_struct * vma, * next, * prev;
  61.274 +	int error = -EINVAL;
  61.275 +
  61.276 +	if (start & ~PAGE_MASK)
  61.277 +		return -EINVAL;
  61.278 +	len = PAGE_ALIGN(len);
  61.279 +	end = start + len;
  61.280 +	if (end < start)
  61.281 +		return -EINVAL;
  61.282 +	if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
  61.283 +		return -EINVAL;
  61.284 +	if (end == start)
  61.285 +		return 0;
  61.286 +
  61.287 +	down_write(&current->mm->mmap_sem);
  61.288 +
  61.289 +	vma = find_vma_prev(current->mm, start, &prev);
  61.290 +	error = -ENOMEM;
  61.291 +	if (!vma || vma->vm_start > start)
  61.292 +		goto out;
  61.293 +
  61.294 +#if defined(CONFIG_XENO_PRIV)
  61.295 +	/* mprotect() unsupported for I/O mappings in Xenolinux. */
  61.296 +	error = -EINVAL;
  61.297 +	if (vma->vm_flags & VM_IO)
  61.298 +		goto out;
  61.299 +#endif
  61.300 +
  61.301 +	for (nstart = start ; ; ) {
  61.302 +		unsigned int newflags;
  61.303 +		int last = 0;
  61.304 +
  61.305 +		/* Here we know that  vma->vm_start <= nstart < vma->vm_end. */
  61.306 +
  61.307 +		newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
  61.308 +		if ((newflags & ~(newflags >> 4)) & 0xf) {
  61.309 +			error = -EACCES;
  61.310 +			goto out;
  61.311 +		}
  61.312 +
  61.313 +		if (vma->vm_end > end) {
  61.314 +			error = mprotect_fixup(vma, &prev, nstart, end, newflags);
  61.315 +			goto out;
  61.316 +		}
  61.317 +		if (vma->vm_end == end)
  61.318 +			last = 1;
  61.319 +
  61.320 +		tmp = vma->vm_end;
  61.321 +		next = vma->vm_next;
  61.322 +		error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
  61.323 +		if (error)
  61.324 +			goto out;
  61.325 +		if (last)
  61.326 +			break;
  61.327 +		nstart = tmp;
  61.328 +		vma = next;
  61.329 +		if (!vma || vma->vm_start != nstart) {
  61.330 +			error = -ENOMEM;
  61.331 +			goto out;
  61.332 +		}
  61.333 +	}
  61.334 +	if (next && prev->vm_end == next->vm_start && can_vma_merge(next, prev->vm_flags) &&
  61.335 +	    !prev->vm_file && !(prev->vm_flags & VM_SHARED)) {
  61.336 +		spin_lock(&prev->vm_mm->page_table_lock);
  61.337 +		prev->vm_end = next->vm_end;
  61.338 +		__vma_unlink(prev->vm_mm, next, prev);
  61.339 +		spin_unlock(&prev->vm_mm->page_table_lock);
  61.340 +
  61.341 +		kmem_cache_free(vm_area_cachep, next);
  61.342 +		prev->vm_mm->map_count--;
  61.343 +	}
  61.344 +out:
  61.345 +	up_write(&current->mm->mmap_sem);
  61.346 +	return error;
  61.347 +}
    62.1 --- a/xenolinux-2.4.21-sparse/mm/mremap.c	Thu Jul 10 13:42:56 2003 +0000
    62.2 +++ b/xenolinux-2.4.21-sparse/mm/mremap.c	Sat Jul 12 22:26:07 2003 +0000
    62.3 @@ -293,6 +293,13 @@ unsigned long do_mremap(unsigned long ad
    62.4  	    !vm_enough_memory((new_len - old_len) >> PAGE_SHIFT))
    62.5  		goto out;
    62.6  
    62.7 +#if defined(CONFIG_XENO_PRIV)
    62.8 +	/* mremap() unsupported for I/O mappings in Xenolinux. */
    62.9 +	ret = -EINVAL;
   62.10 +	if (vma->vm_flags & VM_IO)
   62.11 +		goto out;
   62.12 +#endif
   62.13 +
   62.14  	/* old_len exactly to the end of the area..
   62.15  	 * And we're not relocating the area.
   62.16  	 */
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/xenolinux-2.4.21-sparse/mm/vmalloc.c	Sat Jul 12 22:26:07 2003 +0000
    63.3 @@ -0,0 +1,334 @@
    63.4 +/*
    63.5 + *  linux/mm/vmalloc.c
    63.6 + *
    63.7 + *  Copyright (C) 1993  Linus Torvalds
    63.8 + *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
    63.9 + *  SMP-safe vmalloc/vfree/ioremap, Tigran Aivazian <tigran@veritas.com>, May 2000
   63.10 + */
   63.11 +
   63.12 +#include <linux/config.h>
   63.13 +#include <linux/slab.h>
   63.14 +#include <linux/vmalloc.h>
   63.15 +#include <linux/spinlock.h>
   63.16 +#include <linux/highmem.h>
   63.17 +#include <linux/smp_lock.h>
   63.18 +
   63.19 +#include <asm/uaccess.h>
   63.20 +#include <asm/pgalloc.h>
   63.21 +
   63.22 +rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
   63.23 +struct vm_struct * vmlist;
   63.24 +
   63.25 +static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned long size)
   63.26 +{
   63.27 +	pte_t * pte;
   63.28 +	unsigned long end;
   63.29 +
   63.30 +	if (pmd_none(*pmd))
   63.31 +		return;
   63.32 +	if (pmd_bad(*pmd)) {
   63.33 +		pmd_ERROR(*pmd);
   63.34 +		pmd_clear(pmd);
   63.35 +		return;
   63.36 +	}
   63.37 +	pte = pte_offset(pmd, address);
   63.38 +	address &= ~PMD_MASK;
   63.39 +	end = address + size;
   63.40 +	if (end > PMD_SIZE)
   63.41 +		end = PMD_SIZE;
   63.42 +	do {
   63.43 +		pte_t page;
   63.44 +		page = ptep_get_and_clear(pte);
   63.45 +		address += PAGE_SIZE;
   63.46 +		pte++;
   63.47 +		if (pte_none(page))
   63.48 +			continue;
   63.49 +		if (pte_present(page)) {
   63.50 +			struct page *ptpage = pte_page(page);
   63.51 +			if (VALID_PAGE(ptpage) && (!PageReserved(ptpage)))
   63.52 +				__free_page(ptpage);
   63.53 +			continue;
   63.54 +		}
   63.55 +		printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n");
   63.56 +	} while (address < end);
   63.57 +}
   63.58 +
   63.59 +static inline void free_area_pmd(pgd_t * dir, unsigned long address, unsigned long size)
   63.60 +{
   63.61 +	pmd_t * pmd;
   63.62 +	unsigned long end;
   63.63 +
   63.64 +	if (pgd_none(*dir))
   63.65 +		return;
   63.66 +	if (pgd_bad(*dir)) {
   63.67 +		pgd_ERROR(*dir);
   63.68 +		pgd_clear(dir);
   63.69 +		return;
   63.70 +	}
   63.71 +	pmd = pmd_offset(dir, address);
   63.72 +	address &= ~PGDIR_MASK;
   63.73 +	end = address + size;
   63.74 +	if (end > PGDIR_SIZE)
   63.75 +		end = PGDIR_SIZE;
   63.76 +	do {
   63.77 +		free_area_pte(pmd, address, end - address);
   63.78 +		address = (address + PMD_SIZE) & PMD_MASK;
   63.79 +		pmd++;
   63.80 +	} while (address < end);
   63.81 +}
   63.82 +
   63.83 +void vmfree_area_pages(unsigned long address, unsigned long size)
   63.84 +{
   63.85 +	pgd_t * dir;
   63.86 +	unsigned long end = address + size;
   63.87 +
   63.88 +	dir = pgd_offset_k(address);
   63.89 +	flush_cache_all();
   63.90 +	do {
   63.91 +		free_area_pmd(dir, address, end - address);
   63.92 +		address = (address + PGDIR_SIZE) & PGDIR_MASK;
   63.93 +		dir++;
   63.94 +	} while (address && (address < end));
   63.95 +	flush_tlb_all();
   63.96 +}
   63.97 +
   63.98 +static inline int alloc_area_pte (pte_t * pte, unsigned long address,
   63.99 +			unsigned long size, int gfp_mask, pgprot_t prot)
  63.100 +{
  63.101 +	unsigned long end;
  63.102 +
  63.103 +	address &= ~PMD_MASK;
  63.104 +	end = address + size;
  63.105 +	if (end > PMD_SIZE)
  63.106 +		end = PMD_SIZE;
  63.107 +	do {
  63.108 +		struct page * page;
  63.109 +		spin_unlock(&init_mm.page_table_lock);
  63.110 +		page = alloc_page(gfp_mask);
  63.111 +		spin_lock(&init_mm.page_table_lock);
  63.112 +		if (!pte_none(*pte))
  63.113 +			printk(KERN_ERR "alloc_area_pte: page already exists\n");
  63.114 +		if (!page)
  63.115 +			return -ENOMEM;
  63.116 +		set_pte(pte, mk_pte(page, prot));
  63.117 +		address += PAGE_SIZE;
  63.118 +		pte++;
  63.119 +	} while (address < end);
  63.120 +	return 0;
  63.121 +}
  63.122 +
  63.123 +static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, int gfp_mask, pgprot_t prot)
  63.124 +{
  63.125 +	unsigned long end;
  63.126 +
  63.127 +	address &= ~PGDIR_MASK;
  63.128 +	end = address + size;
  63.129 +	if (end > PGDIR_SIZE)
  63.130 +		end = PGDIR_SIZE;
  63.131 +	do {
  63.132 +		pte_t * pte = pte_alloc(&init_mm, pmd, address);
  63.133 +		if (!pte)
  63.134 +			return -ENOMEM;
  63.135 +		if (alloc_area_pte(pte, address, end - address, gfp_mask, prot))
  63.136 +			return -ENOMEM;
  63.137 +		address = (address + PMD_SIZE) & PMD_MASK;
  63.138 +		pmd++;
  63.139 +	} while (address < end);
  63.140 +	return 0;
  63.141 +}
  63.142 +
  63.143 +inline int vmalloc_area_pages (unsigned long address, unsigned long size,
  63.144 +                               int gfp_mask, pgprot_t prot)
  63.145 +{
  63.146 +	pgd_t * dir;
  63.147 +	unsigned long end = address + size;
  63.148 +	int ret;
  63.149 +
  63.150 +	dir = pgd_offset_k(address);
  63.151 +	spin_lock(&init_mm.page_table_lock);
  63.152 +	do {
  63.153 +		pmd_t *pmd;
  63.154 +		
  63.155 +		pmd = pmd_alloc(&init_mm, dir, address);
  63.156 +		ret = -ENOMEM;
  63.157 +		if (!pmd)
  63.158 +			break;
  63.159 +
  63.160 +		ret = -ENOMEM;
  63.161 +		if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot))
  63.162 +			break;
  63.163 +
  63.164 +		address = (address + PGDIR_SIZE) & PGDIR_MASK;
  63.165 +		dir++;
  63.166 +
  63.167 +		ret = 0;
  63.168 +	} while (address && (address < end));
  63.169 +	spin_unlock(&init_mm.page_table_lock);
  63.170 +	flush_cache_all();
  63.171 +	return ret;
  63.172 +}
  63.173 +
  63.174 +struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
  63.175 +{
  63.176 +	unsigned long addr, next;
  63.177 +	struct vm_struct **p, *tmp, *area;
  63.178 +
  63.179 +	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
  63.180 +	if (!area)
  63.181 +		return NULL;
  63.182 +
  63.183 +	size += PAGE_SIZE;
  63.184 +	if (!size) {
  63.185 +		kfree (area);
  63.186 +		return NULL;
  63.187 +	}
  63.188 +
  63.189 +	addr = VMALLOC_START;
  63.190 +	write_lock(&vmlist_lock);
  63.191 +	for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
  63.192 +		if ((size + addr) < addr)
  63.193 +			goto out;
  63.194 +		if (size + addr <= (unsigned long) tmp->addr)
  63.195 +			break;
  63.196 +		next = tmp->size + (unsigned long) tmp->addr;
  63.197 +		if (next > addr) 
  63.198 +			addr = next;
  63.199 +		if (addr > VMALLOC_END-size)
  63.200 +			goto out;
  63.201 +	}
  63.202 +	area->flags = flags;
  63.203 +	area->addr = (void *)addr;
  63.204 +	area->size = size;
  63.205 +	area->next = *p;
  63.206 +	*p = area;
  63.207 +	write_unlock(&vmlist_lock);
  63.208 +	return area;
  63.209 +
  63.210 +out:
  63.211 +	write_unlock(&vmlist_lock);
  63.212 +	kfree(area);
  63.213 +	return NULL;
  63.214 +}
  63.215 +
  63.216 +void vfree(void * addr)
  63.217 +{
  63.218 +	struct vm_struct **p, *tmp;
  63.219 +
  63.220 +	if (!addr)
  63.221 +		return;
  63.222 +	if ((PAGE_SIZE-1) & (unsigned long) addr) {
  63.223 +		printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr);
  63.224 +		return;
  63.225 +	}
  63.226 +	write_lock(&vmlist_lock);
  63.227 +	for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
  63.228 +		if (tmp->addr == addr) {
  63.229 +			*p = tmp->next;
  63.230 +#ifdef CONFIG_XENO_PRIV
  63.231 +			if (tmp->flags & VM_IOREMAP)
  63.232 +				zap_page_range(&init_mm, VMALLOC_VMADDR(tmp->addr), tmp->size);
  63.233 +			else
  63.234 +#endif
  63.235 +			vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
  63.236 +			write_unlock(&vmlist_lock);
  63.237 +			kfree(tmp);
  63.238 +			return;
  63.239 +		}
  63.240 +	}
  63.241 +	write_unlock(&vmlist_lock);
  63.242 +	printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr);
  63.243 +}
  63.244 +
  63.245 +void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot)
  63.246 +{
  63.247 +	void * addr;
  63.248 +	struct vm_struct *area;
  63.249 +
  63.250 +	size = PAGE_ALIGN(size);
  63.251 +	if (!size || (size >> PAGE_SHIFT) > num_physpages)
  63.252 +		return NULL;
  63.253 +	area = get_vm_area(size, VM_ALLOC);
  63.254 +	if (!area)
  63.255 +		return NULL;
  63.256 +	addr = area->addr;
  63.257 +	if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask, prot)) {
  63.258 +		vfree(addr);
  63.259 +		return NULL;
  63.260 +	}
  63.261 +	return addr;
  63.262 +}
  63.263 +
  63.264 +long vread(char *buf, char *addr, unsigned long count)
  63.265 +{
  63.266 +	struct vm_struct *tmp;
  63.267 +	char *vaddr, *buf_start = buf;
  63.268 +	unsigned long n;
  63.269 +
  63.270 +	/* Don't allow overflow */
  63.271 +	if ((unsigned long) addr + count < count)
  63.272 +		count = -(unsigned long) addr;
  63.273 +
  63.274 +	read_lock(&vmlist_lock);
  63.275 +	for (tmp = vmlist; tmp; tmp = tmp->next) {
  63.276 +		vaddr = (char *) tmp->addr;
  63.277 +		if (addr >= vaddr + tmp->size - PAGE_SIZE)
  63.278 +			continue;
  63.279 +		while (addr < vaddr) {
  63.280 +			if (count == 0)
  63.281 +				goto finished;
  63.282 +			*buf = '\0';
  63.283 +			buf++;
  63.284 +			addr++;
  63.285 +			count--;
  63.286 +		}
  63.287 +		n = vaddr + tmp->size - PAGE_SIZE - addr;
  63.288 +		do {
  63.289 +			if (count == 0)
  63.290 +				goto finished;
  63.291 +			*buf = *addr;
  63.292 +			buf++;
  63.293 +			addr++;
  63.294 +			count--;
  63.295 +		} while (--n > 0);
  63.296 +	}
  63.297 +finished:
  63.298 +	read_unlock(&vmlist_lock);
  63.299 +	return buf - buf_start;
  63.300 +}
  63.301 +
  63.302 +long vwrite(char *buf, char *addr, unsigned long count)
  63.303 +{
  63.304 +	struct vm_struct *tmp;
  63.305 +	char *vaddr, *buf_start = buf;
  63.306 +	unsigned long n;
  63.307 +
  63.308 +	/* Don't allow overflow */
  63.309 +	if ((unsigned long) addr + count < count)
  63.310 +		count = -(unsigned long) addr;
  63.311 +
  63.312 +	read_lock(&vmlist_lock);
  63.313 +	for (tmp = vmlist; tmp; tmp = tmp->next) {
  63.314 +		vaddr = (char *) tmp->addr;
  63.315 +		if (addr >= vaddr + tmp->size - PAGE_SIZE)
  63.316 +			continue;
  63.317 +		while (addr < vaddr) {
  63.318 +			if (count == 0)
  63.319 +				goto finished;
  63.320 +			buf++;
  63.321 +			addr++;
  63.322 +			count--;
  63.323 +		}
  63.324 +		n = vaddr + tmp->size - PAGE_SIZE - addr;
  63.325 +		do {
  63.326 +			if (count == 0)
  63.327 +				goto finished;
  63.328 +			*addr = *buf;
  63.329 +			buf++;
  63.330 +			addr++;
  63.331 +			count--;
  63.332 +		} while (--n > 0);
  63.333 +	}
  63.334 +finished:
  63.335 +	read_unlock(&vmlist_lock);
  63.336 +	return buf - buf_start;
  63.337 +}