ia64/xen-unstable
changeset 1223:9eb1d25256fa
bitkeeper revision 1.825.1.4 (4062dc0766Es7F8I-0OuMpp-TFgN5A)
Merge tetris.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into tetris.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xeno.bk
Merge tetris.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into tetris.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xeno.bk
author | iap10@tetris.cl.cam.ac.uk |
---|---|
date | Thu Mar 25 13:17:59 2004 +0000 (2004-03-25) |
parents | d75495926616 78af768e6129 |
children | ee077109a7b3 |
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/xen/shadow.h xen/net/dev.c |
line diff
1.1 --- a/.rootkeys Thu Mar 25 12:18:14 2004 +0000 1.2 +++ b/.rootkeys Thu Mar 25 13:17:59 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 @@ -574,6 +575,7 @@ 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/inclu 1.12 40589969nPq3DMzv24RDb5LXE9brHw xen/include/xen/sched-if.h 1.13 3ddb79c0LzqqS0LhAQ50ekgj4oGl7Q xen/include/xen/sched.h 1.14 403a06a7H0hpHcKpAiDe5BPnaXWTlA xen/include/xen/serial.h 1.15 +405b8599BsDsDwKEJLS0XipaiQW3TA xen/include/xen/shadow.h 1.16 3ddb79c0VDeD-Oft5eNfMneTU3D1dQ xen/include/xen/skbuff.h 1.17 3ddb79c14dXIhP7C2ahnoD08K90G_w xen/include/xen/slab.h 1.18 3ddb79c09xbS-xxfKxuV3JETIhBzmg xen/include/xen/smp.h
2.1 --- a/BitKeeper/etc/ignore Thu Mar 25 12:18:14 2004 +0000 2.2 +++ b/BitKeeper/etc/ignore Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 3.2 +++ b/xen/arch/i386/domain_page.c Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 4.2 +++ b/xen/arch/i386/process.c Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 5.2 +++ b/xen/arch/i386/traps.c Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 6.2 +++ b/xen/common/debug.c Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 7.2 +++ b/xen/common/domain.c Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 8.2 +++ b/xen/common/kernel.c Thu Mar 25 13:17:59 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 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 12:18:14 2004 +0000 9.2 +++ b/xen/common/memory.c Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 10.2 +++ b/xen/common/perfc.c Thu Mar 25 13:17:59 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 13:17:59 2004 +0000 11.3 @@ -0,0 +1,793 @@ 11.4 +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 11.5 + 11.6 +#include <xen/config.h> 11.7 +#include <xen/types.h> 11.8 +#include <xen/mm.h> 11.9 +#include <xen/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(¤t->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(¤t->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(¤t->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(¤t->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(¤t->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 12:18:14 2004 +0000 12.2 +++ b/xen/include/asm-i386/config.h Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 13.2 +++ b/xen/include/asm-i386/page.h Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 14.2 +++ b/xen/include/asm-i386/processor.h Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 15.2 +++ b/xen/include/xen/mm.h Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 16.2 +++ b/xen/include/xen/perfc.h Thu Mar 25 13:17:59 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 12:18:14 2004 +0000 17.2 +++ b/xen/include/xen/perfc_defn.h Thu Mar 25 13:17:59 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/xen/shadow.h Thu Mar 25 13:17:59 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 <xen/config.h> 18.10 +#include <xen/types.h> 18.11 +#include <xen/mm.h> 18.12 +#include <xen/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 12:18:14 2004 +0000 19.2 +++ b/xen/net/dev.c Thu Mar 25 13:17:59 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 /*