Merge remote-tracking branch 'qemu-kvm/uq/master' into staging
# By Alex Williamson (1) and others # Via Paolo Bonzini * qemu-kvm/uq/master: target-i386: fix cpuid leaf 0x0d qemu: mempath: prefault pages manually (v4) kvm: Query KVM for available memory slots Message-id: 1386345276-9803-1-git-send-email-pbonzini@redhat.com Signed-off-by: Anthony Liguori <aliguori@amazon.com>
This commit is contained in:
		
						commit
						0c0cb6a237
					
				
							
								
								
									
										59
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								exec.c
									
									
									
									
									
								
							| @ -904,6 +904,13 @@ static long gethugepagesize(const char *path) | ||||
|     return fs.f_bsize; | ||||
| } | ||||
| 
 | ||||
| static sigjmp_buf sigjump; | ||||
| 
 | ||||
| static void sigbus_handler(int signal) | ||||
| { | ||||
|     siglongjmp(sigjump, 1); | ||||
| } | ||||
| 
 | ||||
| static void *file_ram_alloc(RAMBlock *block, | ||||
|                             ram_addr_t memory, | ||||
|                             const char *path) | ||||
| @ -913,9 +920,6 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|     char *c; | ||||
|     void *area; | ||||
|     int fd; | ||||
| #ifdef MAP_POPULATE | ||||
|     int flags; | ||||
| #endif | ||||
|     unsigned long hpagesize; | ||||
| 
 | ||||
|     hpagesize = gethugepagesize(path); | ||||
| @ -963,21 +967,52 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|     if (ftruncate(fd, memory)) | ||||
|         perror("ftruncate"); | ||||
| 
 | ||||
| #ifdef MAP_POPULATE | ||||
|     /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
 | ||||
|      * MAP_PRIVATE is requested.  For mem_prealloc we mmap as MAP_SHARED | ||||
|      * to sidestep this quirk. | ||||
|      */ | ||||
|     flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE; | ||||
|     area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0); | ||||
| #else | ||||
|     area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | ||||
| #endif | ||||
|     if (area == MAP_FAILED) { | ||||
|         perror("file_ram_alloc: can't mmap RAM pages"); | ||||
|         close(fd); | ||||
|         return (NULL); | ||||
|     } | ||||
| 
 | ||||
|     if (mem_prealloc) { | ||||
|         int ret, i; | ||||
|         struct sigaction act, oldact; | ||||
|         sigset_t set, oldset; | ||||
| 
 | ||||
|         memset(&act, 0, sizeof(act)); | ||||
|         act.sa_handler = &sigbus_handler; | ||||
|         act.sa_flags = 0; | ||||
| 
 | ||||
|         ret = sigaction(SIGBUS, &act, &oldact); | ||||
|         if (ret) { | ||||
|             perror("file_ram_alloc: failed to install signal handler"); | ||||
|             exit(1); | ||||
|         } | ||||
| 
 | ||||
|         /* unblock SIGBUS */ | ||||
|         sigemptyset(&set); | ||||
|         sigaddset(&set, SIGBUS); | ||||
|         pthread_sigmask(SIG_UNBLOCK, &set, &oldset); | ||||
| 
 | ||||
|         if (sigsetjmp(sigjump, 1)) { | ||||
|             fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n"); | ||||
|             exit(1); | ||||
|         } | ||||
| 
 | ||||
|         /* MAP_POPULATE silently ignores failures */ | ||||
|         for (i = 0; i < (memory/hpagesize)-1; i++) { | ||||
|             memset(area + (hpagesize*i), 0, 1); | ||||
|         } | ||||
| 
 | ||||
|         ret = sigaction(SIGBUS, &oldact, NULL); | ||||
|         if (ret) { | ||||
|             perror("file_ram_alloc: failed to reinstall signal handler"); | ||||
|             exit(1); | ||||
|         } | ||||
| 
 | ||||
|         pthread_sigmask(SIG_SETMASK, &oldset, NULL); | ||||
|     } | ||||
| 
 | ||||
