Skip to content

Commit 9ae5fce

Browse files
committed
Merge tag 'for-linus-5.15-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross: - some small cleanups - a fix for a bug when running as Xen PV guest which could result in not all memory being transferred in case of a migration of the guest - a small series for getting rid of code for supporting very old Xen hypervisor versions nobody should be using since many years now - a series for hardening the Xen block frontend driver - a fix for Xen PV boot code issuing warning messages due to a stray preempt_disable() on the non-boot processors * tag 'for-linus-5.15-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen: remove stray preempt_disable() from PV AP startup code xen/pcifront: Removed unnecessary __ref annotation x86: xen: platform-pci-unplug: use pr_err() and pr_warn() instead of raw printk() drivers/xen/xenbus/xenbus_client.c: fix bugon.cocci warnings xen/blkfront: don't trust the backend response data blindly xen/blkfront: don't take local copy of a request from the ring page xen/blkfront: read response from backend only once xen: assume XENFEAT_gnttab_map_avail_bits being set for pv guests xen: assume XENFEAT_mmu_pt_update_preserve_ad being set for pv guests xen: check required Xen features xen: fix setting of max_pfn in shared_info
2 parents a2d616b + 58e6360 commit 9ae5fce

10 files changed

Lines changed: 141 additions & 115 deletions

File tree

arch/x86/xen/enlighten_pv.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,8 @@ static void __init xen_banner(void)
116116
HYPERVISOR_xen_version(XENVER_extraversion, &extra);
117117

118118
pr_info("Booting paravirtualized kernel on %s\n", pv_info.name);
119-
printk(KERN_INFO "Xen version: %d.%d%s%s\n",
120-
version >> 16, version & 0xffff, extra.extraversion,
121-
xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
119+
pr_info("Xen version: %d.%d%s (preserve-AD)\n",
120+
version >> 16, version & 0xffff, extra.extraversion);
122121
}
123122

124123
static void __init xen_pv_init_platform(void)
@@ -1302,13 +1301,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
13021301
xen_init_apic();
13031302
#endif
13041303

1305-
if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
1306-
pv_ops.mmu.ptep_modify_prot_start =
1307-
xen_ptep_modify_prot_start;
1308-
pv_ops.mmu.ptep_modify_prot_commit =
1309-
xen_ptep_modify_prot_commit;
1310-
}
1311-
13121304
machine_ops = xen_machine_ops;
13131305

