Commit 1c89ac55 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus

* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  fix spinlock recursion in hvc_console
  stop_machine: remove unused variable
  modules: extend initcall_debug functionality to the module loader
  export virtio_rng.h
  lguest: use get_user_pages_fast() instead of get_user_pages()
  mm: Make generic weak get_user_pages_fast and EXPORT_GPL it
  lguest: don't set MAC address for guest unless specified
parents 88fa08f6 b1b135c8
...@@ -1447,21 +1447,6 @@ static void configure_device(int fd, const char *tapif, u32 ipaddr) ...@@ -1447,21 +1447,6 @@ static void configure_device(int fd, const char *tapif, u32 ipaddr)
err(1, "Bringing interface %s up", tapif); err(1, "Bringing interface %s up", tapif);
} }
static void get_mac(int fd, const char *tapif, unsigned char hwaddr[6])
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, tapif);
/* SIOC stands for Socket I/O Control. G means Get (vs S for Set
* above). IF means Interface, and HWADDR is hardware address.
* Simple! */
if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0)
err(1, "getting hw address for %s", tapif);
memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
}
static int get_tun_device(char tapif[IFNAMSIZ]) static int get_tun_device(char tapif[IFNAMSIZ])
{ {
struct ifreq ifr; struct ifreq ifr;
...@@ -1531,11 +1516,8 @@ static void setup_tun_net(char *arg) ...@@ -1531,11 +1516,8 @@ static void setup_tun_net(char *arg)
p = strchr(arg, ':'); p = strchr(arg, ':');
if (p) { if (p) {
str2mac(p+1, conf.mac); str2mac(p+1, conf.mac);
add_feature(dev, VIRTIO_NET_F_MAC);
*p = '\0'; *p = '\0';
} else {
p = arg + strlen(arg);
/* None supplied; query the randomly assigned mac. */
get_mac(ipfd, tapif, conf.mac);
} }
/* arg is now either an IP address or a bridge name */ /* arg is now either an IP address or a bridge name */
...@@ -1547,13 +1529,10 @@ static void setup_tun_net(char *arg) ...@@ -1547,13 +1529,10 @@ static void setup_tun_net(char *arg)
/* Set up the tun device. */ /* Set up the tun device. */
configure_device(ipfd, tapif, ip); configure_device(ipfd, tapif, ip);
/* Tell Guest what MAC address to use. */
add_feature(dev, VIRTIO_NET_F_MAC);
add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
/* Expect Guest to handle everything except UFO */ /* Expect Guest to handle everything except UFO */
add_feature(dev, VIRTIO_NET_F_CSUM); add_feature(dev, VIRTIO_NET_F_CSUM);
add_feature(dev, VIRTIO_NET_F_GUEST_CSUM); add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
add_feature(dev, VIRTIO_NET_F_MAC);
add_feature(dev, VIRTIO_NET_F_GUEST_TSO4); add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
add_feature(dev, VIRTIO_NET_F_GUEST_TSO6); add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
add_feature(dev, VIRTIO_NET_F_GUEST_ECN); add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
......
...@@ -42,9 +42,6 @@ config GENERIC_HARDIRQS ...@@ -42,9 +42,6 @@ config GENERIC_HARDIRQS
bool bool
default y default y
config HAVE_GET_USER_PAGES_FAST
def_bool PPC64
config HAVE_SETUP_PER_CPU_AREA config HAVE_SETUP_PER_CPU_AREA
def_bool PPC64 def_bool PPC64
......
...@@ -22,7 +22,6 @@ config X86 ...@@ -22,7 +22,6 @@ config X86
select HAVE_IDE select HAVE_IDE
select HAVE_OPROFILE select HAVE_OPROFILE
select HAVE_IOREMAP_PROT select HAVE_IOREMAP_PROT
select HAVE_GET_USER_PAGES_FAST
select HAVE_KPROBES select HAVE_KPROBES
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_KRETPROBES select HAVE_KRETPROBES
......
obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
pat.o pgtable.o pat.o pgtable.o gup.o
obj-$(CONFIG_HAVE_GET_USER_PAGES_FAST) += gup.o
obj-$(CONFIG_X86_32) += pgtable_32.o obj-$(CONFIG_X86_32) += pgtable_32.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
......
...@@ -322,11 +322,10 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) ...@@ -322,11 +322,10 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
hp->tty = tty; hp->tty = tty;
if (hp->ops->notifier_add)
rc = hp->ops->notifier_add(hp, hp->data);
spin_unlock_irqrestore(&hp->lock, flags); spin_unlock_irqrestore(&hp->lock, flags);
if (hp->ops->notifier_add)
rc = hp->ops->notifier_add(hp, hp->data);
/* /*
* If the notifier fails we return an error. The tty layer * If the notifier fails we return an error. The tty layer
......
...@@ -108,9 +108,8 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr) ...@@ -108,9 +108,8 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
} }
/*:*/ /*:*/
/*M:014 get_pfn is slow; it takes the mmap sem and calls get_user_pages. We /*M:014 get_pfn is slow: we could probably try to grab batches of pages here as
* could probably try to grab batches of pages here as an optimization * an optimization (ie. pre-faulting). :*/
* (ie. pre-faulting). :*/
/*H:350 This routine takes a page number given by the Guest and converts it to /*H:350 This routine takes a page number given by the Guest and converts it to
* an actual, physical page number. It can fail for several reasons: the * an actual, physical page number. It can fail for several reasons: the
...@@ -123,19 +122,13 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr) ...@@ -123,19 +122,13 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
static unsigned long get_pfn(unsigned long virtpfn, int write) static unsigned long get_pfn(unsigned long virtpfn, int write)
{ {
struct page *page; struct page *page;
/* This value indicates failure. */
unsigned long ret = -1UL;
/* get_user_pages() is a complex interface: it gets the "struct /* gup me one page at this address please! */
* vm_area_struct" and "struct page" assocated with a range of pages. if (get_user_pages_fast(virtpfn << PAGE_SHIFT, 1, write, &page) == 1)
* It also needs the task's mmap_sem held, and is not very quick. return page_to_pfn(page);
* It returns the number of pages it got. */
down_read(&current->mm->mmap_sem); /* This value indicates failure. */
if (get_user_pages(current, current->mm, virtpfn << PAGE_SHIFT, return -1UL;
1, write, 1, &page, NULL) == 1)
ret = page_to_pfn(page);
up_read(&current->mm->mmap_sem);
return ret;
} }
/*H:340 Converting a Guest page table entry to a shadow (ie. real) page table /*H:340 Converting a Guest page table entry to a shadow (ie. real) page table
...@@ -174,7 +167,7 @@ static pte_t gpte_to_spte(struct lg_cpu *cpu, pte_t gpte, int write) ...@@ -174,7 +167,7 @@ static pte_t gpte_to_spte(struct lg_cpu *cpu, pte_t gpte, int write)
/*H:460 And to complete the chain, release_pte() looks like this: */ /*H:460 And to complete the chain, release_pte() looks like this: */
static void release_pte(pte_t pte) static void release_pte(pte_t pte)
{ {
/* Remember that get_user_pages() took a reference to the page, in /* Remember that get_user_pages_fast() took a reference to the page, in
* get_pfn()? We have to put it back now. */ * get_pfn()? We have to put it back now. */
if (pte_flags(pte) & _PAGE_PRESENT) if (pte_flags(pte) & _PAGE_PRESENT)
put_page(pfn_to_page(pte_pfn(pte))); put_page(pfn_to_page(pte_pfn(pte)));
......
...@@ -356,6 +356,7 @@ unifdef-y += virtio_balloon.h ...@@ -356,6 +356,7 @@ unifdef-y += virtio_balloon.h
unifdef-y += virtio_console.h unifdef-y += virtio_console.h
unifdef-y += virtio_pci.h unifdef-y += virtio_pci.h
unifdef-y += virtio_ring.h unifdef-y += virtio_ring.h
unifdef-y += virtio_rng.h
unifdef-y += vt.h unifdef-y += vt.h
unifdef-y += wait.h unifdef-y += wait.h
unifdef-y += wanrouter.h unifdef-y += wanrouter.h
......
...@@ -139,6 +139,7 @@ extern initcall_t __con_initcall_start[], __con_initcall_end[]; ...@@ -139,6 +139,7 @@ extern initcall_t __con_initcall_start[], __con_initcall_end[];
extern initcall_t __security_initcall_start[], __security_initcall_end[]; extern initcall_t __security_initcall_start[], __security_initcall_end[];
/* Defined in init/main.c */ /* Defined in init/main.c */
extern int do_one_initcall(initcall_t fn);
extern char __initdata boot_command_line[]; extern char __initdata boot_command_line[];
extern char *saved_command_line; extern char *saved_command_line;
extern unsigned int reset_devices; extern unsigned int reset_devices;
......
...@@ -834,7 +834,6 @@ extern int mprotect_fixup(struct vm_area_struct *vma, ...@@ -834,7 +834,6 @@ extern int mprotect_fixup(struct vm_area_struct *vma,
struct vm_area_struct **pprev, unsigned long start, struct vm_area_struct **pprev, unsigned long start,
unsigned long end, unsigned long newflags); unsigned long end, unsigned long newflags);
#ifdef CONFIG_HAVE_GET_USER_PAGES_FAST
/* /*
* get_user_pages_fast provides equivalent functionality to get_user_pages, * get_user_pages_fast provides equivalent functionality to get_user_pages,
* operating on current and current->mm (force=0 and doesn't return any vmas). * operating on current and current->mm (force=0 and doesn't return any vmas).
...@@ -848,25 +847,6 @@ extern int mprotect_fixup(struct vm_area_struct *vma, ...@@ -848,25 +847,6 @@ extern int mprotect_fixup(struct vm_area_struct *vma,
int get_user_pages_fast(unsigned long start, int nr_pages, int write, int get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct page **pages); struct page **pages);
#else
/*
* Should probably be moved to asm-generic, and architectures can include it if
* they don't implement their own get_user_pages_fast.
*/
#define get_user_pages_fast(start, nr_pages, write, pages) \
({ \
struct mm_struct *mm = current->mm; \
int ret; \
\
down_read(&mm->mmap_sem); \
ret = get_user_pages(current, mm, start, nr_pages, \
write, 0, pages, NULL); \
up_read(&mm->mmap_sem); \
\
ret; \
})
#endif
/* /*
* A callback you can register to apply pressure to ageable caches. * A callback you can register to apply pressure to ageable caches.
* *
......
...@@ -691,7 +691,7 @@ asmlinkage void __init start_kernel(void) ...@@ -691,7 +691,7 @@ asmlinkage void __init start_kernel(void)
rest_init(); rest_init();
} }
static int __initdata initcall_debug; static int initcall_debug;
static int __init initcall_debug_setup(char *str) static int __init initcall_debug_setup(char *str)
{ {
...@@ -700,7 +700,7 @@ static int __init initcall_debug_setup(char *str) ...@@ -700,7 +700,7 @@ static int __init initcall_debug_setup(char *str)
} }
__setup("initcall_debug", initcall_debug_setup); __setup("initcall_debug", initcall_debug_setup);
static void __init do_one_initcall(initcall_t fn) int do_one_initcall(initcall_t fn)
{ {
int count = preempt_count(); int count = preempt_count();
ktime_t t0, t1, delta; ktime_t t0, t1, delta;
...@@ -740,6 +740,8 @@ static void __init do_one_initcall(initcall_t fn) ...@@ -740,6 +740,8 @@ static void __init do_one_initcall(initcall_t fn)
print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn); print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn);
printk(" returned with %s\n", msgbuf); printk(" returned with %s\n", msgbuf);
} }
return result;
} }
......
...@@ -2288,7 +2288,7 @@ sys_init_module(void __user *umod, ...@@ -2288,7 +2288,7 @@ sys_init_module(void __user *umod,
/* Start the module */ /* Start the module */
if (mod->init != NULL) if (mod->init != NULL)
ret = mod->init(); ret = do_one_initcall(mod->init);
if (ret < 0) { if (ret < 0) {
/* Init routine failed: abort. Try to protect us from /* Init routine failed: abort. Try to protect us from
buggy refcounters. */ buggy refcounters. */
......
...@@ -65,7 +65,6 @@ static void ack_state(void) ...@@ -65,7 +65,6 @@ static void ack_state(void)
static int stop_cpu(struct stop_machine_data *smdata) static int stop_cpu(struct stop_machine_data *smdata)
{ {
enum stopmachine_state curstate = STOPMACHINE_NONE; enum stopmachine_state curstate = STOPMACHINE_NONE;
int uninitialized_var(ret);
/* Simple state machine */ /* Simple state machine */
do { do {
......
...@@ -77,9 +77,6 @@ config FLAT_NODE_MEM_MAP ...@@ -77,9 +77,6 @@ config FLAT_NODE_MEM_MAP
def_bool y def_bool y
depends on !SPARSEMEM depends on !SPARSEMEM
config HAVE_GET_USER_PAGES_FAST
bool
# #
# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's # Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
# to represent different areas of memory. This variable allows # to represent different areas of memory. This variable allows
......
...@@ -171,3 +171,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm) ...@@ -171,3 +171,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
mm->unmap_area = arch_unmap_area; mm->unmap_area = arch_unmap_area;
} }
#endif #endif
int __attribute__((weak)) get_user_pages_fast(unsigned long start,
int nr_pages, int write, struct page **pages)
{
struct mm_struct *mm = current->mm;
int ret;
down_read(&mm->mmap_sem);
ret = get_user_pages(current, mm, start, nr_pages,
write, 0, pages, NULL);
up_read(&mm->mmap_sem);
return ret;
}
EXPORT_SYMBOL_GPL(get_user_pages_fast);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment