Skip to content

Commit 4b97280

Browse files
committed
Merge tag 'stable/for-linus-3.12-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull Xen fixes from Konrad Rzeszutek Wilk: "Bug-fixes and one update to the kernel-paramters.txt documentation. - Fix PV spinlocks triggering jump_label code bug - Remove extraneous code in the tpm front driver - Fix ballooning out of pages when non-preemptible - Fix deadlock when using a 32-bit initial domain with large amount of memory - Add xen_nopvpsin parameter to the documentation" * tag 'stable/for-linus-3.12-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/spinlock: Document the xen_nopvspin parameter. xen/p2m: check MFN is in range before using the m2p table xen/balloon: don't alloc page while non-preemptible xen: Do not enable spinlocks before jump_label_init() has executed tpm: xen-tpmfront: Remove the locality sysfs attribute tpm: xen-tpmfront: Fix default durations
2 parents e93dd91 + 15a3eac commit 4b97280

File tree

6 files changed

+63
-67
lines changed

6 files changed

+63
-67
lines changed

Documentation/kernel-parameters.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3485,6 +3485,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
34853485
the unplug protocol
34863486
never -- do not unplug even if version check succeeds
34873487

3488+
xen_nopvspin [X86,XEN]
3489+
Disables the ticketlock slowpath using Xen PV
3490+
optimizations.
3491+
34883492
xirc2ps_cs= [NET,PCMCIA]
34893493
Format:
34903494
<irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]

arch/x86/include/asm/xen/page.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,30 +79,38 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
7979
return get_phys_to_machine(pfn) != INVALID_P2M_ENTRY;
8080
}
8181

82-
static inline unsigned long mfn_to_pfn(unsigned long mfn)
82+
static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn)
8383
{
8484
unsigned long pfn;
85-
int ret = 0;
85+
int ret;
8686

8787
if (xen_feature(XENFEAT_auto_translated_physmap))
8888
return mfn;
8989

90-
if (unlikely(mfn >= machine_to_phys_nr)) {
91-
pfn = ~0;
92-
goto try_override;
93-
}
94-
pfn = 0;
90+
if (unlikely(mfn >= machine_to_phys_nr))
91+
return ~0;
92+
9593
/*
9694
* The array access can fail (e.g., device space beyond end of RAM).
9795
* In such cases it doesn't matter what we return (we return garbage),
9896
* but we must handle the fault without crashing!
9997
*/
10098
ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
101-
try_override:
102-
/* ret might be < 0 if there are no entries in the m2p for mfn */
10399
if (ret < 0)
104-
pfn = ~0;
105-
else if (get_phys_to_machine(pfn) != mfn)
100+
return ~0;
101+
102+
return pfn;
103+
}
104+
105+
static inline unsigned long mfn_to_pfn(unsigned long mfn)
106+
{
107+
unsigned long pfn;
108+
109+
if (xen_feature(XENFEAT_auto_translated_physmap))
110+
return mfn;
111+
112+
pfn = mfn_to_pfn_no_overrides(mfn);
113+
if (get_phys_to_machine(pfn) != mfn) {
106114
/*
107115
* If this appears to be a foreign mfn (because the pfn
108116
* doesn't map back to the mfn), then check the local override
@@ -111,6 +119,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
111119
* m2p_find_override_pfn returns ~0 if it doesn't find anything.
112120
*/
113121
pfn = m2p_find_override_pfn(mfn, ~0);
122+
}
114123

115124
/*
116125
* pfn is ~0 if there are no entries in the m2p for mfn or if the

arch/x86/xen/p2m.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
879879
unsigned long uninitialized_var(address);
880880
unsigned level;
881881
pte_t *ptep = NULL;
882-
int ret = 0;
883882

884883
pfn = page_to_pfn(page);
885884
if (!PageHighMem(page)) {
@@ -926,8 +925,8 @@ int m2p_add_override(unsigned long mfn, struct page *page,
926925
* frontend pages while they are being shared with the backend,
927926
* because mfn_to_pfn (that ends up being called by GUPF) will
928927
* return the backend pfn rather than the frontend pfn. */
929-
ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
930-
if (ret == 0 && get_phys_to_machine(pfn) == mfn)
928+
pfn = mfn_to_pfn_no_overrides(mfn);
929+
if (get_phys_to_machine(pfn) == mfn)
931930
set_phys_to_machine(pfn, FOREIGN_FRAME(mfn));
932931

933932
return 0;
@@ -942,7 +941,6 @@ int m2p_remove_override(struct page *page,
942941
unsigned long uninitialized_var(address);
943942
unsigned level;
944943
pte_t *ptep = NULL;
945-
int ret = 0;
946944

947945
pfn = page_to_pfn(page);
948946
mfn = get_phys_to_machine(pfn);
@@ -1029,8 +1027,8 @@ int m2p_remove_override(struct page *page,
10291027
* the original pfn causes mfn_to_pfn(mfn) to return the frontend
10301028
* pfn again. */
10311029
mfn &= ~FOREIGN_FRAME_BIT;
1032-
ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
1033-
if (ret == 0 && get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) &&
1030+
pfn = mfn_to_pfn_no_overrides(mfn);
1031+
if (get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) &&
10341032
m2p_find_override(mfn) == NULL)
10351033
set_phys_to_machine(pfn, mfn);
10361034

arch/x86/xen/spinlock.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ void xen_uninit_lock_cpu(int cpu)
259259
}
260260

261261

262+
/*
263+
* Our init of PV spinlocks is split in two init functions due to us
264+
* using paravirt patching and jump labels patching and having to do
265+
* all of this before SMP code is invoked.
266+
*
267+
* The paravirt patching needs to be done _before_ the alternative asm code
268+
* is started, otherwise we would not patch the core kernel code.
269+
*/
262270
void __init xen_init_spinlocks(void)
263271
{
264272

@@ -267,12 +275,26 @@ void __init xen_init_spinlocks(void)
267275
return;
268276
}
269277

270-
static_key_slow_inc(&paravirt_ticketlocks_enabled);
271-
272278
pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning);
273279
pv_lock_ops.unlock_kick = xen_unlock_kick;
274280
}
275281

