]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.xen/863-blktap-vma-close.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.xen / 863-blktap-vma-close.patch
1 From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/464a925d73f1
2 # HG changeset 863 patch
3 # User Keir Fraser <keir.fraser@citrix.com>
4 # Date 1239969802 -3600
5 # Node ID 464a925d73f141d8ca568026ee2e6635489affa2
6 # Parent dfd2adc5874021b52c13d317df1f55b46ec38e3d
7 Subject: blktap: don't access deallocated data
8 References: bnc#484210, bnc#485652
9 Patch-mainline: obsolete
10
11 Dereferencing filp->private_data->vma in the file_operations.release
12 actor isn't permitted, as the vma generally has been destroyed by that
13 time. The kfree()ing of vma->vm_private_data must be done in the
14 vm_operations.close actor, and the call to zap_page_range() seems
15 redundant with the caller of that actor altogether.
16
17 Signed-off-by: Jan Beulich <jbeulich@novell.com>
18
19 --- sle11-2009-04-20.orig/drivers/xen/blktap/blktap.c 2009-04-20 11:35:28.000000000 +0200
20 +++ sle11-2009-04-20/drivers/xen/blktap/blktap.c 2009-04-20 11:35:40.000000000 +0200
21 @@ -293,6 +293,10 @@ static inline int OFFSET_TO_SEG(int offs
22 /******************************************************************
23 * BLKTAP VM OPS
24 */
25 +struct tap_vma_priv {
26 + tap_blkif_t *info;
27 + struct page *map[];
28 +};
29
30 static struct page *blktap_nopage(struct vm_area_struct *vma,
31 unsigned long address,
32 @@ -315,7 +319,7 @@ static pte_t blktap_clear_pte(struct vm_
33 int offset, seg, usr_idx, pending_idx, mmap_idx;
34 unsigned long uvstart = vma->vm_start + (RING_PAGES << PAGE_SHIFT);
35 unsigned long kvaddr;
36 - struct page **map;
37 + struct tap_vma_priv *priv;
38 struct page *pg;
39 struct grant_handle_pair *khandle;
40 struct gnttab_unmap_grant_ref unmap[2];
41 @@ -330,12 +334,12 @@ static pte_t blktap_clear_pte(struct vm_
42 ptep, is_fullmm);
43
44 info = vma->vm_file->private_data;
45 - map = vma->vm_private_data;
46 + priv = vma->vm_private_data;
47
48 /* TODO Should these be changed to if statements? */
49 BUG_ON(!info);
50 BUG_ON(!info->idx_map);
51 - BUG_ON(!map);
52 + BUG_ON(!priv);
53
54 offset = (int) ((uvaddr - uvstart) >> PAGE_SHIFT);
55 usr_idx = OFFSET_TO_USR_IDX(offset);
56 @@ -347,7 +351,7 @@ static pte_t blktap_clear_pte(struct vm_
57 kvaddr = idx_to_kaddr(mmap_idx, pending_idx, seg);
58 pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
59 ClearPageReserved(pg);
60 - map[offset + RING_PAGES] = NULL;
61 + priv->map[offset + RING_PAGES] = NULL;
62
63 khandle = &pending_handle(mmap_idx, pending_idx, seg);
64
65 @@ -388,9 +392,20 @@ static pte_t blktap_clear_pte(struct vm_
66 return copy;
67 }
68
69 +static void blktap_vma_close(struct vm_area_struct *vma)
70 +{
71 + struct tap_vma_priv *priv = vma->vm_private_data;
72 +
73 + if (priv) {
74 + priv->info->vma = NULL;
75 + kfree(priv);
76 + }
77 +}
78 +
79 struct vm_operations_struct blktap_vm_ops = {
80 nopage: blktap_nopage,
81 zap_pte: blktap_clear_pte,
82 + close: blktap_vma_close,
83 };
84
85 /******************************************************************
86 @@ -609,21 +624,6 @@ static int blktap_release(struct inode *
87 ClearPageReserved(virt_to_page(info->ufe_ring.sring));
88 free_page((unsigned long) info->ufe_ring.sring);
89
90 - /* Clear any active mappings and free foreign map table */
91 - if (info->vma) {
92 - struct mm_struct *mm = info->vma->vm_mm;
93 -
94 - down_write(&mm->mmap_sem);
95 - zap_page_range(
96 - info->vma, info->vma->vm_start,
97 - info->vma->vm_end - info->vma->vm_start, NULL);
98 - up_write(&mm->mmap_sem);
99 -
100 - kfree(info->vma->vm_private_data);
101 -
102 - info->vma = NULL;
103 - }
104 -
105 if (info->idx_map) {
106 kfree(info->idx_map);
107 info->idx_map = NULL;
108 @@ -662,8 +662,7 @@ static int blktap_release(struct inode *
109 static int blktap_mmap(struct file *filp, struct vm_area_struct *vma)
110 {
111 int size;
112 - struct page **map;
113 - int i;
114 + struct tap_vma_priv *priv;
115 tap_blkif_t *info = filp->private_data;
116 int ret;
117
118 @@ -700,18 +699,16 @@ static int blktap_mmap(struct file *filp
119 }
120
121 /* Mark this VM as containing foreign pages, and set up mappings. */
122 - map = kzalloc(((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)
123 - * sizeof(struct page *),
124 - GFP_KERNEL);
125 - if (map == NULL) {
126 + priv = kzalloc(sizeof(*priv) + ((vma->vm_end - vma->vm_start)
127 + >> PAGE_SHIFT) * sizeof(*priv->map),
128 + GFP_KERNEL);
129 + if (priv == NULL) {
130 WPRINTK("Couldn't alloc VM_FOREIGN map.\n");
131 goto fail;
132 }
133 + priv->info = info;
134
135 - for (i = 0; i < ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT); i++)
136 - map[i] = NULL;
137 -
138 - vma->vm_private_data = map;
139 + vma->vm_private_data = priv;
140 vma->vm_flags |= VM_FOREIGN;
141 vma->vm_flags |= VM_DONTCOPY;
142
143 @@ -1190,7 +1187,7 @@ static int blktap_read_ufe_ring(tap_blki
144 for (j = 0; j < pending_req->nr_pages; j++) {
145
146 unsigned long kvaddr, uvaddr;
147 - struct page **map = info->vma->vm_private_data;
148 + struct tap_vma_priv *priv = info->vma->vm_private_data;
149 struct page *pg;
150 int offset;
151
152 @@ -1201,7 +1198,7 @@ static int blktap_read_ufe_ring(tap_blki
153 ClearPageReserved(pg);
154 offset = (uvaddr - info->vma->vm_start)
155 >> PAGE_SHIFT;
156 - map[offset] = NULL;
157 + priv->map[offset] = NULL;
158 }
159 fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
160 info->idx_map[usr_idx] = INVALID_REQ;
161 @@ -1359,6 +1356,7 @@ static void dispatch_rw_block_io(blkif_t
162 unsigned int nseg;
163 int ret, i, nr_sects = 0;
164 tap_blkif_t *info;
165 + struct tap_vma_priv *priv;
166 blkif_request_t *target;
167 int pending_idx = RTN_PEND_IDX(pending_req,pending_req->mem_idx);
168 int usr_idx;
169 @@ -1407,6 +1405,7 @@ static void dispatch_rw_block_io(blkif_t
170 pending_req->status = BLKIF_RSP_OKAY;
171 pending_req->nr_pages = nseg;
172 op = 0;
173 + priv = info->vma->vm_private_data;
174 mm = info->vma->vm_mm;
175 if (!xen_feature(XENFEAT_auto_translated_physmap))
176 down_write(&mm->mmap_sem);
177 @@ -1490,8 +1489,7 @@ static void dispatch_rw_block_io(blkif_t
178 >> PAGE_SHIFT));
179 offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
180 pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
181 - ((struct page **)info->vma->vm_private_data)[offset] =
182 - pg;
183 + priv->map[offset] = pg;
184 }
185 } else {
186 for (i = 0; i < nseg; i++) {
187 @@ -1518,8 +1516,7 @@ static void dispatch_rw_block_io(blkif_t
188
189 offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
190 pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
191 - ((struct page **)info->vma->vm_private_data)[offset] =
192 - pg;
193 + priv->map[offset] = pg;
194 }
195 }
196