ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @ 6538:84ee014ebd41

Merge xen-vtx-unstable.hg
author adsharma@los-vmm.sc.intel.com
date Wed Aug 17 12:34:38 2005 -0800 (2005-08-17)
parents 23979fb12c49 25b8b05ad991
children 99914b54f7bf
line source
1 /******************************************************************************
2 * blkfront.c
3 *
4 * XenLinux virtual block-device driver.
5 *
6 * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
7 * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
8 * Copyright (c) 2004, Christian Limpach
9 * Copyright (c) 2004, Andrew Warfield
10 * Copyright (c) 2005, Christopher Clark
11 *
12 * This file may be distributed separately from the Linux kernel, or
13 * incorporated into other software packages, subject to the following license:
14 *
15 * Permission is hereby granted, free of charge, to any person obtaining a copy
16 * of this source file (the "Software"), to deal in the Software without
17 * restriction, including without limitation the rights to use, copy, modify,
18 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
19 * and to permit persons to whom the Software is furnished to do so, subject to
20 * the following conditions:
21 *
22 * The above copyright notice and this permission notice shall be included in
23 * all copies or substantial portions of the Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 * IN THE SOFTWARE.
32 */
34 #if 1
35 #define ASSERT(_p) \
36 if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
37 __LINE__, __FILE__); *(int*)0=0; }
38 #else
39 #define ASSERT(_p)
40 #endif
42 #include <linux/version.h>
44 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
45 #include "block.h"
46 #else
47 #include "common.h"
48 #include <linux/blk.h>
49 #include <linux/tqueue.h>
50 #endif
52 #include <linux/cdrom.h>
53 #include <linux/sched.h>
54 #include <linux/interrupt.h>
55 #include <scsi/scsi.h>
56 #include <asm-xen/ctrl_if.h>
57 #include <asm-xen/evtchn.h>
58 #ifdef CONFIG_XEN_BLKDEV_GRANT
59 #include <asm-xen/xen-public/grant_table.h>
60 #include <asm-xen/gnttab.h>
61 #endif
63 typedef unsigned char byte; /* from linux/ide.h */
65 /* Control whether runtime update of vbds is enabled. */
66 #define ENABLE_VBD_UPDATE 1
68 #if ENABLE_VBD_UPDATE
69 static void vbd_update(void);
70 #else
71 static void vbd_update(void){};
72 #endif
74 #define BLKIF_STATE_CLOSED 0
75 #define BLKIF_STATE_DISCONNECTED 1
76 #define BLKIF_STATE_CONNECTED 2
78 static int blkif_handle = 0;
79 static unsigned int blkif_state = BLKIF_STATE_CLOSED;
80 static unsigned int blkif_evtchn = 0;
82 static int blkif_control_rsp_valid;
83 static blkif_response_t blkif_control_rsp;
85 static blkif_front_ring_t blk_ring;
87 #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
89 #ifdef CONFIG_XEN_BLKDEV_GRANT
90 static domid_t rdomid = 0;
91 static grant_ref_t gref_head, gref_terminal;
92 #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
93 (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
94 #define GRANTREF_INVALID (1<<15)
95 #endif
97 static struct blk_shadow {
98 blkif_request_t req;
99 unsigned long request;
100 unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
101 } blk_shadow[BLK_RING_SIZE];
102 unsigned long blk_shadow_free;
104 static int recovery = 0; /* Recovery in progress: protected by blkif_io_lock */
106 static void kick_pending_request_queues(void);
108 int __init xlblk_init(void);
110 static void blkif_completion(struct blk_shadow *s);
112 static inline int GET_ID_FROM_FREELIST(void)
113 {
114 unsigned long free = blk_shadow_free;
115 BUG_ON(free > BLK_RING_SIZE);
116 blk_shadow_free = blk_shadow[free].req.id;
117 blk_shadow[free].req.id = 0x0fffffee; /* debug */
118 return free;
119 }
121 static inline void ADD_ID_TO_FREELIST(unsigned long id)
122 {
123 blk_shadow[id].req.id = blk_shadow_free;
124 blk_shadow[id].request = 0;
125 blk_shadow_free = id;
126 }
129 /************************ COMMON CODE (inlined) ************************/
131 /* Kernel-specific definitions used in the common code */
132 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
133 #define DISABLE_SCATTERGATHER()
134 #else
135 static int sg_operation = -1;
136 #define DISABLE_SCATTERGATHER() (sg_operation = -1)
137 #endif
139 static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r)
140 {
141 #ifndef CONFIG_XEN_BLKDEV_GRANT
142 int i;
143 #endif
145 s->req = *r;
147 #ifndef CONFIG_XEN_BLKDEV_GRANT
148 for ( i = 0; i < r->nr_segments; i++ )
149 s->req.frame_and_sects[i] = machine_to_phys(r->frame_and_sects[i]);
150 #endif
151 }
153 static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s)
154 {
155 #ifndef CONFIG_XEN_BLKDEV_GRANT
156 int i;
157 #endif
159 *r = s->req;
161 #ifndef CONFIG_XEN_BLKDEV_GRANT
162 for ( i = 0; i < s->req.nr_segments; i++ )
163 r->frame_and_sects[i] = phys_to_machine(s->req.frame_and_sects[i]);
164 #endif
165 }
168 static inline void flush_requests(void)
169 {
170 DISABLE_SCATTERGATHER();
171 RING_PUSH_REQUESTS(&blk_ring);
172 notify_via_evtchn(blkif_evtchn);
173 }
176 /************************** KERNEL VERSION 2.6 **************************/
178 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
180 module_init(xlblk_init);
182 #if ENABLE_VBD_UPDATE
183 static void update_vbds_task(void *unused)
184 {
185 xlvbd_update_vbds();
186 }
188 static void vbd_update(void)
189 {
190 static DECLARE_WORK(update_tq, update_vbds_task, NULL);
191 schedule_work(&update_tq);
192 }
193 #endif /* ENABLE_VBD_UPDATE */
195 static struct xlbd_disk_info *head_waiting = NULL;
196 static void kick_pending_request_queues(void)
197 {
198 struct xlbd_disk_info *di;
199 while ( ((di = head_waiting) != NULL) && !RING_FULL(&blk_ring) )
200 {
201 head_waiting = di->next_waiting;
202 di->next_waiting = NULL;
203 /* Re-enable calldowns. */
204 blk_start_queue(di->rq);
205 /* Kick things off immediately. */
206 do_blkif_request(di->rq);
207 }
208 }
210 int blkif_open(struct inode *inode, struct file *filep)
211 {
212 struct gendisk *gd = inode->i_bdev->bd_disk;
213 struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
215 /* Update of usage count is protected by per-device semaphore. */
216 di->mi->usage++;
218 return 0;
219 }
222 int blkif_release(struct inode *inode, struct file *filep)
223 {
224 struct gendisk *gd = inode->i_bdev->bd_disk;
225 struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
227 /*
228 * When usage drops to zero it may allow more VBD updates to occur.
229 * Update of usage count is protected by a per-device semaphore.
230 */
231 if ( --di->mi->usage == 0 )
232 vbd_update();
234 return 0;
235 }
238 int blkif_ioctl(struct inode *inode, struct file *filep,
239 unsigned command, unsigned long argument)
240 {
241 int i;
243 DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
244 command, (long)argument, inode->i_rdev);
246 switch ( command )
247 {
248 case HDIO_GETGEO:
249 /* return ENOSYS to use defaults */
250 return -ENOSYS;
252 case CDROMMULTISESSION:
253 DPRINTK("FIXME: support multisession CDs later\n");
254 for ( i = 0; i < sizeof(struct cdrom_multisession); i++ )
255 if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT;
256 return 0;
258 default:
259 /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
260 command);*/
261 return -EINVAL; /* same return as native Linux */
262 }
264 return 0;
265 }
268 /*
269 * blkif_queue_request
270 *
271 * request block io
272 *
273 * id: for guest use only.
274 * operation: BLKIF_OP_{READ,WRITE,PROBE}
275 * buffer: buffer to read/write into. this should be a
276 * virtual address in the guest os.
277 */
278 static int blkif_queue_request(struct request *req)
279 {
280 struct xlbd_disk_info *di = req->rq_disk->private_data;
281 unsigned long buffer_ma;
282 blkif_request_t *ring_req;
283 struct bio *bio;
284 struct bio_vec *bvec;
285 int idx;
286 unsigned long id;
287 unsigned int fsect, lsect;
288 #ifdef CONFIG_XEN_BLKDEV_GRANT
289 int ref;
290 #endif
292 if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
293 return 1;
295 /* Fill out a communications ring structure. */
296 ring_req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
297 id = GET_ID_FROM_FREELIST();
298 blk_shadow[id].request = (unsigned long)req;
300 ring_req->id = id;
301 ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE :
302 BLKIF_OP_READ;
303 ring_req->sector_number = (blkif_sector_t)req->sector;
304 ring_req->device = di->xd_device;
306 ring_req->nr_segments = 0;
307 rq_for_each_bio(bio, req)
308 {
309 bio_for_each_segment(bvec, bio, idx)
310 {
311 if ( ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST )
312 BUG();
313 buffer_ma = page_to_phys(bvec->bv_page);
314 fsect = bvec->bv_offset >> 9;
315 lsect = fsect + (bvec->bv_len >> 9) - 1;
316 #ifdef CONFIG_XEN_BLKDEV_GRANT
317 /* install a grant reference. */
318 ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
319 ASSERT( ref != -ENOSPC );
321 gnttab_grant_foreign_access_ref(
322 ref,
323 rdomid,
324 buffer_ma >> PAGE_SHIFT,
325 rq_data_dir(req) );
327 blk_shadow[id].frame[ring_req->nr_segments] =
328 buffer_ma >> PAGE_SHIFT;
330 ring_req->frame_and_sects[ring_req->nr_segments++] =
331 blkif_fas_from_gref(ref, fsect, lsect);
333 #else
334 ring_req->frame_and_sects[ring_req->nr_segments++] =
335 blkif_fas(buffer_ma, fsect, lsect);
336 #endif
337 }
338 }
340 blk_ring.req_prod_pvt++;
342 /* Keep a private copy so we can reissue requests when recovering. */
343 pickle_request(&blk_shadow[id], ring_req);
345 return 0;
346 }
349 /*
350 * do_blkif_request
351 * read a block; request is in a request queue
352 */
353 void do_blkif_request(request_queue_t *rq)
354 {
355 struct xlbd_disk_info *di;
356 struct request *req;
357 int queued;
359 DPRINTK("Entered do_blkif_request\n");
361 queued = 0;
363 while ( (req = elv_next_request(rq)) != NULL )
364 {
365 if ( !blk_fs_request(req) )
366 {
367 end_request(req, 0);
368 continue;
369 }
371 if ( RING_FULL(&blk_ring) )
372 goto wait;
374 DPRINTK("do_blk_req %p: cmd %p, sec %lx, (%u/%li) buffer:%p [%s]\n",
375 req, req->cmd, req->sector, req->current_nr_sectors,
376 req->nr_sectors, req->buffer,
377 rq_data_dir(req) ? "write" : "read");
379 blkdev_dequeue_request(req);
380 if ( blkif_queue_request(req) )
381 {
382 wait:
383 di = req->rq_disk->private_data;
384 if ( di->next_waiting == NULL )
385 {
386 di->next_waiting = head_waiting;
387 head_waiting = di;
388 /* Avoid pointless unplugs. */
389 blk_stop_queue(rq);
390 }
391 break;
392 }
394 queued++;
395 }
397 if ( queued != 0 )
398 flush_requests();
399 }
402 static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
403 {
404 struct request *req;
405 blkif_response_t *bret;
406 RING_IDX i, rp;
407 unsigned long flags;
409 spin_lock_irqsave(&blkif_io_lock, flags);
411 if ( unlikely(blkif_state == BLKIF_STATE_CLOSED) ||
412 unlikely(recovery) )
413 {
414 spin_unlock_irqrestore(&blkif_io_lock, flags);
415 return IRQ_HANDLED;
416 }
418 rp = blk_ring.sring->rsp_prod;
419 rmb(); /* Ensure we see queued responses up to 'rp'. */
421 for ( i = blk_ring.rsp_cons; i != rp; i++ )
422 {
423 unsigned long id;
425 bret = RING_GET_RESPONSE(&blk_ring, i);
426 id = bret->id;
427 req = (struct request *)blk_shadow[id].request;
429 blkif_completion(&blk_shadow[id]);
431 ADD_ID_TO_FREELIST(id);
433 switch ( bret->operation )
434 {
435 case BLKIF_OP_READ:
436 case BLKIF_OP_WRITE:
437 if ( unlikely(bret->status != BLKIF_RSP_OKAY) )
438 DPRINTK("Bad return from blkdev data request: %x\n",
439 bret->status);
441 if ( unlikely(end_that_request_first
442 (req,
443 (bret->status == BLKIF_RSP_OKAY),
444 req->hard_nr_sectors)) )
445 BUG();
446 end_that_request_last(req);
448 break;
449 case BLKIF_OP_PROBE:
450 memcpy(&blkif_control_rsp, bret, sizeof(*bret));
451 blkif_control_rsp_valid = 1;
452 break;
453 default:
454 BUG();
455 }
456 }
458 blk_ring.rsp_cons = i;
460 kick_pending_request_queues();
462 spin_unlock_irqrestore(&blkif_io_lock, flags);
464 return IRQ_HANDLED;
465 }
467 #else
468 /************************** KERNEL VERSION 2.4 **************************/
470 static kdev_t sg_dev;
471 static unsigned long sg_next_sect;
473 /*
474 * Request queues with outstanding work, but ring is currently full.
475 * We need no special lock here, as we always access this with the
476 * blkif_io_lock held. We only need a small maximum list.
477 */
478 #define MAX_PENDING 8
479 static request_queue_t *pending_queues[MAX_PENDING];
480 static int nr_pending;
483 #define blkif_io_lock io_request_lock
485 /*============================================================================*/
486 #if ENABLE_VBD_UPDATE
488 /*
489 * blkif_update_int/update-vbds_task - handle VBD update events.
490 * Schedule a task for keventd to run, which will update the VBDs and perform
491 * the corresponding updates to our view of VBD state.
492 */
493 static void update_vbds_task(void *unused)
494 {
495 xlvbd_update_vbds();
496 }
498 static void vbd_update(void)
499 {
500 static struct tq_struct update_tq;
501 update_tq.routine = update_vbds_task;
502 schedule_task(&update_tq);
503 }
505 #endif /* ENABLE_VBD_UPDATE */
506 /*============================================================================*/
508 static void kick_pending_request_queues(void)
509 {
510 /* We kick pending request queues if the ring is reasonably empty. */
511 if ( (nr_pending != 0) &&
512 (RING_PENDING_REQUESTS(&blk_ring) < (BLK_RING_SIZE >> 1)) )
513 {
514 /* Attempt to drain the queue, but bail if the ring becomes full. */
515 while ( (nr_pending != 0) && !RING_FULL(&blk_ring) )
516 do_blkif_request(pending_queues[--nr_pending]);
517 }
518 }
520 int blkif_open(struct inode *inode, struct file *filep)
521 {
522 short xldev = inode->i_rdev;
523 struct gendisk *gd = get_gendisk(xldev);
524 xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
525 short minor = MINOR(xldev);
527 if ( gd->part[minor].nr_sects == 0 )
528 {
529 /*
530 * Device either doesn't exist, or has zero capacity; we use a few
531 * cheesy heuristics to return the relevant error code
532 */
533 if ( (gd->sizes[minor >> gd->minor_shift] != 0) ||
534 ((minor & (gd->max_p - 1)) != 0) )
535 {
536 /*
537 * We have a real device, but no such partition, or we just have a
538 * partition number so guess this is the problem.
539 */
540 return -ENXIO; /* no such device or address */
541 }
542 else if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE )
543 {
544 /* This is a removable device => assume that media is missing. */
545 return -ENOMEDIUM; /* media not present (this is a guess) */
546 }
547 else
548 {
549 /* Just go for the general 'no such device' error. */
550 return -ENODEV; /* no such device */
551 }
552 }
554 /* Update of usage count is protected by per-device semaphore. */
555 disk->usage++;
557 return 0;
558 }
561 int blkif_release(struct inode *inode, struct file *filep)
562 {
563 xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
565 /*
566 * When usage drops to zero it may allow more VBD updates to occur.
567 * Update of usage count is protected by a per-device semaphore.
568 */
569 if ( --disk->usage == 0 ) {
570 vbd_update();
571 }
573 return 0;
574 }
577 int blkif_ioctl(struct inode *inode, struct file *filep,
578 unsigned command, unsigned long argument)
579 {
580 kdev_t dev = inode->i_rdev;
581 struct hd_geometry *geo = (struct hd_geometry *)argument;
582 struct gendisk *gd;
583 struct hd_struct *part;
584 int i;
585 unsigned short cylinders;
586 byte heads, sectors;
588 /* NB. No need to check permissions. That is done for us. */
590 DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
591 command, (long) argument, dev);
593 gd = get_gendisk(dev);
594 part = &gd->part[MINOR(dev)];
596 switch ( command )
597 {
598 case BLKGETSIZE:
599 DPRINTK_IOCTL(" BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects);
600 return put_user(part->nr_sects, (unsigned long *) argument);
602 case BLKGETSIZE64:
603 DPRINTK_IOCTL(" BLKGETSIZE64: %x %llx\n", BLKGETSIZE64,
604 (u64)part->nr_sects * 512);
605 return put_user((u64)part->nr_sects * 512, (u64 *) argument);
607 case BLKRRPART: /* re-read partition table */
608 DPRINTK_IOCTL(" BLKRRPART: %x\n", BLKRRPART);
609 return blkif_revalidate(dev);
611 case BLKSSZGET:
612 return hardsect_size[MAJOR(dev)][MINOR(dev)];
614 case BLKBSZGET: /* get block size */
615 DPRINTK_IOCTL(" BLKBSZGET: %x\n", BLKBSZGET);
616 break;
618 case BLKBSZSET: /* set block size */
619 DPRINTK_IOCTL(" BLKBSZSET: %x\n", BLKBSZSET);
620 break;
622 case BLKRASET: /* set read-ahead */
623 DPRINTK_IOCTL(" BLKRASET: %x\n", BLKRASET);
624 break;
626 case BLKRAGET: /* get read-ahead */
627 DPRINTK_IOCTL(" BLKRAFET: %x\n", BLKRAGET);
628 break;
630 case HDIO_GETGEO:
631 DPRINTK_IOCTL(" HDIO_GETGEO: %x\n", HDIO_GETGEO);
632 if (!argument) return -EINVAL;
634 /* We don't have real geometry info, but let's at least return
635 values consistent with the size of the device */
637 heads = 0xff;
638 sectors = 0x3f;
639 cylinders = part->nr_sects / (heads * sectors);
641 if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
642 if (put_user(heads, (byte *)&geo->heads)) return -EFAULT;
643 if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT;
644 if (put_user(cylinders, (unsigned short *)&geo->cylinders)) return -EFAULT;
646 return 0;
648 case HDIO_GETGEO_BIG:
649 DPRINTK_IOCTL(" HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG);
650 if (!argument) return -EINVAL;
652 /* We don't have real geometry info, but let's at least return
653 values consistent with the size of the device */
655 heads = 0xff;
656 sectors = 0x3f;
657 cylinders = part->nr_sects / (heads * sectors);
659 if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
660 if (put_user(heads, (byte *)&geo->heads)) return -EFAULT;
661 if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT;
662 if (put_user(cylinders, (unsigned int *) &geo->cylinders)) return -EFAULT;
664 return 0;
666 case CDROMMULTISESSION:
667 DPRINTK("FIXME: support multisession CDs later\n");
668 for ( i = 0; i < sizeof(struct cdrom_multisession); i++ )
669 if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT;
670 return 0;
672 case SCSI_IOCTL_GET_BUS_NUMBER:
673 DPRINTK("FIXME: SCSI_IOCTL_GET_BUS_NUMBER ioctl in XL blkif");
674 return -ENOSYS;
676 default:
677 WPRINTK("ioctl %08x not supported by XL blkif\n", command);
678 return -ENOSYS;
679 }
681 return 0;
682 }
686 /* check media change: should probably do something here in some cases :-) */
687 int blkif_check(kdev_t dev)
688 {
689 DPRINTK("blkif_check\n");
690 return 0;
691 }
693 int blkif_revalidate(kdev_t dev)
694 {
695 struct block_device *bd;
696 struct gendisk *gd;
697 xl_disk_t *disk;
698 unsigned long capacity;
699 int i, rc = 0;
701 if ( (bd = bdget(dev)) == NULL )
702 return -EINVAL;
704 /*
705 * Update of partition info, and check of usage count, is protected
706 * by the per-block-device semaphore.
707 */
708 down(&bd->bd_sem);
710 if ( ((gd = get_gendisk(dev)) == NULL) ||
711 ((disk = xldev_to_xldisk(dev)) == NULL) ||
712 ((capacity = gd->part[MINOR(dev)].nr_sects) == 0) )
713 {
714 rc = -EINVAL;
715 goto out;
716 }
718 if ( disk->usage > 1 )
719 {
720 rc = -EBUSY;
721 goto out;
722 }
724 /* Only reread partition table if VBDs aren't mapped to partitions. */
725 if ( !(gd->flags[MINOR(dev) >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) )
726 {
727 for ( i = gd->max_p - 1; i >= 0; i-- )
728 {
729 invalidate_device(dev+i, 1);
730 gd->part[MINOR(dev+i)].start_sect = 0;
731 gd->part[MINOR(dev+i)].nr_sects = 0;
732 gd->sizes[MINOR(dev+i)] = 0;
733 }
735 grok_partitions(gd, MINOR(dev)>>gd->minor_shift, gd->max_p, capacity);
736 }
738 out:
739 up(&bd->bd_sem);
740 bdput(bd);
741 return rc;
742 }
745 /*
746 * blkif_queue_request
747 *
748 * request block io
749 *
750 * id: for guest use only.
751 * operation: BLKIF_OP_{READ,WRITE,PROBE}
752 * buffer: buffer to read/write into. this should be a
753 * virtual address in the guest os.
754 */
755 static int blkif_queue_request(unsigned long id,
756 int operation,
757 char * buffer,
758 unsigned long sector_number,
759 unsigned short nr_sectors,
760 kdev_t device)
761 {
762 unsigned long buffer_ma = virt_to_bus(buffer);
763 unsigned long xid;
764 struct gendisk *gd;
765 blkif_request_t *req;
766 struct buffer_head *bh;
767 unsigned int fsect, lsect;
768 #ifdef CONFIG_XEN_BLKDEV_GRANT
769 int ref;
770 #endif
772 fsect = (buffer_ma & ~PAGE_MASK) >> 9;
773 lsect = fsect + nr_sectors - 1;
775 /* Buffer must be sector-aligned. Extent mustn't cross a page boundary. */
776 if ( unlikely((buffer_ma & ((1<<9)-1)) != 0) )
777 BUG();
778 if ( lsect > ((PAGE_SIZE/512)-1) )
779 BUG();
781 buffer_ma &= PAGE_MASK;
783 if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
784 return 1;
786 switch ( operation )
787 {
789 case BLKIF_OP_READ:
790 case BLKIF_OP_WRITE:
791 gd = get_gendisk(device);
793 /*
794 * Update the sector_number we'll pass down as appropriate; note that
795 * we could sanity check that resulting sector will be in this
796 * partition, but this will happen in driver backend anyhow.
797 */
798 sector_number += gd->part[MINOR(device)].start_sect;
800 /*
801 * If this unit doesn't consist of virtual partitions then we clear
802 * the partn bits from the device number.
803 */
804 if ( !(gd->flags[MINOR(device)>>gd->minor_shift] &
805 GENHD_FL_VIRT_PARTNS) )
806 device &= ~(gd->max_p - 1);
808 if ( (sg_operation == operation) &&
809 (sg_dev == device) &&
810 (sg_next_sect == sector_number) )
811 {
812 req = RING_GET_REQUEST(&blk_ring,
813 blk_ring.req_prod_pvt - 1);
814 bh = (struct buffer_head *)id;
816 bh->b_reqnext = (struct buffer_head *)blk_shadow[req->id].request;
817 blk_shadow[req->id].request = (unsigned long)id;
819 #ifdef CONFIG_XEN_BLKDEV_GRANT
820 /* install a grant reference. */
821 ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
822 ASSERT( ref != -ENOSPC );
824 gnttab_grant_foreign_access_ref(
825 ref,
826 rdomid,
827 buffer_ma >> PAGE_SHIFT,
828 ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
830 blk_shadow[req->id].frame[req->nr_segments] =
831 buffer_ma >> PAGE_SHIFT;
833 req->frame_and_sects[req->nr_segments] =
834 blkif_fas_from_gref(ref, fsect, lsect);
835 #else
836 req->frame_and_sects[req->nr_segments] =
837 blkif_fas(buffer_ma, fsect, lsect);
838 #endif
839 if ( ++req->nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST )
840 sg_next_sect += nr_sectors;
841 else
842 DISABLE_SCATTERGATHER();
844 /* Update the copy of the request in the recovery ring. */
845 pickle_request(&blk_shadow[req->id], req );
847 return 0;
848 }
849 else if ( RING_FULL(&blk_ring) )
850 {
851 return 1;
852 }
853 else
854 {
855 sg_operation = operation;
856 sg_dev = device;
857 sg_next_sect = sector_number + nr_sectors;
858 }
859 break;
861 default:
862 panic("unknown op %d\n", operation);
863 }
865 /* Fill out a communications ring structure. */
866 req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
868 xid = GET_ID_FROM_FREELIST();
869 blk_shadow[xid].request = (unsigned long)id;
871 req->id = xid;
872 req->operation = operation;
873 req->sector_number = (blkif_sector_t)sector_number;
874 req->device = device;
875 req->nr_segments = 1;
876 #ifdef CONFIG_XEN_BLKDEV_GRANT
877 /* install a grant reference. */
878 ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
879 ASSERT( ref != -ENOSPC );
881 gnttab_grant_foreign_access_ref(
882 ref,
883 rdomid,
884 buffer_ma >> PAGE_SHIFT,
885 ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
887 blk_shadow[xid].frame[0] = buffer_ma >> PAGE_SHIFT;
889 req->frame_and_sects[0] = blkif_fas_from_gref(ref, fsect, lsect);
890 #else
891 req->frame_and_sects[0] = blkif_fas(buffer_ma, fsect, lsect);
892 #endif
894 /* Keep a private copy so we can reissue requests when recovering. */
895 pickle_request(&blk_shadow[xid], req);
897 blk_ring.req_prod_pvt++;
899 return 0;
900 }
903 /*
904 * do_blkif_request
905 * read a block; request is in a request queue
906 */
907 void do_blkif_request(request_queue_t *rq)
908 {
909 struct request *req;
910 struct buffer_head *bh, *next_bh;
911 int rw, nsect, full, queued = 0;
913 DPRINTK("Entered do_blkif_request\n");
915 while ( !rq->plugged && !list_empty(&rq->queue_head))
916 {
917 if ( (req = blkdev_entry_next_request(&rq->queue_head)) == NULL )
918 goto out;
920 DPRINTK("do_blkif_request %p: cmd %i, sec %lx, (%li/%li) bh:%p\n",
921 req, req->cmd, req->sector,
922 req->current_nr_sectors, req->nr_sectors, req->bh);
924 rw = req->cmd;
925 if ( rw == READA )
926 rw = READ;
927 if ( unlikely((rw != READ) && (rw != WRITE)) )
928 panic("XenoLinux Virtual Block Device: bad cmd: %d\n", rw);
930 req->errors = 0;
932 bh = req->bh;
933 while ( bh != NULL )
934 {
935 next_bh = bh->b_reqnext;
936 bh->b_reqnext = NULL;
938 full = blkif_queue_request(
939 (unsigned long)bh,
940 (rw == READ) ? BLKIF_OP_READ : BLKIF_OP_WRITE,
941 bh->b_data, bh->b_rsector, bh->b_size>>9, bh->b_rdev);
943 if ( full )
944 {
945 bh->b_reqnext = next_bh;
946 pending_queues[nr_pending++] = rq;
947 if ( unlikely(nr_pending >= MAX_PENDING) )
948 BUG();
949 goto out;
950 }
952 queued++;
954 /* Dequeue the buffer head from the request. */
955 nsect = bh->b_size >> 9;
956 bh = req->bh = next_bh;
958 if ( bh != NULL )
959 {
960 /* There's another buffer head to do. Update the request. */
961 req->hard_sector += nsect;
962 req->hard_nr_sectors -= nsect;
963 req->sector = req->hard_sector;
964 req->nr_sectors = req->hard_nr_sectors;
965 req->current_nr_sectors = bh->b_size >> 9;
966 req->buffer = bh->b_data;
967 }
968 else
969 {
970 /* That was the last buffer head. Finalise the request. */
971 if ( unlikely(end_that_request_first(req, 1, "XenBlk")) )
972 BUG();
973 blkdev_dequeue_request(req);
974 end_that_request_last(req);
975 }
976 }
977 }
979 out:
980 if ( queued != 0 )
981 flush_requests();
982 }
985 static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
986 {
987 RING_IDX i, rp;
988 unsigned long flags;
989 struct buffer_head *bh, *next_bh;
991 spin_lock_irqsave(&io_request_lock, flags);
993 if ( unlikely(blkif_state == BLKIF_STATE_CLOSED || recovery) )
994 {
995 spin_unlock_irqrestore(&io_request_lock, flags);
996 return;
997 }
999 rp = blk_ring.sring->rsp_prod;
1000 rmb(); /* Ensure we see queued responses up to 'rp'. */
1002 for ( i = blk_ring.rsp_cons; i != rp; i++ )
1004 unsigned long id;
1005 blkif_response_t *bret;
1007 bret = RING_GET_RESPONSE(&blk_ring, i);
1008 id = bret->id;
1009 bh = (struct buffer_head *)blk_shadow[id].request;
1011 blkif_completion(&blk_shadow[id]);
1013 ADD_ID_TO_FREELIST(id);
1015 switch ( bret->operation )
1017 case BLKIF_OP_READ:
1018 case BLKIF_OP_WRITE:
1019 if ( unlikely(bret->status != BLKIF_RSP_OKAY) )
1020 DPRINTK("Bad return from blkdev data request: %lx\n",
1021 bret->status);
1022 for ( ; bh != NULL; bh = next_bh )
1024 next_bh = bh->b_reqnext;
1025 bh->b_reqnext = NULL;
1026 bh->b_end_io(bh, bret->status == BLKIF_RSP_OKAY);
1029 break;
1030 case BLKIF_OP_PROBE:
1031 memcpy(&blkif_control_rsp, bret, sizeof(*bret));
1032 blkif_control_rsp_valid = 1;
1033 break;
1034 default:
1035 BUG();
1039 blk_ring.rsp_cons = i;
1041 kick_pending_request_queues();
1043 spin_unlock_irqrestore(&io_request_lock, flags);
1046 #endif
1048 /***************************** COMMON CODE *******************************/
1050 #ifdef CONFIG_XEN_BLKDEV_GRANT
1051 void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
1052 unsigned long address)
1054 int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
1055 ASSERT( ref != -ENOSPC );
1057 gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
1059 req->frame_and_sects[0] = blkif_fas_from_gref(ref, 0, (PAGE_SIZE/512)-1);
1061 blkif_control_send(req, rsp);
1063 #endif
1065 void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
1067 unsigned long flags, id;
1068 blkif_request_t *req_d;
1070 retry:
1071 while ( RING_FULL(&blk_ring) )
1073 set_current_state(TASK_INTERRUPTIBLE);
1074 schedule_timeout(1);
1077 spin_lock_irqsave(&blkif_io_lock, flags);
1078 if ( RING_FULL(&blk_ring) )
1080 spin_unlock_irqrestore(&blkif_io_lock, flags);
1081 goto retry;
1084 DISABLE_SCATTERGATHER();
1085 req_d = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
1086 *req_d = *req;
1088 id = GET_ID_FROM_FREELIST();
1089 req_d->id = id;
1090 blk_shadow[id].request = (unsigned long)req;
1092 pickle_request(&blk_shadow[id], req);
1094 blk_ring.req_prod_pvt++;
1095 flush_requests();
1097 spin_unlock_irqrestore(&blkif_io_lock, flags);
1099 while ( !blkif_control_rsp_valid )
1101 set_current_state(TASK_INTERRUPTIBLE);
1102 schedule_timeout(1);
1105 memcpy(rsp, &blkif_control_rsp, sizeof(*rsp));
1106 blkif_control_rsp_valid = 0;
1110 /* Send a driver status notification to the domain controller. */
1111 static void send_driver_status(int ok)
1113 ctrl_msg_t cmsg = {
1114 .type = CMSG_BLKIF_FE,
1115 .subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
1116 .length = sizeof(blkif_fe_driver_status_t),
1117 };
1118 blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
1120 msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
1122 ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
1125 /* Tell the controller to bring up the interface. */
1126 static void blkif_send_interface_connect(void)
1128 ctrl_msg_t cmsg = {
1129 .type = CMSG_BLKIF_FE,
1130 .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
1131 .length = sizeof(blkif_fe_interface_connect_t),
1132 };
1133 blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
1135 msg->handle = 0;
1136 msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
1138 #ifdef CONFIG_XEN_BLKDEV_GRANT
1139 msg->shmem_ref = gnttab_claim_grant_reference( &gref_head, gref_terminal );
1140 ASSERT( msg->shmem_ref != -ENOSPC );
1141 gnttab_grant_foreign_access_ref ( msg->shmem_ref , rdomid, msg->shmem_frame, 0 );
1142 #endif
1144 ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
1147 static void blkif_free(void)
1149 /* Prevent new requests being issued until we fix things up. */
1150 spin_lock_irq(&blkif_io_lock);
1151 recovery = 1;
1152 blkif_state = BLKIF_STATE_DISCONNECTED;
1153 spin_unlock_irq(&blkif_io_lock);
1155 /* Free resources associated with old device channel. */
1156 if ( blk_ring.sring != NULL )
1158 free_page((unsigned long)blk_ring.sring);
1159 blk_ring.sring = NULL;
1161 unbind_evtchn_from_irqhandler(blkif_evtchn, NULL);
1162 blkif_evtchn = 0;
1165 static void blkif_close(void)
1169 /* Move from CLOSED to DISCONNECTED state. */
1170 static void blkif_disconnect(void)
1172 blkif_sring_t *sring;
1174 if ( blk_ring.sring != NULL )
1175 free_page((unsigned long)blk_ring.sring);
1177 sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
1178 SHARED_RING_INIT(sring);
1179 FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
1180 blkif_state = BLKIF_STATE_DISCONNECTED;
1181 blkif_send_interface_connect();
1184 static void blkif_reset(void)
1186 blkif_free();
1187 blkif_disconnect();
1190 static void blkif_recover(void)
1192 int i;
1193 blkif_request_t *req;
1194 struct blk_shadow *copy;
1195 #ifdef CONFIG_XEN_BLKDEV_GRANT
1196 int j;
1197 #endif
1199 /* Stage 1: Make a safe copy of the shadow state. */
1200 copy = (struct blk_shadow *)kmalloc(sizeof(blk_shadow), GFP_KERNEL);
1201 BUG_ON(copy == NULL);
1202 memcpy(copy, blk_shadow, sizeof(blk_shadow));
1204 /* Stage 2: Set up free list. */
1205 memset(&blk_shadow, 0, sizeof(blk_shadow));
1206 for ( i = 0; i < BLK_RING_SIZE; i++ )
1207 blk_shadow[i].req.id = i+1;
1208 blk_shadow_free = blk_ring.req_prod_pvt;
1209 blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
1211 /* Stage 3: Find pending requests and requeue them. */
1212 for ( i = 0; i < BLK_RING_SIZE; i++ )
1214 /* Not in use? */
1215 if ( copy[i].request == 0 )
1216 continue;
1218 /* Grab a request slot and unpickle shadow state into it. */
1219 req = RING_GET_REQUEST(
1220 &blk_ring, blk_ring.req_prod_pvt);
1221 unpickle_request(req, &copy[i]);
1223 /* We get a new request id, and must reset the shadow state. */
1224 req->id = GET_ID_FROM_FREELIST();
1225 memcpy(&blk_shadow[req->id], &copy[i], sizeof(copy[i]));
1227 #ifdef CONFIG_XEN_BLKDEV_GRANT
1228 /* Rewrite any grant references invalidated by suspend/resume. */
1229 for ( j = 0; j < req->nr_segments; j++ )
1231 if ( req->frame_and_sects[j] & GRANTREF_INVALID )
1232 gnttab_grant_foreign_access_ref(
1233 blkif_gref_from_fas(req->frame_and_sects[j]),
1234 rdomid,
1235 blk_shadow[req->id].frame[j],
1236 rq_data_dir((struct request *)
1237 blk_shadow[req->id].request));
1238 req->frame_and_sects[j] &= ~GRANTREF_INVALID;
1240 blk_shadow[req->id].req = *req;
1241 #endif
1243 blk_ring.req_prod_pvt++;
1246 kfree(copy);
1248 recovery = 0;
1250 /* blk_ring->req_prod will be set when we flush_requests().*/
1251 wmb();
1253 /* Kicks things back into life. */
1254 flush_requests();
1256 /* Now safe to left other people use the interface. */
1257 blkif_state = BLKIF_STATE_CONNECTED;
1260 static void blkif_connect(blkif_fe_interface_status_t *status)
1262 int err = 0;
1264 blkif_evtchn = status->evtchn;
1266 err = bind_evtchn_to_irqhandler(
1267 blkif_evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
1268 if ( err != 0 )
1270 WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
1271 return;
1274 if ( recovery )
1276 blkif_recover();
1278 else
1280 /* Transition to connected in case we need to do
1281 * a partition probe on a whole disk. */
1282 blkif_state = BLKIF_STATE_CONNECTED;
1284 /* Probe for discs attached to the interface. */
1285 xlvbd_init();
1288 /* Kick pending requests. */
1289 spin_lock_irq(&blkif_io_lock);
1290 kick_pending_request_queues();
1291 spin_unlock_irq(&blkif_io_lock);
1294 static void unexpected(blkif_fe_interface_status_t *status)
1296 DPRINTK(" Unexpected blkif status %u in state %u\n",
1297 status->status, blkif_state);
1300 static void blkif_status(blkif_fe_interface_status_t *status)
1302 #ifdef CONFIG_XEN_BLKDEV_GRANT
1303 rdomid = status->domid; /* need to set rdomid early */
1304 #endif
1306 if ( status->handle != blkif_handle )
1308 WPRINTK(" Invalid blkif: handle=%u\n", status->handle);
1309 unexpected(status);
1310 return;
1313 switch ( status->status )
1315 case BLKIF_INTERFACE_STATUS_CLOSED:
1316 switch ( blkif_state )
1318 case BLKIF_STATE_CLOSED:
1319 unexpected(status);
1320 break;
1321 case BLKIF_STATE_DISCONNECTED:
1322 case BLKIF_STATE_CONNECTED:
1323 unexpected(status);
1324 blkif_close();
1325 break;
1327 break;
1329 case BLKIF_INTERFACE_STATUS_DISCONNECTED:
1330 switch ( blkif_state )
1332 case BLKIF_STATE_CLOSED:
1333 blkif_disconnect();
1334 break;
1335 case BLKIF_STATE_DISCONNECTED:
1336 case BLKIF_STATE_CONNECTED:
1337 /* unexpected(status); */ /* occurs during suspend/resume */
1338 blkif_reset();
1339 break;
1341 break;
1343 case BLKIF_INTERFACE_STATUS_CONNECTED:
1344 switch ( blkif_state )
1346 case BLKIF_STATE_CLOSED:
1347 unexpected(status);
1348 blkif_disconnect();
1349 blkif_connect(status);
1350 break;
1351 case BLKIF_STATE_DISCONNECTED:
1352 blkif_connect(status);
1353 break;
1354 case BLKIF_STATE_CONNECTED:
1355 unexpected(status);
1356 blkif_connect(status);
1357 break;
1359 break;
1361 case BLKIF_INTERFACE_STATUS_CHANGED:
1362 switch ( blkif_state )
1364 case BLKIF_STATE_CLOSED:
1365 case BLKIF_STATE_DISCONNECTED:
1366 unexpected(status);
1367 break;
1368 case BLKIF_STATE_CONNECTED:
1369 vbd_update();
1370 break;
1372 break;
1374 default:
1375 WPRINTK(" Invalid blkif status: %d\n", status->status);
1376 break;
1381 static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
1383 switch ( msg->subtype )
1385 case CMSG_BLKIF_FE_INTERFACE_STATUS:
1386 blkif_status((blkif_fe_interface_status_t *)
1387 &msg->msg[0]);
1388 break;
1389 default:
1390 msg->length = 0;
1391 break;
1394 ctrl_if_send_response(msg);
1397 int wait_for_blkif(void)
1399 int err = 0;
1400 int i;
1401 send_driver_status(1);
1403 /*
1404 * We should read 'nr_interfaces' from response message and wait
1405 * for notifications before proceeding. For now we assume that we
1406 * will be notified of exactly one interface.
1407 */
1408 for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*HZ); i++ )
1410 set_current_state(TASK_INTERRUPTIBLE);
1411 schedule_timeout(1);
1414 if ( blkif_state != BLKIF_STATE_CONNECTED )
1416 WPRINTK("Timeout connecting to device!\n");
1417 err = -ENOSYS;
1419 return err;
1422 int __init xlblk_init(void)
1424 int i;
1426 #ifdef CONFIG_XEN_BLKDEV_GRANT
1427 /* A grant for every ring slot, plus one for the ring itself. */
1428 if ( 0 > gnttab_alloc_grant_references(MAXIMUM_OUTSTANDING_BLOCK_REQS + 1,
1429 &gref_head, &gref_terminal) )
1430 return 1;
1431 printk(KERN_ALERT "Blkif frontend is using grant tables.\n");
1432 #endif
1434 if ( (xen_start_info.flags & SIF_INITDOMAIN) ||
1435 (xen_start_info.flags & SIF_BLK_BE_DOMAIN) )
1436 return 0;
1438 IPRINTK("Initialising virtual block device driver\n");
1440 blk_shadow_free = 0;
1441 memset(blk_shadow, 0, sizeof(blk_shadow));
1442 for ( i = 0; i < BLK_RING_SIZE; i++ )
1443 blk_shadow[i].req.id = i+1;
1444 blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
1446 (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
1447 CALLBACK_IN_BLOCKING_CONTEXT);
1449 wait_for_blkif();
1451 return 0;
1454 void blkdev_suspend(void)
1458 void blkdev_resume(void)
1460 #ifdef CONFIG_XEN_BLKDEV_GRANT
1461 int i, j;
1462 for ( i = 0; i < BLK_RING_SIZE; i++ )
1463 for ( j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++ )
1464 blk_shadow[i].req.frame_and_sects[j] |= GRANTREF_INVALID;
1465 #endif
1466 send_driver_status(1);
1469 static void blkif_completion(struct blk_shadow *s)
1471 int i;
1472 #ifdef CONFIG_XEN_BLKDEV_GRANT
1473 for ( i = 0; i < s->req.nr_segments; i++ )
1474 gnttab_release_grant_reference(
1475 &gref_head, blkif_gref_from_fas(s->req.frame_and_sects[i]));
1476 #else
1477 /* This is a hack to get the dirty logging bits set */
1478 if ( s->req.operation == BLKIF_OP_READ )
1480 for ( i = 0; i < s->req.nr_segments; i++ )
1482 unsigned long pfn = s->req.frame_and_sects[i] >> PAGE_SHIFT;
1483 unsigned long mfn = phys_to_machine_mapping[pfn];
1484 xen_machphys_update(mfn, pfn);
1487 #endif