282+
/*
283+
* While the jump_label init code needs to happend _after_ the jump labels are
284+
* enabled and before SMP is started. Hence we use pre-SMP initcall level
285+
* init. We cannot do it in xen_init_spinlocks as that is done before
286+
* jump labels are activated.
287+
*/
288+
static __init int xen_init_spinlocks_jump(void)
289+
{
290+
if (!xen_pvspin)
291+
return 0;
292+
293+
static_key_slow_inc(&paravirt_ticketlocks_enabled);
294+
return 0;
295+
}
296+
early_initcall(xen_init_spinlocks_jump);
297+
276298
static __init int xen_parse_nopvspin(char *arg)
277299
{
278300
xen_pvspin = false;

drivers/char/tpm/xen-tpmfront.c

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -142,32 +142,6 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
142142
return length;
143143
}
144144

145-
ssize_t tpm_show_locality(struct device *dev, struct device_attribute *attr,
146-
char *buf)
147-
{
148-
struct tpm_chip *chip = dev_get_drvdata(dev);
149-
struct tpm_private *priv = TPM_VPRIV(chip);
150-
u8 locality = priv->shr->locality;
151-
152-
return sprintf(buf, "%d\n", locality);
153-
}
154-
155-
ssize_t tpm_store_locality(struct device *dev, struct device_attribute *attr,
156-
const char *buf, size_t len)
157-
{
158-
struct tpm_chip *chip = dev_get_drvdata(dev);
159-
struct tpm_private *priv = TPM_VPRIV(chip);
160-
u8 val;
161-
162-
int rv = kstrtou8(buf, 0, &val);
163-
if (rv)
164-
return rv;
165-
166-
priv->shr->locality = val;
167-
168-
return len;
169-
}
170-
171145
static const struct file_operations vtpm_ops = {
172146
.owner = THIS_MODULE,
173147
.llseek = no_llseek,
@@ -188,8 +162,6 @@ static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
188162
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
189163
static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
190164
static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
191-
static DEVICE_ATTR(locality, S_IRUGO | S_IWUSR, tpm_show_locality,
192-
tpm_store_locality);
193165

194166
static struct attribute *vtpm_attrs[] = {
195167
&dev_attr_pubek.attr,
@@ -202,16 +174,13 @@ static struct attribute *vtpm_attrs[] = {
202174
&dev_attr_cancel.attr,
203175
&dev_attr_durations.attr,
204176
&dev_attr_timeouts.attr,
205-
&dev_attr_locality.attr,
206177
NULL,
207178
};
208179

209180
static struct attribute_group vtpm_attr_grp = {
210181
.attrs = vtpm_attrs,
211182
};
212183

213-
#define TPM_LONG_TIMEOUT (10 * 60 * HZ)
214-
215184
static const struct tpm_vendor_specific tpm_vtpm = {
216185
.status = vtpm_status,
217186
.recv = vtpm_recv,
@@ -224,11 +193,6 @@ static const struct tpm_vendor_specific tpm_vtpm = {
224193
.miscdev = {
225194
.fops = &vtpm_ops,
226195
},
227-
.duration = {
228-
TPM_LONG_TIMEOUT,
229-
TPM_LONG_TIMEOUT,
230-
TPM_LONG_TIMEOUT,
231-
},
232196
};
233197

234198
static irqreturn_t tpmif_interrupt(int dummy, void *dev_id)

drivers/xen/balloon.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,6 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
398398
if (nr_pages > ARRAY_SIZE(frame_list))
399399
nr_pages = ARRAY_SIZE(frame_list);
400400

401-
scratch_page = get_balloon_scratch_page();
402-
403401
for (i = 0; i < nr_pages; i++) {
404402
page = alloc_page(gfp);
405403
if (page == NULL) {
@@ -413,6 +411,12 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
413411

414412
scrub_page(page);
415413

414+
/*
415+
* Ballooned out frames are effectively replaced with
416+
* a scratch frame. Ensure direct mappings and the
417+
* p2m are consistent.
418+
*/
419+
scratch_page = get_balloon_scratch_page();
416420
#ifdef CONFIG_XEN_HAVE_PVMMU
417421
if (xen_pv_domain() && !PageHighMem(page)) {
418422
ret = HYPERVISOR_update_va_mapping(
@@ -422,24 +426,19 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
422426
BUG_ON(ret);
423427
}
424428
#endif
425-
}
426-
427-
/* Ensure that ballooned highmem pages don't have kmaps. */
428-
kmap_flush_unused();
429-
flush_tlb_all();
430-
431-
/* No more mappings: invalidate P2M and add to balloon. */
432-
for (i = 0; i < nr_pages; i++) {
433-
pfn = mfn_to_pfn(frame_list[i]);
434429
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
435430
unsigned long p;
436431
p = page_to_pfn(scratch_page);
437432
__set_phys_to_machine(pfn, pfn_to_mfn(p));
438433
}
434+
put_balloon_scratch_page();
435+
439436
balloon_append(pfn_to_page(pfn));
440437
}
441438

442-
put_balloon_scratch_page();
439+
/* Ensure that ballooned highmem pages don't have kmaps. */
440+
kmap_flush_unused();
441+
flush_tlb_all();
443442

444443
set_xen_guest_handle(reservation.extent_start, frame_list);
445444
reservation.nr_extents = nr_pages;

0 commit comments

Comments
 (0)