13141306
/*

arch/x86/xen/mmu_pv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,8 +2099,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
20992099
.set_pte = xen_set_pte_init,
21002100
.set_pmd = xen_set_pmd_hyper,
21012101

2102-
.ptep_modify_prot_start = __ptep_modify_prot_start,
2103-
.ptep_modify_prot_commit = __ptep_modify_prot_commit,
2102+
.ptep_modify_prot_start = xen_ptep_modify_prot_start,
2103+
.ptep_modify_prot_commit = xen_ptep_modify_prot_commit,
21042104

21052105
.pte_val = PV_CALLEE_SAVE(xen_pte_val),
21062106
.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),

arch/x86/xen/p2m.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,8 @@ int xen_alloc_p2m_entry(unsigned long pfn)
618618
}
619619

620620
/* Expanded the p2m? */
621-
if (pfn > xen_p2m_last_pfn) {
622-
xen_p2m_last_pfn = pfn;
621+
if (pfn >= xen_p2m_last_pfn) {
622+
xen_p2m_last_pfn = ALIGN(pfn + 1, P2M_PER_PAGE);
623623
HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
624624
}
625625

arch/x86/xen/platform-pci-unplug.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* Copyright (c) 2010, Citrix
88
*/
99

10+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11+
1012
#include <linux/init.h>
1113
#include <linux/io.h>
1214
#include <linux/export.h>
@@ -30,26 +32,26 @@ static int check_platform_magic(void)
3032

3133
magic = inw(XEN_IOPORT_MAGIC);
3234
if (magic != XEN_IOPORT_MAGIC_VAL) {
33-
printk(KERN_ERR "Xen Platform PCI: unrecognised magic value\n");
35+
pr_err("Xen Platform PCI: unrecognised magic value\n");
3436
return XEN_PLATFORM_ERR_MAGIC;
3537
}
3638

3739
protocol = inb(XEN_IOPORT_PROTOVER);
3840

39-
printk(KERN_DEBUG "Xen Platform PCI: I/O protocol version %d\n",
41+
pr_debug("Xen Platform PCI: I/O protocol version %d\n",
4042
protocol);
4143

4244
switch (protocol) {
4345
case 1:
4446
outw(XEN_IOPORT_LINUX_PRODNUM, XEN_IOPORT_PRODNUM);
4547
outl(XEN_IOPORT_LINUX_DRVVER, XEN_IOPORT_DRVVER);
4648
if (inw(XEN_IOPORT_MAGIC) != XEN_IOPORT_MAGIC_VAL) {
47-
printk(KERN_ERR "Xen Platform: blacklisted by host\n");
49+
pr_err("Xen Platform: blacklisted by host\n");
4850
return XEN_PLATFORM_ERR_BLACKLIST;
4951
}
5052
break;
5153
default:
52-
printk(KERN_WARNING "Xen Platform PCI: unknown I/O protocol version\n");
54+
pr_warn("Xen Platform PCI: unknown I/O protocol version\n");
5355
return XEN_PLATFORM_ERR_PROTOCOL;
5456
}
5557

@@ -155,12 +157,12 @@ void xen_unplug_emulated_devices(void)
155157
* been compiled for this kernel (modules or built-in are both OK). */
156158
if (!xen_emul_unplug) {
157159
if (xen_must_unplug_nics()) {
158-
printk(KERN_INFO "Netfront and the Xen platform PCI driver have "
160+
pr_info("Netfront and the Xen platform PCI driver have "
159161
"been compiled for this kernel: unplug emulated NICs.\n");
160162
xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
161163
}
162164
if (xen_must_unplug_disks()) {
163-
printk(KERN_INFO "Blkfront and the Xen platform PCI driver have "
165+
pr_info("Blkfront and the Xen platform PCI driver have "
164166
"been compiled for this kernel: unplug emulated disks.\n"
165167
"You might have to change the root device\n"
166168
"from /dev/hd[a-d] to /dev/xvd[a-d]\n"
@@ -200,7 +202,7 @@ static int __init parse_xen_emul_unplug(char *arg)
200202
else if (!strncmp(p, "never", l))
201203
xen_emul_unplug |= XEN_UNPLUG_NEVER;
202204
else
203-
printk(KERN_WARNING "unrecognised option '%s' "
205+
pr_warn("unrecognised option '%s' "
204206
"in parameter 'xen_emul_unplug'\n", p);
205207
}
206208
return 0;

arch/x86/xen/smp_pv.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ static void cpu_bringup(void)
6464
cr4_init();
6565
cpu_init();
6666
touch_softlockup_watchdog();
67-
preempt_disable();
6867

6968
/* PVH runs in ring 0 and allows us to do native syscalls. Yay! */
7069
if (!xen_feature(XENFEAT_supervisor_mode_kernel)) {

drivers/block/xen-blkfront.c

Lines changed: 84 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ enum blkif_state {
8080
BLKIF_STATE_DISCONNECTED,
8181
BLKIF_STATE_CONNECTED,
8282
BLKIF_STATE_SUSPENDED,
83+
BLKIF_STATE_ERROR,
8384
};
8485

8586
struct grant {
@@ -89,6 +90,7 @@ struct grant {
8990
};
9091

9192
enum blk_req_status {
93+
REQ_PROCESSING,
9294
REQ_WAITING,
9395
REQ_DONE,
9496
REQ_ERROR,
@@ -530,22 +532,23 @@ static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
530532

531533
id = get_id_from_freelist(rinfo);
532534
rinfo->shadow[id].request = req;
533-
rinfo->shadow[id].status = REQ_WAITING;
535+
rinfo->shadow[id].status = REQ_PROCESSING;
534536
rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID;
535537

536-
(*ring_req)->u.rw.id = id;
538+
rinfo->shadow[id].req.u.rw.id = id;
537539

538540
return id;
539541
}
540542

541543
static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo)
542544
{
543545
struct blkfront_info *info = rinfo->dev_info;
544-
struct blkif_request *ring_req;
546+
struct blkif_request *ring_req, *final_ring_req;
545547
unsigned long id;
546548

547549
/* Fill out a communications ring structure. */
548-
id = blkif_ring_get_request(rinfo, req, &ring_req);
550+
id = blkif_ring_get_request(rinfo, req, &final_ring_req);
551+
ring_req = &rinfo->shadow[id].req;
549552

550553
ring_req->operation = BLKIF_OP_DISCARD;
551554
ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
@@ -556,8 +559,9 @@ static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_inf
556559
else
557560
ring_req->u.discard.flag = 0;
558561

559-
/* Keep a private copy so we can reissue requests when recovering. */
560-
rinfo->shadow[id].req = *ring_req;
562+
/* Copy the request to the ring page. */
563+
*final_ring_req = *ring_req;
564+
rinfo->shadow[id].status = REQ_WAITING;
561565

562566
return 0;
563567
}
@@ -690,6 +694,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
690694
{
691695
struct blkfront_info *info = rinfo->dev_info;
692696
struct blkif_request *ring_req, *extra_ring_req = NULL;
697+
struct blkif_request *final_ring_req, *final_extra_ring_req = NULL;
693698
unsigned long id, extra_id = NO_ASSOCIATED_ID;
694699
bool require_extra_req = false;
695700
int i;
@@ -734,7 +739,8 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
734739
}
735740

736741
/* Fill out a communications ring structure. */
737-
id = blkif_ring_get_request(rinfo, req, &ring_req);
742+
id = blkif_ring_get_request(rinfo, req, &final_ring_req);
743+
ring_req = &rinfo->shadow[id].req;
738744

739745
num_sg = blk_rq_map_sg(req->q, req, rinfo->shadow[id].sg);
740746
num_grant = 0;
@@ -785,7 +791,9 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
785791
ring_req->u.rw.nr_segments = num_grant;
786792
if (unlikely(require_extra_req)) {
787793
extra_id = blkif_ring_get_request(rinfo, req,
788-
&extra_ring_req);
794+
&final_extra_ring_req);
795+
extra_ring_req = &rinfo->shadow[extra_id].req;
796+
789797
/*
790798
* Only the first request contains the scatter-gather
791799
* list.
@@ -827,10 +835,13 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
827835
if (setup.segments)
828836
kunmap_atomic(setup.segments);
829837

830-
/* Keep a private copy so we can reissue requests when recovering. */
831-
rinfo->shadow[id].req = *ring_req;
832-
if (unlikely(require_extra_req))
833-
rinfo->shadow[extra_id].req = *extra_ring_req;
838+
/* Copy request(s) to the ring page. */
839+
*final_ring_req = *ring_req;
840+
rinfo->shadow[id].status = REQ_WAITING;
841+
if (unlikely(require_extra_req)) {
842+
*final_extra_ring_req = *extra_ring_req;
843+
rinfo->shadow[extra_id].status = REQ_WAITING;
844+
}
834845

835846
if (new_persistent_gnts)
836847
gnttab_free_grant_references(setup.gref_head);
@@ -1353,8 +1364,8 @@ static enum blk_req_status blkif_rsp_to_req_status(int rsp)
13531364
static int blkif_get_final_status(enum blk_req_status s1,
13541365
enum blk_req_status s2)
13551366
{
1356-
BUG_ON(s1 == REQ_WAITING);
1357-
BUG_ON(s2 == REQ_WAITING);
1367+
BUG_ON(s1 < REQ_DONE);
1368+
BUG_ON(s2 < REQ_DONE);
13581369

13591370
if (s1 == REQ_ERROR || s2 == REQ_ERROR)
13601371
return BLKIF_RSP_ERROR;
@@ -1387,7 +1398,7 @@ static bool blkif_completion(unsigned long *id,
13871398
s->status = blkif_rsp_to_req_status(bret->status);
13881399

13891400
/* Wait the second response if not yet here. */
1390-
if (s2->status == REQ_WAITING)
1401+
if (s2->status < REQ_DONE)
13911402
return false;
13921403

13931404
bret->status = blkif_get_final_status(s->status,
@@ -1495,7 +1506,7 @@ static bool blkif_completion(unsigned long *id,
14951506
static irqreturn_t blkif_interrupt(int irq, void *dev_id)
14961507
{
14971508
struct request *req;
1498-
struct blkif_response *bret;
1509+
struct blkif_response bret;
14991510
RING_IDX i, rp;
15001511
unsigned long flags;
15011512
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
@@ -1506,54 +1517,76 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
15061517

15071518
spin_lock_irqsave(&rinfo->ring_lock, flags);
15081519
again:
1509-
rp = rinfo->ring.sring->rsp_prod;
1510-
rmb(); /* Ensure we see queued responses up to 'rp'. */
1520+
rp = READ_ONCE(rinfo->ring.sring->rsp_prod);
1521+
virt_rmb(); /* Ensure we see queued responses up to 'rp'. */
1522+
if (RING_RESPONSE_PROD_OVERFLOW(&rinfo->ring, rp)) {
1523+
pr_alert("%s: illegal number of responses %u\n",
1524+
info->gd->disk_name, rp - rinfo->ring.rsp_cons);
1525+
goto err;
1526+
}
15111527

15121528
for (i = rinfo->ring.rsp_cons; i != rp; i++) {
15131529
unsigned long id;
1530+
unsigned int op;
1531+
1532+
RING_COPY_RESPONSE(&rinfo->ring, i, &bret);
1533+
id = bret.id;
15141534

1515-
bret = RING_GET_RESPONSE(&rinfo->ring, i);
1516-
id = bret->id;
15171535
/*
15181536
* The backend has messed up and given us an id that we would
15191537
* never have given to it (we stamp it up to BLK_RING_SIZE -
15201538
* look in get_id_from_freelist.
15211539
*/
15221540
if (id >= BLK_RING_SIZE(info)) {
1523-
WARN(1, "%s: response to %s has incorrect id (%ld)\n",
1524-
info->gd->disk_name, op_name(bret->operation), id);
1525-
/* We can't safely get the 'struct request' as
1526-
* the id is busted. */
1527-
continue;
1541+
pr_alert("%s: response has incorrect id (%ld)\n",
1542+
info->gd->disk_name, id);
1543+
goto err;
15281544
}
1545+
if (rinfo->shadow[id].status != REQ_WAITING) {
1546+
pr_alert("%s: response references no pending request\n",
1547+
info->gd->disk_name);
1548+
goto err;
1549+
}
1550+
1551+
rinfo->shadow[id].status = REQ_PROCESSING;
15291552
req = rinfo->shadow[id].request;
15301553

1531-
if (bret->operation != BLKIF_OP_DISCARD) {
1554+
op = rinfo->shadow[id].req.operation;
1555+
if (op == BLKIF_OP_INDIRECT)
1556+
op = rinfo->shadow[id].req.u.indirect.indirect_op;
1557+
if (bret.operation != op) {
1558+
pr_alert("%s: response has wrong operation (%u instead of %u)\n",
1559+
info->gd->disk_name, bret.operation, op);
1560+
goto err;
1561+
}
1562+
1563+
if (bret.operation != BLKIF_OP_DISCARD) {
15321564
/*
15331565
* We may need to wait for an extra response if the
15341566
* I/O request is split in 2
15351567
*/
1536-
if (!blkif_completion(&id, rinfo, bret))
1568+
if (!blkif_completion(&id, rinfo, &bret))
15371569
continue;
15381570
}
15391571

15401572
if (add_id_to_freelist(rinfo, id)) {
15411573
WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n",
1542-
info->gd->disk_name, op_name(bret->operation), id);
1574+
info->gd->disk_name, op_name(bret.operation), id);
15431575
continue;
15441576
}
15451577

1546-
if (bret->status == BLKIF_RSP_OKAY)
1578+
if (bret.status == BLKIF_RSP_OKAY)
15471579
blkif_req(req)->error = BLK_STS_OK;
15481580
else
15491581
blkif_req(req)->error = BLK_STS_IOERR;
15501582

1551-
switch (bret->operation) {
1583+
switch (bret.operation) {
15521584
case BLKIF_OP_DISCARD:
1553-
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
1585+
if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
15541586
struct request_queue *rq = info->rq;
1555-
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
1556-
info->gd->disk_name, op_name(bret->operation));
1587+
1588+
pr_warn_ratelimited("blkfront: %s: %s op failed\n",
1589+
info->gd->disk_name, op_name(bret.operation));
15571590
blkif_req(req)->error = BLK_STS_NOTSUPP;
15581591
info->feature_discard = 0;
15591592
info->feature_secdiscard = 0;
@@ -1563,15 +1596,15 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
15631596
break;
15641597
case BLKIF_OP_FLUSH_DISKCACHE:
15651598
case BLKIF_OP_WRITE_BARRIER:
1566-
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
1567-
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
1568-
info->gd->disk_name, op_name(bret->operation));
1599+
if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
1600+
pr_warn_ratelimited("blkfront: %s: %s op failed\n",
1601+
info->gd->disk_name, op_name(bret.operation));
15691602
blkif_req(req)->error = BLK_STS_NOTSUPP;
15701603
}
1571-
if (unlikely(bret->status == BLKIF_RSP_ERROR &&
1604+
if (unlikely(bret.status == BLKIF_RSP_ERROR &&
15721605
rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
1573-
printk(KERN_WARNING "blkfront: %s: empty %s op failed\n",
1574-
info->gd->disk_name, op_name(bret->operation));
1606+
pr_warn_ratelimited("blkfront: %s: empty %s op failed\n",
1607+
info->gd->disk_name, op_name(bret.operation));
15751608
blkif_req(req)->error = BLK_STS_NOTSUPP;
15761609
}
15771610
if (unlikely(blkif_req(req)->error)) {
@@ -1584,9 +1617,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
15841617
fallthrough;
15851618
case BLKIF_OP_READ:
15861619
case BLKIF_OP_WRITE:
1587-
if (unlikely(bret->status != BLKIF_RSP_OKAY))
1588-
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
1589-
"request: %x\n", bret->status);
1620+
if (unlikely(bret.status != BLKIF_RSP_OKAY))
1621+
dev_dbg_ratelimited(&info->xbdev->dev,
1622+
"Bad return from blkdev data request: %#x\n",
1623+
bret.status);
15901624

15911625
break;
15921626
default:
@@ -1612,6 +1646,14 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
16121646
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
16131647

16141648
return IRQ_HANDLED;
1649+
1650+
err:
1651+
info->connected = BLKIF_STATE_ERROR;
1652+
1653+
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
1654+
1655+
pr_alert("%s disabled for further use\n", info->gd->disk_name);
1656+
return IRQ_HANDLED;
16151657
}
16161658

16171659

0 commit comments

Comments
 (0)