|     block->fd = fd; | ||||
|     return area; | ||||
| } | ||||
|  | ||||
							
								
								
									
										30
									
								
								kvm-all.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								kvm-all.c
									
									
									
									
									
								
							| @ -72,7 +72,8 @@ typedef struct kvm_dirty_log KVMDirtyLog; | ||||
| 
 | ||||
| struct KVMState | ||||
| { | ||||
|     KVMSlot slots[32]; | ||||
|     KVMSlot *slots; | ||||
|     int nr_slots; | ||||
|     int fd; | ||||
|     int vmfd; | ||||
|     int coalesced_mmio; | ||||
| @ -125,7 +126,7 @@ static KVMSlot *kvm_alloc_slot(KVMState *s) | ||||
| { | ||||
|     int i; | ||||
| 
 | ||||
|     for (i = 0; i < ARRAY_SIZE(s->slots); i++) { | ||||
|     for (i = 0; i < s->nr_slots; i++) { | ||||
|         if (s->slots[i].memory_size == 0) { | ||||
|             return &s->slots[i]; | ||||
|         } | ||||
| @ -141,7 +142,7 @@ static KVMSlot *kvm_lookup_matching_slot(KVMState *s, | ||||
| { | ||||
|     int i; | ||||
| 
 | ||||
|     for (i = 0; i < ARRAY_SIZE(s->slots); i++) { | ||||
|     for (i = 0; i < s->nr_slots; i++) { | ||||
|         KVMSlot *mem = &s->slots[i]; | ||||
| 
 | ||||
|         if (start_addr == mem->start_addr && | ||||
| @ -163,7 +164,7 @@ static KVMSlot *kvm_lookup_overlapping_slot(KVMState *s, | ||||
|     KVMSlot *found = NULL; | ||||
|     int i; | ||||
| 
 | ||||
|     for (i = 0; i < ARRAY_SIZE(s->slots); i++) { | ||||
|     for (i = 0; i < s->nr_slots; i++) { | ||||
|         KVMSlot *mem = &s->slots[i]; | ||||
| 
 | ||||
|         if (mem->memory_size == 0 || | ||||
| @ -185,7 +186,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram, | ||||
| { | ||||
|     int i; | ||||
| 
 | ||||
|     for (i = 0; i < ARRAY_SIZE(s->slots); i++) { | ||||
|     for (i = 0; i < s->nr_slots; i++) { | ||||
|         KVMSlot *mem = &s->slots[i]; | ||||
| 
 | ||||
|         if (ram >= mem->ram && ram < mem->ram + mem->memory_size) { | ||||
| @ -357,7 +358,7 @@ static int kvm_set_migration_log(int enable) | ||||
| 
 | ||||
|     s->migration_log = enable; | ||||
| 
 | ||||
|     for (i = 0; i < ARRAY_SIZE(s->slots); i++) { | ||||
|     for (i = 0; i < s->nr_slots; i++) { | ||||
|         mem = &s->slots[i]; | ||||
| 
 | ||||
|         if (!mem->memory_size) { | ||||
| @ -1383,9 +1384,6 @@ int kvm_init(void) | ||||
| #ifdef KVM_CAP_SET_GUEST_DEBUG | ||||
|     QTAILQ_INIT(&s->kvm_sw_breakpoints); | ||||
| #endif | ||||
|     for (i = 0; i < ARRAY_SIZE(s->slots); i++) { | ||||
|         s->slots[i].slot = i; | ||||
|     } | ||||
|     s->vmfd = -1; | ||||
|     s->fd = qemu_open("/dev/kvm", O_RDWR); | ||||
|     if (s->fd == -1) { | ||||
| @ -1409,6 +1407,19 @@ int kvm_init(void) | ||||
|         goto err; | ||||
|     } | ||||
| 
 | ||||
|     s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS); | ||||
| 
 | ||||
|     /* If unspecified, use the default value */ | ||||
|     if (!s->nr_slots) { | ||||
|         s->nr_slots = 32; | ||||
|     } | ||||
| 
 | ||||
|     s->slots = g_malloc0(s->nr_slots * sizeof(KVMSlot)); | ||||
| 
 | ||||
|     for (i = 0; i < s->nr_slots; i++) { | ||||
|         s->slots[i].slot = i; | ||||
|     } | ||||
| 
 | ||||
|     /* check the vcpu limits */ | ||||
|     soft_vcpus_limit = kvm_recommended_vcpus(s); | ||||
|     hard_vcpus_limit = kvm_max_vcpus(s); | ||||
| @ -1527,6 +1538,7 @@ err: | ||||
|     if (s->fd != -1) { | ||||
|         close(s->fd); | ||||
|     } | ||||
|     g_free(s->slots); | ||||
|     g_free(s); | ||||
| 
 | ||||
|     return ret; | ||||
|  | ||||
| @ -228,7 +228,6 @@ STEXI | ||||
| Allocate guest RAM from a temporarily created file in @var{path}. | ||||
| ETEXI | ||||
| 
 | ||||
| #ifdef MAP_POPULATE | ||||
| DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc, | ||||
|     "-mem-prealloc   preallocate guest memory (use with -mem-path)\n", | ||||
|     QEMU_ARCH_ALL) | ||||
| @ -237,7 +236,6 @@ STEXI | ||||
| @findex -mem-prealloc | ||||
| Preallocate memory when using -mem-path. | ||||
| ETEXI | ||||
| #endif | ||||
| 
 | ||||
| DEF("k", HAS_ARG, QEMU_OPTION_k, | ||||
|     "-k language     use keyboard layout (for example 'fr' for French)\n", | ||||
|  | ||||
| @ -335,7 +335,7 @@ typedef struct ExtSaveArea { | ||||
| 
 | ||||
| static const ExtSaveArea ext_save_areas[] = { | ||||
|     [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX, | ||||
|             .offset = 0x100, .size = 0x240 }, | ||||
|             .offset = 0x240, .size = 0x100 }, | ||||
| }; | ||||
| 
 | ||||
| const char *get_register_name_32(unsigned int reg) | ||||
| @ -2227,8 +2227,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, | ||||
|             const ExtSaveArea *esa = &ext_save_areas[count]; | ||||
|             if ((env->features[esa->feature] & esa->bits) == esa->bits && | ||||
|                 (kvm_mask & (1 << count)) != 0) { | ||||
|                 *eax = esa->offset; | ||||
|                 *ebx = esa->size; | ||||
|                 *eax = esa->size; | ||||
|                 *ebx = esa->offset; | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
|  | ||||
							
								
								
									
										4
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								vl.c
									
									
									
									
									
								
							| @ -188,9 +188,7 @@ static int display_remote; | ||||
| const char* keyboard_layout = NULL; | ||||
| ram_addr_t ram_size; | ||||
| const char *mem_path = NULL; | ||||
| #ifdef MAP_POPULATE | ||||
| int mem_prealloc = 0; /* force preallocation of physical target memory */ | ||||
| #endif | ||||
| int nb_nics; | ||||
| NICInfo nd_table[MAX_NICS]; | ||||
| int autostart; | ||||
| @ -3211,11 +3209,9 @@ int main(int argc, char **argv, char **envp) | ||||
|             case QEMU_OPTION_mempath: | ||||
|                 mem_path = optarg; | ||||
|                 break; | ||||
| #ifdef MAP_POPULATE | ||||
|             case QEMU_OPTION_mem_prealloc: | ||||
|                 mem_prealloc = 1; | ||||
|                 break; | ||||
| #endif | ||||
|             case QEMU_OPTION_d: | ||||
|                 log_mask = optarg; | ||||
|                 break; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Anthony Liguori
						Anthony Liguori