Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 98406
b: refs/heads/master
c: 62786b9
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Jun 23, 2008
1 parent 0f586e1 commit 7fc01e4
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 69 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 03fa9e84e5dc10aeacb0e4eb2f708cd9fc36a5b8
refs/heads/master: 62786b9e81a2dbe9c073a2ade52d33a2627d6d85
5 changes: 5 additions & 0 deletions trunk/arch/x86/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,11 @@ asmlinkage void __init xen_start_kernel(void)
if (xen_feature(XENFEAT_supervisor_mode_kernel))
pv_info.kernel_rpl = 0;

/* Prevent unwanted bits from being set in PTEs. */
__supported_pte_mask &= ~_PAGE_GLOBAL;
if (!is_initial_xendomain())
__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);

/* set the limit of our address space */
xen_reserve_top();

Expand Down
56 changes: 30 additions & 26 deletions trunk/arch/x86/xen/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,48 +179,54 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
preempt_enable();
}

pteval_t xen_pte_val(pte_t pte)
/* Assume pteval_t is equivalent to all the other *val_t types. */
static pteval_t pte_mfn_to_pfn(pteval_t val)
{
pteval_t ret = pte.pte;
if (val & _PAGE_PRESENT) {
unsigned long mfn = (val & PTE_MASK) >> PAGE_SHIFT;
pteval_t flags = val & ~PTE_MASK;
val = (mfn_to_pfn(mfn) << PAGE_SHIFT) | flags;
}

return val;
}

static pteval_t pte_pfn_to_mfn(pteval_t val)
{
if (val & _PAGE_PRESENT) {
unsigned long pfn = (val & PTE_MASK) >> PAGE_SHIFT;
pteval_t flags = val & ~PTE_MASK;
val = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flags;
}

if (ret & _PAGE_PRESENT)
ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT;
return val;
}

return ret;
pteval_t xen_pte_val(pte_t pte)
{
return pte_mfn_to_pfn(pte.pte);
}

pgdval_t xen_pgd_val(pgd_t pgd)
{
pgdval_t ret = pgd.pgd;
if (ret & _PAGE_PRESENT)
ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT;
return ret;
return pte_mfn_to_pfn(pgd.pgd);
}

pte_t xen_make_pte(pteval_t pte)
{
if (pte & _PAGE_PRESENT) {
pte = phys_to_machine(XPADDR(pte)).maddr;
pte &= ~(_PAGE_PCD | _PAGE_PWT);
}

return (pte_t){ .pte = pte };
pte = pte_pfn_to_mfn(pte);
return native_make_pte(pte);
}

pgd_t xen_make_pgd(pgdval_t pgd)
{
if (pgd & _PAGE_PRESENT)
pgd = phys_to_machine(XPADDR(pgd)).maddr;

return (pgd_t){ pgd };
pgd = pte_pfn_to_mfn(pgd);
return native_make_pgd(pgd);
}

pmdval_t xen_pmd_val(pmd_t pmd)
{
pmdval_t ret = native_pmd_val(pmd);
if (ret & _PAGE_PRESENT)
ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT;
return ret;
return pte_mfn_to_pfn(pmd.pmd);
}
#ifdef CONFIG_X86_PAE
void xen_set_pud(pud_t *ptr, pud_t val)
Expand Down Expand Up @@ -267,9 +273,7 @@ void xen_pmd_clear(pmd_t *pmdp)

pmd_t xen_make_pmd(pmdval_t pmd)
{
if (pmd & _PAGE_PRESENT)
pmd = phys_to_machine(XPADDR(pmd)).maddr;

pmd = pte_pfn_to_mfn(pmd);
return native_make_pmd(pmd);
}
#else /* !PAE */
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/xen/xen-head.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ENTRY(startup_xen)

__FINIT

