Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 98401
b: refs/heads/master
c: 1b7558e
h: refs/heads/master
i:
  98399: 7abdc7e
v: v3
  • Loading branch information
Thomas Gleixner authored and Ingo Molnar committed Jun 23, 2008
1 parent 67ec101 commit f146925
Show file tree
Hide file tree
Showing 16 changed files with 136 additions and 134 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: 0e053738b50836e9d1e94b2295ef2942eb471078
refs/heads/master: 1b7558e457ed0de61023cfc913d2c342c7c3d9f2
5 changes: 0 additions & 5 deletions trunk/arch/x86/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,11 +1228,6 @@ 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: 26 additions & 30 deletions trunk/arch/x86/xen/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,54 +179,48 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
preempt_enable();
}

/* Assume pteval_t is equivalent to all the other *val_t types. */
static pteval_t pte_mfn_to_pfn(pteval_t val)
{
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)
pteval_t xen_pte_val(pte_t pte)
{
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;
}
pteval_t ret = pte.pte;

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

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

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

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

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

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

return (pgd_t){ pgd };
}

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

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

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 .text
.pushsection .bss.page_aligned
.align PAGE_SIZE_asm
ENTRY(hypercall_page)
.skip 0x1000
Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/char/tty_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -981,9 +981,16 @@ EXPORT_SYMBOL_GPL(tty_perform_flush);
int n_tty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct tty_struct *real_tty;
unsigned long flags;
int retval;

if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER)
real_tty = tty->link;
else
real_tty = tty;

switch (cmd) {
case TCXONC:
retval = tty_check_change(tty);
Expand Down
6 changes: 1 addition & 5 deletions trunk/drivers/infiniband/hw/mthca/mthca_memfree.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,7 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
{
struct page *page;

/*
* 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);
page = alloc_pages(gfp_mask, order);
if (!page)
return -ENOMEM;

Expand Down
15 changes: 6 additions & 9 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)
unlazy_fpu(current);
lguest_set_ts();

/* 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,23 +196,20 @@ 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.
* 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. */
* we have to restore the FPU it expects to see. */
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. */
wmb();
rmb();
#endif
pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
while (pending_words != 0) {
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/select.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
retval++;
}
}
cond_resched();
}
if (res_in)
*rinp = res_in;
if (res_out)
*routp = res_out;
if (res_ex)
*rexp = res_ex;
cond_resched();
}
wait = NULL;
if (retval || !*timeout || signal_pending(current))
Expand Down
5 changes: 3 additions & 2 deletions trunk/include/linux/tty_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
* This routine is called by the kernel to write a series of
* characters to the tty device. The characters may come from
* user space or kernel space. This routine will return the
* number of characters actually accepted for writing.
* number of characters actually accepted for writing. This
* routine is mandatory.
*
* Optional: Required for writable devices.
*
Expand Down Expand Up @@ -133,7 +134,7 @@
* This routine notifies the tty driver that it should hangup the
* tty device.
*
* Optional:
* Required:
*
* void (*break_ctl)(struct tty_stuct *tty, int state);
*
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: 8 additions & 6 deletions trunk/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -4398,20 +4398,22 @@ do_wait_for_common(struct completion *x, long timeout, int state)
signal_pending(current)) ||
(state == TASK_KILLABLE &&
fatal_signal_pending(current))) {
timeout = -ERESTARTSYS;
break;
__remove_wait_queue(&x->wait, &wait);
return -ERESTARTSYS;
}
__set_current_state(state);
spin_unlock_irq(&x->wait.lock);
timeout = schedule_timeout(timeout);
spin_lock_irq(&x->wait.lock);
} while (!x->done && timeout);
if (!timeout) {
__remove_wait_queue(&x->wait, &wait);
return timeout;
}
} while (!x->done);
__remove_wait_queue(&x->wait, &wait);
if (!x->done)
return timeout;
}
x->done--;
return timeout ?: 1;
return timeout;
}

static long __sched
Expand Down
Loading

0 comments on commit f146925

Please sign in to comment.