History

Merge tag 'for-linus-5.6-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen updates from Juergen Gross: - fix a bug introduced in 5.5 in the Xen gntdev driver - fix the Xen balloon driver when running on ancient Xen versions - allow Xen stubdoms to control interrupt enable flags of passed-through PCI cards - release resources in Xen backends under memory pressure * tag 'for-linus-5.6-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/blkback: Consistently insert one empty line between functions xen/blkback: Remove unnecessary static variable name prefixes xen/blkback: Squeeze page pools if a memory pressure is detected xenbus/backend: Protect xenbus callback with lock xenbus/backend: Add memory pressure handler callback xen/gntdev: Do not use mm notifiers with autotranslating guests xen/balloon: Support xend-based toolstack take two xen-pciback: optionally allow interrupt enable flag writes

Linus Torvalds committed 6 years ago

Commit d271ab22 parents 2634744 8557bbe16 files · +346 −39Browse files

Unified · Split

16 files
  1. Documentation/ABI/testing/sysfs-driver-pciback +13 −0
  2. Documentation/ABI/testing/sysfs-driver-xen-blkback +10 −0
  3. drivers/block/xen-blkback/blkback.c +21 −21
  4. drivers/block/xen-blkback/common.h +1 −0
  5. drivers/block/xen-blkback/xenbus.c +22 −4
  6. drivers/xen/gntdev.c +12 −12
  7. drivers/xen/xen-balloon.c +1 −1
  8. drivers/xen/xen-pciback/conf_space.c +37 −0
  9. drivers/xen/xen-pciback/conf_space.h +7 −0
  10. drivers/xen/xen-pciback/conf_space_capability.c +89 −0
  11. drivers/xen/xen-pciback/conf_space_header.c +19 −0
  12. drivers/xen/xen-pciback/pci_stub.c +66 −0
  13. drivers/xen/xen-pciback/pciback.h +1 −0
  14. drivers/xen/xenbus/xenbus_probe.c +7 −1
  15. drivers/xen/xenbus/xenbus_probe_backend.c +38 −0
  16. include/xen/xenbus.h +2 −0