.pushsection .bss.page_aligned
.pushsection .text
.align PAGE_SIZE_asm
ENTRY(hypercall_page)
.skip 0x1000
Expand Down
6 changes: 5 additions & 1 deletion trunk/drivers/infiniband/hw/mthca/mthca_memfree.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
{
struct page *page;

page = alloc_pages(gfp_mask, order);
/*
* Use __GFP_ZERO because buggy firmware assumes ICM pages are
* cleared, and subtle failures are seen if they aren't.
*/
page = alloc_pages(gfp_mask | __GFP_ZERO, order);
if (!page)
return -ENOMEM;

Expand Down
15 changes: 9 additions & 6 deletions trunk/drivers/lguest/x86/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
* we set it now, so we can trap and pass that trap to the Guest if it
* uses the FPU. */
if (cpu->ts)
lguest_set_ts();
unlazy_fpu(current);

/* SYSENTER is an optimized way of doing system calls. We can't allow
* it because it always jumps to privilege level 0. A normal Guest
Expand All @@ -196,20 +196,23 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
* trap made the switcher code come back, and an error code which some
* traps set. */

/* Restore SYSENTER if it's supposed to be on. */
if (boot_cpu_has(X86_FEATURE_SEP))
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);

/* If the Guest page faulted, then the cr2 register will tell us the
* bad virtual address. We have to grab this now, because once we
* re-enable interrupts an interrupt could fault and thus overwrite
* cr2, or we could even move off to a different CPU. */
if (cpu->regs->trapnum == 14)
cpu->arch.last_pagefault = read_cr2();
/* Similarly, if we took a trap because the Guest used the FPU,
* we have to restore the FPU it expects to see. */
* we have to restore the FPU it expects to see.
* math_state_restore() may sleep and we may even move off to
* a different CPU. So all the critical stuff should be done
* before this. */
else if (cpu->regs->trapnum == 7)
math_state_restore();

/* Restore SYSENTER if it's supposed to be on. */
if (boot_cpu_has(X86_FEATURE_SEP))
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
}

/*H:130 Now we've examined the hypercall code; our Guest can make requests.
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/xen/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)

#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
/* Clear master flag /before/ clearing selector flag. */
rmb();
wmb();
#endif
pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
while (pending_words != 0) {
Expand Down
93 changes: 73 additions & 20 deletions trunk/kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,48 +1096,100 @@ static void unqueue_me_pi(struct futex_q *q)
* private futexes.
*/
static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
struct task_struct *newowner)
struct task_struct *newowner,
struct rw_semaphore *fshared)
{
u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS;
struct futex_pi_state *pi_state = q->pi_state;
struct task_struct *oldowner = pi_state->owner;
u32 uval, curval, newval;
int ret;
int ret, attempt = 0;

/* Owner died? */
if (!pi_state->owner)
newtid |= FUTEX_OWNER_DIED;

/*
* We are here either because we stole the rtmutex from the
* pending owner or we are the pending owner which failed to
* get the rtmutex. We have to replace the pending owner TID
* in the user space variable. This must be atomic as we have
* to preserve the owner died bit here.
*
* Note: We write the user space value _before_ changing the
* pi_state because we can fault here. Imagine swapped out
* pages or a fork, which was running right before we acquired
* mmap_sem, that marked all the anonymous memory readonly for
* cow.
*
* Modifying pi_state _before_ the user space value would
* leave the pi_state in an inconsistent state when we fault
* here, because we need to drop the hash bucket lock to
* handle the fault. This might be observed in the PID check
* in lookup_pi_state.
*/
retry:
if (get_futex_value_locked(&uval, uaddr))
goto handle_fault;

while (1) {
newval = (uval & FUTEX_OWNER_DIED) | newtid;

curval = cmpxchg_futex_value_locked(uaddr, uval, newval);

if (curval == -EFAULT)
goto handle_fault;
if (curval == uval)
break;
uval = curval;
}

/*
* We fixed up user space. Now we need to fix the pi_state
* itself.
*/
if (pi_state->owner != NULL) {
spin_lock_irq(&pi_state->owner->pi_lock);
WARN_ON(list_empty(&pi_state->list));
list_del_init(&pi_state->list);
spin_unlock_irq(&pi_state->owner->pi_lock);
} else
newtid |= FUTEX_OWNER_DIED;
}

pi_state->owner = newowner;

spin_lock_irq(&newowner->pi_lock);
WARN_ON(!list_empty(&pi_state->list));
list_add(&pi_state->list, &newowner->pi_state_list);
spin_unlock_irq(&newowner->pi_lock);
return 0;

