[Qemu-devel] [PATCH] snapshot=on and cache=off compatibility
This patch allows to use snapshot with disabled host cache (i.e. -drive cache=off,snapshot=on). To do that, memory allocated for snapshot is aligned on a 512 bytes boundary, and read/write uses offset and count aligned on this value. When it is not possible or too complex (for instance for some metadata), the cache is reactivated temporarily. All comments are welcome, Laurent --- block-qcow2.c | 40 +++- block-raw-posix.c | 31 +++ block.c | 35 --- qemu-img.c| 16 vl.c | 11 +-- 5 files changed, 103 insertions(+), 30 deletions(-) Index: qemu/block-raw-posix.c === --- qemu.orig/block-raw-posix.c 2008-01-22 10:12:20.0 +0100 +++ qemu/block-raw-posix.c 2008-01-22 11:10:41.0 +0100 @@ -141,16 +141,39 @@ static int raw_open(BlockDriverState *bs #endif */ +static long raw_save_directio(int fd) +{ +long fd_arg; + +fd_arg = fcntl(fd, F_GETFL); +if ((fd_arg O_DIRECT) == 0) +return 0; +fcntl(fd, F_SETFL, fd_arg ~O_DIRECT); +return fd_arg; +} + +static void raw_restore_directio(int fd, long fd_arg) +{ +if (fd_arg) { +fdatasync(fd); +fcntl(fd, F_SETFL, fd_arg); +} +} + static int raw_pread(BlockDriverState *bs, int64_t offset, uint8_t *buf, int count) { BDRVRawState *s = bs-opaque; +long fd_arg = 0; int ret; ret = fd_open(bs); if (ret 0) return ret; +if ((count 0x1FF) || (offset 0x1FF) || ((long)buf 0x1FF)) +fd_arg = raw_save_directio(s-fd); + if (offset = 0 lseek(s-fd, offset, SEEK_SET) == (off_t)-1) { ++(s-lseek_err_cnt); if(s-lseek_err_cnt = 10) { @@ -159,6 +182,7 @@ static int raw_pread(BlockDriverState *b s-fd, bs-filename, offset, buf, count, bs-total_sectors, errno, strerror(errno)); } +raw_restore_directio(s-fd, fd_arg); return -1; } s-lseek_err_cnt=0; @@ -190,6 +214,7 @@ static int raw_pread(BlockDriverState *b } label__raw_read__success: +raw_restore_directio(s-fd, fd_arg); return ret; } @@ -198,12 +223,16 @@ static int raw_pwrite(BlockDriverState * const uint8_t *buf, int count) { BDRVRawState *s = bs-opaque; +long fd_arg = 0; int ret; ret = fd_open(bs); if (ret 0) return ret; +if ((count 0x1FF) || (offset 0x1FF) || ((long)buf 0x1FF)) +fd_arg = raw_save_directio(s-fd); + if (offset = 0 lseek(s-fd, offset, SEEK_SET) == (off_t)-1) { ++(s-lseek_err_cnt); if(s-lseek_err_cnt) { @@ -212,6 +241,7 @@ static int raw_pwrite(BlockDriverState * s-fd, bs-filename, offset, buf, count, bs-total_sectors, errno, strerror(errno)); } +raw_restore_directio(s-fd, fd_arg); return -1; } s-lseek_err_cnt = 0; @@ -226,6 +256,7 @@ static int raw_pwrite(BlockDriverState * bs-total_sectors, ret, errno, strerror(errno)); label__raw_write__success: +raw_restore_directio(s-fd, fd_arg); return ret; } Index: qemu/vl.c === --- qemu.orig/vl.c 2008-01-22 10:12:20.0 +0100 +++ qemu/vl.c 2008-01-22 10:12:30.0 +0100 @@ -5593,7 +5593,7 @@ struct QEMUFile { when reading */ int buf_index; int buf_size; /* 0 when writing */ -uint8_t buf[IO_BUF_SIZE]; +uint8_t *buf; }; QEMUFile *qemu_fopen(const char *filename, const char *mode) @@ -5629,6 +5629,12 @@ static QEMUFile *qemu_fopen_bdrv(BlockDr f = qemu_mallocz(sizeof(QEMUFile)); if (!f) return NULL; +f-buf = qemu_memalign(512, IO_BUF_SIZE); +if (f-buf == NULL) { +qemu_free(f); +return NULL; +} +memset(f-buf, 0, IO_BUF_SIZE); f-is_file = 0; f-bs = bs; f-is_writable = is_writable; @@ -5682,6 +5688,7 @@ void qemu_fclose(QEMUFile *f) if (f-is_file) { fclose(f-outfile); } +qemu_free(f-buf); qemu_free(f); } @@ -7545,7 +7552,7 @@ static void help(int exitcode) -hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n -cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n -drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n - [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off] + [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n [,cache=on|off]\n use 'file' as a drive image\n -mtdblock file use 'file' as on-board Flash memory image\n Index: qemu/block-qcow2.c
[Qemu-devel] [PATCH] allow setting static slot values for pci devices from the command line
hi, 2 months ago i sent a patch that was called static devfn i described it as a patch that allow setting static value for the devfn due to a bad name that i gave it there was a confusion about this patch, what it really was doing is allowing setting static values for the pci slot, i cleaned this patch again and change some stuff in it to make it more clear and send it now again. this patch make it possible to define from the command line the static slot value for each pci device, it was wrote for addressing a problem that right now qemu devices get their slot value in random way (almost random, by the order in fact) the problem with this is that when adding and removing devices some slot values can be changed for each device, this make at least windows unable to understand what happned to the device and mark it in yellow color. (and will want you to reinstall it) thanks -- woof. diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c index 545901c..9362ae7 100644 --- a/qemu/hw/pci.c +++ b/qemu/hw/pci.c @@ -85,6 +85,9 @@ static int pcibus_load(QEMUFile *f, void *opaque, int version_id) return 0; } +char static_slots[PCI_DEVICES_MAX][64]; +int static_slots_index = 0; + PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, qemu_irq *pic, int devfn_min, int nirq) { @@ -146,6 +149,67 @@ int pci_device_load(PCIDevice *s, QEMUFile *f) return 0; } +int pci_read_static_slot(PCIBus *bus, const char *name) +{ +int i; +int y; +int count; + +for (i = 0; i static_slots_index; i++) { +count = 0; +for (y = 0; y sizeof(static_slots[0]) name[y]; y++) { +if (tolower(static_slots[i][y]) != tolower(name[y])) +continue; +count++; +} +/*if count is y we found slot value for this device name */ +if (count == y y sizeof(static_slots[0]) +static_slots[i][y] == '=') { +int slot; +char *value_buffer; + +static_slots[i][sizeof(static_slots[0]) - 1] = '\0'; +value_buffer = strstr(static_slots[i], =); +if (!value_buffer) +return -1; +value_buffer++; +slot = atoi(value_buffer); +if (slot 0) +return -1; +/* + * check if the slot is already registered in case this pci device + * is registering now not for the first time. + * in this case we increase the value of the slot by one untill + * we find a free slot + * note: you should provide devices we big enougth spaces beteween + * them if you want to register the same devices more than once + */ +for (; slot 32; slot++) +if (!bus-devices[slot * 8]) +return slot; +return -1; +} +} +return -1; +} + +int pci_is_static_slot(int slot) +{ +int i; +char *value_buffer; + +for (i = 0; i static_slots_index; i++) { +static_slots[i][sizeof(static_slots[0]) - 1] = '\0'; +value_buffer = strstr(static_slots[i], =); +if (!value_buffer) +continue; +value_buffer++; +if (slot == atoi(value_buffer)) +return 1; +} +return 0; +} + /* -1 for devfn means auto assign */ PCIDevice *pci_register_device(PCIBus *bus, const char *name, int instance_size, int devfn, @@ -158,13 +222,20 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, return NULL; if (devfn 0) { -for(devfn = bus-devfn_min ; devfn 256; devfn += 8) { -if (!bus-devices[devfn]) -goto found; -} -return NULL; -found: ; +int slot; + +slot = pci_read_static_slot(bus, name); +if (slot 0) { +for(devfn = bus-devfn_min ; devfn 256; devfn += 8) { +if (!bus-devices[devfn] !pci_is_static_slot(devfn / 8)) +goto found; +} +return NULL; +found: ; +} else +devfn = slot * 8; } + pci_dev = qemu_mallocz(instance_size); if (!pci_dev) return NULL; diff --git a/qemu/vl.c b/qemu/vl.c index 756e13d..54ddb9e 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -29,6 +29,7 @@ #include hw/fdc.h #include hw/audiodev.h #include hw/isa.h +#include hw/pci.h #include net.h #include console.h #include sysemu.h @@ -906,6 +907,26 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t); #endif /* _WIN32 */ +static void set_static_slot(const char *optarg) +{ +int i; +extern int static_slots_index; +extern char static_slots[PCI_DEVICES_MAX][64]; + +if (static_slots_index = PCI_DEVICES_MAX) { +fprintf(stderr, Too many static-slots registred\n); +exit(1); +} +pstrcpy(static_slots[static_slots_index], +
[Qemu-devel] PATCH: minor simplification in ide.c
Hi, there is no need to alloc and free a buffer in guess_disk_lchs. io_buffer can be used instead. This slightly simplify the code. ide.diff Description: Binary data
Re: [Qemu-devel] PATCH: minor simplification in ide.c
Le mardi 22 janvier 2008 à 17:14 +0100, Tristan Gingold a écrit : Hi, there is no need to alloc and free a buffer in guess_disk_lchs. io_buffer can be used instead. This slightly simplify the code. I agree. Laurent -- - [EMAIL PROTECTED] -- La perfection est atteinte non quand il ne reste rien à ajouter mais quand il ne reste rien à enlever. Saint Exupéry
[Qemu-devel] Re: qemu softmmu_header.h
Sorry for that. consul at collegeclub was my old spam-get-all account. Now the reply address is valid, (not void yet :). I'm not sure if this post will get through though. Johannes Schindelin [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Hi, On Mon, 21 Jan 2008, C.W. Betts wrote: Builds fine on MinGW gcc 3.4.5 Maybe it was a combination of changes? I don't remember. Just to make sure, I will recompile and test again, but that will have to wait until after work. Ciao, Dscho P.S.: do other posters also get that SMTP error while sending to [EMAIL PROTECTED]
Re: AW: Re: [Qemu-devel] VMport patch
Alexander Graf wrote: On Jan 21, 2008, at 3:41 AM, Anthony Liguori wrote: Mark Williamson wrote: I think it would be great to maintain compatibility with the binary-only versions of the vm tools though. But you're changing the semantics of the x86 instruction set. You potentially break a real operating system. It also eliminates the possibility of nesting with something like kqemu because you can't trap all PIO operations. Maybe have a commandline flag, and have it switched off by default? Or, even better, would be to detect valid vmware tools behaviour and switch it on iff that happened; the default being to behave normally for OSes that aren't running the VMware tools.. There is no way to know for sure that it's vm-tools running. You would have to make use of the cpu option to support it I reckon. I completely agree with the point of breaking x86 semantics is bad. Yes, it is. What is the point in emulating the VMWare interface though, if the only program actually requiring that interface does not work, namely vmware tools, especially the windows version. So as far as I know VMWare uses VMX to run 64-bit code on Intel as well, so there has to be a way to forcefully break the checks. vmmouse uses the vmport interface but runs in ring 0 under Linux so it's not an issue. FWIW, the folks on open-vm-tools-devel have expressed an interest in moving to a different interface then their backdoor interface. Regards, Anthony Liguori Regards, Alex Regards, Anthony Liguori Cheers, Mark Regards, Anthony Liguori Regards, Alex - Ursprüngliche Nachricht - Von: Anthony Liguori [EMAIL PROTECTED] Gesendet: Sonntag, 20. Januar 2008 22:40 An: qemu-devel@nongnu.org Betreff: Re: [Qemu-devel] VMport patch Filip Navara wrote: Hello, the current version of QEMU emulates the VMware backdoor I/O port and it works quite well. Unfortunately it doesn't emulate the VMware behavior of ignoring the I/O permissions when accessing this special port. The attached patch corrects it. It's important to ignore the permissions, so that user mode VMware tools can communicate to the backdoor. = I really dislike that VMware relies on this. It's very hard to implement in kqemu or KVM. I think it would be better to modify open-vm-tools than to modify QEMU. Regards, Anthony Liguori Best regards, Filip Navara
[Qemu-devel] qemu cocoa.m
CVSROOT:/sources/qemu Module name:qemu Changes by: Thiemo Seufer ths 08/01/22 23:25:16 Modified files: . : cocoa.m Log message: Core Graphics support (cocoa.m rewrite), by Mike Kronenberg. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/qemu/cocoa.m?cvsroot=qemur1=1.14r2=1.15
[Qemu-devel] [PATCH] hw/slavio_timer.c user timer limit bit fix
Set limit bit when user timer expires. Clear limit bit when user timer count set. Set ptimer count when user timer count set. Index: hw/slavio_timer.c === RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v retrieving revision 1.28 diff -p -u -r1.28 slavio_timer.c --- hw/slavio_timer.c 1 Jan 2008 17:06:38 - 1.28 +++ hw/slavio_timer.c 23 Jan 2008 02:33:57 - @@ -122,10 +122,9 @@ static void slavio_timer_irq(void *opaqu slavio_timer_get_out(s); DPRINTF(callback: count %x%08x\n, s-counthigh, s-count); -if (!slavio_timer_is_user(s)) { -s-reached = TIMER_REACHED; +s-reached = TIMER_REACHED; +if (!slavio_timer_is_user(s)) qemu_irq_raise(s-irq); -} } static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) @@ -141,7 +140,7 @@ static uint32_t slavio_timer_mem_readl(v if (slavio_timer_is_user(s)) { // read user timer MSW slavio_timer_get_out(s); -ret = s-counthigh; +ret = s-counthigh | s-reached; } else { // read limit // clear irq @@ -155,7 +154,7 @@ static uint32_t slavio_timer_mem_readl(v // of counter (user mode) slavio_timer_get_out(s); if (slavio_timer_is_user(s)) // read user timer LSW -ret = s-count TIMER_COUNT_MASK32; +ret = s-count TIMER_MAX_COUNT64; else // read limit ret = (s-count TIMER_MAX_COUNT32) | s-reached; break; @@ -190,12 +189,19 @@ static void slavio_timer_mem_writel(void switch (saddr) { case TIMER_LIMIT: if (slavio_timer_is_user(s)) { +uint64_t count; // set user counter MSW, reset counter qemu_irq_lower(s-irq); s-limit = TIMER_MAX_COUNT64; -DPRINTF(processor %d user timer reset\n, s-slave_index); -if (s-timer) -ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 1); +s-counthigh = val (TIMER_MAX_COUNT64 32); +s-reached = 0; +count = ((uint64_t)s-counthigh 32) | s-count; +DPRINTF(processor %d user timer set to %016llx\n, s-slave_index, +count); +if (s-timer) { +ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count)); +ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0); +} } else { // set limit, reset counter qemu_irq_lower(s-irq); @@ -210,12 +216,19 @@ static void slavio_timer_mem_writel(void break; case TIMER_COUNTER: if (slavio_timer_is_user(s)) { +uint64_t count; // set user counter LSW, reset counter qemu_irq_lower(s-irq); s-limit = TIMER_MAX_COUNT64; -DPRINTF(processor %d user timer reset\n, s-slave_index); -if (s-timer) -ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 1); +s-count = val TIMER_MAX_COUNT64; +s-reached = 0; +count = ((uint64_t)s-counthigh) 32 | s-count; +DPRINTF(processor %d user timer set to %016llx\n, s-slave_index, +count); +if (s-timer) { +ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count)); +ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0); +} } else DPRINTF(not user timer\n); break;
[Qemu-devel] [PATCH] hw/slavio_timer.c user timer mode change fix
Change ptimer limit only when mode changes. Update timer configuration register user timer bits properly. --- hw/slavio_timer.c.old 2008-01-22 21:35:33.0 -0500 +++ hw/slavio_timer.c 2008-01-22 21:36:13.0 -0500 @@ -198,10 +198,8 @@ static void slavio_timer_mem_writel(void count = ((uint64_t)s-counthigh 32) | s-count; DPRINTF(processor %d user timer set to %016llx\n, s-slave_index, count); -if (s-timer) { +if (s-timer) ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count)); -ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0); -} } else { // set limit, reset counter qemu_irq_lower(s-irq); @@ -225,10 +223,8 @@ static void slavio_timer_mem_writel(void count = ((uint64_t)s-counthigh) 32 | s-count; DPRINTF(processor %d user timer set to %016llx\n, s-slave_index, count); -if (s-timer) { +if (s-timer) ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count)); -ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0); -} } else DPRINTF(not user timer\n); break; @@ -263,22 +259,38 @@ static void slavio_timer_mem_writel(void unsigned int i; for (i = 0; i s-num_slaves; i++) { -if (val (1 i)) { -qemu_irq_lower(s-slave[i]-irq); -s-slave[i]-limit = -1ULL; -} else { -ptimer_stop(s-slave[i]-timer); -} -if ((val (1 i)) != (s-slave_mode (1 i))) { -ptimer_stop(s-slave[i]-timer); -ptimer_set_limit(s-slave[i]-timer, - LIMIT_TO_PERIODS(s-slave[i]-limit), 1); -DPRINTF(processor %d timer changed\n, -s-slave[i]-slave_index); -ptimer_run(s-slave[i]-timer, 0); +unsigned int processor = 1 i; +// check for a change in timer mode for this processor +if ((val processor) != (s-slave_mode processor)) { +if (val processor) { // counter - user timer +qemu_irq_lower(s-slave[i]-irq); +// counters are always running +ptimer_stop(s-slave[i]-timer); +s-slave[i]-running = 0; +// user timer limit is always the same +s-slave[i]-limit = TIMER_MAX_COUNT64; +ptimer_set_limit(s-slave[i]-timer, + LIMIT_TO_PERIODS(s-slave[i]-limit), 1); +// set this processors user timer bit in config +// register +s-slave_mode |= processor; +DPRINTF(processor %d changed from counter to user +timer\n, s-slave[i]-slave_index); +} else { // user timer - counter +// stop the user timer if it is running +if (s-slave[i]-running) +ptimer_stop(s-slave[i]-timer); +// start the counter +ptimer_run(s-slave[i]-timer, 0); +s-slave[i]-running = 1; +// clear this processors user timer bit in config +// register +s-slave_mode = ~processor; +DPRINTF(processor %d changed from user timer to +counter\n, s-slave[i]-slave_index); +} } } -s-slave_mode = val ((1 s-num_slaves) - 1); } else DPRINTF(not system timer\n); break;