Commit 0c0cb6a2 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

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: default avatarAnthony Liguori <aliguori@amazon.com>
parents 3c88da3c 33f373d7
Loading
Loading
Loading
Loading
+47 −12
Original line number Diff line number Diff line
@@ -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;
}
+21 −9
Original line number Diff line number Diff line
@@ -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;
+0 −2
Original line number Diff line number Diff line
@@ -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",
+3 −3
Original line number Diff line number Diff line
@@ -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;
+0 −4
Original line number Diff line number Diff line
@@ -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;