From: Jeff D. <jd...@ad...> - 2007-02-21 20:33:08
|
Add some locking to host_ldt_entries to prevent racing when reading LDT information from the host. Also fixed some style violations. Signed-off-by: Jeff Dike <jd...@ad...> -- arch/um/sys-i386/ldt.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) Index: linux-2.6.18-mm/arch/um/sys-i386/ldt.c =================================================================== --- linux-2.6.18-mm.orig/arch/um/sys-i386/ldt.c 2007-01-14 17:29:35.000000000 +1100 +++ linux-2.6.18-mm/arch/um/sys-i386/ldt.c 2007-01-15 17:03:25.000000000 +1100 @@ -7,6 +7,7 @@ #include "linux/slab.h" #include "linux/types.h" #include "linux/errno.h" +#include "linux/spinlock.h" #include "asm/uaccess.h" #include "asm/smp.h" #include "asm/ldt.h" @@ -386,15 +387,20 @@ static long do_modify_ldt_skas(int func, return ret; } -short dummy_list[9] = {0, -1}; -short * host_ldt_entries = NULL; +static DEFINE_SPINLOCK(host_ldt_lock); +static short dummy_list[9] = {0, -1}; +static short * host_ldt_entries = NULL; -void ldt_get_host_info(void) +static void ldt_get_host_info(void) { long ret; struct ldt_entry * ldt; int i, size, k, order; + spin_lock(&host_ldt_lock); + if(host_ldt_entries != NULL) + goto out_unlock; + host_ldt_entries = dummy_list+1; for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++); @@ -402,8 +408,9 @@ void ldt_get_host_info(void) ldt = (struct ldt_entry *) __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); if(ldt == NULL) { - printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n"); - return; + printk("ldt_get_host_info: couldn't allocate buffer for host " + "ldt\n"); + goto out_unlock; } ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE); @@ -428,7 +435,8 @@ void ldt_get_host_info(void) size = (size + 1) * sizeof(dummy_list[0]); host_ldt_entries = kmalloc(size, GFP_KERNEL); if(host_ldt_entries == NULL) { - printk("ldt_get_host_info: couldn't allocate host ldt list\n"); + printk("ldt_get_host_info: couldn't allocate host ldt " + "list\n"); goto out_free; } } @@ -442,6 +450,8 @@ void ldt_get_host_info(void) out_free: free_pages((unsigned long)ldt, order); +out_unlock: + spin_unlock(&host_ldt_lock); } long init_new_ldt(struct mmu_context_skas * new_mm, @@ -480,8 +490,7 @@ long init_new_ldt(struct mmu_context_ska * inherited from the host. All ldt-entries found * will be reset in the following loop */ - if(host_ldt_entries == NULL) - ldt_get_host_info(); + ldt_get_host_info(); for(num_p=host_ldt_entries; *num_p != -1; num_p++){ desc.entry_number = *num_p; err = write_ldt_entry(&new_mm->id, 1, &desc, @@ -560,6 +569,6 @@ void free_ldt(struct mmu_context_skas * int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) { - return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, - ptr, bytecount)); + return CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, + ptr, bytecount); } |
From: Blaisorblade <bla...@ya...> - 2007-02-21 22:40:47
|
On Wednesday 21 February 2007 21:25, Jeff Dike wrote: > Add some locking to host_ldt_entries to prevent racing when reading > LDT information from the host. Please remove GFP_KERNEL allocation under spin_lock - simplest way is using a mutex unless this can be important for performance. > @@ -386,15 +387,20 @@ static long do_modify_ldt_skas(int func, > return ret; > } > > -short dummy_list[9] = {0, -1}; > -short * host_ldt_entries = NULL; > +static DEFINE_SPINLOCK(host_ldt_lock); > +static short dummy_list[9] = {0, -1}; > +static short * host_ldt_entries = NULL; > > -void ldt_get_host_info(void) > +static void ldt_get_host_info(void) > { > long ret; > struct ldt_entry * ldt; > int i, size, k, order; > > + spin_lock(&host_ldt_lock); > + if(host_ldt_entries != NULL) > + goto out_unlock; > + > host_ldt_entries = dummy_list+1; > > for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++); > @@ -402,8 +408,9 @@ void ldt_get_host_info(void) > ldt = (struct ldt_entry *) > __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); > if(ldt == NULL) { > - printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n"); > - return; > + printk("ldt_get_host_info: couldn't allocate buffer for host " > + "ldt\n"); > + goto out_unlock; > } > > ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE); > @@ -428,7 +435,8 @@ void ldt_get_host_info(void) > size = (size + 1) * sizeof(dummy_list[0]); > host_ldt_entries = kmalloc(size, GFP_KERNEL); > if(host_ldt_entries == NULL) { > - printk("ldt_get_host_info: couldn't allocate host ldt list\n"); > + printk("ldt_get_host_info: couldn't allocate host ldt " > + "list\n"); > goto out_free; > } > } > @@ -442,6 +450,8 @@ void ldt_get_host_info(void) > > out_free: > free_pages((unsigned long)ldt, order); > +out_unlock: > + spin_unlock(&host_ldt_lock); > } > > long init_new_ldt(struct mmu_context_skas * new_mm, > @@ -480,8 +490,7 @@ long init_new_ldt(struct mmu_context_ska > * inherited from the host. All ldt-entries found > * will be reset in the following loop > */ > - if(host_ldt_entries == NULL) > - ldt_get_host_info(); > + ldt_get_host_info(); > for(num_p=host_ldt_entries; *num_p != -1; num_p++){ > desc.entry_number = *num_p; > err = write_ldt_entry(&new_mm->id, 1, &desc, > @@ -560,6 +569,6 @@ void free_ldt(struct mmu_context_skas * > > int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) > { > - return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, > - ptr, bytecount)); > + return CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, > + ptr, bytecount); > } > > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share > your opinions on IT & business topics through brief surveys-and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > User-mode-linux-devel mailing list > Use...@li... > https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel -- Inform me of my mistakes, so I can add them to my list! Paolo Giarrusso, aka Blaisorblade http://www.user-mode-linux.org/~blaisorblade Chiacchiera con i tuoi amici in tempo reale! http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com |
From: Jeff D. <jd...@ad...> - 2007-02-22 17:50:54
|
On Wed, Feb 21, 2007 at 11:40:28PM +0100, Blaisorblade wrote: > Please remove GFP_KERNEL allocation under spin_lock Nice spotting - I'll redo the patch. Jeff -- Work email - jdike at linux dot intel dot com |