Skip to content

Commit f47e331

Browse files
committed
Merge tag 'stable/for-linus-4.0-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen bug fixes from David Vrabel: - fix a PV regression in 3.19. - fix a dom0 crash on hosts with large numbers of PIRQs. - prevent pcifront from disabling memory or I/O port access, which may trigger host crashes. * tag 'stable/for-linus-4.0-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen-pciback: limit guest control of command register xen/events: avoid NULL pointer dereference in dom0 on large machines xen: Remove trailing semicolon from xenbus_register_frontend() definition x86/xen: correct bug in p2m list initialization
2 parents bbc54a0 + af6fc85 commit f47e331

File tree

6 files changed

+66
-23
lines changed

6 files changed

+66
-23
lines changed

arch/x86/xen/p2m.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ static bool alloc_p2m(unsigned long pfn)
563563
if (p2m_pfn == PFN_DOWN(__pa(p2m_missing)))
564564
p2m_init(p2m);
565565
else
566-
p2m_init_identity(p2m, pfn);
566+
p2m_init_identity(p2m, pfn & ~(P2M_PER_PAGE - 1));
567567

568568
spin_lock_irqsave(&p2m_update_lock, flags);
569569

drivers/xen/events/events_base.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,20 +526,26 @@ static unsigned int __startup_pirq(unsigned int irq)
526526
pirq_query_unmask(irq);
527527

528528
rc = set_evtchn_to_irq(evtchn, irq);
529-
if (rc != 0) {
530-
pr_err("irq%d: Failed to set port to irq mapping (%d)\n",
531-
irq, rc);
532-
xen_evtchn_close(evtchn);
533-
return 0;
534-
}
529+
if (rc)
530+
goto err;
531+
535532
bind_evtchn_to_cpu(evtchn, 0);
536533
info->evtchn = evtchn;
537534

535+
rc = xen_evtchn_port_setup(info);
536+
if (rc)
537+
goto err;
538+
538539
out:
539540
unmask_evtchn(evtchn);
540541
eoi_pirq(irq_get_irq_data(irq));
541542

542543
return 0;
544+
545+
err:
546+
pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc);
547+
xen_evtchn_close(evtchn);
548+
return 0;
543549
}
544550

545551
static unsigned int startup_pirq(struct irq_data *data)

drivers/xen/xen-pciback/conf_space.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "conf_space.h"
1717
#include "conf_space_quirks.h"
1818

19-
static bool permissive;
19+
bool permissive;
2020
module_param(permissive, bool, 0644);
2121

2222
/* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word,

drivers/xen/xen-pciback/conf_space.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ struct config_field_entry {
6464
void *data;
6565
};
6666

67+
extern bool permissive;
68+
6769
#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
6870

6971
/* Add fields to a device - the add_fields macro expects to get a pointer to

drivers/xen/xen-pciback/conf_space_header.c

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#include "pciback.h"
1212
#include "conf_space.h"
1313

14+
struct pci_cmd_info {
15+
u16 val;
16+
};
17+
1418
struct pci_bar_info {
1519
u32 val;
1620
u32 len_val;
@@ -20,29 +24,45 @@ struct pci_bar_info {
2024
#define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
2125
#define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
2226

23-
static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
27+
/* Bits guests are allowed to control in permissive mode. */
28+
#define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \
29+
PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \
30+
PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK)
31+
32+
static void *command_init(struct pci_dev *dev, int offset)
2433
{
25-
int i;
26-
int ret;
27-
28-
ret = xen_pcibk_read_config_word(dev, offset, value, data);
29-
if (!pci_is_enabled(dev))
30-
return ret;
31-
32-
for (i = 0; i < PCI_ROM_RESOURCE; i++) {
33-
if (dev->resource[i].flags & IORESOURCE_IO)
34-
*value |= PCI_COMMAND_IO;
35-
if (dev->resource[i].flags & IORESOURCE_MEM)
36-
*value |= PCI_COMMAND_MEMORY;
34+
struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
35+
int err;
36+
37+
if (!cmd)
38+
return ERR_PTR(-ENOMEM);
39+
40+
err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val);
41+
if (err) {
42+
kfree(cmd);
43+
return ERR_PTR(err);
3744
}
3845

46+
return cmd;
47+
}
48+
49+
static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
50+
{
51+
int ret = pci_read_config_word(dev, offset, value);
52+
const struct pci_cmd_info *cmd = data;
53+
54+
*value &= PCI_COMMAND_GUEST;
55+
*value |= cmd->val & ~PCI_COMMAND_GUEST;
56+
3957
return ret;
4058
}
4159

4260
static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
4361
{
4462
struct xen_pcibk_dev_data *dev_data;
4563
int err;
64+
u16 val;
65+
struct pci_cmd_info *cmd = data;
4666

4767
dev_data = pci_get_drvdata(dev);
4868
if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
@@ -83,6 +103,19 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
83103
}
84104
}
85105

106+
cmd->val = value;
107+
108+
if (!permissive && (!dev_data || !dev_data->permissive))
109+
return 0;
110+
111+
/* Only allow the guest to control certain bits. */
112+
err = pci_read_config_word(dev, offset, &val);
113+
if (err || val == value)
114+
return err;
115+
116+
value &= PCI_COMMAND_GUEST;
117+
value |= val & ~PCI_COMMAND_GUEST;
118+
86119
return pci_write_config_word(dev, offset, value);
87120
}
88121

@@ -282,6 +315,8 @@ static const struct config_field header_common[] = {
282315
{
283316
.offset = PCI_COMMAND,
284317
.size = 2,
318+
.init = command_init,
319+
.release = bar_release,
285320
.u.w.read = command_read,
286321
.u.w.write = command_write,
287322
},

include/xen/xenbus.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ int __must_check __xenbus_register_backend(struct xenbus_driver *drv,
114114
const char *mod_name);
115115

116116
#define xenbus_register_frontend(drv) \
117-
__xenbus_register_frontend(drv, THIS_MODULE, KBUILD_MODNAME);
117+
__xenbus_register_frontend(drv, THIS_MODULE, KBUILD_MODNAME)
118118
#define xenbus_register_backend(drv) \
119-
__xenbus_register_backend(drv, THIS_MODULE, KBUILD_MODNAME);
119+
__xenbus_register_backend(drv, THIS_MODULE, KBUILD_MODNAME)
120120

121121
void xenbus_unregister_driver(struct xenbus_driver *drv);
122122

0 commit comments

Comments
 (0)