1 /****************************************************************************** 2 * Xen balloon driver - enables returning/claiming memory to/from Xen. 3 * 4 * Copyright (c) 2003, B Dragovic 5 * Copyright (c) 2003-2004, M Williamson, K Fraser 6 * Copyright (c) 2005 Dan M. Smith, IBM Corporation 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License version 2 10 * as published by the Free Software Foundation; or, when distributed 11 * separately from the Linux kernel or incorporated into other 12 * software packages, subject to the following license: 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining a copy 15 * of this source file (the "Software"), to deal in the Software without 16 * restriction, including without limitation the rights to use, copy, modify, 17 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 18 * and to permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be included in 22 * all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 30 * IN THE SOFTWARE. 31 */ 32 33 #include <linux/kernel.h> 34 #include <linux/module.h> 35 #include <linux/capability.h> 36 37 #include <xen/xen.h> 38 #include <xen/interface/xen.h> 39 #include <xen/balloon.h> 40 #include <xen/xenbus.h> 41 #include <xen/features.h> 42 #include <xen/page.h> 43 44 #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) 45 46 #define BALLOON_CLASS_NAME "xen_memory" 47 48 static struct device balloon_dev; 49 50 static int register_balloon(struct device *dev); 51 52 /* React to a change in the target key */ 53 static void watch_target(struct xenbus_watch *watch, 54 const char **vec, unsigned int len) 55 { 56 unsigned long long new_target; 57 int err; 58 59 err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target); 60 if (err != 1) { 61 /* This is ok (for domain0 at least) - so just return */ 62 return; 63 } 64 65 /* The given memory/target value is in KiB, so it needs converting to 66 * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. 67 */ 68 balloon_set_new_target(new_target >> (PAGE_SHIFT - 10)); 69 } 70 static struct xenbus_watch target_watch = { 71 .node = "memory/target", 72 .callback = watch_target, 73 }; 74 75 76 static int balloon_init_watcher(struct notifier_block *notifier, 77 unsigned long event, 78 void *data) 79 { 80 int err; 81 82 err = register_xenbus_watch(&target_watch); 83 if (err) 84 printk(KERN_ERR "Failed to set balloon watcher\n"); 85 86 return NOTIFY_DONE; 87 } 88 89 static struct notifier_block xenstore_notifier = { 90 .notifier_call = balloon_init_watcher, 91 }; 92 93 static int __init balloon_init(void) 94 { 95 if (!xen_domain()) 96 return -ENODEV; 97 98 pr_info("xen-balloon: Initialising balloon driver.\n"); 99 100 register_balloon(&balloon_dev); 101 102 register_xen_selfballooning(&balloon_dev); 103 104 register_xenstore_notifier(&xenstore_notifier); 105 106 return 0; 107 } 108 subsys_initcall(balloon_init); 109 110 static void balloon_exit(void) 111 { 112 /* XXX - release balloon here */ 113 return; 114 } 115 116 module_exit(balloon_exit); 117 118 #define BALLOON_SHOW(name, format, args...) \ 119 static ssize_t show_##name(struct device *dev, \ 120 struct device_attribute *attr, \ 121 char *buf) \ 122 { \ 123 return sprintf(buf, format, ##args); \ 124 } \ 125 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) 126 127 BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); 128 BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); 129 BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); 130 131 static DEVICE_ULONG_ATTR(schedule_delay, 0444, balloon_stats.schedule_delay); 132 static DEVICE_ULONG_ATTR(max_schedule_delay, 0644, balloon_stats.max_schedule_delay); 133 static DEVICE_ULONG_ATTR(retry_count, 0444, balloon_stats.retry_count); 134 static DEVICE_ULONG_ATTR(max_retry_count, 0644, balloon_stats.max_retry_count); 135 136 static ssize_t show_target_kb(struct device *dev, struct device_attribute *attr, 137 char *buf) 138 { 139 return sprintf(buf, "%lu\n", PAGES2KB(balloon_stats.target_pages)); 140 } 141 142 static ssize_t store_target_kb(struct device *dev, 143 struct device_attribute *attr, 144 const char *buf, 145 size_t count) 146 { 147 char *endchar; 148 unsigned long long target_bytes; 149 150 if (!capable(CAP_SYS_ADMIN)) 151 return -EPERM; 152 153 target_bytes = simple_strtoull(buf, &endchar, 0) * 1024; 154 155 balloon_set_new_target(target_bytes >> PAGE_SHIFT); 156 157 return count; 158 } 159 160 static DEVICE_ATTR(target_kb, S_IRUGO | S_IWUSR, 161 show_target_kb, store_target_kb); 162 163 164 static ssize_t show_target(struct device *dev, struct device_attribute *attr, 165 char *buf) 166 { 167 return sprintf(buf, "%llu\n", 168 (unsigned long long)balloon_stats.target_pages 169 << PAGE_SHIFT); 170 } 171 172 static ssize_t store_target(struct device *dev, 173 struct device_attribute *attr, 174 const char *buf, 175 size_t count) 176 { 177 char *endchar; 178 unsigned long long target_bytes; 179 180 if (!capable(CAP_SYS_ADMIN)) 181 return -EPERM; 182 183 target_bytes = memparse(buf, &endchar); 184 185 balloon_set_new_target(target_bytes >> PAGE_SHIFT); 186 187 return count; 188 } 189 190 static DEVICE_ATTR(target, S_IRUGO | S_IWUSR, 191 show_target, store_target); 192 193 194 static struct device_attribute *balloon_attrs[] = { 195 &dev_attr_target_kb, 196 &dev_attr_target, 197 &dev_attr_schedule_delay.attr, 198 &dev_attr_max_schedule_delay.attr, 199 &dev_attr_retry_count.attr, 200 &dev_attr_max_retry_count.attr 201 }; 202 203 static struct attribute *balloon_info_attrs[] = { 204 &dev_attr_current_kb.attr, 205 &dev_attr_low_kb.attr, 206 &dev_attr_high_kb.attr, 207 NULL 208 }; 209 210 static const struct attribute_group balloon_info_group = { 211 .name = "info", 212 .attrs = balloon_info_attrs 213 }; 214 215 static struct bus_type balloon_subsys = { 216 .name = BALLOON_CLASS_NAME, 217 .dev_name = BALLOON_CLASS_NAME, 218 }; 219 220 static int register_balloon(struct device *dev) 221 { 222 int i, error; 223 224 error = subsys_system_register(&balloon_subsys, NULL); 225 if (error) 226 return error; 227 228 dev->id = 0; 229 dev->bus = &balloon_subsys; 230 231 error = device_register(dev); 232 if (error) { 233 bus_unregister(&balloon_subsys); 234 return error; 235 } 236 237 for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++) { 238 error = device_create_file(dev, balloon_attrs[i]); 239 if (error) 240 goto fail; 241 } 242 243 error = sysfs_create_group(&dev->kobj, &balloon_info_group); 244 if (error) 245 goto fail; 246 247 return 0; 248 249 fail: 250 while (--i >= 0) 251 device_remove_file(dev, balloon_attrs[i]); 252 device_unregister(dev); 253 bus_unregister(&balloon_subsys); 254 return error; 255 } 256 257 MODULE_LICENSE("GPL"); 258