/*
* We own it, so we have to replace the pending owner
* TID. This must be atomic as we have preserve the
* owner died bit here.
* To handle the page fault we need to drop the hash bucket
* lock here. That gives the other task (either the pending
* owner itself or the task which stole the rtmutex) the
* chance to try the fixup of the pi_state. So once we are
* back from handling the fault we need to check the pi_state
* after reacquiring the hash bucket lock and before trying to
* do another fixup. When the fixup has been done already we
* simply return.
*/
ret = get_futex_value_locked(&uval, uaddr);
handle_fault:
spin_unlock(q->lock_ptr);

while (!ret) {
newval = (uval & FUTEX_OWNER_DIED) | newtid;
ret = futex_handle_fault((unsigned long)uaddr, fshared, attempt++);

curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
spin_lock(q->lock_ptr);

if (curval == -EFAULT)
ret = -EFAULT;
if (curval == uval)
break;
uval = curval;
}
return ret;
/*
* Check if someone else fixed it for us:
*/
if (pi_state->owner != oldowner)
return 0;

if (ret)
return ret;

goto retry;
}

/*
Expand Down Expand Up @@ -1507,7 +1559,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
* that case:
*/
if (q.pi_state->owner != curr)
ret = fixup_pi_state_owner(uaddr, &q, curr);
ret = fixup_pi_state_owner(uaddr, &q, curr, fshared);
} else {
/*
* Catch the rare case, where the lock was released
Expand Down Expand Up @@ -1539,7 +1591,8 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
int res;

owner = rt_mutex_owner(&q.pi_state->pi_mutex);
res = fixup_pi_state_owner(uaddr, &q, owner);
res = fixup_pi_state_owner(uaddr, &q, owner,
fshared);

/* propagate -EFAULT, if the fixup failed */
if (res)
Expand Down
14 changes: 6 additions & 8 deletions trunk/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -4398,22 +4398,20 @@ do_wait_for_common(struct completion *x, long timeout, int state)
signal_pending(current)) ||
(state == TASK_KILLABLE &&
fatal_signal_pending(current))) {
__remove_wait_queue(&x->wait, &wait);
return -ERESTARTSYS;
timeout = -ERESTARTSYS;
break;
}
__set_current_state(state);
spin_unlock_irq(&x->wait.lock);
timeout = schedule_timeout(timeout);
spin_lock_irq(&x->wait.lock);
if (!timeout) {
__remove_wait_queue(&x->wait, &wait);
return timeout;
}
} while (!x->done);
} while (!x->done && timeout);
__remove_wait_queue(&x->wait, &wait);
if (!x->done)
return timeout;
}
x->done--;
return timeout;
return timeout ?: 1;
}

static long __sched
Expand Down
3 changes: 2 additions & 1 deletion trunk/kernel/sched_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
if (rt_rq->rt_time || rt_rq->rt_nr_running)
idle = 0;
spin_unlock(&rt_rq->rt_runtime_lock);
}
} else if (rt_rq->rt_nr_running)
idle = 0;

if (enqueue)
sched_rt_rq_enqueue(rt_rq);
Expand Down
4 changes: 2 additions & 2 deletions trunk/sound/isa/sb/sb_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -925,15 +925,15 @@ static unsigned char als4000_saved_regs[] = {
static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
{
unsigned char *val = chip->saved_regs;
snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return);
for (; num_regs; num_regs--)
*val++ = snd_sbmixer_read(chip, *regs++);
}

static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
{
unsigned char *val = chip->saved_regs;
snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return);
for (; num_regs; num_regs--)
snd_sbmixer_write(chip, *regs++, *val++);
}
Expand Down
4 changes: 2 additions & 2 deletions trunk/sound/pci/aw2/aw2-alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ static int __devinit snd_aw2_create(struct snd_card *card,
return -ENOMEM;
}

/* (2) initialization of the chip hardware */
snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);

if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
IRQF_SHARED, "Audiowerk2", chip)) {
Expand All @@ -329,8 +331,6 @@ static int __devinit snd_aw2_create(struct snd_card *card,
}
chip->irq = pci->irq;

/* (2) initialization of the chip hardware */
snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
free_irq(chip->irq, (void *)chip);
Expand Down

0 comments on commit 7fc01e4

Please sign in to comment.