Documentation/ABI/testing/sysfs-driver-pciback+13−0
@@ -11,3 +11,16 @@ Description: · 10 unmodified lines
11 #echo 00:19.0-E0:2:FF > /sys/bus/pci/drivers/pciback/quirks11 #echo 00:19.0-E0:2:FF > /sys/bus/pci/drivers/pciback/quirks
12 will allow the guest to read and write to the configuration12 will allow the guest to read and write to the configuration
13 register 0x0E.13 register 0x0E.
14
15What: /sys/bus/pci/drivers/pciback/allow_interrupt_control
16Date: Jan 2020
17KernelVersion: 5.6
18Contact: xen-devel@lists.xenproject.org
19Description:
20 List of devices which can have interrupt control flag (INTx,
21 MSI, MSI-X) set by a connected guest. It is meant to be set
22 only when the guest is a stubdomain hosting device model (qemu)
23 and the actual device is assigned to a HVM. It is not safe
24 (similar to permissive attribute) to set for a devices assigned
25 to a PV guest. The device is automatically removed from this
26 list when the connected pcifront terminates.
Documentation/ABI/testing/sysfs-driver-xen-blkback+10−0
@@ -25,3 +25,13 @@ Description: · 24 unmodified lines
25 allocated without being in use. The time is in25 allocated without being in use. The time is in
26 seconds, 0 means indefinitely long.26 seconds, 0 means indefinitely long.
27 The default is 60 seconds.27 The default is 60 seconds.
28
29What: /sys/module/xen_blkback/parameters/buffer_squeeze_duration_ms
30Date: December 2019
31KernelVersion: 5.6
32Contact: SeongJae Park <sjpark@amazon.de>
33Description:
34 When memory pressure is reported to blkback this option
35 controls the duration in milliseconds that blkback will not
36 cache any page not backed by a grant mapping.
37 The default is 10ms.
drivers/block/xen-blkback/blkback.c+21−21
@@ -62,8 +62,8 @@ · 61 unmodified lines
62 * IO workloads.62 * IO workloads.
63 */63 */
64 64
65static int xen_blkif_max_buffer_pages = 1024;65static int max_buffer_pages = 1024;
66module_param_named(max_buffer_pages, xen_blkif_max_buffer_pages, int, 0644);66module_param_named(max_buffer_pages, max_buffer_pages, int, 0644);
67MODULE_PARM_DESC(max_buffer_pages,67MODULE_PARM_DESC(max_buffer_pages,
68"Maximum number of free pages to keep in each block backend buffer");68"Maximum number of free pages to keep in each block backend buffer");
69 69
@@ -78,8 +78,8 @@ MODULE_PARM_DESC(max_buffer_pages, · 8 unmodified lines
78 * algorithm.78 * algorithm.
79 */79 */
80 80
81static int xen_blkif_max_pgrants = 1056;81static int max_pgrants = 1056;
82module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);82module_param_named(max_persistent_grants, max_pgrants, int, 0644);
83MODULE_PARM_DESC(max_persistent_grants,83MODULE_PARM_DESC(max_persistent_grants,
84 "Maximum number of grants to map persistently");84 "Maximum number of grants to map persistently");
85 85
@@ -88,8 +88,8 @@ MODULE_PARM_DESC(max_persistent_grants, · 2 unmodified lines
88 * use. The time is in seconds, 0 means indefinitely long.88 * use. The time is in seconds, 0 means indefinitely long.
89 */89 */
90 90
91static unsigned int xen_blkif_pgrant_timeout = 60;91static unsigned int pgrant_timeout = 60;
92module_param_named(persistent_grant_unused_seconds, xen_blkif_pgrant_timeout,92module_param_named(persistent_grant_unused_seconds, pgrant_timeout,
93 uint, 0644);93 uint, 0644);
94MODULE_PARM_DESC(persistent_grant_unused_seconds,94MODULE_PARM_DESC(persistent_grant_unused_seconds,
95 "Time in seconds an unused persistent grant is allowed to "95 "Time in seconds an unused persistent grant is allowed to "
@@ -137,9 +137,8 @@ module_param(log_stats, int, 0644); · 41 unmodified lines
137 137
138static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)138static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)
139{139{
140 return xen_blkif_pgrant_timeout &&140 return pgrant_timeout && (jiffies - persistent_gnt->last_used >=
141 (jiffies - persistent_gnt->last_used >=141 HZ * pgrant_timeout);
142 HZ * xen_blkif_pgrant_timeout);
143}142}
144 143
145static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)144static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
@@ -234,7 +233,7 @@ static int add_persistent_gnt(struct xen_blkif_ring *ring, · 88 unmodified lines
234 struct persistent_gnt *this;233 struct persistent_gnt *this;
235 struct xen_blkif *blkif = ring->blkif;234 struct xen_blkif *blkif = ring->blkif;
236 235
237 if (ring->persistent_gnt_c >= xen_blkif_max_pgrants) {236 if (ring->persistent_gnt_c >= max_pgrants) {
238 if (!blkif->vbd.overflow_max_grants)237 if (!blkif->vbd.overflow_max_grants)
239 blkif->vbd.overflow_max_grants = 1;238 blkif->vbd.overflow_max_grants = 1;
240 return -EBUSY;239 return -EBUSY;
@@ -397,14 +396,13 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring) · 156 unmodified lines
397 goto out;396 goto out;
398 }397 }
399 398
400 if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||399 if (ring->persistent_gnt_c < max_pgrants ||
401 (ring->persistent_gnt_c == xen_blkif_max_pgrants &&400 (ring->persistent_gnt_c == max_pgrants &&
402 !ring->blkif->vbd.overflow_max_grants)) {401 !ring->blkif->vbd.overflow_max_grants)) {
403 num_clean = 0;402 num_clean = 0;
404 } else {403 } else {
405 num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;404 num_clean = (max_pgrants / 100) * LRU_PERCENT_CLEAN;
406 num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants +405 num_clean = ring->persistent_gnt_c - max_pgrants + num_clean;
407 num_clean;
408 num_clean = min(ring->persistent_gnt_c, num_clean);406 num_clean = min(ring->persistent_gnt_c, num_clean);
409 pr_debug("Going to purge at least %u persistent grants\n",407 pr_debug("Going to purge at least %u persistent grants\n",
410 num_clean);408 num_clean);
@@ -599,8 +597,7 @@ static void print_stats(struct xen_blkif_ring *ring) · 188 unmodified lines
599 current->comm, ring->st_oo_req,597 current->comm, ring->st_oo_req,
600 ring->st_rd_req, ring->st_wr_req,598 ring->st_rd_req, ring->st_wr_req,
601 ring->st_f_req, ring->st_ds_req,599 ring->st_f_req, ring->st_ds_req,
602 ring->persistent_gnt_c,600 ring->persistent_gnt_c, max_pgrants);
603 xen_blkif_max_pgrants);
604 ring->st_print = jiffies + msecs_to_jiffies(10 * 1000);601 ring->st_print = jiffies + msecs_to_jiffies(10 * 1000);
605 ring->st_rd_req = 0;602 ring->st_rd_req = 0;
606 ring->st_wr_req = 0;603 ring->st_wr_req = 0;
@@ -656,8 +653,11 @@ purge_gnt_list: · 49 unmodified lines
656 ring->next_lru = jiffies + msecs_to_jiffies(LRU_INTERVAL);653 ring->next_lru = jiffies + msecs_to_jiffies(LRU_INTERVAL);
657 }654 }
658 655
659 /* Shrink if we have more than xen_blkif_max_buffer_pages */656 /* Shrink the free pages pool if it is too large. */
660 shrink_free_pagepool(ring, xen_blkif_max_buffer_pages);657 if (time_before(jiffies, blkif->buffer_squeeze_end))
658 shrink_free_pagepool(ring, 0);
659 else
660 shrink_free_pagepool(ring, max_buffer_pages);
661 661
662 if (log_stats && time_after(jiffies, ring->st_print))662 if (log_stats && time_after(jiffies, ring->st_print))
663 print_stats(ring);663 print_stats(ring);
@@ -884,7 +884,7 @@ again: · 220 unmodified lines
884 continue;884 continue;
885 }885 }
886 if (use_persistent_gnts &&886 if (use_persistent_gnts &&
887 ring->persistent_gnt_c < xen_blkif_max_pgrants) {887 ring->persistent_gnt_c < max_pgrants) {
888 /*888 /*
889 * We are using persistent grants, the grant is889 * We are using persistent grants, the grant is
890 * not mapped but we might have room for it.890 * not mapped but we might have room for it.
@@ -911,7 +911,7 @@ again: · 20 unmodified lines
911 pages[seg_idx]->persistent_gnt = persistent_gnt;911 pages[seg_idx]->persistent_gnt = persistent_gnt;
912 pr_debug("grant %u added to the tree of persistent grants, using %u/%u\n",912 pr_debug("grant %u added to the tree of persistent grants, using %u/%u\n",
913 persistent_gnt->gnt, ring->persistent_gnt_c,913 persistent_gnt->gnt, ring->persistent_gnt_c,
914 xen_blkif_max_pgrants);914 max_pgrants);
915 goto next;915 goto next;
916 }916 }
917 if (use_persistent_gnts && !blkif->vbd.overflow_max_grants) {917 if (use_persistent_gnts && !blkif->vbd.overflow_max_grants) {
drivers/block/xen-blkback/common.h+1−0
@@ -319,6 +319,7 @@ struct xen_blkif { · 318 unmodified lines
319 /* All rings for this device. */319 /* All rings for this device. */
320 struct xen_blkif_ring *rings;320 struct xen_blkif_ring *rings;
321 unsigned int nr_rings;321 unsigned int nr_rings;
322 unsigned long buffer_squeeze_end;
322};323};
323 324
324struct seg_buf {325struct seg_buf {
drivers/block/xen-blkback/xenbus.c+22−4
@@ -467,7 +467,6 @@ static void xenvbd_sysfs_delif(struct xenbus_device *dev) · 466 unmodified lines
467 device_remove_file(&dev->dev, &dev_attr_physical_device);467 device_remove_file(&dev->dev, &dev_attr_physical_device);
468}468}
469 469
470
471static void xen_vbd_free(struct xen_vbd *vbd)470static void xen_vbd_free(struct xen_vbd *vbd)
472{471{
473 if (vbd->bdev)472 if (vbd->bdev)
@@ -524,6 +523,7 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, · 50 unmodified lines
524 handle, blkif->domid);523 handle, blkif->domid);
525 return 0;524 return 0;
526}525}
526
527static int xen_blkbk_remove(struct xenbus_device *dev)527static int xen_blkbk_remove(struct xenbus_device *dev)
528{528{
529 struct backend_info *be = dev_get_drvdata(&dev->dev);529 struct backend_info *be = dev_get_drvdata(&dev->dev);
@@ -607,6 +607,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info · 77 unmodified lines
607 if (err)607 if (err)
608 dev_warn(&dev->dev, "writing feature-discard (%d)", err);608 dev_warn(&dev->dev, "writing feature-discard (%d)", err);
609}609}
610
610int xen_blkbk_barrier(struct xenbus_transaction xbt,611int xen_blkbk_barrier(struct xenbus_transaction xbt,
611 struct backend_info *be, int state)612 struct backend_info *be, int state)
612{613{
@@ -691,7 +692,6 @@ fail: · 78 unmodified lines
691 return err;692 return err;
692}693}
693 694
694
695/*695/*
696 * Callback received when the hotplug scripts have placed the physical-device696 * Callback received when the hotplug scripts have placed the physical-device
697 * node. Read it and the mode node, and create a vbd. If the frontend is697 * node. Read it and the mode node, and create a vbd. If the frontend is
@@ -783,7 +783,6 @@ static void backend_changed(struct xenbus_watch *watch, · 85 unmodified lines
783 }783 }
784}784}
785 785
786
787/*786/*
788 * Callback received when the frontend's state changes.787 * Callback received when the frontend's state changes.
789 */788 */
@@ -858,9 +857,27 @@ static void frontend_changed(struct xenbus_device *dev, · 68 unmodified lines
858 }857 }
859}858}
860 859
860/* Once a memory pressure is detected, squeeze free page pools for a while. */
861static unsigned int buffer_squeeze_duration_ms = 10;
862module_param_named(buffer_squeeze_duration_ms,
863 buffer_squeeze_duration_ms, int, 0644);
864MODULE_PARM_DESC(buffer_squeeze_duration_ms,
865"Duration in ms to squeeze pages buffer when a memory pressure is detected");
861 866
862/* ** Connection ** */867/*
868 * Callback received when the memory pressure is detected.
869 */
870static void reclaim_memory(struct xenbus_device *dev)
871{
872 struct backend_info *be = dev_get_drvdata(&dev->dev);
863 873
874 if (!be)
875 return;
876 be->blkif->buffer_squeeze_end = jiffies +
877 msecs_to_jiffies(buffer_squeeze_duration_ms);
878}
879
880/* ** Connection ** */
864 881
865/*882/*
866 * Write the physical details regarding the block device to the store, and883 * Write the physical details regarding the block device to the store, and
@@ -1152,6 +1169,7 @@ static struct xenbus_driver xen_blkbk_driver = { · 285 unmodified lines
1152 .remove = xen_blkbk_remove,1169 .remove = xen_blkbk_remove,
1153 .otherend_changed = frontend_changed,1170 .otherend_changed = frontend_changed,
1154 .allow_rebind = true,1171 .allow_rebind = true,
1172 .reclaim_memory = reclaim_memory,
1155};1173};
1156 1174
1157int xen_blkif_xenbus_init(void)1175int xen_blkif_xenbus_init(void)
drivers/xen/gntdev.c+12−12
@@ -1006,19 +1006,19 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) · 1005 unmodified lines
1006 }1006 }
1007 mutex_unlock(&priv->lock);1007 mutex_unlock(&priv->lock);
1008 1008
1009 /*
1010 * gntdev takes the address of the PTE in find_grant_ptes() and passes
1011 * it to the hypervisor in gntdev_map_grant_pages(). The purpose of
1012 * the notifier is to prevent the hypervisor pointer to the PTE from
1013 * going stale.
1014 *
1015 * Since this vma's mappings can't be touched without the mmap_sem,
1016 * and we are holding it now, there is no need for the notifier_range
1017 * locking pattern.
1018 */
1019 mmu_interval_read_begin(&map->notifier);
1020
1021 if (use_ptemod) {1009 if (use_ptemod) {
1010 /*
1011 * gntdev takes the address of the PTE in find_grant_ptes() and
1012 * passes it to the hypervisor in gntdev_map_grant_pages(). The
1013 * purpose of the notifier is to prevent the hypervisor pointer
1014 * to the PTE from going stale.
1015 *
1016 * Since this vma's mappings can't be touched without the
1017 * mmap_sem, and we are holding it now, there is no need for
1018 * the notifier_range locking pattern.
1019 */
1020 mmu_interval_read_begin(&map->notifier);
1021
1022 map->pages_vm_start = vma->vm_start;1022 map->pages_vm_start = vma->vm_start;
1023 err = apply_to_page_range(vma->vm_mm, vma->vm_start,1023 err = apply_to_page_range(vma->vm_mm, vma->vm_start,
1024 vma->vm_end - vma->vm_start,1024 vma->vm_end - vma->vm_start,
drivers/xen/xen-balloon.c+1−1
@@ -94,7 +94,7 @@ static void watch_target(struct xenbus_watch *watch, · 93 unmodified lines
94 "%llu", &static_max) == 1))94 "%llu", &static_max) == 1))
95 static_max >>= PAGE_SHIFT - 10;95 static_max >>= PAGE_SHIFT - 10;
96 else96 else
97 static_max = new_target;97 static_max = balloon_stats.current_pages;
98 98
99 target_diff = (xen_pv_domain() || xen_initial_domain()) ? 099 target_diff = (xen_pv_domain() || xen_initial_domain()) ? 0
100 : static_max - balloon_stats.target_pages;100 : static_max - balloon_stats.target_pages;
drivers/xen/xen-pciback/conf_space.c+37−0
@@ -286,6 +286,43 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value) · 285 unmodified lines
286 return xen_pcibios_err_to_errno(err);286 return xen_pcibios_err_to_errno(err);
287}287}
288 288
289int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
290{
291 int err;
292 u16 val;
293 int ret = 0;
294
295 err = pci_read_config_word(dev, PCI_COMMAND, &val);
296 if (err)
297 return err;
298 if (!(val & PCI_COMMAND_INTX_DISABLE))
299 ret |= INTERRUPT_TYPE_INTX;
300
301 /*
302 * Do not trust dev->msi(x)_enabled here, as enabling could be done
303 * bypassing the pci_*msi* functions, by the qemu.
304 */
305 if (dev->msi_cap) {
306 err = pci_read_config_word(dev,
307 dev->msi_cap + PCI_MSI_FLAGS,
308 &val);
309 if (err)
310 return err;
311 if (val & PCI_MSI_FLAGS_ENABLE)
312 ret |= INTERRUPT_TYPE_MSI;
313 }
314 if (dev->msix_cap) {
315 err = pci_read_config_word(dev,
316 dev->msix_cap + PCI_MSIX_FLAGS,
317 &val);
318 if (err)
319 return err;
320 if (val & PCI_MSIX_FLAGS_ENABLE)
321 ret |= INTERRUPT_TYPE_MSIX;
322 }
323 return ret;
324}
325
289void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev)326void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev)
290{327{
291 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);328 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
drivers/xen/xen-pciback/conf_space.h+7−0
@@ -65,6 +65,11 @@ struct config_field_entry { · 64 unmodified lines
65 void *data;65 void *data;
66};66};
67 67
68#define INTERRUPT_TYPE_NONE (1<<0)
69#define INTERRUPT_TYPE_INTX (1<<1)
70#define INTERRUPT_TYPE_MSI (1<<2)
71#define INTERRUPT_TYPE_MSIX (1<<3)
72
68extern bool xen_pcibk_permissive;73extern bool xen_pcibk_permissive;
69 74
70#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)75#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
@@ -126,4 +131,6 @@ int xen_pcibk_config_capability_init(void); · 55 unmodified lines
126int xen_pcibk_config_header_add_fields(struct pci_dev *dev);131int xen_pcibk_config_header_add_fields(struct pci_dev *dev);
127int xen_pcibk_config_capability_add_fields(struct pci_dev *dev);132int xen_pcibk_config_capability_add_fields(struct pci_dev *dev);
128 133
134int xen_pcibk_get_interrupt_type(struct pci_dev *dev);
135
129#endif /* __XEN_PCIBACK_CONF_SPACE_H__ */136#endif /* __XEN_PCIBACK_CONF_SPACE_H__ */
drivers/xen/xen-pciback/conf_space_capability.c+89−0
@@ -189,6 +189,85 @@ static const struct config_field caplist_pm[] = { · 188 unmodified lines
189 {}189 {}
190};190};
191 191
192static struct msi_msix_field_config {
193 u16 enable_bit; /* bit for enabling MSI/MSI-X */
194 unsigned int int_type; /* interrupt type for exclusiveness check */
195} msi_field_config = {
196 .enable_bit = PCI_MSI_FLAGS_ENABLE,
197 .int_type = INTERRUPT_TYPE_MSI,
198}, msix_field_config = {
199 .enable_bit = PCI_MSIX_FLAGS_ENABLE,
200 .int_type = INTERRUPT_TYPE_MSIX,
201};
202
203static void *msi_field_init(struct pci_dev *dev, int offset)
204{
205 return &msi_field_config;
206}
207
208static void *msix_field_init(struct pci_dev *dev, int offset)
209{
210 return &msix_field_config;
211}
212
213static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
214 void *data)
215{
216 int err;
217 u16 old_value;
218 const struct msi_msix_field_config *field_config = data;
219 const struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
220
221 if (xen_pcibk_permissive || dev_data->permissive)
222 goto write;
223
224 err = pci_read_config_word(dev, offset, &old_value);
225 if (err)
226 return err;
227
228 if (new_value == old_value)
229 return 0;
230
231 if (!dev_data->allow_interrupt_control ||
232 (new_value ^ old_value) & ~field_config->enable_bit)
233 return PCIBIOS_SET_FAILED;
234
235 if (new_value & field_config->enable_bit) {
236 /* don't allow enabling together with other interrupt types */
237 int int_type = xen_pcibk_get_interrupt_type(dev);
238
239 if (int_type == INTERRUPT_TYPE_NONE ||
240 int_type == field_config->int_type)
241 goto write;
242 return PCIBIOS_SET_FAILED;
243 }
244
245write:
246 return pci_write_config_word(dev, offset, new_value);
247}
248
249static const struct config_field caplist_msix[] = {
250 {
251 .offset = PCI_MSIX_FLAGS,
252 .size = 2,
253 .init = msix_field_init,
254 .u.w.read = xen_pcibk_read_config_word,
255 .u.w.write = msi_msix_flags_write,
256 },
257 {}
258};
259
260static const struct config_field caplist_msi[] = {
261 {
262 .offset = PCI_MSI_FLAGS,
263 .size = 2,
264 .init = msi_field_init,
265 .u.w.read = xen_pcibk_read_config_word,
266 .u.w.write = msi_msix_flags_write,
267 },
268 {}
269};
270
192static struct xen_pcibk_config_capability xen_pcibk_config_capability_pm = {271static struct xen_pcibk_config_capability xen_pcibk_config_capability_pm = {
193 .capability = PCI_CAP_ID_PM,272 .capability = PCI_CAP_ID_PM,
194 .fields = caplist_pm,273 .fields = caplist_pm,
@@ -197,11 +276,21 @@ static struct xen_pcibk_config_capability xen_pcibk_config_capability_vpd = { · 2 unmodified lines
197 .capability = PCI_CAP_ID_VPD,276 .capability = PCI_CAP_ID_VPD,
198 .fields = caplist_vpd,277 .fields = caplist_vpd,
199};278};
279static struct xen_pcibk_config_capability xen_pcibk_config_capability_msi = {
280 .capability = PCI_CAP_ID_MSI,
281 .fields = caplist_msi,
282};
283static struct xen_pcibk_config_capability xen_pcibk_config_capability_msix = {
284 .capability = PCI_CAP_ID_MSIX,
285 .fields = caplist_msix,
286};
200 287
201int xen_pcibk_config_capability_init(void)288int xen_pcibk_config_capability_init(void)
202{289{
203 register_capability(&xen_pcibk_config_capability_vpd);290 register_capability(&xen_pcibk_config_capability_vpd);
204 register_capability(&xen_pcibk_config_capability_pm);291 register_capability(&xen_pcibk_config_capability_pm);
292 register_capability(&xen_pcibk_config_capability_msi);
293 register_capability(&xen_pcibk_config_capability_msix);
205 294
206 return 0;295 return 0;
207}296}
drivers/xen/xen-pciback/conf_space_header.c+19−0
@@ -117,6 +117,25 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) · 116 unmodified lines
117 pci_clear_mwi(dev);117 pci_clear_mwi(dev);
118 }118 }
119 119
120 if (dev_data && dev_data->allow_interrupt_control) {
121 if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) {
122 if (value & PCI_COMMAND_INTX_DISABLE) {
123 pci_intx(dev, 0);
124 } else {
125 /* Do not allow enabling INTx together with MSI or MSI-X. */
126 switch (xen_pcibk_get_interrupt_type(dev)) {
127 case INTERRUPT_TYPE_NONE:
128 pci_intx(dev, 1);
129 break;
130 case INTERRUPT_TYPE_INTX:
131 break;
132 default:
133 return PCIBIOS_SET_FAILED;
134 }
135 }
136 }
137 }
138
120 cmd->val = value;139 cmd->val = value;
121 140
122 if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))141 if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))
drivers/xen/xen-pciback/pci_stub.c+66−0
@@ -304,6 +304,8 @@ void pcistub_put_pci_dev(struct pci_dev *dev) · 303 unmodified lines
304 xen_pcibk_config_reset_dev(dev);304 xen_pcibk_config_reset_dev(dev);
305 xen_pcibk_config_free_dyn_fields(dev);305 xen_pcibk_config_free_dyn_fields(dev);
306 306
307 dev_data->allow_interrupt_control = 0;
308
307 xen_unregister_device_domain_owner(dev);309 xen_unregister_device_domain_owner(dev);
308 310
309 spin_lock_irqsave(&found_psdev->lock, flags);311 spin_lock_irqsave(&found_psdev->lock, flags);
@@ -1431,6 +1433,65 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf) · 1121 unmodified lines
1431}1433}
1432static DRIVER_ATTR_RW(permissive);1434static DRIVER_ATTR_RW(permissive);
1433 1435
1436static ssize_t allow_interrupt_control_store(struct device_driver *drv,
1437 const char *buf, size_t count)
1438{
1439 int domain, bus, slot, func;
1440 int err;
1441 struct pcistub_device *psdev;
1442 struct xen_pcibk_dev_data *dev_data;
1443
1444 err = str_to_slot(buf, &domain, &bus, &slot, &func);
1445 if (err)
1446 goto out;
1447
1448 psdev = pcistub_device_find(domain, bus, slot, func);
1449 if (!psdev) {
1450 err = -ENODEV;
1451 goto out;
1452 }
1453
1454 dev_data = pci_get_drvdata(psdev->dev);
1455 /* the driver data for a device should never be null at this point */
1456 if (!dev_data) {
1457 err = -ENXIO;
1458 goto release;
1459 }
1460 dev_data->allow_interrupt_control = 1;
1461release:
1462 pcistub_device_put(psdev);
1463out:
1464 if (!err)
1465 err = count;
1466 return err;
1467}
1468
1469static ssize_t allow_interrupt_control_show(struct device_driver *drv,
1470 char *buf)
1471{
1472 struct pcistub_device *psdev;
1473 struct xen_pcibk_dev_data *dev_data;
1474 size_t count = 0;
1475 unsigned long flags;
1476
1477 spin_lock_irqsave(&pcistub_devices_lock, flags);
1478 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
1479 if (count >= PAGE_SIZE)
1480 break;
1481 if (!psdev->dev)
1482 continue;
1483 dev_data = pci_get_drvdata(psdev->dev);
1484 if (!dev_data || !dev_data->allow_interrupt_control)
1485 continue;
1486 count +=
1487 scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
1488 pci_name(psdev->dev));
1489 }
1490 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
1491 return count;
1492}
1493static DRIVER_ATTR_RW(allow_interrupt_control);
1494
1434static void pcistub_exit(void)1495static void pcistub_exit(void)
1435{1496{
1436 driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_new_slot);1497 driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_new_slot);
@@ -1440,6 +1501,8 @@ static void pcistub_exit(void) · 3 unmodified lines
1440 driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_quirks);1501 driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_quirks);
1441 driver_remove_file(&xen_pcibk_pci_driver.driver,1502 driver_remove_file(&xen_pcibk_pci_driver.driver,
1442 &driver_attr_permissive);1503 &driver_attr_permissive);
1504 driver_remove_file(&xen_pcibk_pci_driver.driver,
1505 &driver_attr_allow_interrupt_control);
1443 driver_remove_file(&xen_pcibk_pci_driver.driver,1506 driver_remove_file(&xen_pcibk_pci_driver.driver,
1444 &driver_attr_irq_handlers);1507 &driver_attr_irq_handlers);
1445 driver_remove_file(&xen_pcibk_pci_driver.driver,1508 driver_remove_file(&xen_pcibk_pci_driver.driver,
@@ -1530,6 +1593,9 @@ static int __init pcistub_init(void) · 84 unmodified lines
1530 if (!err)1593 if (!err)
1531 err = driver_create_file(&xen_pcibk_pci_driver.driver,1594 err = driver_create_file(&xen_pcibk_pci_driver.driver,
1532 &driver_attr_permissive);1595 &driver_attr_permissive);
1596 if (!err)
1597 err = driver_create_file(&xen_pcibk_pci_driver.driver,
1598 &driver_attr_allow_interrupt_control);
1533 1599
1534 if (!err)1600 if (!err)
1535 err = driver_create_file(&xen_pcibk_pci_driver.driver,1601 err = driver_create_file(&xen_pcibk_pci_driver.driver,
drivers/xen/xen-pciback/pciback.h+1−0
@@ -45,6 +45,7 @@ struct xen_pcibk_dev_data { · 44 unmodified lines
45 struct list_head config_fields;45 struct list_head config_fields;
46 struct pci_saved_state *pci_saved_state;46 struct pci_saved_state *pci_saved_state;
47 unsigned int permissive:1;47 unsigned int permissive:1;
48 unsigned int allow_interrupt_control:1;
48 unsigned int warned_on_write:1;49 unsigned int warned_on_write:1;
49 unsigned int enable_intx:1;50 unsigned int enable_intx:1;
50 unsigned int isr_on:1; /* Whether the IRQ handler is installed. */51 unsigned int isr_on:1; /* Whether the IRQ handler is installed. */
drivers/xen/xenbus/xenbus_probe.c+7−1
@@ -239,7 +239,9 @@ int xenbus_dev_probe(struct device *_dev) · 238 unmodified lines
239 goto fail;239 goto fail;
240 }240 }
241 241
242 spin_lock(&dev->reclaim_lock);
242 err = drv->probe(dev, id);243 err = drv->probe(dev, id);
244 spin_unlock(&dev->reclaim_lock);
243 if (err)245 if (err)
244 goto fail_put;246 goto fail_put;
245 247
@@ -268,8 +270,11 @@ int xenbus_dev_remove(struct device *_dev) · 22 unmodified lines
268 270
269 free_otherend_watch(dev);271 free_otherend_watch(dev);
270 272
271 if (drv->remove)273 if (drv->remove) {
274 spin_lock(&dev->reclaim_lock);
272 drv->remove(dev);275 drv->remove(dev);
276 spin_unlock(&dev->reclaim_lock);
277 }
273 278
274 module_put(drv->driver.owner);279 module_put(drv->driver.owner);
275 280
@@ -468,6 +473,7 @@ int xenbus_probe_node(struct xen_bus_type *bus, · 192 unmodified lines
468 goto fail;473 goto fail;
469 474
470 dev_set_name(&xendev->dev, "%s", devname);475 dev_set_name(&xendev->dev, "%s", devname);
476 spin_lock_init(&xendev->reclaim_lock);
471 477
472 /* Register with generic device framework. */478 /* Register with generic device framework. */
473 err = device_register(&xendev->dev);479 err = device_register(&xendev->dev);
drivers/xen/xenbus/xenbus_probe_backend.c+38−0
@@ -247,6 +247,41 @@ static int backend_probe_and_watch(struct notifier_block *notifier, · 246 unmodified lines
247 return NOTIFY_DONE;247 return NOTIFY_DONE;
248}248}
249 249
250static int backend_reclaim_memory(struct device *dev, void *data)
251{
252 const struct xenbus_driver *drv;
253 struct xenbus_device *xdev;
254
255 if (!dev->driver)
256 return 0;
257 drv = to_xenbus_driver(dev->driver);
258 if (drv && drv->reclaim_memory) {
259 xdev = to_xenbus_device(dev);
260 if (!spin_trylock(&xdev->reclaim_lock))
261 return 0;
262 drv->reclaim_memory(xdev);
263 spin_unlock(&xdev->reclaim_lock);
264 }
265 return 0;
266}
267
268/*
269 * Returns 0 always because we are using shrinker to only detect memory
270 * pressure.
271 */
272static unsigned long backend_shrink_memory_count(struct shrinker *shrinker,
273 struct shrink_control *sc)
274{
275 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL,
276 backend_reclaim_memory);
277 return 0;
278}
279
280static struct shrinker backend_memory_shrinker = {
281 .count_objects = backend_shrink_memory_count,
282 .seeks = DEFAULT_SEEKS,
283};
284
250static int __init xenbus_probe_backend_init(void)285static int __init xenbus_probe_backend_init(void)
251{286{
252 static struct notifier_block xenstore_notifier = {287 static struct notifier_block xenstore_notifier = {
@@ -263,6 +298,9 @@ static int __init xenbus_probe_backend_init(void) · 10 unmodified lines
263 298
264 register_xenstore_notifier(&xenstore_notifier);299 register_xenstore_notifier(&xenstore_notifier);
265 300
301 if (register_shrinker(&backend_memory_shrinker))
302 pr_warn("shrinker registration failed\n");
303
266 return 0;304 return 0;
267}305}
268subsys_initcall(xenbus_probe_backend_init);306subsys_initcall(xenbus_probe_backend_init);
include/xen/xenbus.h+2−0
@@ -76,6 +76,7 @@ struct xenbus_device { · 75 unmodified lines
76 enum xenbus_state state;76 enum xenbus_state state;
77 struct completion down;77 struct completion down;
78 struct work_struct work;78 struct work_struct work;
79 spinlock_t reclaim_lock;
79};80};
80 81
81static inline struct xenbus_device *to_xenbus_device(struct device *dev)82static inline struct xenbus_device *to_xenbus_device(struct device *dev)
@@ -105,6 +106,7 @@ struct xenbus_driver { · 23 unmodified lines
105 struct device_driver driver;106 struct device_driver driver;
106 int (*read_otherend_details)(struct xenbus_device *dev);107 int (*read_otherend_details)(struct xenbus_device *dev);
107 int (*is_ready)(struct xenbus_device *dev);108 int (*is_ready)(struct xenbus_device *dev);
109 void (*reclaim_memory)(struct xenbus_device *dev);
108};110};
109 111
110static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)112static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t