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
This commit is contained in:
commit
1c89ac5501
|
@ -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)
|
||||||
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)
|
||||||
/* 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
|
||||||
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
|
||||||
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
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
/*:*/
|
/*:*/
|
||||||
|
|
||||||
/*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)
|
||||||
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(¤t->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(¤t->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)
|
||||||
/*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
|
||||||
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[];
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
__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)
|
||||||
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,
|
||||||
|
|
||||||
/* 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)
|
||||||
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
|
||||||
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
|
||||||
|
|
15
mm/util.c
15
mm/util.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue