ia64/xen-unstable

changeset 1221:0b18f5295cff

bitkeeper revision 1.825.2.1 (4062d28avHqOBupTrfJcONXWeibf9A)

grand unification of shadow table stuff
author iap10@tetris.cl.cam.ac.uk
date Thu Mar 25 12:37:30 2004 +0000 (2004-03-25)
parents fc8ea15b6dcf ee66ecf7b0f5
children 78af768e6129
files .rootkeys BitKeeper/etc/ignore xen/arch/i386/domain_page.c xen/arch/i386/process.c xen/arch/i386/traps.c xen/common/debug.c xen/common/domain.c xen/common/kernel.c xen/common/memory.c xen/common/perfc.c xen/common/shadow.c xen/include/asm-i386/config.h xen/include/asm-i386/page.h xen/include/asm-i386/processor.h xen/include/xen/mm.h xen/include/xen/perfc.h xen/include/xen/perfc_defn.h xen/include/xeno/shadow.h xen/net/dev.c
line diff
     1.1 --- a/.rootkeys	Thu Mar 25 11:51:43 2004 +0000
     1.2 +++ b/.rootkeys	Thu Mar 25 12:37:30 2004 +0000
     1.3 @@ -178,6 +178,7 @@ 3ddb79bdHqdQpATqC0rmUZNbsb6L6A xen/commo
     1.4  40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c
     1.5  40589968be_t_n0-w6ggceW7h-sx0w xen/common/sched_rrobin.c
     1.6  3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c
     1.7 +405b8599xI_PoEr3zZoJ2on-jdn7iw xen/common/shadow.c
     1.8  3ddb79bdB9RNMnkQnUyZ5C9hhMSQQw xen/common/slab.c
     1.9  3ddb79bd0gVQYmL2zvuJnldvD0AGxQ xen/common/softirq.c
    1.10  3e7f358awXBC3Vw-wFRwPw18qL1khg xen/common/string.c
    1.11 @@ -590,6 +591,7 @@ 3ddb79c1-kVvF8cVa0k3ZHDdBMj01Q xen/inclu
    1.12  3f055a3dwldYR102YcSuBaxIf9t3Jw xen/include/xen/vbd.h
    1.13  3e8827bdaqPeZAWGVOwswgY9bWSx4g xen/include/xen/version.h
    1.14  3ddb79c2Ae5KpzhC9LCYG7mP_Vi4Aw xen/include/xen/vif.h
    1.15 +405b8599BsDsDwKEJLS0XipaiQW3TA xen/include/xeno/shadow.h
    1.16  3ddb79c4YQCQ6r0xNLLu0jfbM7pVmA xen/net/Makefile
    1.17  3ddb79c4AkfDkTCw0comx4L8wsUOMg xen/net/dev.c
    1.18  3ddb79c4x1L_soh8b-r_1jQW_37Icw xen/net/dev_mcast.c
     2.1 --- a/BitKeeper/etc/ignore	Thu Mar 25 11:51:43 2004 +0000
     2.2 +++ b/BitKeeper/etc/ignore	Thu Mar 25 12:37:30 2004 +0000
     2.3 @@ -1,27 +1,567 @@
     2.4 +*.a
     2.5 +*.o
     2.6 +*.pyc
     2.7 +*.so
     2.8 +*.so.*
     2.9  BitKeeper/*/*
    2.10  PENDING/*
    2.11 -*.o
    2.12 -*.so
    2.13 -*.so.*
    2.14 -*.a
    2.15 -*.pyc
    2.16 +TAGS
    2.17 +URK
    2.18  extras/mini-os/h/hypervisor-ifs
    2.19  tools/*/build/lib*/*.py
    2.20  tools/balloon/balloon
    2.21 +tools/control/.checkstyle
    2.22 +tools/control/.classpath
    2.23 +tools/control/.project
    2.24 +tools/control/build-cmdline/**
    2.25 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/Command.class
    2.26 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/CommandDestroy.class
    2.27 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/CommandHelp.class
    2.28 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/CommandList.class
    2.29 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/CommandNew.class
    2.30 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/CommandStart.class
    2.31 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/CommandStop.class
    2.32 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/Defaults$Handler.class
    2.33 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/Defaults.class
    2.34 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/Domain.class
    2.35 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.class
    2.36 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/Main.class
    2.37 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/Settings.class
    2.38 +tools/control/build-dom/uk/ac/cam/cl/xeno/domctl/StringPattern.class
    2.39 +tools/control/build-web/**
    2.40 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/Command.class
    2.41 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/CommandDestroy.class
    2.42 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/CommandHelp.class
    2.43 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/CommandList.class
    2.44 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/CommandNew.class
    2.45 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/CommandStart.class
    2.46 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/CommandStop.class
    2.47 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/Defaults$Handler.class
    2.48 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/Defaults.class
    2.49 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/Domain.class
    2.50 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.class
    2.51 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/Main.class
    2.52 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/Settings.class
    2.53 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/domctl/StringPattern.class
    2.54 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/Extent.class
    2.55 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/Library.class
    2.56 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/Main.java.orig
    2.57 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/Mode.class
    2.58 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/Parser.class
    2.59 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/Partition.class
    2.60 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/PartitionManager.class
    2.61 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/RootBean.class
    2.62 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/SystemConfigurationBean.class
    2.63 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/VirtualBlockDevice.class
    2.64 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/VirtualDisk.class
    2.65 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/VirtualDiskManager.class
    2.66 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/XML.class
    2.67 +tools/control/build-xen/WEB-INF/classes/uk/ac/cam/cl/xeno/xenctl/XMLHelper.class
    2.68 +tools/control/build-xen/WEB-INF/web.xml
    2.69 +tools/control/build-xen/about.jsp
    2.70 +tools/control/build-xen/dom-del.jsp
    2.71 +tools/control/build-xen/dom-delr.jsp
    2.72 +tools/control/build-xen/dom-lis.jsp
    2.73 +tools/control/build-xen/dom-new.jsp
    2.74 +tools/control/build-xen/dom-newr.jsp
    2.75 +tools/control/build-xen/dom-sta.jsp
    2.76 +tools/control/build-xen/dom-star.jsp
    2.77 +tools/control/build-xen/dom-stp.jsp
    2.78 +tools/control/build-xen/dom-stpr.jsp
    2.79 +tools/control/build-xen/dom.jsp
    2.80 +tools/control/build-xen/help.jsp
    2.81 +tools/control/build-xen/img/cambridge.gif
    2.82 +tools/control/build-xen/img/help.gif
    2.83 +tools/control/build-xen/img/home.gif
    2.84 +tools/control/build-xen/img/pixel.gif
    2.85 +tools/control/build-xen/img/search.gif
    2.86 +tools/control/build-xen/img/xeno.gif
    2.87 +tools/control/build-xen/index.jsp
    2.88 +tools/control/build-xen/newdom.jsp
    2.89 +tools/control/build-xen/tmpl/about.tmpl
    2.90 +tools/control/build-xen/tmpl/dom-del.tmpl
    2.91 +tools/control/build-xen/tmpl/dom-delr.tmpl
    2.92 +tools/control/build-xen/tmpl/dom-lis.tmpl
    2.93 +tools/control/build-xen/tmpl/dom-new.tmpl
    2.94 +tools/control/build-xen/tmpl/dom-newr.tmpl
    2.95 +tools/control/build-xen/tmpl/dom-sta.tmpl
    2.96 +tools/control/build-xen/tmpl/dom-star.tmpl
    2.97 +tools/control/build-xen/tmpl/dom-stp.tmpl
    2.98 +tools/control/build-xen/tmpl/dom-stpr.tmpl
    2.99 +tools/control/build-xen/tmpl/dom.tmpl
   2.100 +tools/control/build-xen/tmpl/dommenu.tmpl
   2.101 +tools/control/build-xen/tmpl/help.tmpl
   2.102 +tools/control/build-xen/tmpl/index.tmpl
   2.103 +tools/control/build-xen/tmpl/install.pl
   2.104 +tools/control/build-xen/tmpl/makefile
   2.105 +tools/control/build-xen/tmpl/newdom.tmpl
   2.106 +tools/control/build-xen/tmpl/vd-fv.tmpl
   2.107 +tools/control/build-xen/tmpl/vd-pa.tmpl
   2.108 +tools/control/build-xen/tmpl/vd-par.tmpl
   2.109 +tools/control/build-xen/tmpl/vd-pv.tmpl
   2.110 +tools/control/build-xen/tmpl/vd-vbdc.tmpl
   2.111 +tools/control/build-xen/tmpl/vd-vbdcr.tmpl
   2.112 +tools/control/build-xen/tmpl/vd-vbdd.tmpl
   2.113 +tools/control/build-xen/tmpl/vd-vbdf.tmpl
   2.114 +tools/control/build-xen/tmpl/vd-vbdfr.tmpl
   2.115 +tools/control/build-xen/tmpl/vd-vbdv.tmpl
   2.116 +tools/control/build-xen/tmpl/vd-vdc.tmpl
   2.117 +tools/control/build-xen/tmpl/vd-vdcr.tmpl
   2.118 +tools/control/build-xen/tmpl/vd-vdd.tmpl
   2.119 +tools/control/build-xen/tmpl/vd-vddr.tmpl
   2.120 +tools/control/build-xen/tmpl/vd-vdr.tmpl
   2.121 +tools/control/build-xen/tmpl/vd-vdrr.tmpl
   2.122 +tools/control/build-xen/tmpl/vd-vdv.tmpl
   2.123 +tools/control/build-xen/tmpl/vd.tmpl
   2.124 +tools/control/build-xen/tmpl/vdmenu.tmpl
   2.125 +tools/control/build-xen/tmpl/xenofoot.def
   2.126 +tools/control/build-xen/tmpl/xenohead.def
   2.127 +tools/control/build-xen/tmpl/xenostyle.css
   2.128 +tools/control/build-xen/vd-fv.jsp
   2.129 +tools/control/build-xen/vd-pa.jsp
   2.130 +tools/control/build-xen/vd-par.jsp
   2.131 +tools/control/build-xen/vd-pv.jsp
   2.132 +tools/control/build-xen/vd-vbdc.jsp
   2.133 +tools/control/build-xen/vd-vbdcr.jsp
   2.134 +tools/control/build-xen/vd-vbdd.jsp
   2.135 +tools/control/build-xen/vd-vbdf.jsp
   2.136 +tools/control/build-xen/vd-vbdfr.jsp
   2.137 +tools/control/build-xen/vd-vbdv.jsp
   2.138 +tools/control/build-xen/vd-vdc.jsp
   2.139 +tools/control/build-xen/vd-vdcr.jsp
   2.140 +tools/control/build-xen/vd-vdd.jsp
   2.141 +tools/control/build-xen/vd-vddr.jsp
   2.142 +tools/control/build-xen/vd-vdr.jsp
   2.143 +tools/control/build-xen/vd-vdrr.jsp
   2.144 +tools/control/build-xen/vd-vdv.jsp
   2.145 +tools/control/build-xen/vd.jsp
   2.146 +tools/control/build-xen/xenostyle.css
   2.147 +tools/control/dist-web/**
   2.148 +tools/control/dist/docs/api/allclasses-frame.html
   2.149 +tools/control/dist/docs/api/allclasses-noframe.html
   2.150 +tools/control/dist/docs/api/constant-values.html
   2.151 +tools/control/dist/docs/api/deprecated-list.html
   2.152 +tools/control/dist/docs/api/help-doc.html
   2.153 +tools/control/dist/docs/api/index-all.html
   2.154 +tools/control/dist/docs/api/index.html
   2.155 +tools/control/dist/docs/api/overview-frame.html
   2.156 +tools/control/dist/docs/api/overview-summary.html
   2.157 +tools/control/dist/docs/api/overview-tree.html
   2.158 +tools/control/dist/docs/api/package-list
   2.159 +tools/control/dist/docs/api/packages.html
   2.160 +tools/control/dist/docs/api/stylesheet.css
   2.161 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/Command.html
   2.162 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/CommandDestroy.html
   2.163 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/CommandHelp.html
   2.164 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/CommandList.html
   2.165 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/CommandNew.html
   2.166 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/CommandStart.html
   2.167 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/CommandStop.html
   2.168 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/Defaults.html
   2.169 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/Domain.html
   2.170 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.html
   2.171 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/Main.html
   2.172 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/Settings.html
   2.173 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/StringPattern.html
   2.174 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/package-frame.html
   2.175 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/package-summary.html
   2.176 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/domctl/package-tree.html
   2.177 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/Extent.html
   2.178 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/Library.html
   2.179 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/Mode.html
   2.180 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/Parser.html
   2.181 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/Partition.html
   2.182 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/PartitionManager.html
   2.183 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/RootBean.html
   2.184 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/SystemConfigurationBean.html
   2.185 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/VirtualBlockDevice.html
   2.186 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/VirtualDisk.html
   2.187 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/VirtualDiskManager.html
   2.188 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/XML.html
   2.189 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/XMLHelper.html
   2.190 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/package-frame.html
   2.191 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/package-summary.html
   2.192 +tools/control/dist/docs/api/uk/ac/cam/cl/xeno/xenctl/package-tree.html
   2.193 +tools/control/dist/docs/empty_dir
   2.194 +tools/control/dist/xenctl-0.1-dev.war
   2.195 +tools/control/domctl.jar
   2.196 +tools/control/eclipsebin/**
   2.197 +tools/control/web/about.jsp
   2.198 +tools/control/web/dom-del.jsp
   2.199 +tools/control/web/dom-delr.jsp
   2.200 +tools/control/web/dom-lis.jsp
   2.201 +tools/control/web/dom-new.jsp
   2.202 +tools/control/web/dom-newr.jsp
   2.203 +tools/control/web/dom-sta.jsp
   2.204 +tools/control/web/dom-star.jsp
   2.205 +tools/control/web/dom-stp.jsp
   2.206 +tools/control/web/dom-stpr.jsp
   2.207 +tools/control/web/dom.jsp
   2.208 +tools/control/web/help.jsp
   2.209 +tools/control/web/index.jsp
   2.210 +tools/control/web/newdom.jsp
   2.211 +tools/control/web/pd-g.jsp
   2.212 +tools/control/web/pd-gr.jsp
   2.213 +tools/control/web/pd-l.jsp
   2.214 +tools/control/web/pd-r.jsp
   2.215 +tools/control/web/pd-rr.jsp
   2.216 +tools/control/web/pd.jsp
   2.217 +tools/control/web/vd-fv.jsp
   2.218 +tools/control/web/vd-pa.jsp
   2.219 +tools/control/web/vd-par.jsp
   2.220 +tools/control/web/vd-pv.jsp
   2.221 +tools/control/web/vd-vbdc.jsp
   2.222 +tools/control/web/vd-vbdcr.jsp
   2.223 +tools/control/web/vd-vbdd.jsp
   2.224 +tools/control/web/vd-vbdf.jsp
   2.225 +tools/control/web/vd-vbdfr.jsp
   2.226 +tools/control/web/vd-vbdv.jsp
   2.227 +tools/control/web/vd-vdc.jsp
   2.228 +tools/control/web/vd-vdcr.jsp
   2.229 +tools/control/web/vd-vdd.jsp
   2.230 +tools/control/web/vd-vddr.jsp
   2.231 +tools/control/web/vd-vdr.jsp
   2.232 +tools/control/web/vd-vdrr.jsp
   2.233 +tools/control/web/vd-vdv.jsp
   2.234 +tools/control/web/vd.jsp
   2.235 +tools/control/web/xenostyle.css
   2.236 +tools/control/xenctl-cmdline.jar
   2.237 +tools/domain_builder/dom_builder.o
   2.238 +tools/domain_builder/dom_kill.o
   2.239 +tools/domain_builder/domain_builder
   2.240 +tools/domain_builder/kill_domain
   2.241 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/Command.class
   2.242 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/CommandDestroy.class
   2.243 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/CommandHelp.class
   2.244 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/CommandNew.class
   2.245 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/CommandStart.class
   2.246 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/CommandStop.class
   2.247 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/Defaults$Handler.class
   2.248 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/Defaults.class
   2.249 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.class
   2.250 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/Main.class
   2.251 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/Settings.class
   2.252 +tools/domctl/build/uk/ac/cam/cl/xeno/domctl/StringPattern.class
   2.253 +tools/domctl/domctl.jar
   2.254 +tools/internal/xi_build
   2.255 +tools/internal/xi_build.o
   2.256 +tools/internal/xi_create
   2.257 +tools/internal/xi_create.o
   2.258 +tools/internal/xi_destroy
   2.259 +tools/internal/xi_destroy.o
   2.260 +tools/internal/xi_list
   2.261 +tools/internal/xi_phys_grant
   2.262 +tools/internal/xi_phys_grant.c~
   2.263 +tools/internal/xi_phys_grant.o
   2.264 +tools/internal/xi_phys_probe
   2.265 +tools/internal/xi_phys_probe.c~
   2.266 +tools/internal/xi_phys_probe.o
   2.267 +tools/internal/xi_phys_revoke
   2.268 +tools/internal/xi_phys_revoke.c~
   2.269 +tools/internal/xi_phys_revoke.o
   2.270 +tools/internal/xi_restore_linux
   2.271 +tools/internal/xi_save_linux
   2.272 +tools/internal/xi_sched_domain
   2.273 +tools/internal/xi_sched_global
   2.274 +tools/internal/xi_start
   2.275 +tools/internal/xi_start.o
   2.276 +tools/internal/xi_stop
   2.277 +tools/internal/xi_stop.o
   2.278 +tools/internal/xi_usage
   2.279 +tools/internal/xi_vbd_add
   2.280 +tools/internal/xi_vbd_create
   2.281 +tools/internal/xi_vbd_info
   2.282 +tools/internal/xi_vbd_list
   2.283 +tools/internal/xi_vif_params
   2.284  tools/misc/miniterm/miniterm
   2.285 -tools/misc/xen_read_console
   2.286  tools/misc/xen_cpuperf
   2.287  tools/misc/xen_log
   2.288 +tools/misc/xen_netwatch
   2.289 +tools/misc/xen_read_console
   2.290 +tools/misc/xen_refresh_dev
   2.291 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/Extent.class
   2.292 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/Library.class
   2.293 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/Main.class
   2.294 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/Mode.class
   2.295 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/Parser.class
   2.296 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/Partition.class
   2.297 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/PartitionManager.class
   2.298 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/VirtualBlockDevice.class
   2.299 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/VirtualDisk.class
   2.300 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/VirtualDiskManager.class
   2.301 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/XML.class
   2.302 +tools/vdmanager/build/uk/ac/cam/cl/xeno/vdmanager/XMLHelper.class
   2.303 +tools/vdmanager/vdmanager.jar
   2.304 +tools/xc/lib/libxc.a
   2.305 +tools/xc/lib/libxc.so
   2.306 +tools/xc/lib/libxc.so.1.3
   2.307 +tools/xc/lib/libxc.so.1.3.0
   2.308 +tools/xc/lib/libxc_bvtsched.o
   2.309 +tools/xc/lib/libxc_domain.o
   2.310 +tools/xc/lib/libxc_linux_build.o
   2.311 +tools/xc/lib/libxc_linux_restore.o
   2.312 +tools/xc/lib/libxc_linux_save.o
   2.313 +tools/xc/lib/libxc_misc.o
   2.314 +tools/xc/lib/libxc_private.o
   2.315 +tools/xc/lib/libxc_vbd.o
   2.316 +tools/xc/lib/libxc_vif.o
   2.317 +tools/xc/lib/xc_bvtsched.o
   2.318 +tools/xc/lib/xc_domain.o
   2.319 +tools/xc/lib/xc_evtchn.o
   2.320 +tools/xc/lib/xc_linux_build.o
   2.321 +tools/xc/lib/xc_linux_restore.o
   2.322 +tools/xc/lib/xc_linux_save.o
   2.323 +tools/xc/lib/xc_misc.o
   2.324 +tools/xc/lib/xc_netbsd_build.o
   2.325 +tools/xc/lib/xc_physdev.o
   2.326 +tools/xc/lib/xc_private.o
   2.327 +tools/xc/lib/xc_vbd.o
   2.328 +tools/xc/lib/xc_vif.o
   2.329 +tools/xc/py/XenoUtil.pyc
   2.330 +tools/xc/py/build/lib.linux-i686-2.2/Xc.so
   2.331 +tools/xc/py/build/lib/XenoUtil.py
   2.332 +tools/xc/py/build/temp.linux-i686-2.2/Xc.o
   2.333 +tools/xend/xend
   2.334 +tools/xend/xend.o
   2.335 +tools/xend/xend_utils.o
   2.336  tools/xentrace/xentrace
   2.337 +xen-2.4.16/common/domain.c.smh
   2.338 +xen-2.4.16/common/kernel.c.ok-ish
   2.339 +xen-2.4.16/common/kernel.c.old
   2.340 +xen-2.4.16/drivers/block/ll_rw_blk.c.orig
   2.341 +xen-2.4.16/drivers/ide/ide-disk.c.orig
   2.342 +xen-2.4.16/drivers/ide/ide-probe.c.orig
   2.343 +xen-2.4.16/drivers/ide/ide-taskfile.c.orig
   2.344 +xen-2.4.16/drivers/ide/ide.c.orig
   2.345 +xen-2.4.16/drivers/net/e1000/e1000.o
   2.346 +xen-2.4.16/drivers/net/e1000/e1000_ethtool.o
   2.347 +xen-2.4.16/drivers/net/e1000/e1000_hw.o
   2.348 +xen-2.4.16/drivers/net/e1000/e1000_main.o
   2.349 +xen-2.4.16/drivers/net/e1000/e1000_param.o
   2.350 +xen-2.4.16/foo
   2.351 +xen-2.4.16/include/hypervisor-ifs/block.h.orig
   2.352 +xen-2.4.16/include/xeno/blkdev.h.orig
   2.353 +xen-2.4.16/include/xeno/sched.h.orig
   2.354 +xen-2.4.16/size.image
   2.355 +xen/BLOG
   2.356 +xen/arch/i386/acpitable.o
   2.357 +xen/arch/i386/apic.o
   2.358 +xen/arch/i386/arch.o
   2.359 +xen/arch/i386/boot/boot.o
   2.360 +xen/arch/i386/delay.o
   2.361 +xen/arch/i386/entry.o
   2.362 +xen/arch/i386/extable.o
   2.363 +xen/arch/i386/flushtlb.o
   2.364 +xen/arch/i386/i387.o
   2.365 +xen/arch/i386/i8259.o
   2.366 +xen/arch/i386/idle0_task.o
   2.367 +xen/arch/i386/io_apic.o
   2.368 +xen/arch/i386/ioremap.o
   2.369 +xen/arch/i386/irq.o
   2.370 +xen/arch/i386/mm.o
   2.371 +xen/arch/i386/mpparse.o
   2.372 +xen/arch/i386/nmi.o
   2.373 +xen/arch/i386/pci-dma.o
   2.374 +xen/arch/i386/pci-i386.o
   2.375 +xen/arch/i386/pci-irq.o
   2.376 +xen/arch/i386/pci-pc.o
   2.377 +xen/arch/i386/pdb-stub.o
   2.378 +xen/arch/i386/process.o
   2.379 +xen/arch/i386/rwlock.o
   2.380 +xen/arch/i386/setup.o
   2.381 +xen/arch/i386/smp.o
   2.382 +xen/arch/i386/smpboot.o
   2.383 +xen/arch/i386/time.o
   2.384 +xen/arch/i386/trampoline.o
   2.385 +xen/arch/i386/traps.o
   2.386 +xen/arch/i386/usercopy.o
   2.387 +xen/common/ac_timer.o
   2.388 +xen/common/block.o
   2.389 +xen/common/brlock.o
   2.390 +xen/common/common.o
   2.391 +xen/common/console.o
   2.392 +xen/common/debug-linux.o
   2.393 +xen/common/debug.c~
   2.394 +xen/common/debug.o
   2.395 +xen/common/dom0_ops.o
   2.396 +xen/common/dom_mem_ops.o
   2.397 +xen/common/domain.o
   2.398 +xen/common/domain_page.o
   2.399 +xen/common/event.o
   2.400 +xen/common/event_channel.o
   2.401 +xen/common/kernel.o
   2.402 +xen/common/keyhandler.o
   2.403 +xen/common/lib.o
   2.404 +xen/common/memory.o
   2.405 +xen/common/network.o
   2.406 +xen/common/page_alloc.o
   2.407 +xen/common/perfc.o
   2.408 +xen/common/physdev.o
   2.409 +xen/common/rbtree.o
   2.410 +xen/common/resource.o
   2.411 +xen/common/schedule.o
   2.412 +xen/common/shadow.o
   2.413 +xen/common/slab.o
   2.414 +xen/common/softirq.o
   2.415 +xen/common/string.o
   2.416 +xen/common/timer.o
   2.417 +xen/common/trace.o
   2.418 +xen/common/vsprintf.o
   2.419 +xen/drivers/block/blkpg.o
   2.420 +xen/drivers/block/cciss.o
   2.421 +xen/drivers/block/cciss_scsi.o
   2.422 +xen/drivers/block/driver.o
   2.423 +xen/drivers/block/elevator.o
   2.424 +xen/drivers/block/genhd.o
   2.425 +xen/drivers/block/ll_rw_blk.o
   2.426 +xen/drivers/block/xen_block.c~
   2.427 +xen/drivers/block/xen_block.o
   2.428 +xen/drivers/block/xen_physdisk.c~
   2.429 +xen/drivers/block/xen_physdisk.o
   2.430 +xen/drivers/block/xen_segment.o
   2.431 +xen/drivers/block/xen_vbd.o
   2.432 +xen/drivers/cdrom/cdrom.o
   2.433 +xen/drivers/cdrom/driver.o
   2.434 +xen/drivers/char/console.o
   2.435 +xen/drivers/char/driver.o
   2.436 +xen/drivers/char/keyboard.o
   2.437 +xen/drivers/char/serial.o
   2.438 +xen/drivers/char/xen_kbd.o
   2.439 +xen/drivers/char/xen_serial.o
   2.440 +xen/drivers/ide/driver.o
   2.441 +xen/drivers/ide/ide-cd.o
   2.442 +xen/drivers/ide/ide-disk.o
   2.443 +xen/drivers/ide/ide-dma.o
   2.444 +xen/drivers/ide/ide-features.o
   2.445 +xen/drivers/ide/ide-geometry.o
   2.446 +xen/drivers/ide/ide-pci.o
   2.447 +xen/drivers/ide/ide-probe.o
   2.448 +xen/drivers/ide/ide-taskfile.o
   2.449 +xen/drivers/ide/ide-xeno.o
   2.450 +xen/drivers/ide/ide.o
   2.451 +xen/drivers/ide/piix.o
   2.452 +xen/drivers/message/fusion/driver.o
   2.453 +xen/drivers/message/fusion/mptbase.o
   2.454 +xen/drivers/message/fusion/mptscsih.o
   2.455 +xen/drivers/net/3c59x.o
   2.456 +xen/drivers/net/8139too.o
   2.457 +xen/drivers/net/Space.o
   2.458 +xen/drivers/net/driver.o
   2.459 +xen/drivers/net/dummy.o
   2.460 +xen/drivers/net/e100/e100.o
   2.461 +xen/drivers/net/e100/e100_config.o
   2.462 +xen/drivers/net/e100/e100_eeprom.o
   2.463 +xen/drivers/net/e100/e100_main.o
   2.464 +xen/drivers/net/e100/e100_phy.o
   2.465 +xen/drivers/net/e100/e100_test.o
   2.466 +xen/drivers/net/e1000/e1000.o
   2.467 +xen/drivers/net/e1000/e1000_ethtool.o
   2.468 +xen/drivers/net/e1000/e1000_hw.o
   2.469 +xen/drivers/net/e1000/e1000_main.o
   2.470 +xen/drivers/net/e1000/e1000_param.o
   2.471 +xen/drivers/net/e1000/kcompat.o
   2.472 +xen/drivers/net/ne/8390.o
   2.473 +xen/drivers/net/ne/ne.o
   2.474 +xen/drivers/net/ne/ne_drv.o
   2.475 +xen/drivers/net/net_init.o
   2.476 +xen/drivers/net/pcnet32.o
   2.477 +xen/drivers/net/setup.o
   2.478 +xen/drivers/net/tg3.o
   2.479 +xen/drivers/net/tulip/21142.o
   2.480 +xen/drivers/net/tulip/eeprom.o
   2.481 +xen/drivers/net/tulip/interrupt.o
   2.482 +xen/drivers/net/tulip/media.o
   2.483 +xen/drivers/net/tulip/pnic.o
   2.484 +xen/drivers/net/tulip/pnic2.o
   2.485 +xen/drivers/net/tulip/timer.o
   2.486 +xen/drivers/net/tulip/tulip.o
   2.487 +xen/drivers/net/tulip/tulip_core.o
   2.488 +xen/drivers/net/via-rhine.o
   2.489 +xen/drivers/pci/classlist.h
   2.490 +xen/drivers/pci/compat.o
   2.491 +xen/drivers/pci/devlist.h
   2.492 +xen/drivers/pci/driver.o
   2.493 +xen/drivers/pci/gen-devlist
   2.494 +xen/drivers/pci/names.o
   2.495 +xen/drivers/pci/pci.o
   2.496 +xen/drivers/pci/quirks.o
   2.497 +xen/drivers/pci/setup-res.o
   2.498 +xen/drivers/scsi/BusLogic.o
   2.499 +xen/drivers/scsi/aacraid/aachba.o
   2.500 +xen/drivers/scsi/aacraid/aacraid.o
   2.501 +xen/drivers/scsi/aacraid/commctrl.o
   2.502 +xen/drivers/scsi/aacraid/comminit.o
   2.503 +xen/drivers/scsi/aacraid/commsup.o
   2.504 +xen/drivers/scsi/aacraid/dpcsup.o
   2.505 +xen/drivers/scsi/aacraid/linit.o
   2.506 +xen/drivers/scsi/aacraid/rx.o
   2.507 +xen/drivers/scsi/aacraid/sa.o
   2.508 +xen/drivers/scsi/aic7xxx/aic7770.o
   2.509 +xen/drivers/scsi/aic7xxx/aic7770_osm.o
   2.510 +xen/drivers/scsi/aic7xxx/aic79xx_core.o
   2.511 +xen/drivers/scsi/aic7xxx/aic79xx_osm.o
   2.512 +xen/drivers/scsi/aic7xxx/aic79xx_osm_pci.o
   2.513 +xen/drivers/scsi/aic7xxx/aic79xx_pci.o
   2.514 +xen/drivers/scsi/aic7xxx/aic79xx_proc.o
   2.515 +xen/drivers/scsi/aic7xxx/aic7xxx.o
   2.516 +xen/drivers/scsi/aic7xxx/aic7xxx_93cx6.o
   2.517 +xen/drivers/scsi/aic7xxx/aic7xxx_core.o
   2.518 +xen/drivers/scsi/aic7xxx/aic7xxx_osm.o
   2.519 +xen/drivers/scsi/aic7xxx/aic7xxx_osm_pci.o
   2.520 +xen/drivers/scsi/aic7xxx/aic7xxx_pci.o
   2.521 +xen/drivers/scsi/aic7xxx/aic7xxx_proc.o
   2.522 +xen/drivers/scsi/constants.o
   2.523 +xen/drivers/scsi/driver.o
   2.524 +xen/drivers/scsi/hosts.o
   2.525 +xen/drivers/scsi/megaraid.o
   2.526 +xen/drivers/scsi/scsi.o
   2.527 +xen/drivers/scsi/scsi_dma.o
   2.528 +xen/drivers/scsi/scsi_error.o
   2.529 +xen/drivers/scsi/scsi_ioctl.o
   2.530 +xen/drivers/scsi/scsi_lib.o
   2.531 +xen/drivers/scsi/scsi_merge.o
   2.532 +xen/drivers/scsi/scsi_obsolete.o
   2.533 +xen/drivers/scsi/scsi_proc.o
   2.534 +xen/drivers/scsi/scsi_queue.o
   2.535 +xen/drivers/scsi/scsi_scan.o
   2.536 +xen/drivers/scsi/scsi_syms.o
   2.537 +xen/drivers/scsi/scsicam.o
   2.538 +xen/drivers/scsi/sd.o
   2.539 +xen/drivers/scsi/sym53c8xx_2/sym53c8xx.o
   2.540 +xen/drivers/scsi/sym53c8xx_2/sym_fw.o
   2.541 +xen/drivers/scsi/sym53c8xx_2/sym_glue.o
   2.542 +xen/drivers/scsi/sym53c8xx_2/sym_hipd.o
   2.543 +xen/drivers/scsi/sym53c8xx_2/sym_malloc.o
   2.544 +xen/drivers/scsi/sym53c8xx_2/sym_misc.o
   2.545 +xen/drivers/scsi/sym53c8xx_2/sym_nvram.o
   2.546 +xen/image
   2.547 +xen/image.dis
   2.548 +xen/image.gz
   2.549 +xen/image.s
   2.550 +xen/include/asm
   2.551 +xen/include/hypervisor-ifs/arch
   2.552 +xen/include/hypervisor-ifs/hypervisor-ifs
   2.553 +xen/include/hypervisor-ifs/segment.h~
   2.554 +xen/include/linux
   2.555 +xen/include/xen/compile.h
   2.556 +xen/include/xeno/compile.h
   2.557 +xen/include/xeno/physdisk.h~
   2.558 +xen/net/dev.o
   2.559 +xen/net/dev_mcast.o
   2.560 +xen/net/devinit.o
   2.561 +xen/net/eth.o
   2.562 +xen/net/network.o
   2.563 +xen/net/skbuff.o
   2.564 +xen/tools/elf-reloc
   2.565 +xen/tools/figlet/figlet
   2.566  xen/xen
   2.567  xen/xen.gz
   2.568  xen/xen.s
   2.569 -xen/drivers/pci/classlist.h
   2.570 -xen/drivers/pci/devlist.h
   2.571 -xen/drivers/pci/gen-devlist
   2.572 -xen/include/asm
   2.573 -xen/include/hypervisor-ifs/arch
   2.574 -xen/include/xen/compile.h
   2.575 -xen/tools/elf-reloc
   2.576 -xen/tools/figlet/figlet
   2.577 -TAGS
   2.578 +xenolinux-2.4.16-sparse/arch/xeno/drivers/block/Makefile.orig
   2.579 +xenolinux-2.4.16-sparse/arch/xeno/drivers/block/block.c.orig
   2.580 +xenolinux-2.4.16-sparse/scripts/kconfig.tk
   2.581 +xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c~
   2.582 +xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c.bak
   2.583 +xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c~
   2.584 +xenolinux-2.4.21-sparse/include/linux/blk.h~
   2.585 +xenolinux-2.4.22-sparse/arch/xeno/drivers/block/device
     3.1 --- a/xen/arch/i386/domain_page.c	Thu Mar 25 11:51:43 2004 +0000
     3.2 +++ b/xen/arch/i386/domain_page.c	Thu Mar 25 12:37:30 2004 +0000
     3.3 @@ -45,6 +45,8 @@ void *map_domain_mem(unsigned long pa)
     3.4      unsigned long *cache = mapcache;
     3.5      unsigned long flags;
     3.6  
     3.7 +    perfc_incrc(map_domain_mem_count);
     3.8 +
     3.9      spin_lock_irqsave(&map_lock, flags);
    3.10  
    3.11      /* Has some other CPU caused a wrap? We must flush if so. */
     4.1 --- a/xen/arch/i386/process.c	Thu Mar 25 11:51:43 2004 +0000
     4.2 +++ b/xen/arch/i386/process.c	Thu Mar 25 12:37:30 2004 +0000
     4.3 @@ -29,9 +29,9 @@
     4.4  #include <asm/i387.h>
     4.5  #include <asm/mpspec.h>
     4.6  #include <asm/ldt.h>
     4.7 -
     4.8  #include <xen/irq.h>
     4.9  #include <xen/event.h>
    4.10 +#include <xen/shadow.h>
    4.11  
    4.12  int hlt_counter;
    4.13  
    4.14 @@ -281,7 +281,13 @@ void switch_to(struct task_struct *prev_
    4.15      }
    4.16  
    4.17      /* Switch page tables.  */
    4.18 -    write_cr3_counted(pagetable_val(next_p->mm.pagetable));
    4.19 +    if( next_p->mm.shadow_mode )
    4.20 +      {
    4.21 +	check_pagetable( next_p, next_p->mm.pagetable, "switch" );
    4.22 +	write_cr3_counted(pagetable_val(next_p->mm.shadow_table));
    4.23 +      }
    4.24 +    else
    4.25 +      write_cr3_counted(pagetable_val(next_p->mm.pagetable));
    4.26  
    4.27      set_current(next_p);
    4.28  
     5.1 --- a/xen/arch/i386/traps.c	Thu Mar 25 11:51:43 2004 +0000
     5.2 +++ b/xen/arch/i386/traps.c	Thu Mar 25 12:37:30 2004 +0000
     5.3 @@ -39,6 +39,7 @@
     5.4  #include <xen/spinlock.h>
     5.5  #include <xen/irq.h>
     5.6  #include <xen/perfc.h>
     5.7 +#include <xen/shadow.h>
     5.8  #include <asm/domain_page.h>
     5.9  #include <asm/system.h>
    5.10  #include <asm/io.h>
    5.11 @@ -323,6 +324,8 @@ asmlinkage void do_page_fault(struct pt_
    5.12  
    5.13      __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
    5.14  
    5.15 +    perfc_incrc(page_faults);
    5.16 +
    5.17      if ( unlikely(addr >= LDT_VIRT_START) && 
    5.18           (addr < (LDT_VIRT_START + (p->mm.ldt_ents*LDT_ENTRY_SIZE))) )
    5.19      {
    5.20 @@ -336,6 +339,12 @@ asmlinkage void do_page_fault(struct pt_
    5.21              return; /* successfully copied the mapping */
    5.22      }
    5.23  
    5.24 +    if ( unlikely( p->mm.shadow_mode ) && addr < PAGE_OFFSET &&
    5.25 +	 shadow_fault( addr, error_code ) )
    5.26 +      {
    5.27 +	return; // return true if fault was handled 
    5.28 +      }
    5.29 +
    5.30      if ( unlikely(!(regs->xcs & 3)) )
    5.31          goto fault_in_hypervisor;
    5.32  
    5.33 @@ -353,7 +362,8 @@ asmlinkage void do_page_fault(struct pt_
    5.34  
    5.35      if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
    5.36      {
    5.37 -        DPRINTK("Page fault: %08lx -> %08lx\n", regs->eip, fixup);
    5.38 +        perfc_incrc(copy_user_faults);
    5.39 +        //DPRINTK("copy_user fault: %08lx -> %08lx\n", regs->eip, fixup);
    5.40          regs->eip = fixup;
    5.41          regs->xds = regs->xes = regs->xfs = regs->xgs = __HYPERVISOR_DS;
    5.42          return;
     6.1 --- a/xen/common/debug.c	Thu Mar 25 11:51:43 2004 +0000
     6.2 +++ b/xen/common/debug.c	Thu Mar 25 12:37:30 2004 +0000
     6.3 @@ -91,7 +91,11 @@ int pdb_change_values(domid_t domain, u_
     6.4  
     6.5      if ((addr >> PAGE_SHIFT) == ((addr + length - 1) >> PAGE_SHIFT))
     6.6      {
     6.7 -        l2_table = map_domain_mem(pagetable_val(p->mm.pagetable));
     6.8 +        if (p->mm.shadow_mode )
     6.9 +          l2_table = map_domain_mem(pagetable_val(p->mm.shadow_table));
    6.10 +	else
    6.11 +          l2_table = map_domain_mem(pagetable_val(p->mm.pagetable));
    6.12 +
    6.13  	l2_table += l2_table_offset(addr);
    6.14  	if (!(l2_pgentry_val(*l2_table) & _PAGE_PRESENT)) 
    6.15  	{
     7.1 --- a/xen/common/domain.c	Thu Mar 25 11:51:43 2004 +0000
     7.2 +++ b/xen/common/domain.c	Thu Mar 25 12:37:30 2004 +0000
     7.3 @@ -9,6 +9,7 @@
     7.4  #include <xen/delay.h>
     7.5  #include <xen/event.h>
     7.6  #include <xen/time.h>
     7.7 +#include <xen/shadow.h>
     7.8  #include <hypervisor-ifs/dom0_ops.h>
     7.9  #include <asm/io.h>
    7.10  #include <asm/domain_page.h>
    7.11 @@ -332,12 +333,14 @@ void free_domain_page(struct pfn_info *p
    7.12          if ( !(page->count_and_flags & PGC_zombie) )
    7.13          {
    7.14              page->tlbflush_timestamp = tlbflush_clock;
    7.15 -            page->u.cpu_mask = 1 << p->processor;
    7.16 -
    7.17 -            spin_lock(&p->page_list_lock);
    7.18 -            list_del(&page->list);
    7.19 -            p->tot_pages--;
    7.20 -            spin_unlock(&p->page_list_lock);
    7.21 +	    if (p)
    7.22 +	    {
    7.23 +                page->u.cpu_mask = 1 << p->processor;
    7.24 +                spin_lock(&p->page_list_lock);
    7.25 +		list_del(&page->list);
    7.26 +		p->tot_pages--;
    7.27 +		spin_unlock(&p->page_list_lock);
    7.28 +	    }
    7.29          }
    7.30  
    7.31          page->count_and_flags = 0;
    7.32 @@ -846,6 +849,10 @@ int setup_guestos(struct task_struct *p,
    7.33  
    7.34      set_bit(PF_CONSTRUCTED, &p->flags);
    7.35  
    7.36 +#if 0 // XXXXX DO NOT CHECK IN ENBALED !!! (but useful for testing so leave) 
    7.37 +    shadow_mode_enable(p, SHM_test); 
    7.38 +#endif
    7.39 +
    7.40      new_thread(p, 
    7.41                 (unsigned long)virt_load_address, 
    7.42                 (unsigned long)virt_stack_address, 
     8.1 --- a/xen/common/kernel.c	Thu Mar 25 11:51:43 2004 +0000
     8.2 +++ b/xen/common/kernel.c	Thu Mar 25 12:37:30 2004 +0000
     8.3 @@ -107,6 +107,7 @@ void cmain(unsigned long magic, multiboo
     8.4      module_t *mod;
     8.5      void *heap_start;
     8.6      int i;
     8.7 +    unsigned long frametable_pages, max_mem;
     8.8  
     8.9      /* Parse the command-line options. */
    8.10      cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
    8.11 @@ -196,25 +197,35 @@ void cmain(unsigned long magic, multiboo
    8.12      max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
    8.13  
    8.14      /* The array of pfn_info structures must fit into the reserved area. */
    8.15 -    if ( (sizeof(struct pfn_info) * max_page) > 
    8.16 +    if ( (sizeof(struct pfn_info) * max_page) >
    8.17           (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) )
    8.18      {
    8.19 -        unsigned long new_max = 
    8.20 +        unsigned long new_max =
    8.21              (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) /
    8.22              sizeof(struct pfn_info);
    8.23 -	printk("Truncating available memory to %lu/%luMB\n", 
    8.24 +        printk("Truncating available memory to %lu/%luMB\n",
    8.25                 new_max >> (20 - PAGE_SHIFT), max_page >> (20 - PAGE_SHIFT));
    8.26 -	max_page = new_max;
    8.27 +        max_page = new_max;
    8.28      }
    8.29  
    8.30      set_current(&idle0_task);
    8.31  
    8.32      init_frametable(max_page);
    8.33 -    printk("Initialised all memory on a %luMB machine\n",
    8.34 -           max_page >> (20-PAGE_SHIFT));
    8.35 +    printk("Initialised %luMB memory on a %luMB machine\n",
    8.36 +           max_page >> (20-PAGE_SHIFT),
    8.37 +	   max_mem  >> (20-PAGE_SHIFT) );
    8.38  
    8.39      heap_start = memguard_init(&_end);
    8.40  
    8.41 +    printk("Xen heap size is %luKB\n", 
    8.42 +	   (MAX_MONITOR_ADDRESS-__pa(heap_start))/1024 );
    8.43 +
    8.44 +    if ( ((MAX_MONITOR_ADDRESS-__pa(heap_start))/1024) <= 4096 )
    8.45 +    {
    8.46 +        printk("Xen heap size is too small to safely continue!\n");
    8.47 +        for ( ; ; ) ;
    8.48 +    }
    8.49 +
    8.50      init_page_allocator(__pa(heap_start), MAX_MONITOR_ADDRESS);
    8.51   
    8.52      /* Initialise the slab allocator. */
     9.1 --- a/xen/common/memory.c	Thu Mar 25 11:51:43 2004 +0000
     9.2 +++ b/xen/common/memory.c	Thu Mar 25 12:37:30 2004 +0000
     9.3 @@ -133,6 +133,7 @@
     9.4  #include <xen/errno.h>
     9.5  #include <xen/perfc.h>
     9.6  #include <xen/interrupt.h>
     9.7 +#include <xen/shadow.h>
     9.8  #include <asm/page.h>
     9.9  #include <asm/flushtlb.h>
    9.10  #include <asm/io.h>
    9.11 @@ -182,6 +183,7 @@ static struct {
    9.12      struct task_struct *subject_p;
    9.13  } percpu_info[NR_CPUS] __cacheline_aligned;
    9.14  
    9.15 +
    9.16  /*
    9.17   * init_frametable:
    9.18   * Initialise per-frame memory information. This goes directly after
    9.19 @@ -762,9 +764,25 @@ void free_page_type(struct pfn_info *pag
    9.20      switch ( type )
    9.21      {
    9.22      case PGT_l1_page_table:
    9.23 -        return free_l1_table(page);
    9.24 +        free_l1_table(page);
    9.25 +	if ( unlikely(current->mm.shadow_mode) && 
    9.26 +	     (get_shadow_status(current, page-frame_table) & PSH_shadowed) )
    9.27 +	{
    9.28 +	    unshadow_table( page-frame_table, type );
    9.29 +	    put_shadow_status(current);
    9.30 +        }
    9.31 +	return;
    9.32 +
    9.33      case PGT_l2_page_table:
    9.34 -        return free_l2_table(page);
    9.35 +        free_l2_table(page);
    9.36 +	if ( unlikely(current->mm.shadow_mode) && 
    9.37 +	     (get_shadow_status(current, page-frame_table) & PSH_shadowed) )
    9.38 +	{
    9.39 +	    unshadow_table( page-frame_table, type );
    9.40 +	    put_shadow_status(current);
    9.41 +        }
    9.42 +	return;
    9.43 +
    9.44      default:
    9.45          BUG();
    9.46      }
    9.47 @@ -831,11 +849,22 @@ static int do_extended_command(unsigned 
    9.48          if ( likely(okay) )
    9.49          {
    9.50              invalidate_shadow_ldt();
    9.51 +
    9.52              percpu_info[cpu].deferred_ops &= ~DOP_FLUSH_TLB;
    9.53              old_base_pfn = pagetable_val(current->mm.pagetable) >> PAGE_SHIFT;
    9.54              current->mm.pagetable = mk_pagetable(pfn << PAGE_SHIFT);
    9.55 -            write_cr3_counted(pfn << PAGE_SHIFT);
    9.56 -            put_page_and_type(&frame_table[old_base_pfn]);
    9.57 +
    9.58 +            if( unlikely(current->mm.shadow_mode))
    9.59 +            {
    9.60 +                current->mm.shadow_table = 
    9.61 +                    shadow_mk_pagetable(current, pfn<<PAGE_SHIFT);
    9.62 +                write_cr3_counted(pagetable_val(current->mm.shadow_table));
    9.63 +            }
    9.64 +            else
    9.65 +            {
    9.66 +                write_cr3_counted(pfn << PAGE_SHIFT);
    9.67 +            }
    9.68 +            put_page_and_type(&frame_table[old_base_pfn]);    
    9.69          }
    9.70          else
    9.71          {
    9.72 @@ -919,6 +948,8 @@ int do_mmu_update(mmu_update_t *ureqs, i
    9.73      struct pfn_info *page;
    9.74      int rc = 0, okay = 1, i, cpu = smp_processor_id();
    9.75      unsigned int cmd;
    9.76 +    unsigned long prev_spfn = 0;
    9.77 +    l1_pgentry_t *prev_spl1e = 0;
    9.78  
    9.79      perfc_incrc(calls_to_mmu_update); 
    9.80      perfc_addc(num_page_updates, count);
    9.81 @@ -969,6 +1000,16 @@ int do_mmu_update(mmu_update_t *ureqs, i
    9.82                  {
    9.83                      okay = mod_l1_entry((l1_pgentry_t *)va, 
    9.84                                          mk_l1_pgentry(req.val)); 
    9.85 +
    9.86 +		    if ( okay && unlikely(current->mm.shadow_mode) &&
    9.87 +			 (get_shadow_status(current, page-frame_table) &
    9.88 +			  PSH_shadowed) )
    9.89 +		    {
    9.90 +		        shadow_l1_normal_pt_update( req.ptr, req.val, 
    9.91 +						    &prev_spfn, &prev_spl1e );
    9.92 +			put_shadow_status(current);
    9.93 +		    }
    9.94 +
    9.95                      put_page_type(page);
    9.96                  }
    9.97                  break;
    9.98 @@ -978,6 +1019,15 @@ int do_mmu_update(mmu_update_t *ureqs, i
    9.99                      okay = mod_l2_entry((l2_pgentry_t *)va, 
   9.100                                          mk_l2_pgentry(req.val),
   9.101                                          pfn); 
   9.102 +
   9.103 +		    if ( okay && unlikely(current->mm.shadow_mode) &&
   9.104 +			 (get_shadow_status(current, page-frame_table) & 
   9.105 +			  PSH_shadowed) )
   9.106 +		    {
   9.107 +		        shadow_l2_normal_pt_update( req.ptr, req.val );
   9.108 +			put_shadow_status(current);
   9.109 +		    }
   9.110 +
   9.111                      put_page_type(page);
   9.112                  }
   9.113                  break;
   9.114 @@ -987,10 +1037,12 @@ int do_mmu_update(mmu_update_t *ureqs, i
   9.115                      *(unsigned long *)va = req.val;
   9.116                      okay = 1;
   9.117                      put_page_type(page);
   9.118 +
   9.119 +                    // at present, we don't shadowing such pages
   9.120                  }
   9.121                  break;
   9.122              }
   9.123 -            
   9.124 +
   9.125              put_page(page);
   9.126  
   9.127              break;
   9.128 @@ -1033,11 +1085,23 @@ int do_mmu_update(mmu_update_t *ureqs, i
   9.129      if ( prev_pfn != 0 )
   9.130          unmap_domain_mem((void *)va);
   9.131  
   9.132 +    if( prev_spl1e != 0 ) 
   9.133 +        unmap_domain_mem((void *)prev_spl1e);
   9.134 +
   9.135      deferred_ops = percpu_info[cpu].deferred_ops;
   9.136      percpu_info[cpu].deferred_ops = 0;
   9.137  
   9.138      if ( deferred_ops & DOP_FLUSH_TLB )
   9.139 -        write_cr3_counted(pagetable_val(current->mm.pagetable));
   9.140 +    {
   9.141 +        if ( unlikely(current->mm.shadow_mode) )
   9.142 +	{
   9.143 +            check_pagetable( current, 
   9.144 +			     current->mm.pagetable, "pre-stlb-flush" );
   9.145 +	    write_cr3_counted(pagetable_val(current->mm.shadow_table));
   9.146 +        }
   9.147 +        else
   9.148 +  	    write_cr3_counted(pagetable_val(current->mm.pagetable));
   9.149 +    }
   9.150  
   9.151      if ( deferred_ops & DOP_RELOAD_LDT )
   9.152          (void)map_ldt_shadow_page(0);
   9.153 @@ -1061,19 +1125,58 @@ int do_update_va_mapping(unsigned long p
   9.154      unsigned int cpu = p->processor;
   9.155      unsigned long deferred_ops;
   9.156  
   9.157 +    perfc_incrc(calls_to_update_va);
   9.158 +
   9.159      if ( unlikely(page_nr >= (HYPERVISOR_VIRT_START >> PAGE_SHIFT)) )
   9.160          return -EINVAL;
   9.161  
   9.162 +    // XXX when we make this support 4MB pages we should also
   9.163 +    // deal with the case of updating L2s
   9.164 +
   9.165      if ( unlikely(!mod_l1_entry(&linear_pg_table[page_nr], 
   9.166                                  mk_l1_pgentry(val))) )
   9.167          err = -EINVAL;
   9.168  
   9.169 +    if ( unlikely(p->mm.shadow_mode) )
   9.170 +    {
   9.171 +        unsigned long sval = 0;
   9.172 +
   9.173 +	// XXX this only works for l1 entries, with no translation
   9.174 +
   9.175 +        if ( (val & _PAGE_PRESENT) && (val & _PAGE_ACCESSED) )
   9.176 +        {
   9.177 +	    sval = val;
   9.178 +            if ( !(val & _PAGE_DIRTY) ) 
   9.179 +	        sval &= ~_PAGE_RW;
   9.180 +	}
   9.181 +
   9.182 +	/*	printk("update_va_map: page_nr=%08lx val =%08lx sval =%08lx\n", 
   9.183 +	       page_nr, val, sval);*/
   9.184 +
   9.185 +	if ( __put_user( sval, ((unsigned long *) (&shadow_linear_pg_table[page_nr])) ) )
   9.186 +	{
   9.187 +	    // Since L2's are guranteed RW, failure indicates the page
   9.188 +	    // was not shadowed, so ignore.
   9.189 +            perfc_incrc(shadow_update_va_fail);
   9.190 +	    //MEM_LOG("update_va_map: couldn't write update\n");	
   9.191 +	}
   9.192 +
   9.193 +	check_pagetable( p, p->mm.pagetable, "va" ); // debug
   9.194 +    
   9.195 +    }
   9.196 +
   9.197 +
   9.198      deferred_ops = percpu_info[cpu].deferred_ops;
   9.199      percpu_info[cpu].deferred_ops = 0;
   9.200  
   9.201      if ( unlikely(deferred_ops & DOP_FLUSH_TLB) || 
   9.202           unlikely(flags & UVMF_FLUSH_TLB) )
   9.203 -        write_cr3_counted(pagetable_val(p->mm.pagetable));
   9.204 +    {
   9.205 +        if ( unlikely(p->mm.shadow_mode) )
   9.206 +            write_cr3_counted(pagetable_val(p->mm.shadow_table));
   9.207 +        else
   9.208 +            write_cr3_counted(pagetable_val(p->mm.pagetable));
   9.209 +    }
   9.210      else if ( unlikely(flags & UVMF_INVLPG) )
   9.211          __flush_tlb_one(page_nr << PAGE_SHIFT);
   9.212  
    10.1 --- a/xen/common/perfc.c	Thu Mar 25 11:51:43 2004 +0000
    10.2 +++ b/xen/common/perfc.c	Thu Mar 25 12:37:30 2004 +0000
    10.3 @@ -8,12 +8,20 @@
    10.4  #undef  PERFCOUNTER
    10.5  #undef  PERFCOUNTER_CPU
    10.6  #undef  PERFCOUNTER_ARRAY
    10.7 +#undef  PERFSTATUS
    10.8 +#undef  PERFSTATUS_CPU
    10.9 +#undef  PERFSTATUS_ARRAY
   10.10  #define PERFCOUNTER( var, name )              { name, TYPE_SINGLE, 0 },
   10.11  #define PERFCOUNTER_CPU( var, name )          { name, TYPE_CPU,    0 },
   10.12  #define PERFCOUNTER_ARRAY( var, name, size )  { name, TYPE_ARRAY,  size },
   10.13 +#define PERFSTATUS( var, name )               { name, TYPE_S_SINGLE, 0 },
   10.14 +#define PERFSTATUS_CPU( var, name )           { name, TYPE_S_CPU,    0 },
   10.15 +#define PERFSTATUS_ARRAY( var, name, size )   { name, TYPE_S_ARRAY,  size },
   10.16  static struct {
   10.17      char *name;
   10.18 -    enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY } type;
   10.19 +    enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY,
   10.20 +	   TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY
   10.21 +    } type;
   10.22      int nr_elements;
   10.23  } perfc_info[] = {
   10.24  #include <xen/perfc_defn.h>
   10.25 @@ -38,10 +46,12 @@ void perfc_printall(u_char key, void *de
   10.26          switch ( perfc_info[i].type )
   10.27          {
   10.28          case TYPE_SINGLE:
   10.29 +        case TYPE_S_SINGLE:
   10.30              printk("TOTAL[%10d]", atomic_read(&counters[0]));
   10.31              counters += 1;
   10.32              break;
   10.33          case TYPE_CPU:
   10.34 +        case TYPE_S_CPU:
   10.35              for ( j = sum = 0; j < smp_num_cpus; j++ )
   10.36                  sum += atomic_read(&counters[j]);
   10.37              printk("TOTAL[%10d]  ", sum);
   10.38 @@ -50,6 +60,7 @@ void perfc_printall(u_char key, void *de
   10.39              counters += NR_CPUS;
   10.40              break;
   10.41          case TYPE_ARRAY:
   10.42 +        case TYPE_S_ARRAY:
   10.43              for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
   10.44                  sum += atomic_read(&counters[j]);
   10.45              printk("TOTAL[%10d]  ", sum);
   10.46 @@ -64,9 +75,37 @@ void perfc_printall(u_char key, void *de
   10.47  
   10.48  void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs)
   10.49  {
   10.50 +    int i, j, sum;
   10.51      s_time_t now = NOW();
   10.52 +    atomic_t *counters = (atomic_t *)&perfcounters;
   10.53 +
   10.54      printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
   10.55             (u32)(now>>32), (u32)now);
   10.56 -    memset(&perfcounters, 0, sizeof(perfcounters));
   10.57 +
   10.58 +    // leave STATUS counters alone -- don't reset
   10.59 +
   10.60 +    for ( i = 0; i < NR_PERFCTRS; i++ ) 
   10.61 +    {
   10.62 +        switch ( perfc_info[i].type )
   10.63 +        {
   10.64 +        case TYPE_SINGLE:
   10.65 +	    atomic_set(&counters[0],0);
   10.66 +        case TYPE_S_SINGLE:
   10.67 +            counters += 1;
   10.68 +            break;
   10.69 +        case TYPE_CPU:
   10.70 +            for ( j = sum = 0; j < smp_num_cpus; j++ )
   10.71 +	      	atomic_set(&counters[j],0);
   10.72 +        case TYPE_S_CPU:
   10.73 +            counters += NR_CPUS;
   10.74 +            break;
   10.75 +        case TYPE_ARRAY:
   10.76 +            for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
   10.77 +	      	atomic_set(&counters[j],0);
   10.78 +        case TYPE_S_ARRAY:
   10.79 +            counters += perfc_info[i].nr_elements;
   10.80 +            break;
   10.81 +        }
   10.82 +    }
   10.83  }
   10.84  
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xen/common/shadow.c	Thu Mar 25 12:37:30 2004 +0000
    11.3 @@ -0,0 +1,793 @@
    11.4 +/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*- */
    11.5 +
    11.6 +#include <xeno/config.h>
    11.7 +#include <xeno/types.h>
    11.8 +#include <xeno/mm.h>
    11.9 +#include <xeno/shadow.h>
   11.10 +#include <asm/domain_page.h>
   11.11 +#include <asm/page.h>
   11.12 +
   11.13 +
   11.14 +/********
   11.15 +
   11.16 +To use these shadow page tables, guests must not rely on the ACCESSED
   11.17 +and DIRTY bits on L2 pte's being accurate -- they will typically all be set.
   11.18 +
   11.19 +I doubt this will break anything. (If guests want to use the va_update
   11.20 +mechanism they've signed up for this anyhow...)
   11.21 +
   11.22 +There's a per-domain shadow table spin lock which works fine for SMP
   11.23 +hosts. We don't have to worry about interrupts as no shadow operations
   11.24 +happen in an interrupt context. It's probably not quite ready for SMP
   11.25 +guest operation as we have to worry about synchonisation between gpte
   11.26 +and spte updates. Its possible that this might only happen in a
   11.27 +hypercall context, in which case we'll probably at have a per-domain
   11.28 +hypercall lock anyhow (at least initially).
   11.29 +
   11.30 +********/
   11.31 +
   11.32 +
   11.33 +int shadow_mode_enable( struct task_struct *p, unsigned int mode )
   11.34 +{
   11.35 +	struct shadow_status **fptr;
   11.36 +	int i;
   11.37 +
   11.38 +	// sychronously stop domain
   11.39 +    // XXX for the moment, only use on already stopped domains!!!
   11.40 +
   11.41 +	spin_lock_init(&p->mm.shadow_lock);
   11.42 +	spin_lock(&p->mm.shadow_lock);
   11.43 +
   11.44 +    p->mm.shadow_mode = mode;
   11.45 +	
   11.46 +	// allocate hashtable
   11.47 +    p->mm.shadow_ht = kmalloc( shadow_ht_buckets * 
   11.48 +							   sizeof(struct shadow_status), GFP_KERNEL );
   11.49 +	if( ! p->mm.shadow_ht )
   11.50 +		goto nomem;
   11.51 +
   11.52 +	memset( p->mm.shadow_ht, 0, shadow_ht_buckets * 
   11.53 +							   sizeof(struct shadow_status) );
   11.54 +
   11.55 +
   11.56 +	// allocate space for first lot of extra nodes
   11.57 +    p->mm.shadow_ht_extras = kmalloc( sizeof(void*) + (shadow_ht_extra_size * 
   11.58 +							   sizeof(struct shadow_status)), GFP_KERNEL );
   11.59 +
   11.60 +	if( ! p->mm.shadow_ht_extras )
   11.61 +		goto nomem;
   11.62 +
   11.63 +	memset( p->mm.shadow_ht_extras, 0, sizeof(void*) + (shadow_ht_extra_size * 
   11.64 +							   sizeof(struct shadow_status)) );
   11.65 +	
   11.66 +    // add extras to free list
   11.67 +	fptr = &p->mm.shadow_ht_free;
   11.68 +	for ( i=0; i<shadow_ht_extra_size; i++ )
   11.69 +	{
   11.70 +		*fptr = &p->mm.shadow_ht_extras[i];
   11.71 +		fptr = &(p->mm.shadow_ht_extras[i].next);
   11.72 +	}
   11.73 +	*fptr = NULL;
   11.74 +	*((struct shadow_status ** ) &p->mm.shadow_ht_extras[shadow_ht_extra_size]) = NULL;
   11.75 +
   11.76 +	spin_unlock(&p->mm.shadow_lock);
   11.77 +
   11.78 +    // call shadow_mk_pagetable
   11.79 +	p->mm.shadow_table = shadow_mk_pagetable( p, 
   11.80 +											  pagetable_val(p->mm.pagetable) );
   11.81 +
   11.82 +	return 0;
   11.83 +
   11.84 +nomem:
   11.85 +	spin_unlock(&p->mm.shadow_lock);
   11.86 +	return -ENOMEM;
   11.87 +}
   11.88 +
   11.89 +void shadow_mode_disable( )
   11.90 +{
   11.91 +
   11.92 +    // free the hash buckets as you go
   11.93 +
   11.94 +    // free the hashtable itself
   11.95 +}
   11.96 +
   11.97 +
   11.98 +static inline void free_shadow_page( struct task_struct *p, unsigned int pfn )
   11.99 +{
  11.100 +    unsigned long flags;
  11.101 +
  11.102 +	p->mm.shadow_page_count--;
  11.103 +
  11.104 +    spin_lock_irqsave(&free_list_lock, flags);
  11.105 +    list_add(&frame_table[pfn].list, &free_list);
  11.106 +    free_pfns++;
  11.107 +    spin_unlock_irqrestore(&free_list_lock, flags);
  11.108 +}
  11.109 +
  11.110 +static inline struct pfn_info *alloc_shadow_page( struct task_struct *p )
  11.111 +{
  11.112 +	p->mm.shadow_page_count++;
  11.113 +
  11.114 +	return alloc_domain_page( NULL );
  11.115 +}
  11.116 +
  11.117 +
  11.118 +static void __free_shadow_table( struct task_struct *p )
  11.119 +{
  11.120 +	int j;
  11.121 +	struct shadow_status *a;
  11.122 +	
  11.123 +	// the code assumes you're not using the page tables i.e.
  11.124 +    // the domain is stopped and cr3 is something else!!
  11.125 +
  11.126 +    // walk the hash table and call free_shadow_page on all pages
  11.127 +
  11.128 +    for(j=0;j<shadow_ht_buckets;j++)
  11.129 +    {
  11.130 +        a = &p->mm.shadow_ht[j];        
  11.131 +        if (a->pfn)
  11.132 +        {
  11.133 +            free_shadow_page( p, a->spfn_and_flags & PSH_pfn_mask );
  11.134 +            a->pfn = 0;
  11.135 +            a->spfn_and_flags = 0;
  11.136 +        }
  11.137 +        a=a->next;
  11.138 +        while(a)
  11.139 +		{ 
  11.140 +            struct shadow_status *next = a->next;
  11.141 +            free_shadow_page( p, a->spfn_and_flags & PSH_pfn_mask );
  11.142 +            a->pfn = 0;
  11.143 +            a->spfn_and_flags = 0;
  11.144 +            a->next = p->mm.shadow_ht_free;
  11.145 +            p->mm.shadow_ht_free = a;
  11.146 +            a=next;
  11.147 +		}
  11.148 +	}
  11.149 +}
  11.150 +
  11.151 +static void flush_shadow_table( struct task_struct *p )
  11.152 +{
  11.153 +	
  11.154 +    // XXX synchronously stop domain (needed for SMP guests)
  11.155 +
  11.156 +    // switch to idle task's page tables
  11.157 + 
  11.158 +    // walk the hash table and call free_shadow_page on all pages
  11.159 +	spin_lock(&p->mm.shadow_lock);
  11.160 +	__free_shadow_table( p );
  11.161 +	spin_unlock(&p->mm.shadow_lock);
  11.162 +
  11.163 +    // XXX unpause domain
  11.164 +}
  11.165 +
  11.166 +
  11.167 +
  11.168 +void unshadow_table( unsigned long gpfn, unsigned int type )
  11.169 +{
  11.170 +	unsigned long spfn;
  11.171 +
  11.172 +    SH_VLOG("unshadow_table type=%08x gpfn=%08lx",
  11.173 +		 type,
  11.174 +		 gpfn );
  11.175 +
  11.176 +	perfc_incrc(unshadow_table_count);
  11.177 +
  11.178 +	// this function is the same for both l1 and l2 tables
  11.179 +
  11.180 +	// even in the SMP guest case, there won't be a race here as
  11.181 +    // this CPU was the one that cmpxchg'ed the page to invalid
  11.182 +
  11.183 +	spfn = __shadow_status(current, gpfn) & PSH_pfn_mask;
  11.184 +	delete_shadow_status(current, gpfn);
  11.185 +
  11.186 +#if 0 // XXX leave as might be useful for later debugging
  11.187 +	{ 
  11.188 +		int i;
  11.189 +		unsigned long * spl1e = map_domain_mem( spfn<<PAGE_SHIFT );
  11.190 +
  11.191 +		for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
  11.192 +	        {
  11.193 +				spl1e[i] = 0xdead0000;
  11.194 +			}
  11.195 +		unmap_domain_mem( spl1e );
  11.196 +	}
  11.197 +#endif
  11.198 +
  11.199 +	if (type == PGT_l1_page_table)
  11.200 +		perfc_decr(shadow_l1_pages);
  11.201 +    else
  11.202 +		perfc_decr(shadow_l2_pages);
  11.203 +
  11.204 +	free_shadow_page( current, spfn );
  11.205 +
  11.206 +}
  11.207 +
  11.208 +
  11.209 +static unsigned long shadow_l2_table( 
  11.210 +                     struct task_struct *p, unsigned long gpfn )
  11.211 +{
  11.212 +	struct pfn_info *spfn_info;
  11.213 +	unsigned long spfn;
  11.214 +	l2_pgentry_t *spl2e, *gpl2e;
  11.215 +	int i;
  11.216 +
  11.217 +	SH_VVLOG("shadow_l2_table( %08lx )",gpfn);
  11.218 +	spin_lock(&p->mm.shadow_lock);
  11.219 +
  11.220 +	perfc_incrc(shadow_l2_table_count);
  11.221 +	perfc_incr(shadow_l2_pages);
  11.222 +
  11.223 +    // XXX in future, worry about racing in SMP guests 
  11.224 +    //      -- use cmpxchg with PSH_pending flag to show progress (and spin)
  11.225 +
  11.226 +	spfn_info = alloc_shadow_page(p);
  11.227 +
  11.228 +    ASSERT( spfn_info ); // XXX deal with failure later e.g. blow cache
  11.229 +
  11.230 +	spfn = (unsigned long) (spfn_info - frame_table);
  11.231 +
  11.232 +	// mark pfn as being shadowed, update field to point at shadow
  11.233 +	set_shadow_status(p, gpfn, spfn | PSH_shadowed);
  11.234 +	
  11.235 +	// we need to do this before the linear map is set up
  11.236 +	spl2e = (l2_pgentry_t *) map_domain_mem(spfn << PAGE_SHIFT);
  11.237 +
  11.238 +	// get hypervisor and 2x linear PT mapings installed 
  11.239 +	memcpy(&spl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
  11.240 +           &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
  11.241 +           HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
  11.242 +    spl2e[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
  11.243 +        mk_l2_pgentry((gpfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  11.244 +    spl2e[SH_LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
  11.245 +        mk_l2_pgentry((spfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  11.246 +    spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
  11.247 +        mk_l2_pgentry(__pa(frame_table[gpfn].u.domain->mm.perdomain_pt) | 
  11.248 +                      __PAGE_HYPERVISOR);
  11.249 +
  11.250 +	// can't use the linear map as we may not be in the right PT
  11.251 +	gpl2e = (l2_pgentry_t *) map_domain_mem(gpfn << PAGE_SHIFT);
  11.252 +
  11.253 +	// proactively create entries for pages that are already shadowed
  11.254 +	for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
  11.255 +	{
  11.256 +		unsigned long spte = 0;
  11.257 +
  11.258 +#if 0  // Turns out this doesn't really help
  11.259 +        unsigned long gpte;
  11.260 +
  11.261 +        gpte = l2_pgentry_val(gpl2e[i]);
  11.262 +
  11.263 +		if (gpte & _PAGE_PRESENT)
  11.264 +		{
  11.265 +			unsigned long s_sh = 
  11.266 +				__shadow_status(p, gpte>>PAGE_SHIFT);
  11.267 +
  11.268 +			if( s_sh & PSH_shadowed ) // PSH_shadowed
  11.269 +			{
  11.270 +				if ( unlikely( (__shadow_status(p, gpte>>PAGE_SHIFT) & PGT_type_mask) == PGT_l2_page_table) )
  11.271 +                {
  11.272 +					printk("Linear mapping detected\n");
  11.273 +  				    spte = gpte & ~_PAGE_RW;
  11.274 +                }
  11.275 +				else
  11.276 +                {
  11.277 +  				    spte = ( gpte & ~PAGE_MASK ) | (s_sh<<PAGE_SHIFT) |
  11.278 +						_PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED ;
  11.279 +				}
  11.280 +				// XXX should probably update guest to ACCESSED|DIRTY too...
  11.281 +
  11.282 +		    }
  11.283 +
  11.284 +		}
  11.285 +#endif
  11.286 +
  11.287 +		spl2e[i] = mk_l2_pgentry( spte );
  11.288 +
  11.289 +	}
  11.290 +
  11.291 +	// its arguable we should 'preemptively shadow' a few active L1 pages
  11.292 +    // to avoid taking a string of faults when 'jacking' a running domain
  11.293 +
  11.294 +    unmap_domain_mem( gpl2e );
  11.295 +    unmap_domain_mem( spl2e );
  11.296 +
  11.297 +	SH_VLOG("shadow_l2_table( %08lx -> %08lx)",gpfn,spfn);
  11.298 +
  11.299 +	spin_unlock(&p->mm.shadow_lock);
  11.300 +	return spfn;
  11.301 +}
  11.302 +
  11.303 +pagetable_t shadow_mk_pagetable( struct task_struct *p, 
  11.304 +											   unsigned long gptbase)
  11.305 +{
  11.306 +	unsigned long gpfn, spfn=0;
  11.307 +
  11.308 +	SH_VVLOG("shadow_mk_pagetable( gptbase=%08lx, mode=%d )",
  11.309 +			 gptbase, p->mm.shadow_mode );
  11.310 +
  11.311 +	if ( likely(p->mm.shadow_mode) )  // should always be true if we're here
  11.312 +	{
  11.313 +		gpfn =  gptbase >> PAGE_SHIFT;
  11.314 +		
  11.315 +		if ( unlikely((spfn=__shadow_status(p, gpfn)) == 0 ) )
  11.316 +		{
  11.317 +			spfn = shadow_l2_table(p, gpfn );
  11.318 +		}      
  11.319 +	}
  11.320 +
  11.321 +	SH_VVLOG("leaving shadow_mk_pagetable( gptbase=%08lx, mode=%d )",
  11.322 +			 gptbase, p->mm.shadow_mode );
  11.323 +
  11.324 +	return mk_pagetable(spfn<<PAGE_SHIFT);
  11.325 +}
  11.326 +
  11.327 +int shadow_fault( unsigned long va, long error_code )
  11.328 +{
  11.329 +	unsigned long gpte, spte;
  11.330 +
  11.331 +	SH_VVLOG("shadow_fault( va=%08lx, code=%ld )", va, error_code );
  11.332 +
  11.333 +    check_pagetable( current, current->mm.pagetable, "pre-sf" );
  11.334 +
  11.335 +	if ( unlikely(__get_user(gpte, (unsigned long*)&linear_pg_table[va>>PAGE_SHIFT])) )
  11.336 +	{
  11.337 +		SH_VVLOG("shadow_fault - EXIT: read gpte faulted" );
  11.338 +		return 0;  // propagate to guest
  11.339 +	}
  11.340 +
  11.341 +	if ( ! (gpte & _PAGE_PRESENT) )
  11.342 +	{
  11.343 +		SH_VVLOG("shadow_fault - EXIT: gpte not present (%lx)",gpte );
  11.344 +		return 0;  // we're not going to be able to help
  11.345 +    }
  11.346 +
  11.347 +    if ( (error_code & 2)  && ! (gpte & _PAGE_RW) )
  11.348 +    {
  11.349 +	    // write fault on RO page
  11.350 +	    return 0;
  11.351 +	}
  11.352 +
  11.353 +    spin_lock(&current->mm.shadow_lock);
  11.354 +    // take the lock and reread gpte
  11.355 +
  11.356 +	if ( unlikely(__get_user(gpte, (unsigned long*)&linear_pg_table[va>>PAGE_SHIFT])) )
  11.357 +	{
  11.358 +		SH_VVLOG("shadow_fault - EXIT: read gpte faulted" );
  11.359 +		spin_unlock(&current->mm.shadow_lock);
  11.360 +		return 0;  // propagate to guest
  11.361 +	}
  11.362 +
  11.363 +	if ( unlikely(!(gpte & _PAGE_PRESENT)) )
  11.364 +	{
  11.365 +		SH_VVLOG("shadow_fault - EXIT: gpte not present (%lx)",gpte );
  11.366 +		spin_unlock(&current->mm.shadow_lock);
  11.367 +		return 0;  // we're not going to be able to help
  11.368 +    }
  11.369 +
  11.370 +    spte = gpte;
  11.371 +
  11.372 +	if ( error_code & 2  )  
  11.373 +	{  // write fault
  11.374 +		if ( likely(gpte & _PAGE_RW) )
  11.375 +	    {
  11.376 +			gpte |= _PAGE_DIRTY | _PAGE_ACCESSED;
  11.377 +			spte |= _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED; 
  11.378 +            // (we're about to dirty it anyhow...)
  11.379 +		}
  11.380 +		else
  11.381 +		{   // write fault on RO page
  11.382 +            SH_VVLOG("shadow_fault - EXIT: write fault on RO page (%lx)",gpte );
  11.383 +            spin_unlock(&current->mm.shadow_lock);
  11.384 +			return 0; // propagate to guest
  11.385 +			// not clear whether we should set accessed bit here...
  11.386 +		}
  11.387 +	}
  11.388 +	else
  11.389 +	{
  11.390 +		gpte |= _PAGE_ACCESSED;
  11.391 +        spte |= _PAGE_ACCESSED; // about to happen anyway
  11.392 +		if ( ! (gpte & _PAGE_DIRTY) ) 
  11.393 +			spte &= ~_PAGE_RW;  // force clear unless already dirty
  11.394 +	}
  11.395 +
  11.396 + 	SH_VVLOG("plan: gpte=%08lx  spte=%08lx", gpte, spte );
  11.397 +
  11.398 +	// write back updated gpte
  11.399 +    // XXX watch out for read-only L2 entries! (not used in Linux)
  11.400 +	if ( unlikely( __put_user( gpte, (unsigned long*)&linear_pg_table[va>>PAGE_SHIFT])) )
  11.401 +		BUG();  // fixme!
  11.402 +
  11.403 +    if ( unlikely( __put_user( spte, (unsigned long*)&shadow_linear_pg_table[va>>PAGE_SHIFT])) )
  11.404 +	{ 
  11.405 +		// failed:
  11.406 +        //  the L1 may not be shadowed, or the L2 entry may be insufficient
  11.407 +
  11.408 +		unsigned long gpde, spde, gl1pfn, sl1pfn;
  11.409 +
  11.410 +        SH_VVLOG("3: not shadowed or l2 insufficient gpte=%08lx  spte=%08lx",gpte,spte );
  11.411 +
  11.412 +        gpde = l2_pgentry_val(linear_l2_table[va>>L2_PAGETABLE_SHIFT]);
  11.413 +
  11.414 +        gl1pfn = gpde>>PAGE_SHIFT;
  11.415 +
  11.416 +        
  11.417 +        if ( ! (sl1pfn=__shadow_status(current, gl1pfn) ) )
  11.418 +        {
  11.419 +            // this L1 is NOT already shadowed so we need to shadow it
  11.420 +            struct pfn_info *sl1pfn_info;
  11.421 +            unsigned long *gpl1e, *spl1e;
  11.422 +            int i;
  11.423 +            sl1pfn_info = alloc_domain_page( NULL ); // XXX account properly! 
  11.424 +            sl1pfn = sl1pfn_info - frame_table;
  11.425 +
  11.426 +            SH_VVLOG("4a: l1 not shadowed ( %08lx )",sl1pfn);
  11.427 +	        perfc_incrc(shadow_l1_table_count);
  11.428 +	        perfc_incr(shadow_l1_pages);
  11.429 +
  11.430 +            set_shadow_status(current, gl1pfn, PSH_shadowed | sl1pfn);
  11.431 +
  11.432 +            gpde = gpde | _PAGE_ACCESSED | _PAGE_DIRTY;
  11.433 +            spde = (gpde & ~PAGE_MASK) | _PAGE_RW | (sl1pfn<<PAGE_SHIFT);
  11.434 +        
  11.435 +
  11.436 +            linear_l2_table[va>>L2_PAGETABLE_SHIFT] = mk_l2_pgentry(gpde);
  11.437 +            shadow_linear_l2_table[va>>L2_PAGETABLE_SHIFT] =  mk_l2_pgentry(spde);
  11.438 +
  11.439 +            gpl1e = (unsigned long *) &(linear_pg_table[
  11.440 +                         (va>>PAGE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1) ]);
  11.441 +
  11.442 +            spl1e = (unsigned long *) &shadow_linear_pg_table[
  11.443 +                         (va>>PAGE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1) ];
  11.444 +
  11.445 +
  11.446 +			// XXX can only do this is the shadow/guest is writeable
  11.447 +            // disable write protection if ! gpde & _PAGE_RW ????
  11.448 +
  11.449 +            for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
  11.450 +	        {
  11.451 +#if SHADOW_OPTIMISE
  11.452 +                if ( (gpl1e[i] & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 
  11.453 +                                (_PAGE_PRESENT|_PAGE_ACCESSED) )
  11.454 +                {
  11.455 +                    spl1e[i] = gpl1e[i];
  11.456 +                    if ( !(gpl1e[i] & _PAGE_DIRTY) )
  11.457 +                        spl1e[i] &= ~_PAGE_RW;
  11.458 +                }
  11.459 +                else
  11.460 +#endif
  11.461 +                    spl1e[i] = 0;
  11.462 +            }
  11.463 +
  11.464 +
  11.465 +        }
  11.466 +        else
  11.467 +        {
  11.468 +            // this L1 was shadowed (by another PT) but we didn't have an L2
  11.469 +            // entry for it
  11.470 +
  11.471 +            SH_VVLOG("4b: was shadowed, l2 missing ( %08lx )",sl1pfn);
  11.472 +
  11.473 +		    spde = (gpde & ~PAGE_MASK) | (sl1pfn<<PAGE_SHIFT) | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY;
  11.474 +
  11.475 +            gpde = gpde | _PAGE_ACCESSED | _PAGE_DIRTY;
  11.476 +
  11.477 +
  11.478 +			if ( unlikely( (sl1pfn<<PAGE_SHIFT) == (gl1pfn<<PAGE_SHIFT)  ) )
  11.479 +			{   // detect linear map, and keep pointing at guest
  11.480 +                SH_VLOG("4c: linear mapping ( %08lx )",sl1pfn);
  11.481 +				spde = (spde & ~PAGE_MASK) | (gl1pfn<<PAGE_SHIFT);
  11.482 +			}
  11.483 +
  11.484 +            linear_l2_table[va>>L2_PAGETABLE_SHIFT] = mk_l2_pgentry(gpde);
  11.485 +            shadow_linear_l2_table[va>>L2_PAGETABLE_SHIFT] = mk_l2_pgentry(spde);
  11.486 +			
  11.487 +
  11.488 +        }              
  11.489 +
  11.490 +        shadow_linear_pg_table[va>>PAGE_SHIFT] = mk_l1_pgentry(spte);
  11.491 +        // (we need to do the above even if we've just made the shadow L1)
  11.492 +
  11.493 +    } // end of fixup writing the shadow L1 directly failed
  11.494 +    	
  11.495 +    perfc_incrc(shadow_fixup_count);
  11.496 +
  11.497 +    check_pagetable( current, current->mm.pagetable, "post-sf" );
  11.498 +
  11.499 +    spin_unlock(&current->mm.shadow_lock);
  11.500 +
  11.501 +    return 1; // let's try the faulting instruction again...
  11.502 +
  11.503 +}
  11.504 +
  11.505 +
  11.506 +void shadow_l1_normal_pt_update( unsigned long pa, unsigned long gpte,
  11.507 +                                 unsigned long *prev_spfn_ptr,
  11.508 +				 l1_pgentry_t **prev_spl1e_ptr )
  11.509 +{
  11.510 +    unsigned long gpfn, spfn, spte, prev_spfn = *prev_spfn_ptr;    
  11.511 +    l1_pgentry_t * spl1e, * prev_spl1e = *prev_spl1e_ptr;
  11.512 +
  11.513 +
  11.514 +SH_VVLOG("shadow_l1_normal_pt_update pa=%08lx, gpte=%08lx, prev_spfn=%08lx, prev_spl1e=%08lx\n",
  11.515 +pa,gpte,prev_spfn, prev_spl1e);
  11.516 +
  11.517 +    // to get here, we know the l1 page *must* be shadowed
  11.518 +
  11.519 +    gpfn = pa >> PAGE_SHIFT;
  11.520 +    spfn = __shadow_status(current, gpfn) & PSH_pfn_mask;
  11.521 +
  11.522 +    if ( spfn == prev_spfn )
  11.523 +    {
  11.524 +        spl1e = prev_spl1e;
  11.525 +    }
  11.526 +    else
  11.527 +    {
  11.528 +        if( prev_spl1e ) unmap_domain_mem( prev_spl1e );
  11.529 +        spl1e = (l1_pgentry_t *) map_domain_mem( spfn << PAGE_SHIFT );
  11.530 +	    *prev_spfn_ptr  = spfn;
  11.531 +	    *prev_spl1e_ptr = spl1e;
  11.532 +    }
  11.533 +	// XXX we assume only pagetables can be shadowed; this will have to change
  11.534 +	// to allow arbitrary CoW etc.
  11.535 +
  11.536 +    spte = 0;
  11.537 +
  11.538 +#if SHADOW_OPTIMISE
  11.539 +	if ( (gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 
  11.540 +		 (_PAGE_PRESENT|_PAGE_ACCESSED) )
  11.541 +    {
  11.542 +        spte = gpte;
  11.543 +		if ( !(gpte & _PAGE_DIRTY ) )
  11.544 +			gpte &= ~ _PAGE_RW;
  11.545 +	}
  11.546 +#endif
  11.547 +
  11.548 +	spl1e[(pa & ~PAGE_MASK) / sizeof(l1_pgentry_t) ] = 
  11.549 +		mk_l1_pgentry( spte );
  11.550 +
  11.551 +	//unmap_domain_mem( (void *) spl1e );
  11.552 +}
  11.553 +
  11.554 +void shadow_l2_normal_pt_update( unsigned long pa, unsigned long gpte )
  11.555 +{
  11.556 +    unsigned long gpfn, spfn, spte;
  11.557 +    l2_pgentry_t * sp2le;
  11.558 +    unsigned long s_sh=0;
  11.559 +
  11.560 +    SH_VVLOG("shadow_l2_normal_pt_update pa=%08lx, gpte=%08lx",pa,gpte);
  11.561 +
  11.562 +    // to get here, we know the l2 page has a shadow
  11.563 +
  11.564 +    gpfn = pa >> PAGE_SHIFT;
  11.565 +    spfn = __shadow_status(current, gpfn) & PSH_pfn_mask;
  11.566 +
  11.567 +
  11.568 +    spte = 0;
  11.569 +
  11.570 +	if( gpte & _PAGE_PRESENT )
  11.571 +		s_sh = __shadow_status(current, gpte >> PAGE_SHIFT);
  11.572 +
  11.573 +    sp2le = (l2_pgentry_t *) map_domain_mem( spfn << PAGE_SHIFT );
  11.574 +    // no real need for a cache here
  11.575 +		
  11.576 +	if ( s_sh ) // PSH_shadowed
  11.577 +	{
  11.578 +		if ( unlikely( (frame_table[gpte>>PAGE_SHIFT].type_and_flags & PGT_type_mask) == PGT_l2_page_table) )
  11.579 +		{ 
  11.580 +            // linear page table case
  11.581 +			spte = (gpte & ~_PAGE_RW) | _PAGE_DIRTY | _PAGE_ACCESSED; 
  11.582 +	    }
  11.583 +	    else
  11.584 +			spte = (gpte & ~PAGE_MASK) | (s_sh<<PAGE_SHIFT) | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;
  11.585 +
  11.586 +	}
  11.587 +
  11.588 +	// XXXX Should mark guest pte as DIRTY and ACCESSED too!!!!!
  11.589 +
  11.590 +	sp2le[(pa & ~PAGE_MASK) / sizeof(l2_pgentry_t) ] = 
  11.591 +		mk_l2_pgentry( spte );
  11.592 +
  11.593 +	unmap_domain_mem( (void *) sp2le );
  11.594 +}
  11.595 +
  11.596 +
  11.597 +#if SHADOW_DEBUG
  11.598 +
  11.599 +static int sh_l2_present;
  11.600 +static int sh_l1_present;
  11.601 +char * sh_check_name;
  11.602 +
  11.603 +#define FAIL(_f, _a...)                             \
  11.604 +{printk("XXX %s-FAIL (%d,%d)" _f " g=%08lx s=%08lx\n",  sh_check_name, level, i, ## _a , gpte, spte ); BUG();}
  11.605 +
  11.606 +static int check_pte( struct task_struct *p, 
  11.607 +			   unsigned long gpte, unsigned long spte, int level, int i )
  11.608 +{
  11.609 +	unsigned long mask, gpfn, spfn;
  11.610 +
  11.611 +    if ( spte == 0 || spte == 0xdeadface || spte == 0x00000E00)
  11.612 +        return 1;  // always safe
  11.613 +
  11.614 +    if ( !(spte & _PAGE_PRESENT) )
  11.615 +        FAIL("Non zero not present spte");
  11.616 +
  11.617 +	if( level == 2 ) sh_l2_present++;
  11.618 +	if( level == 1 ) sh_l1_present++;
  11.619 +
  11.620 +    if ( !(gpte & _PAGE_PRESENT) )
  11.621 +        FAIL("Guest not present yet shadow is");
  11.622 +
  11.623 +    mask = ~(_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW|0xFFFFF000);
  11.624 +
  11.625 +    if ( (spte & mask) != (gpte & mask ) )
  11.626 +		FAIL("Corrupt?");
  11.627 +
  11.628 +	if ( (spte & _PAGE_DIRTY ) && !(gpte & _PAGE_DIRTY) )
  11.629 +		FAIL("Dirty coherence");
  11.630 +
  11.631 +	if ( (spte & _PAGE_ACCESSED ) && !(gpte & _PAGE_ACCESSED) )
  11.632 +		FAIL("Accessed coherence");
  11.633 +
  11.634 +	if ( (spte & _PAGE_RW ) && !(gpte & _PAGE_RW) )
  11.635 +		FAIL("RW coherence");
  11.636 +
  11.637 +	if ( (spte & _PAGE_RW ) && !((gpte & _PAGE_RW) && (gpte & _PAGE_DIRTY) ))
  11.638 +		FAIL("RW2 coherence");
  11.639 +	
  11.640 +	spfn = spte>>PAGE_SHIFT;
  11.641 +	gpfn = gpte>>PAGE_SHIFT;
  11.642 +
  11.643 +	if ( gpfn == spfn )
  11.644 +    {
  11.645 +		if ( level > 1 )
  11.646 +			FAIL("Linear map ???");			 // XXX this will fail on BSD
  11.647 +
  11.648 +		return 1;
  11.649 +	}
  11.650 +	else
  11.651 +	{
  11.652 +		if ( level < 2 )
  11.653 +			FAIL("Shadow in L1 entry?");
  11.654 +
  11.655 +		if ( __shadow_status(p, gpfn) != (PSH_shadowed | spfn) )
  11.656 +			FAIL("spfn problem g.sf=%08lx", 
  11.657 +				 __shadow_status(p, gpfn) );
  11.658 +	}
  11.659 +
  11.660 +	return 1;
  11.661 +}
  11.662 +
  11.663 +
  11.664 +static int check_l1_table( struct task_struct *p, unsigned long va, 
  11.665 +					unsigned long g2, unsigned long s2 )
  11.666 +{
  11.667 +	int j;
  11.668 +	unsigned long *gpl1e, *spl1e;
  11.669 +
  11.670 +	//gpl1e = (unsigned long *) &(linear_pg_table[ va>>PAGE_SHIFT]);
  11.671 +	//spl1e = (unsigned long *) &(shadow_linear_pg_table[ va>>PAGE_SHIFT]);
  11.672 +
  11.673 +	gpl1e = map_domain_mem( g2<<PAGE_SHIFT );
  11.674 +	spl1e = map_domain_mem( s2<<PAGE_SHIFT );
  11.675 +
  11.676 +	for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ )
  11.677 +	{
  11.678 +		unsigned long gpte = gpl1e[j];
  11.679 +		unsigned long spte = spl1e[j];
  11.680 +		
  11.681 +		check_pte( p, gpte, spte, 1, j );
  11.682 +	}
  11.683 +	
  11.684 +	unmap_domain_mem( spl1e );
  11.685 +	unmap_domain_mem( gpl1e );
  11.686 +
  11.687 +	return 1;
  11.688 +}
  11.689 +
  11.690 +#define FAILPT(_f, _a...)                             \
  11.691 +{printk("XXX FAIL %s-PT" _f "\n", s, ## _a ); BUG();}
  11.692 +
  11.693 +int check_pagetable( struct task_struct *p, pagetable_t pt, char *s )
  11.694 +{
  11.695 +	unsigned long gptbase = pagetable_val(pt);
  11.696 +	unsigned long gpfn, spfn;
  11.697 +	int i;
  11.698 +	l2_pgentry_t *gpl2e, *spl2e;
  11.699 +
  11.700 +	sh_check_name = s;
  11.701 +
  11.702 +    SH_VVLOG("%s-PT Audit",s);
  11.703 +
  11.704 +	sh_l2_present = sh_l1_present = 0;
  11.705 +
  11.706 +	gpfn =  gptbase >> PAGE_SHIFT;
  11.707 +
  11.708 +	if ( ! (__shadow_status(p, gpfn) & PSH_shadowed) )
  11.709 +	{
  11.710 +		printk("%s-PT %08lx not shadowed\n", s, gptbase);
  11.711 +
  11.712 +		if( __shadow_status(p, gpfn) != 0 ) BUG();
  11.713 +
  11.714 +		return 0;
  11.715 +	}
  11.716 +	
  11.717 +    spfn = __shadow_status(p, gpfn) & PSH_pfn_mask;
  11.718 +
  11.719 +	if ( ! __shadow_status(p, gpfn) == (PSH_shadowed | spfn) )
  11.720 +		FAILPT("ptbase shadow inconsistent1");
  11.721 +
  11.722 +	gpl2e = (l2_pgentry_t *) map_domain_mem( gpfn << PAGE_SHIFT );
  11.723 +	spl2e = (l2_pgentry_t *) map_domain_mem( spfn << PAGE_SHIFT );
  11.724 +
  11.725 +	//ipl2e = (l2_pgentry_t *) map_domain_mem( spfn << PAGE_SHIFT );
  11.726 +
  11.727 +
  11.728 +	if ( memcmp( &spl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
  11.729 +			&gpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
  11.730 +			((SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT))-DOMAIN_ENTRIES_PER_L2_PAGETABLE)
  11.731 +			* sizeof(l2_pgentry_t)) )
  11.732 +	{
  11.733 +		printk("gpfn=%08lx spfn=%08lx\n", gpfn, spfn);
  11.734 +		for (i=DOMAIN_ENTRIES_PER_L2_PAGETABLE; 
  11.735 +			 i<(SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT));
  11.736 +			 i++ )
  11.737 +			printk("+++ (%d) %08lx %08lx\n",i,
  11.738 +				   l2_pgentry_val(gpl2e[i]), l2_pgentry_val(spl2e[i]) );
  11.739 +		FAILPT("hypervisor entries inconsistent");
  11.740 +	}
  11.741 +
  11.742 +	if ( (l2_pgentry_val(spl2e[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT]) != 
  11.743 +		  l2_pgentry_val(gpl2e[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT])) )
  11.744 +		FAILPT("hypervisor linear map inconsistent");
  11.745 +
  11.746 +	if ( (l2_pgentry_val(spl2e[SH_LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT]) != 
  11.747 +		  ((spfn << PAGE_SHIFT) | __PAGE_HYPERVISOR)) )
  11.748 +		FAILPT("hypervisor shadow linear map inconsistent %08lx %08lx",
  11.749 +			   l2_pgentry_val(spl2e[SH_LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT]),
  11.750 +			   		  (spfn << PAGE_SHIFT) | __PAGE_HYPERVISOR
  11.751 +			   );
  11.752 +
  11.753 +	if ( (l2_pgentry_val(spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT]) !=
  11.754 +		  ((__pa(frame_table[gpfn].u.domain->mm.perdomain_pt) | __PAGE_HYPERVISOR))) )
  11.755 +		FAILPT("hypervisor per-domain map inconsistent");
  11.756 +
  11.757 +
  11.758 +	// check the whole L2
  11.759 +	for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
  11.760 +	{
  11.761 +		unsigned long gpte = l2_pgentry_val(gpl2e[i]);
  11.762 +		unsigned long spte = l2_pgentry_val(spl2e[i]);
  11.763 +
  11.764 +		check_pte( p, gpte, spte, 2, i );
  11.765 +	}
  11.766 +
  11.767 +
  11.768 +	// go back and recurse
  11.769 +	for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
  11.770 +	{
  11.771 +		unsigned long gpte = l2_pgentry_val(gpl2e[i]);
  11.772 +		unsigned long spte = l2_pgentry_val(spl2e[i]);
  11.773 +
  11.774 +		if ( spte )	   
  11.775 +			check_l1_table( p,
  11.776 +				i<<L2_PAGETABLE_SHIFT,
  11.777 +				gpte>>PAGE_SHIFT, spte>>PAGE_SHIFT );
  11.778 +
  11.779 +	}
  11.780 +
  11.781 +	unmap_domain_mem( spl2e );
  11.782 +	unmap_domain_mem( gpl2e );
  11.783 +
  11.784 +	SH_VVLOG("PT verified : l2_present = %d, l1_present = %d\n",
  11.785 +		   sh_l2_present, sh_l1_present );
  11.786 +	
  11.787 +	return 1;
  11.788 +}
  11.789 +
  11.790 +
  11.791 +#endif
  11.792 +
  11.793 +
  11.794 +
  11.795 +
  11.796 +
    12.1 --- a/xen/include/asm-i386/config.h	Thu Mar 25 11:51:43 2004 +0000
    12.2 +++ b/xen/include/asm-i386/config.h	Thu Mar 25 12:37:30 2004 +0000
    12.3 @@ -40,6 +40,7 @@
    12.4  
    12.5  #define CONFIG_XEN_ATTENTION_KEY 1
    12.6  
    12.7 +
    12.8  #define HZ 100
    12.9  
   12.10  /*
   12.11 @@ -68,7 +69,7 @@
   12.12   */
   12.13  #define MAX_MONITOR_ADDRESS   (16*1024*1024)
   12.14  #define MAX_DMA_ADDRESS       (16*1024*1024)
   12.15 -#define MAX_DIRECTMAP_ADDRESS (44*1024*1024)
   12.16 +#define MAX_DIRECTMAP_ADDRESS (40*1024*1024) // XXX was 44
   12.17  /* And the virtual addresses for the direct-map region... */
   12.18  #define DIRECTMAP_VIRT_START  (READONLY_MPT_VIRT_END)
   12.19  #define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
   12.20 @@ -81,8 +82,11 @@
   12.21  /* Next 4MB of virtual address space is used as a linear p.t. mapping. */
   12.22  #define LINEAR_PT_VIRT_START  (DIRECTMAP_VIRT_END)
   12.23  #define LINEAR_PT_VIRT_END    (LINEAR_PT_VIRT_START + (4*1024*1024))
   12.24 +/* Next 4MB of virtual address space is used as a shadow linear p.t. map. */
   12.25 +#define SH_LINEAR_PT_VIRT_START  (LINEAR_PT_VIRT_END)
   12.26 +#define SH_LINEAR_PT_VIRT_END    (SH_LINEAR_PT_VIRT_START + (4*1024*1024))
   12.27  /* Next 4MB of virtual address space used for per-domain mappings (eg. GDT). */
   12.28 -#define PERDOMAIN_VIRT_START  (LINEAR_PT_VIRT_END)
   12.29 +#define PERDOMAIN_VIRT_START  (SH_LINEAR_PT_VIRT_END)
   12.30  #define PERDOMAIN_VIRT_END    (PERDOMAIN_VIRT_START + (4*1024*1024))
   12.31  #define GDT_VIRT_START        (PERDOMAIN_VIRT_START)
   12.32  #define GDT_VIRT_END          (GDT_VIRT_START + (64*1024))
    13.1 --- a/xen/include/asm-i386/page.h	Thu Mar 25 11:51:43 2004 +0000
    13.2 +++ b/xen/include/asm-i386/page.h	Thu Mar 25 12:37:30 2004 +0000
    13.3 @@ -91,6 +91,7 @@ typedef struct { unsigned long pt_lo; } 
    13.4  #include <asm/flushtlb.h>
    13.5  
    13.6  #define linear_pg_table ((l1_pgentry_t *)LINEAR_PT_VIRT_START)
    13.7 +#define linear_l2_table ((l2_pgentry_t *)(LINEAR_PT_VIRT_START+(LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
    13.8  
    13.9  extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
   13.10  extern void paging_init(void);
    14.1 --- a/xen/include/asm-i386/processor.h	Thu Mar 25 11:51:43 2004 +0000
    14.2 +++ b/xen/include/asm-i386/processor.h	Thu Mar 25 12:37:30 2004 +0000
    14.3 @@ -12,6 +12,7 @@
    14.4  #include <asm/cpufeature.h>
    14.5  #include <asm/desc.h>
    14.6  #include <xen/config.h>
    14.7 +#include <xen/spinlock.h>
    14.8  #include <hypervisor-ifs/hypervisor-if.h>
    14.9  
   14.10  struct task_struct;
   14.11 @@ -415,6 +416,16 @@ struct mm_struct {
   14.12       */
   14.13      l1_pgentry_t *perdomain_pt;
   14.14      pagetable_t  pagetable;
   14.15 +
   14.16 +    unsigned int shadow_mode;  /* flags to control shadow table operation */
   14.17 +    pagetable_t  shadow_table;
   14.18 +    spinlock_t shadow_lock;
   14.19 +    struct shadow_status *shadow_ht;
   14.20 +    struct shadow_status *shadow_ht_free;
   14.21 +    struct shadow_status *shadow_ht_extras; // extra allocation units
   14.22 +    unsigned int shadow_page_count;
   14.23 +    unsigned int shadow_max_page_count;
   14.24 +
   14.25      /* Current LDT details. */
   14.26      unsigned long ldt_base, ldt_ents, shadow_ldt_mapcnt;
   14.27      /* Next entry is passed to LGDT on domain switch. */
    15.1 --- a/xen/include/xen/mm.h	Thu Mar 25 11:51:43 2004 +0000
    15.2 +++ b/xen/include/xen/mm.h	Thu Mar 25 12:37:30 2004 +0000
    15.3 @@ -100,6 +100,7 @@ struct pfn_info
    15.4   /* 28-bit count of references to this frame. */
    15.5  #define PGC_count_mask                ((1<<28)-1)
    15.6  
    15.7 +
    15.8  /* We trust the slab allocator in slab.c, and our use of it. */
    15.9  #define PageSlab(page)		(1)
   15.10  #define PageSetSlab(page)	((void)0)
    16.1 --- a/xen/include/xen/perfc.h	Thu Mar 25 11:51:43 2004 +0000
    16.2 +++ b/xen/include/xen/perfc.h	Thu Mar 25 12:37:30 2004 +0000
    16.3 @@ -11,6 +11,11 @@
    16.4   * PERFCOUNTER_CPU (counter, string, size)    define a counter per CPU
    16.5   * PERFCOUNTER_ARRY (counter, string, size)   define an array of counters
    16.6   * 
    16.7 + * unlike "COUNTERS", "STATUS" variables DO NOT RESET
    16.8 + * PERFSTATUS (counter, string)               define a new performance stauts
    16.9 + * PERFSTATUS_CPU (counter, string, size)     define a status var per CPU
   16.10 + * PERFSTATUS_ARRY (counter, string, size)    define an array of status vars
   16.11 + * 
   16.12   * unsigned long perfc_value  (counter)        get value of a counter  
   16.13   * unsigned long perfc_valuec (counter)        get value of a per CPU counter
   16.14   * unsigned long perfc_valuea (counter, index) get value of an array counter
   16.15 @@ -32,6 +37,12 @@
   16.16    atomic_t var[NR_CPUS];
   16.17  #define PERFCOUNTER_ARRAY( var, name, size ) \
   16.18    atomic_t var[size];
   16.19 +#define PERFSTATUS( var, name ) \
   16.20 +  atomic_t var[1];
   16.21 +#define PERFSTATUS_CPU( var, name ) \
   16.22 +  atomic_t var[NR_CPUS];
   16.23 +#define PERFSTATUS_ARRAY( var, name, size ) \
   16.24 +  atomic_t var[size];
   16.25  
   16.26  struct perfcounter_t 
   16.27  {
   16.28 @@ -47,6 +58,7 @@ extern struct perfcounter_t perfcounters
   16.29  #define perfc_setc(x,v)   atomic_set(&perfcounters.x[smp_processor_id()], v)
   16.30  #define perfc_seta(x,y,v) atomic_set(&perfcounters.x[y], v)
   16.31  #define perfc_incr(x)     atomic_inc(&perfcounters.x[0])
   16.32 +#define perfc_decr(x)     atomic_dec(&perfcounters.x[0])
   16.33  #define perfc_incrc(x)    atomic_inc(&perfcounters.x[smp_processor_id()])
   16.34  #define perfc_incra(x,y)  atomic_inc(&perfcounters.x[y])
   16.35  #define perfc_add(x,y)    atomic_add((y), &perfcounters.x[0])
    17.1 --- a/xen/include/xen/perfc_defn.h	Thu Mar 25 11:51:43 2004 +0000
    17.2 +++ b/xen/include/xen/perfc_defn.h	Thu Mar 25 12:37:30 2004 +0000
    17.3 @@ -19,6 +19,17 @@ PERFCOUNTER_CPU( need_flush_tlb_flush, "
    17.4  
    17.5  PERFCOUNTER_CPU( calls_to_mmu_update, "calls_to_mmu_update" )
    17.6  PERFCOUNTER_CPU( num_page_updates, "num_page_updates" )
    17.7 -
    17.8 +PERFCOUNTER_CPU( calls_to_update_va, "calls_to_update_va_map" )
    17.9 +PERFCOUNTER_CPU( page_faults, "page faults" )
   17.10 +PERFCOUNTER_CPU( copy_user_faults, "copy_user faults" )
   17.11 +PERFCOUNTER_CPU( map_domain_mem_count, "map_domain_mem count" )
   17.12  
   17.13 +PERFCOUNTER_CPU( shadow_l2_table_count, "shadow_l2_table count" )
   17.14 +PERFCOUNTER_CPU( shadow_l1_table_count, "shadow_l1_table count" )
   17.15 +PERFCOUNTER_CPU( unshadow_table_count, "unshadow_table count" )
   17.16 +PERFCOUNTER_CPU( shadow_fixup_count, "shadow_fixup count" )
   17.17 +PERFCOUNTER_CPU( shadow_update_va_fail, "shadow_update_va_fail" )
   17.18  
   17.19 +/* STATUS counters do not reset when 'P' is hit */
   17.20 +PERFSTATUS( shadow_l2_pages, "current # shadow L2 pages" )
   17.21 +PERFSTATUS( shadow_l1_pages, "current # shadow L1 pages" )
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/xen/include/xeno/shadow.h	Thu Mar 25 12:37:30 2004 +0000
    18.3 @@ -0,0 +1,344 @@
    18.4 +/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*- */
    18.5 +
    18.6 +#ifndef _XENO_SHADOW_H
    18.7 +#define _XENO_SHADOW_H
    18.8 +
    18.9 +#include <xeno/config.h>
   18.10 +#include <xeno/types.h>
   18.11 +#include <xeno/mm.h>
   18.12 +#include <xeno/perfc.h>
   18.13 +
   18.14 +/* Shadow PT flag bits in pfn_info */
   18.15 +#define PSH_shadowed	(1<<31) /* page has a shadow. PFN points to shadow */
   18.16 +#define PSH_pending	    (1<<29) /* page is in the process of being shadowed */
   18.17 +#define PSH_pfn_mask	((1<<21)-1)
   18.18 +
   18.19 +/* Shadow PT operation mode : shadowmode variable in mm_struct */
   18.20 +#define SHM_test        (1<<0) /* just run domain on shadow PTs */
   18.21 +#define SHM_logdirty    (1<<1) /* log pages that are dirtied */
   18.22 +#define SHM_cow         (1<<2) /* copy on write all dirtied pages */
   18.23 +#define SHM_translate   (1<<3) /* lookup machine pages in translation table */
   18.24 +
   18.25 +#define shadow_linear_pg_table ((l1_pgentry_t *)SH_LINEAR_PT_VIRT_START)
   18.26 +#define shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START+(SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
   18.27 +
   18.28 +extern pagetable_t shadow_mk_pagetable( struct task_struct *p, 
   18.29 +										unsigned long gptbase);
   18.30 +extern int shadow_fault( unsigned long va, long error_code );
   18.31 +extern void shadow_l1_normal_pt_update( unsigned long pa, unsigned long gpte, 
   18.32 +										unsigned long *prev_spfn_ptr,
   18.33 +										l1_pgentry_t **prev_spl1e_ptr  );
   18.34 +extern void shadow_l2_normal_pt_update( unsigned long pa, unsigned long gpte );
   18.35 +extern void unshadow_table( unsigned long gpfn, unsigned int type );
   18.36 +extern int shadow_mode_enable( struct task_struct *p, unsigned int mode );
   18.37 +
   18.38 +#define SHADOW_DEBUG 0
   18.39 +#define SHADOW_HASH_DEBUG 0
   18.40 +#define SHADOW_OPTIMISE 1
   18.41 +
   18.42 +struct shadow_status {
   18.43 +    unsigned long pfn;            // gpfn 
   18.44 +    unsigned long spfn_and_flags; // spfn plus flags
   18.45 +    struct shadow_status *next;   // use pull-to-front list.
   18.46 +};
   18.47 +
   18.48 +#define shadow_ht_extra_size         128 /*128*/
   18.49 +#define shadow_ht_buckets            256 /*256*/
   18.50 +
   18.51 +#ifndef NDEBUG
   18.52 +#define SH_LOG(_f, _a...)                             \
   18.53 +  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
   18.54 +         current->domain , __LINE__ , ## _a )
   18.55 +#else
   18.56 +#define SH_LOG(_f, _a...) 
   18.57 +#endif
   18.58 +
   18.59 +#if SHADOW_DEBUG
   18.60 +#define SH_VLOG(_f, _a...)                             \
   18.61 +  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
   18.62 +         current->domain , __LINE__ , ## _a )
   18.63 +#else
   18.64 +#define SH_VLOG(_f, _a...) 
   18.65 +#endif
   18.66 +
   18.67 +#if 0
   18.68 +#define SH_VVLOG(_f, _a...)                             \
   18.69 +  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
   18.70 +         current->domain , __LINE__ , ## _a )
   18.71 +#else
   18.72 +#define SH_VVLOG(_f, _a...) 
   18.73 +#endif
   18.74 +
   18.75 +
   18.76 +
   18.77 +#if SHADOW_HASH_DEBUG
   18.78 +static void shadow_audit(struct task_struct *p, int print)
   18.79 +{
   18.80 +	int live=0, free=0, j=0, abs;
   18.81 +	struct shadow_status *a;
   18.82 +	
   18.83 +    for(j=0;j<shadow_ht_buckets;j++)
   18.84 +    {
   18.85 +        a = &p->mm.shadow_ht[j];        
   18.86 +		if(a->pfn) live++;
   18.87 +        while(a->next && live<9999)
   18.88 +		{ 
   18.89 +			live++; 
   18.90 +			if(a->pfn == 0)
   18.91 +			{
   18.92 +				printk("XXX live=%d pfn=%08lx sp=%08lx next=%p\n",
   18.93 +					   live, a->pfn, a->spfn_and_flags, a->next);
   18.94 +				BUG();
   18.95 +			}
   18.96 +			a=a->next; 
   18.97 +		}
   18.98 +		ASSERT(live<9999);
   18.99 +	}
  18.100 +
  18.101 +    a = p->mm.shadow_ht_free;
  18.102 +    while(a) { free++; a=a->next; }
  18.103 +
  18.104 +    if(print) printk("live=%d free=%d\n",live,free);
  18.105 +
  18.106 +	abs=(perfc_value(shadow_l1_pages)+perfc_value(shadow_l2_pages))-live;
  18.107 +	if( abs < -1 || abs > 1 )
  18.108 +	{
  18.109 +		printk("live=%d free=%d l1=%d l2=%d\n",live,free,
  18.110 +			  perfc_value(shadow_l1_pages), perfc_value(shadow_l2_pages) );
  18.111 +		BUG();
  18.112 +    }
  18.113 +
  18.114 +}
  18.115 +
  18.116 +#else
  18.117 +#define shadow_audit(p, print)
  18.118 +#endif
  18.119 +
  18.120 +static inline struct shadow_status* hash_bucket( struct task_struct *p,
  18.121 +												 unsigned int gpfn )
  18.122 +{
  18.123 +    return &(p->mm.shadow_ht[gpfn % shadow_ht_buckets]);
  18.124 +}
  18.125 +
  18.126 +
  18.127 +static inline unsigned long __shadow_status( struct task_struct *p,
  18.128 +										   unsigned int gpfn )
  18.129 +{
  18.130 +	struct shadow_status **ob, *b, *B = hash_bucket( p, gpfn );
  18.131 +
  18.132 +    b = B;
  18.133 +    ob = NULL;
  18.134 +
  18.135 +	SH_VVLOG("lookup gpfn=%08lx bucket=%08lx", gpfn, b );
  18.136 +	shadow_audit(p,0);  // if in debug mode
  18.137 +
  18.138 +	do
  18.139 +	{
  18.140 +		if ( b->pfn == gpfn )
  18.141 +		{
  18.142 +			unsigned long t;
  18.143 +			struct shadow_status *x;
  18.144 +
  18.145 +			// swap with head
  18.146 +			t=B->pfn; B->pfn=b->pfn; b->pfn=t;
  18.147 +			t=B->spfn_and_flags; B->spfn_and_flags=b->spfn_and_flags; 
  18.148 +			    b->spfn_and_flags=t;
  18.149 +
  18.150 +			if(ob)
  18.151 +			{   // pull to front
  18.152 +				*ob=b->next;
  18.153 +				x=B->next;
  18.154 +				B->next=b;	
  18.155 +				b->next=x;
  18.156 +			}			
  18.157 +			return B->spfn_and_flags;
  18.158 +		}
  18.159 +#if SHADOW_HASH_DEBUG
  18.160 +		else
  18.161 +		{
  18.162 +			if(b!=B)ASSERT(b->pfn);
  18.163 +		}
  18.164 +#endif
  18.165 +		ob=&b->next;
  18.166 +		b=b->next;
  18.167 +	}
  18.168 +	while (b);
  18.169 +
  18.170 +	return 0;
  18.171 +}
  18.172 +
  18.173 +/* we can make this locking more fine grained e.g. per shadow page if it 
  18.174 +ever becomes a problem, but since we need a spin lock on the hash table 
  18.175 +anyway its probably not worth being too clever. */
  18.176 +
  18.177 +static inline unsigned long get_shadow_status( struct task_struct *p,
  18.178 +										   unsigned int gpfn )
  18.179 +{
  18.180 +	unsigned long res;
  18.181 +
  18.182 +	spin_lock(&p->mm.shadow_lock);
  18.183 +	res = __shadow_status( p, gpfn );
  18.184 +	if (!res) spin_unlock(&p->mm.shadow_lock);
  18.185 +	return res;
  18.186 +}
  18.187 +
  18.188 +
  18.189 +static inline void put_shadow_status( struct task_struct *p )
  18.190 +{
  18.191 +	spin_unlock(&p->mm.shadow_lock);
  18.192 +}
  18.193 +
  18.194 +
  18.195 +static inline void delete_shadow_status( struct task_struct *p,
  18.196 +									  unsigned int gpfn )
  18.197 +{
  18.198 +	struct shadow_status *b, *B, **ob;
  18.199 +
  18.200 +	B = b = hash_bucket( p, gpfn );
  18.201 +
  18.202 +	SH_VVLOG("delete gpfn=%08x bucket=%p", gpfn, b );
  18.203 +	shadow_audit(p,0);
  18.204 +	ASSERT(gpfn);
  18.205 +
  18.206 +	if( b->pfn == gpfn )
  18.207 +    {
  18.208 +		if (b->next)
  18.209 +		{
  18.210 +			struct shadow_status *D=b->next;
  18.211 +			b->spfn_and_flags = b->next->spfn_and_flags;
  18.212 +			b->pfn = b->next->pfn;
  18.213 +
  18.214 +			b->next = b->next->next;
  18.215 +			D->next = p->mm.shadow_ht_free;
  18.216 +			p->mm.shadow_ht_free = D;
  18.217 +		}
  18.218 +		else
  18.219 +		{
  18.220 +			b->pfn = 0;
  18.221 +			b->spfn_and_flags = 0;
  18.222 +		}
  18.223 +
  18.224 +#if SHADOW_HASH_DEBUG
  18.225 +		if( __shadow_status(p,gpfn) ) BUG();  
  18.226 +#endif
  18.227 +		return;
  18.228 +    }
  18.229 +
  18.230 +	ob = &b->next;
  18.231 +	b=b->next;
  18.232 +
  18.233 +	do
  18.234 +	{
  18.235 +		if ( b->pfn == gpfn )			
  18.236 +		{
  18.237 +			b->pfn = 0;
  18.238 +			b->spfn_and_flags = 0;
  18.239 +
  18.240 +			// b is in the list
  18.241 +            *ob=b->next;
  18.242 +			b->next = p->mm.shadow_ht_free;
  18.243 +			p->mm.shadow_ht_free = b;
  18.244 +
  18.245 +#if SHADOW_HASH_DEBUG
  18.246 +			if( __shadow_status(p,gpfn) ) BUG();
  18.247 +#endif
  18.248 +			return;
  18.249 +		}
  18.250 +
  18.251 +		ob = &b->next;
  18.252 +		b=b->next;
  18.253 +	}
  18.254 +	while (b);
  18.255 +
  18.256 +	// if we got here, it wasn't in the list
  18.257 +    BUG();
  18.258 +}
  18.259 +
  18.260 +
  18.261 +static inline void set_shadow_status( struct task_struct *p,
  18.262 +									  unsigned int gpfn, unsigned long s )
  18.263 +{
  18.264 +	struct shadow_status *b, *B, *extra, **fptr;
  18.265 +    int i;
  18.266 +
  18.267 +	B = b = hash_bucket( p, gpfn );
  18.268 +   
  18.269 +    ASSERT(gpfn);
  18.270 +    ASSERT(s);
  18.271 +    SH_VVLOG("set gpfn=%08x s=%08lx bucket=%p(%p)", gpfn, s, b, b->next );
  18.272 +    shadow_audit(p,0);
  18.273 +
  18.274 +	do
  18.275 +	{
  18.276 +		if ( b->pfn == gpfn )			
  18.277 +		{
  18.278 +			b->spfn_and_flags = s;
  18.279 +			return;
  18.280 +		}
  18.281 +
  18.282 +		b=b->next;
  18.283 +	}
  18.284 +	while (b);
  18.285 +
  18.286 +	// if we got here, this is an insert rather than update
  18.287 +
  18.288 +    ASSERT( s );  // deletes must have succeeded by here
  18.289 +
  18.290 +    if ( B->pfn == 0 )
  18.291 +	{
  18.292 +		// we can use this head
  18.293 +        ASSERT( B->next == 0 );
  18.294 +		B->pfn = gpfn;
  18.295 +		B->spfn_and_flags = s;
  18.296 +		return;
  18.297 +	}
  18.298 +
  18.299 +    if( unlikely(p->mm.shadow_ht_free == NULL) )
  18.300 +    {
  18.301 +        SH_LOG("allocate more shadow hashtable blocks");
  18.302 +
  18.303 +        // we need to allocate more space
  18.304 +        extra = kmalloc( sizeof(void*) + (shadow_ht_extra_size * 
  18.305 +							   sizeof(struct shadow_status)), GFP_KERNEL );
  18.306 +
  18.307 +	    if( ! extra ) BUG(); // should be more graceful here....
  18.308 +
  18.309 +	    memset( extra, 0, sizeof(void*) + (shadow_ht_extra_size * 
  18.310 +							   sizeof(struct shadow_status)) );
  18.311 +	
  18.312 +        // add extras to free list
  18.313 +	    fptr = &p->mm.shadow_ht_free;
  18.314 +	    for ( i=0; i<shadow_ht_extra_size; i++ )
  18.315 + 	    {
  18.316 +		    *fptr = &extra[i];
  18.317 +		    fptr = &(extra[i].next);
  18.318 +	    }
  18.319 +	    *fptr = NULL;
  18.320 +
  18.321 +	    *((struct shadow_status ** ) &p->mm.shadow_ht[shadow_ht_extra_size]) = 
  18.322 +                                            p->mm.shadow_ht_extras;
  18.323 +        p->mm.shadow_ht_extras = extra;
  18.324 +
  18.325 +    }
  18.326 +
  18.327 +	// should really put this in B to go right to front
  18.328 +	b = p->mm.shadow_ht_free;
  18.329 +    p->mm.shadow_ht_free = b->next;
  18.330 +    b->spfn_and_flags = s;
  18.331 +	b->pfn = gpfn;
  18.332 +	b->next = B->next;
  18.333 +	B->next = b;
  18.334 +
  18.335 +	return;
  18.336 +}
  18.337 +
  18.338 +
  18.339 +
  18.340 +#if SHADOW_DEBUG
  18.341 +extern int check_pagetable( struct task_struct *p, pagetable_t pt, char *s );
  18.342 +#else
  18.343 +#define check_pagetable( p, pt, s )
  18.344 +#endif
  18.345 +
  18.346 +
  18.347 +#endif
    19.1 --- a/xen/net/dev.c	Thu Mar 25 11:51:43 2004 +0000
    19.2 +++ b/xen/net/dev.c	Thu Mar 25 12:37:30 2004 +0000
    19.3 @@ -28,6 +28,7 @@
    19.4  #include <xen/init.h>
    19.5  #include <xen/module.h>
    19.6  #include <xen/event.h>
    19.7 +#include <xen/shadow.h>
    19.8  #include <asm/domain_page.h>
    19.9  #include <asm/pgalloc.h>
   19.10  #include <asm/io.h>
   19.11 @@ -488,11 +489,12 @@ struct netif_rx_stats netdev_rx_stat[NR_
   19.12  void deliver_packet(struct sk_buff *skb, net_vif_t *vif)
   19.13  {
   19.14      rx_shadow_entry_t *rx;
   19.15 -    unsigned long *ptep, pte; 
   19.16 +    unsigned long *ptep, pte, new_pte; 
   19.17      struct pfn_info *old_page, *new_page, *pte_page;
   19.18      unsigned short size;
   19.19      unsigned char  offset, status = RING_STATUS_OK;
   19.20      struct task_struct *p = vif->domain;
   19.21 +    unsigned long spte_pfn;
   19.22  
   19.23      memcpy(skb->mac.ethernet->h_dest, vif->vmac, ETH_ALEN);
   19.24      if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP )
   19.25 @@ -530,10 +532,12 @@ void deliver_packet(struct sk_buff *skb,
   19.26      wmb(); /* Get type count and set flush bit before updating PTE. */
   19.27  
   19.28      pte = *ptep;
   19.29 +
   19.30 +    new_pte = (pte & ~PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT |
   19.31 +                          ((new_page - frame_table) << PAGE_SHIFT);
   19.32 +
   19.33      if ( unlikely(pte & _PAGE_PRESENT) || 
   19.34 -         unlikely(cmpxchg(ptep, pte, 
   19.35 -                          (pte & ~PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT |
   19.36 -                          ((new_page - frame_table) << PAGE_SHIFT))) != pte )
   19.37 +         unlikely(cmpxchg(ptep, pte, new_pte)) != pte )
   19.38      {
   19.39          DPRINTK("PTE was modified or reused! %08lx %08lx\n", pte, *ptep);
   19.40          unmap_domain_mem(ptep);
   19.41 @@ -543,6 +547,19 @@ void deliver_packet(struct sk_buff *skb,
   19.42          goto out;
   19.43      }
   19.44  
   19.45 +    if ( p->mm.shadow_mode && 
   19.46 +	 (spte_pfn=get_shadow_status(p, pte_page-frame_table)) )
   19.47 +    {
   19.48 +	unsigned long *sptr = map_domain_mem( (spte_pfn<<PAGE_SHIFT) |
   19.49 +			(((unsigned long)ptep)&~PAGE_MASK) );
   19.50 +
   19.51 +        // avoid the fault later
   19.52 +	*sptr = new_pte;
   19.53 +
   19.54 +	unmap_domain_mem(sptr);
   19.55 +	put_shadow_status(p);
   19.56 +    }
   19.57 +
   19.58      machine_to_phys_mapping[new_page - frame_table] 
   19.59          = machine_to_phys_mapping[old_page - frame_table];
   19.60      
   19.61 @@ -2049,7 +2066,7 @@ static void get_rx_bufs(net_vif_t *vif)
   19.62      rx_shadow_entry_t *srx;
   19.63      unsigned long  pte_pfn, buf_pfn;
   19.64      struct pfn_info *pte_page, *buf_page;
   19.65 -    unsigned long *ptep, pte;
   19.66 +    unsigned long *ptep, pte, spfn;
   19.67  
   19.68      spin_lock(&vif->rx_lock);
   19.69  
   19.70 @@ -2068,6 +2085,8 @@ static void get_rx_bufs(net_vif_t *vif)
   19.71  
   19.72          pte_pfn  = rx.addr >> PAGE_SHIFT;
   19.73          pte_page = &frame_table[pte_pfn];
   19.74 +
   19.75 +	//printk("MMM %08lx ", rx.addr);
   19.76              
   19.77          /* The address passed down must be to a valid PTE. */
   19.78          if ( unlikely(pte_pfn >= max_page) ||
   19.79 @@ -2081,7 +2100,7 @@ static void get_rx_bufs(net_vif_t *vif)
   19.80          
   19.81          ptep = map_domain_mem(rx.addr);
   19.82          pte  = *ptep;
   19.83 -        
   19.84 +	//printk("%08lx\n",pte);        
   19.85          /* We must be passed a valid writeable mapping to swizzle. */
   19.86          if ( unlikely((pte & (_PAGE_PRESENT|_PAGE_RW)) != 
   19.87                        (_PAGE_PRESENT|_PAGE_RW)) ||
   19.88 @@ -2092,6 +2111,17 @@ static void get_rx_bufs(net_vif_t *vif)
   19.89              make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
   19.90              goto rx_unmap_and_continue;
   19.91          }
   19.92 +
   19.93 +	if ( p->mm.shadow_mode && 
   19.94 +	     (spfn=get_shadow_status(p, rx.addr>>PAGE_SHIFT)) )
   19.95 +	  {
   19.96 +	    unsigned long * sptr = 
   19.97 +	      map_domain_mem( (spfn<<PAGE_SHIFT) | (rx.addr&~PAGE_MASK) );
   19.98 +
   19.99 +	    *sptr = 0;
  19.100 +	    unmap_domain_mem( sptr );
  19.101 +	    put_shadow_status(p);
  19.102 +	  }
  19.103          
  19.104          buf_pfn  = pte >> PAGE_SHIFT;
  19.105          buf_page = &frame_table[buf_pfn];
  19.106 @@ -2112,6 +2142,8 @@ static void get_rx_bufs(net_vif_t *vif)
  19.107              put_page_and_type(pte_page);
  19.108              make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
  19.109              goto rx_unmap_and_continue;
  19.110 +
  19.111 +	    // XXX IAP should SHADOW_CONFIG do something here?
  19.112          }
  19.113  
  19.114          /*