From 64f5020c86c2e2c7eab69b117d9fc2d577996c2d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mar 14 2013 14:32:48 +0000 Subject: Merge branch 'f18' into el6 Conflicts: qemu.spec --- diff --git a/0001-target-xtensa-convert-host-errno-values-to-guest.patch b/0001-target-xtensa-convert-host-errno-values-to-guest.patch index 7eb51fe..93d4708 100644 --- a/0001-target-xtensa-convert-host-errno-values-to-guest.patch +++ b/0001-target-xtensa-convert-host-errno-values-to-guest.patch @@ -178,6 +178,3 @@ index 6d001c2..e745bef 100644 break; } } --- -1.7.12.1 - diff --git a/0002-target-cris-Fix-buffer-overflow.patch b/0002-target-cris-Fix-buffer-overflow.patch index 79640b1..6614697 100644 --- a/0002-target-cris-Fix-buffer-overflow.patch +++ b/0002-target-cris-Fix-buffer-overflow.patch @@ -30,6 +30,3 @@ index 1ad9ec7..ad31877 100644 for (i = 0; i < 16; i++) { cpu_fprintf(f, "s%2.2d=%8.8x ", i, env->sregs[srs][i]); --- -1.7.12.1 - diff --git a/0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch b/0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch index b5fdd18..70cfd9a 100644 --- a/0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch +++ b/0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch @@ -59,6 +59,3 @@ index e745bef..52be07a 100644 }; if (host_errno == 0) { --- -1.7.12.1 - diff --git a/0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch b/0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch index e6095aa..439dcfa 100644 --- a/0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch +++ b/0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch @@ -128,6 +128,3 @@ index 9c64ef8..f4b62a5 100644 env->fsr |= FSR_FCC1 << FS; \ break; \ default: \ --- -1.7.12.1 - diff --git a/0005-target-s390x-fix-style.patch b/0005-target-s390x-fix-style.patch index 0f0a63e..f4c8187 100644 --- a/0005-target-s390x-fix-style.patch +++ b/0005-target-s390x-fix-style.patch @@ -1598,6 +1598,3 @@ index abc35dd..195e93e 100644 } else { env->regs[r1] = ret; } --- -1.7.12.1 - diff --git a/0006-target-s390x-split-FPU-ops.patch b/0006-target-s390x-split-FPU-ops.patch index 5aabf6f..5b8ee02 100644 --- a/0006-target-s390x-split-FPU-ops.patch +++ b/0006-target-s390x-split-FPU-ops.patch @@ -1751,6 +1751,3 @@ index 1c1baf5..c370df3 100644 tcg_temp_free_i32(tmp32); break; case 0xd: /* DEB R1,D2(X2,B2) [RXE] */ --- -1.7.12.1 - diff --git a/0007-target-s390x-split-condition-code-helpers.patch b/0007-target-s390x-split-condition-code-helpers.patch index 33ddc67..1d1bb40 100644 --- a/0007-target-s390x-split-condition-code-helpers.patch +++ b/0007-target-s390x-split-condition-code-helpers.patch @@ -1153,6 +1153,3 @@ index 270bf14..eced890 100644 /* invalidate pte */ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr) { --- -1.7.12.1 - diff --git a/0008-target-s390x-split-integer-helpers.patch b/0008-target-s390x-split-integer-helpers.patch index 5610e6d..4e51bd7 100644 --- a/0008-target-s390x-split-integer-helpers.patch +++ b/0008-target-s390x-split-integer-helpers.patch @@ -439,6 +439,3 @@ index eced890..3b8b997 100644 void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src) { int len_dest = len >> 4; --- -1.7.12.1 - diff --git a/0009-target-s390x-split-memory-access-helpers.patch b/0009-target-s390x-split-memory-access-helpers.patch index 0e87180..0c5ddb8 100644 --- a/0009-target-s390x-split-memory-access-helpers.patch +++ b/0009-target-s390x-split-memory-access-helpers.patch @@ -2419,6 +2419,3 @@ index 3b8b997..bb8dbf5 100644 -} - #endif --- -1.7.12.1 - diff --git a/0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch b/0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch index e96aa52..fe5c597 100644 --- a/0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch +++ b/0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch @@ -919,6 +919,3 @@ index bb8dbf5..0000000 - return cc; -} -#endif --- -1.7.12.1 - diff --git a/0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch b/0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch index 597face..4c29852 100644 --- a/0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch +++ b/0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch @@ -1213,6 +1213,3 @@ index c370df3..b1f2071 100644 set_cc_static(s); tcg_temp_free_i32(tmp32_1); tcg_temp_free_i32(tmp32_2); --- -1.7.12.1 - diff --git a/0012-target-s390x-avoid-AREG0-for-integer-helpers.patch b/0012-target-s390x-avoid-AREG0-for-integer-helpers.patch index 379d0f7..e44752a 100644 --- a/0012-target-s390x-avoid-AREG0-for-integer-helpers.patch +++ b/0012-target-s390x-avoid-AREG0-for-integer-helpers.patch @@ -197,6 +197,3 @@ index b1f2071..2a61e92 100644 set_cc_static(s); tcg_temp_free_i32(tmp32_1); tcg_temp_free_i32(tmp32_2); --- -1.7.12.1 - diff --git a/0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch b/0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch index eddecbb..eee6b96 100644 --- a/0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch +++ b/0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch @@ -185,6 +185,3 @@ index 2a61e92..1d87272 100644 tcg_temp_free_i64(tmp); tcg_temp_free_i64(tmp2); tcg_temp_free_i64(tmp3); --- -1.7.12.1 - diff --git a/0014-target-s390x-avoid-AREG0-for-misc-helpers.patch b/0014-target-s390x-avoid-AREG0-for-misc-helpers.patch index 11ff8fb..84dc387 100644 --- a/0014-target-s390x-avoid-AREG0-for-misc-helpers.patch +++ b/0014-target-s390x-avoid-AREG0-for-misc-helpers.patch @@ -406,6 +406,3 @@ index 1d87272..0c61e63 100644 set_cc_static(s); tcg_temp_free_i64(tmp); tcg_temp_free_i64(tmp2); --- -1.7.12.1 - diff --git a/0015-target-s390x-switch-to-AREG0-free-mode.patch b/0015-target-s390x-switch-to-AREG0-free-mode.patch index 2329cb2..c01f6d1 100644 --- a/0015-target-s390x-switch-to-AREG0-free-mode.patch +++ b/0015-target-s390x-switch-to-AREG0-free-mode.patch @@ -1579,6 +1579,3 @@ index 0c61e63..66119cd 100644 } set_cc_static(s); tcg_temp_free_i64(tmp); --- -1.7.12.1 - diff --git a/0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch b/0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch index 96c305e..3330efb 100644 --- a/0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch +++ b/0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch @@ -59,6 +59,3 @@ index 04662c1..99b5339 100644 TCG_AREG0); #endif tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]); --- -1.7.12.1 - diff --git a/0017-target-arm-Fix-potential-buffer-overflow.patch b/0017-target-arm-Fix-potential-buffer-overflow.patch index 6b9726e..2f008b5 100644 --- a/0017-target-arm-Fix-potential-buffer-overflow.patch +++ b/0017-target-arm-Fix-potential-buffer-overflow.patch @@ -42,6 +42,3 @@ index dceaa95..e27df96 100644 return EXCP_UDEF; } env->cp15.c6_region[ri->crm] = value; --- -1.7.12.1 - diff --git a/0018-tcg-optimize-split-expression-simplification.patch b/0018-tcg-optimize-split-expression-simplification.patch index 0dcd9b0..d45fc9b 100644 --- a/0018-tcg-optimize-split-expression-simplification.patch +++ b/0018-tcg-optimize-split-expression-simplification.patch @@ -52,6 +52,3 @@ index 9c65474..63f970d 100644 CASE_OP_32_64(or): CASE_OP_32_64(and): if (args[1] == args[2]) { --- -1.7.12.1 - diff --git a/0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch b/0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch index 4f9dd62..a11a168 100644 --- a/0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch +++ b/0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch @@ -25,6 +25,3 @@ index 63f970d..0db849e 100644 if (temps[args[1]].state == TCG_TEMP_CONST) { /* Proceed with possible constant folding. */ break; --- -1.7.12.1 - diff --git a/0020-tcg-optimize-simplify-and-r-a-0-cases.patch b/0020-tcg-optimize-simplify-and-r-a-0-cases.patch index e609e66..1c829c9 100644 --- a/0020-tcg-optimize-simplify-and-r-a-0-cases.patch +++ b/0020-tcg-optimize-simplify-and-r-a-0-cases.patch @@ -24,6 +24,3 @@ index 0db849e..c12cb2b 100644 CASE_OP_32_64(mul): if ((temps[args[2]].state == TCG_TEMP_CONST && temps[args[2]].val == 0)) { --- -1.7.12.1 - diff --git a/0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch b/0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch index d77bf30..02d8ee2 100644 --- a/0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch +++ b/0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch @@ -43,6 +43,3 @@ index c12cb2b..1698ba3 100644 /* Simplify expression for "op r, a, 0 => mov r, a" cases */ switch (op) { CASE_OP_32_64(add): --- -1.7.12.1 - diff --git a/0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch b/0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch index 19135ee..d4d17d6 100644 --- a/0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch +++ b/0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch @@ -44,6 +44,3 @@ index 1698ba3..7debc8a 100644 default: break; } --- -1.7.12.1 - diff --git a/0023-tcg-optimize-add-constant-folding-for-setcond.patch b/0023-tcg-optimize-add-constant-folding-for-setcond.patch index 0968e1e..cfe240a 100644 --- a/0023-tcg-optimize-add-constant-folding-for-setcond.patch +++ b/0023-tcg-optimize-add-constant-folding-for-setcond.patch @@ -109,6 +109,3 @@ index 7debc8a..1cb1f36 100644 case INDEX_op_call: nb_call_args = (args[0] >> 16) + (args[0] & 0xffff); if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) { --- -1.7.12.1 - diff --git a/0024-tcg-optimize-add-constant-folding-for-brcond.patch b/0024-tcg-optimize-add-constant-folding-for-brcond.patch index 0b4c73b..876f86f 100644 --- a/0024-tcg-optimize-add-constant-folding-for-brcond.patch +++ b/0024-tcg-optimize-add-constant-folding-for-brcond.patch @@ -55,6 +55,3 @@ index 1cb1f36..156e8d9 100644 memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); for (i = 0; i < def->nb_args; i++) { *gen_args = *args; --- -1.7.12.1 - diff --git a/0025-tcg-optimize-fix-if-else-break-coding-style.patch b/0025-tcg-optimize-fix-if-else-break-coding-style.patch index ef77b6e..ab070ff 100644 --- a/0025-tcg-optimize-fix-if-else-break-coding-style.patch +++ b/0025-tcg-optimize-fix-if-else-break-coding-style.patch @@ -139,6 +139,3 @@ index 156e8d9..fba0ed9 100644 case INDEX_op_call: nb_call_args = (args[0] >> 16) + (args[0] & 0xffff); if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) { --- -1.7.12.1 - diff --git a/0026-target-s390x-avoid-cpu_single_env.patch b/0026-target-s390x-avoid-cpu_single_env.patch index 2b3e6a4..9914968 100644 --- a/0026-target-s390x-avoid-cpu_single_env.patch +++ b/0026-target-s390x-avoid-cpu_single_env.patch @@ -1332,6 +1332,3 @@ index 66119cd..3214783 100644 num_insns++; if (env->singlestep_enabled) { --- -1.7.12.1 - diff --git a/0027-target-lm32-switch-to-AREG0-free-mode.patch b/0027-target-lm32-switch-to-AREG0-free-mode.patch index 9a92a12..43582fd 100644 --- a/0027-target-lm32-switch-to-AREG0-free-mode.patch +++ b/0027-target-lm32-switch-to-AREG0-free-mode.patch @@ -277,6 +277,3 @@ index 872a2ba..5f6dcba 100644 dc->pc += 4; num_insns++; --- -1.7.12.1 - diff --git a/0028-target-m68k-switch-to-AREG0-free-mode.patch b/0028-target-m68k-switch-to-AREG0-free-mode.patch index 220b78d..48eba15 100644 --- a/0028-target-m68k-switch-to-AREG0-free-mode.patch +++ b/0028-target-m68k-switch-to-AREG0-free-mode.patch @@ -497,6 +497,3 @@ index 9fc1e31..10bb303 100644 } else { switch(dc->is_jmp) { case DISAS_NEXT: --- -1.7.12.1 - diff --git a/0029-target-m68k-avoid-using-cpu_single_env.patch b/0029-target-m68k-avoid-using-cpu_single_env.patch index 871bbe8..5a8538b 100644 --- a/0029-target-m68k-avoid-using-cpu_single_env.patch +++ b/0029-target-m68k-avoid-using-cpu_single_env.patch @@ -896,6 +896,3 @@ index 10bb303..fb707f2 100644 } /* generate intermediate code for basic block 'tb'. */ --- -1.7.12.1 - diff --git a/0030-target-unicore32-switch-to-AREG0-free-mode.patch b/0030-target-unicore32-switch-to-AREG0-free-mode.patch index 4880417..ff07552 100644 --- a/0030-target-unicore32-switch-to-AREG0-free-mode.patch +++ b/0030-target-unicore32-switch-to-AREG0-free-mode.patch @@ -432,6 +432,3 @@ index 188bf8c..b786a6b 100644 s->pc += 4; /* UniCore instructions class: --- -1.7.12.1 - diff --git a/0031-target-arm-convert-void-helpers.patch b/0031-target-arm-convert-void-helpers.patch index 3ea4640..30e06c8 100644 --- a/0031-target-arm-convert-void-helpers.patch +++ b/0031-target-arm-convert-void-helpers.patch @@ -176,6 +176,3 @@ index edef79a..6f651d9 100644 break; case DISAS_SWI: gen_exception(EXCP_SWI); --- -1.7.12.1 - diff --git a/0032-target-arm-convert-remaining-helpers.patch b/0032-target-arm-convert-remaining-helpers.patch index 73dd928..0246b94 100644 --- a/0032-target-arm-convert-remaining-helpers.patch +++ b/0032-target-arm-convert-remaining-helpers.patch @@ -816,6 +816,3 @@ index 6f651d9..9ae3b26 100644 rd = 16; break; case 0xc: /* orr */ --- -1.7.12.1 - diff --git a/0033-target-arm-final-conversion-to-AREG0-free-mode.patch b/0033-target-arm-final-conversion-to-AREG0-free-mode.patch index 8a83359..8883ff4 100644 --- a/0033-target-arm-final-conversion-to-AREG0-free-mode.patch +++ b/0033-target-arm-final-conversion-to-AREG0-free-mode.patch @@ -174,6 +174,3 @@ index 9ae3b26..f4b447a 100644 s->pc += 2; switch (insn >> 12) { --- -1.7.12.1 - diff --git a/0034-target-microblaze-switch-to-AREG0-free-mode.patch b/0034-target-microblaze-switch-to-AREG0-free-mode.patch index fea6bb8..f7dd13f 100644 --- a/0034-target-microblaze-switch-to-AREG0-free-mode.patch +++ b/0034-target-microblaze-switch-to-AREG0-free-mode.patch @@ -710,6 +710,3 @@ index 7470149..9c7d77f 100644 tcg_temp_free_i32(tmp); } else { switch(dc->is_jmp) { --- -1.7.12.1 - diff --git a/0035-target-cris-Avoid-AREG0-for-helpers.patch b/0035-target-cris-Avoid-AREG0-for-helpers.patch index 9314afb..e217da2 100644 --- a/0035-target-cris-Avoid-AREG0-for-helpers.patch +++ b/0035-target-cris-Avoid-AREG0-for-helpers.patch @@ -518,6 +518,3 @@ index 3629629..9a39c6a 100644 cpu_R[dc->src], cpu_PR[PR_CCS]); break; case CRISV10_REG_DSTEP: --- -1.7.12.1 - diff --git a/0036-target-cris-Switch-to-AREG0-free-mode.patch b/0036-target-cris-Switch-to-AREG0-free-mode.patch index 1464e22..bd2f054 100644 --- a/0036-target-cris-Switch-to-AREG0-free-mode.patch +++ b/0036-target-cris-Switch-to-AREG0-free-mode.patch @@ -1533,6 +1533,3 @@ index 9a39c6a..d2cca89 100644 break; } --- -1.7.12.1 - diff --git a/0037-target-sh4-switch-to-AREG0-free-mode.patch b/0037-target-sh4-switch-to-AREG0-free-mode.patch index dbbffb0..cb9d0a7 100644 --- a/0037-target-sh4-switch-to-AREG0-free-mode.patch +++ b/0037-target-sh4-switch-to-AREG0-free-mode.patch @@ -1055,6 +1055,3 @@ index 6532ad2..d05c74c 100644 } else { switch (ctx.bstate) { case BS_STOP: --- -1.7.12.1 - diff --git a/0038-target-mips-switch-to-AREG0-free-mode.patch b/0038-target-mips-switch-to-AREG0-free-mode.patch index 6c8ea5a..51616fb 100644 --- a/0038-target-mips-switch-to-AREG0-free-mode.patch +++ b/0038-target-mips-switch-to-AREG0-free-mode.patch @@ -6331,6 +6331,3 @@ index b293419..7ab769f 100644 } else { switch (ctx.bstate) { case BS_STOP: --- -1.7.12.1 - diff --git a/0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch b/0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch index 72c61e8..cbd9b59 100644 --- a/0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch +++ b/0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch @@ -1678,6 +1678,3 @@ index b9ea9dd..ef9b172 100644 #if defined(DEBUG_SIGNAL) qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", pc, address, is_write, *(unsigned long *)old_set); --- -1.7.12.1 - diff --git a/0040-tcg-i386-allow-constants-in-load-store-ops.patch b/0040-tcg-i386-allow-constants-in-load-store-ops.patch index 0c9066c..2fae1d5 100644 --- a/0040-tcg-i386-allow-constants-in-load-store-ops.patch +++ b/0040-tcg-i386-allow-constants-in-load-store-ops.patch @@ -109,6 +109,3 @@ index 34c2df8..3017858 100644 { INDEX_op_add_i64, { "r", "0", "re" } }, { INDEX_op_mul_i64, { "r", "0", "re" } }, --- -1.7.12.1 - diff --git a/0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch b/0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch index bfab53b..35e9a15 100644 --- a/0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch +++ b/0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch @@ -48,6 +48,3 @@ index 8386b70..c002a88 100644 case INDEX_op_debug_insn_start: args -= def->nb_args; break; --- -1.7.12.1 - diff --git a/0042-revert-TCG-fix-copy-propagation.patch b/0042-revert-TCG-fix-copy-propagation.patch index 9e0a169..bcd9076 100644 --- a/0042-revert-TCG-fix-copy-propagation.patch +++ b/0042-revert-TCG-fix-copy-propagation.patch @@ -80,6 +80,3 @@ index d710694..8fbbc81 100644 #if defined(CONFIG_DEBUG_TCG) /* If you call tcg_clear_temp_count() at the start of a section of * code which is not supposed to leak any TCG temporaries, then --- -1.7.12.1 - diff --git a/0043-target-mips-Set-opn-in-gen_ldst_multiple.patch b/0043-target-mips-Set-opn-in-gen_ldst_multiple.patch index 874c31e..feb145d 100644 --- a/0043-target-mips-Set-opn-in-gen_ldst_multiple.patch +++ b/0043-target-mips-Set-opn-in-gen_ldst_multiple.patch @@ -50,6 +50,3 @@ index 7ab769f..c31f91c 100644 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]); tcg_temp_free(t0); tcg_temp_free(t1); --- -1.7.12.1 - diff --git a/0044-target-mips-Fix-MIPS_DEBUG.patch b/0044-target-mips-Fix-MIPS_DEBUG.patch index 0fa094a..f361872 100644 --- a/0044-target-mips-Fix-MIPS_DEBUG.patch +++ b/0044-target-mips-Fix-MIPS_DEBUG.patch @@ -283,6 +283,3 @@ index c31f91c..4937f6b 100644 break; case OPC_J ... OPC_JAL: /* Jump */ offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; --- -1.7.12.1 - diff --git a/0045-target-mips-Always-evaluate-debugging-macro-argument.patch b/0045-target-mips-Always-evaluate-debugging-macro-argument.patch index e424bcf..ee41de3 100644 --- a/0045-target-mips-Always-evaluate-debugging-macro-argument.patch +++ b/0045-target-mips-Always-evaluate-debugging-macro-argument.patch @@ -65,6 +65,3 @@ index 4937f6b..aba7935 100644 /* General purpose registers moves. */ static inline void gen_load_gpr (TCGv t, int reg) --- -1.7.12.1 - diff --git a/0046-tcg-optimize-fix-end-of-basic-block-detection.patch b/0046-tcg-optimize-fix-end-of-basic-block-detection.patch index c498962..1bf628a 100644 --- a/0046-tcg-optimize-fix-end-of-basic-block-detection.patch +++ b/0046-tcg-optimize-fix-end-of-basic-block-detection.patch @@ -57,6 +57,3 @@ index 10d9773..9da333c 100644 } for (i = 0; i < def->nb_args; i++) { gen_args[i] = args[i]; --- -1.7.12.1 - diff --git a/0047-target-xtensa-fix-extui-shift-amount.patch b/0047-target-xtensa-fix-extui-shift-amount.patch index c654322..15506f6 100644 --- a/0047-target-xtensa-fix-extui-shift-amount.patch +++ b/0047-target-xtensa-fix-extui-shift-amount.patch @@ -52,6 +52,3 @@ index 1900bd5..7a1c528 100644 tcg_temp_free(tmp); } break; --- -1.7.12.1 - diff --git a/0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch b/0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch index 2e8e219..6136b50 100644 --- a/0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch +++ b/0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch @@ -30,6 +30,3 @@ index 7a1c528..b6643eb 100644 dc->pc = dc->next_pc; return; --- -1.7.12.1 - diff --git a/0049-tcg-Introduce-movcond.patch b/0049-tcg-Introduce-movcond.patch index 3ead932..f2321b5 100644 --- a/0049-tcg-Introduce-movcond.patch +++ b/0049-tcg-Introduce-movcond.patch @@ -328,6 +328,3 @@ index 30a0f21..6d89495 100644 #endif /* TCG_TARGET_REG_BITS == 64 */ /* Offset to user memory in user mode. */ --- -1.7.12.1 - diff --git a/0050-target-alpha-Use-movcond.patch b/0050-target-alpha-Use-movcond.patch index 0bd5272..5091803 100644 --- a/0050-target-alpha-Use-movcond.patch +++ b/0050-target-alpha-Use-movcond.patch @@ -155,6 +155,3 @@ index 12de6a3..4a9011a 100644 } #define QUAL_RM_N 0x080 /* Round mode nearest even */ --- -1.7.12.1 - diff --git a/0051-tcg-i386-Implement-movcond.patch b/0051-tcg-i386-Implement-movcond.patch index 4d3983f..0c9e0d7 100644 --- a/0051-tcg-i386-Implement-movcond.patch +++ b/0051-tcg-i386-Implement-movcond.patch @@ -113,6 +113,3 @@ index 504f953..b356d76 100644 #endif #define TCG_TARGET_deposit_i32_valid(ofs, len) \ --- -1.7.12.1 - diff --git a/0052-tcg-Optimize-movcond-for-constant-comparisons.patch b/0052-tcg-Optimize-movcond-for-constant-comparisons.patch index ce0f00b..2a61fda 100644 --- a/0052-tcg-Optimize-movcond-for-constant-comparisons.patch +++ b/0052-tcg-Optimize-movcond-for-constant-comparisons.patch @@ -68,6 +68,3 @@ index 9da333c..26038a6 100644 case INDEX_op_call: nb_call_args = (args[0] >> 16) + (args[0] & 0xffff); if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) { --- -1.7.12.1 - diff --git a/0053-tcg-Optimize-two-address-commutative-operations.patch b/0053-tcg-Optimize-two-address-commutative-operations.patch index adacbb8..1e034c6 100644 --- a/0053-tcg-Optimize-two-address-commutative-operations.patch +++ b/0053-tcg-Optimize-two-address-commutative-operations.patch @@ -52,6 +52,3 @@ index 26038a6..1be7631 100644 default: break; } --- -1.7.12.1 - diff --git a/0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch b/0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch index 250f893..4ce049a 100644 --- a/0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch +++ b/0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch @@ -187,6 +187,3 @@ index 5d37dd9..a91709f 100644 default: return 0; } --- -1.7.12.1 - diff --git a/0055-tcg-Fix-USE_DIRECT_JUMP.patch b/0055-tcg-Fix-USE_DIRECT_JUMP.patch index 3f88ee8..3dfb656 100644 --- a/0055-tcg-Fix-USE_DIRECT_JUMP.patch +++ b/0055-tcg-Fix-USE_DIRECT_JUMP.patch @@ -30,6 +30,3 @@ index f454107..609ed86 100644 uint16_t *tb_next_offset; uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */ --- -1.7.12.1 - diff --git a/0056-tcg-hppa-Fix-brcond2-and-setcond2.patch b/0056-tcg-hppa-Fix-brcond2-and-setcond2.patch index fa1f7cb..8244946 100644 --- a/0056-tcg-hppa-Fix-brcond2-and-setcond2.patch +++ b/0056-tcg-hppa-Fix-brcond2-and-setcond2.patch @@ -103,6 +103,3 @@ index 8b81b70..a76569d 100644 } tcg_out_mov(s, TCG_TYPE_I32, ret, scratch); --- -1.7.12.1 - diff --git a/0057-tcg-hppa-Fix-broken-load-store-helpers.patch b/0057-tcg-hppa-Fix-broken-load-store-helpers.patch index 3666a95..36d41a6 100644 --- a/0057-tcg-hppa-Fix-broken-load-store-helpers.patch +++ b/0057-tcg-hppa-Fix-broken-load-store-helpers.patch @@ -244,6 +244,3 @@ index a76569d..5385d45 100644 addrlo_reg = TCG_REG_R31; } tcg_out_qemu_st_direct(s, datalo_reg, datahi_reg, addrlo_reg, opc); --- -1.7.12.1 - diff --git a/0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch b/0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch index a4e1059..628251b 100644 --- a/0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch +++ b/0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch @@ -60,6 +60,3 @@ index 74db83d..9293745 100644 { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } }, #if TARGET_LONG_BITS == 32 --- -1.7.12.1 - diff --git a/0059-tcg-mips-kill-warnings-in-user-mode.patch b/0059-tcg-mips-kill-warnings-in-user-mode.patch index 96de9cb..1b32a2a 100644 --- a/0059-tcg-mips-kill-warnings-in-user-mode.patch +++ b/0059-tcg-mips-kill-warnings-in-user-mode.patch @@ -161,6 +161,3 @@ index 9293745..a09c0d6 100644 #if defined(CONFIG_SOFTMMU) tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); --- -1.7.12.1 - diff --git a/0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch b/0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch index a6eb42f..ffe9c4c 100644 --- a/0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch +++ b/0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch @@ -241,6 +241,3 @@ index a09c0d6..8b38f98 100644 # endif #endif data_regl = *args++; --- -1.7.12.1 - diff --git a/0061-tcg-mips-don-t-use-global-pointer.patch b/0061-tcg-mips-don-t-use-global-pointer.patch index a9aaf69..c29193c 100644 --- a/0061-tcg-mips-don-t-use-global-pointer.patch +++ b/0061-tcg-mips-don-t-use-global-pointer.patch @@ -32,6 +32,3 @@ index 8b38f98..0ea6a76 100644 tcg_add_target_add_op_defs(mips_op_defs); tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf), --- -1.7.12.1 - diff --git a/0062-tcg-mips-use-stack-for-TCG-temps.patch b/0062-tcg-mips-use-stack-for-TCG-temps.patch index 09ea3fb..38c7b50 100644 --- a/0062-tcg-mips-use-stack-for-TCG-temps.patch +++ b/0062-tcg-mips-use-stack-for-TCG-temps.patch @@ -42,6 +42,3 @@ index 0ea6a76..c05169f 100644 - tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf), - CPU_TEMP_BUF_NLONGS * sizeof(long)); } --- -1.7.12.1 - diff --git a/0063-tcg-mips-optimize-brcond-arg-0.patch b/0063-tcg-mips-optimize-brcond-arg-0.patch index e21fcac..12a8e21 100644 --- a/0063-tcg-mips-optimize-brcond-arg-0.patch +++ b/0063-tcg-mips-optimize-brcond-arg-0.patch @@ -94,6 +94,3 @@ index c05169f..6aa4527 100644 break; case TCG_COND_GTU: tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1); --- -1.7.12.1 - diff --git a/0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch b/0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch index 45a881d..fdb6cbf 100644 --- a/0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch +++ b/0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch @@ -156,6 +156,3 @@ index 9c68a32..c5c13f7 100644 /* optional instructions automatically implemented */ #define TCG_TARGET_HAS_neg_i32 0 /* sub rd, zero, rt */ #define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */ --- -1.7.12.1 - diff --git a/0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch b/0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch index 6134676..b1da826 100644 --- a/0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch +++ b/0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch @@ -87,6 +87,3 @@ index c5c13f7..470314c 100644 #endif /* optional instructions automatically implemented */ --- -1.7.12.1 - diff --git a/0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch b/0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch index fe54bc0..13a2688 100644 --- a/0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch +++ b/0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch @@ -72,6 +72,3 @@ index 470314c..897a737 100644 #endif /* optional instructions automatically implemented */ --- -1.7.12.1 - diff --git a/0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch b/0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch index 7f06797..a27ad5d 100644 --- a/0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch +++ b/0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch @@ -135,6 +135,3 @@ index 897a737..d147e70 100644 /* optional instructions only implemented on MIPS32R2 */ #ifdef _MIPS_ARCH_MIPS32R2 --- -1.7.12.1 - diff --git a/0068-tcg-optimize-remove-TCG_TEMP_ANY.patch b/0068-tcg-optimize-remove-TCG_TEMP_ANY.patch index 0702187..1187432 100644 --- a/0068-tcg-optimize-remove-TCG_TEMP_ANY.patch +++ b/0068-tcg-optimize-remove-TCG_TEMP_ANY.patch @@ -57,6 +57,3 @@ index 1be7631..308b7f9 100644 } } --- -1.7.12.1 - diff --git a/0069-tcg-optimize-check-types-in-copy-propagation.patch b/0069-tcg-optimize-check-types-in-copy-propagation.patch index 6627679..12b231f 100644 --- a/0069-tcg-optimize-check-types-in-copy-propagation.patch +++ b/0069-tcg-optimize-check-types-in-copy-propagation.patch @@ -73,6 +73,3 @@ index 308b7f9..da8dffe 100644 gen_args += 2; args += 2; break; --- -1.7.12.1 - diff --git a/0070-tcg-optimize-rework-copy-progagation.patch b/0070-tcg-optimize-rework-copy-progagation.patch index ca39c5a..c797cce 100644 --- a/0070-tcg-optimize-rework-copy-progagation.patch +++ b/0070-tcg-optimize-rework-copy-progagation.patch @@ -372,6 +372,3 @@ index da8dffe..1904b39 100644 } } for (i = 0; i < def->nb_args; i++) { --- -1.7.12.1 - diff --git a/0071-tcg-optimize-do-copy-propagation-for-all-operations.patch b/0071-tcg-optimize-do-copy-propagation-for-all-operations.patch index 62a4efb..d502253 100644 --- a/0071-tcg-optimize-do-copy-propagation-for-all-operations.patch +++ b/0071-tcg-optimize-do-copy-propagation-for-all-operations.patch @@ -37,6 +37,3 @@ index 1904b39..aeb2225 100644 for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) { if (temps[args[i]].state == TCG_TEMP_COPY) { args[i] = find_better_copy(s, args[i]); --- -1.7.12.1 - diff --git a/0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch b/0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch index 65f5c50..5c0a3c2 100644 --- a/0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch +++ b/0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch @@ -26,6 +26,3 @@ index aeb2225..b9a7da9 100644 if (temps_are_copies(args[0], args[1])) { gen_opc_buf[op_index] = INDEX_op_nop; } else { --- -1.7.12.1 - diff --git a/0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch b/0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch index 48ad5fe..f5ebe44 100644 --- a/0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch +++ b/0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch @@ -41,6 +41,3 @@ index b9a7da9..ceea644 100644 /* Propagate constants through copy operations and do constant folding. Constants will be substituted to arguments by register allocator where needed and possible. Also detect copies. */ --- -1.7.12.1 - diff --git a/0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch b/0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch index 9b9180d..1277768 100644 --- a/0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch +++ b/0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch @@ -187,6 +187,3 @@ index ceea644..abe016a 100644 if (temps_are_copies(args[0], args[4-tmp])) { gen_opc_buf[op_index] = INDEX_op_nop; } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) { --- -1.7.12.1 - diff --git a/0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch b/0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch index 4cb003b..8d30fc5 100644 --- a/0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch +++ b/0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch @@ -33,6 +33,3 @@ index abe016a..c8ae50b 100644 tmp = args[1]; args[1] = args[2]; args[2] = tmp; --- -1.7.12.1 - diff --git a/0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch b/0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch index 214a022..5eaf355 100644 --- a/0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch +++ b/0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch @@ -63,6 +63,3 @@ index 24ce830..93421cd 100644 tcg_reg_alloc_movi(s, args); break; case INDEX_op_debug_insn_start: --- -1.7.12.1 - diff --git a/0077-tcg-optimize-add-constant-folding-for-deposit.patch b/0077-tcg-optimize-add-constant-folding-for-deposit.patch index 63566ce..85331af 100644 --- a/0077-tcg-optimize-add-constant-folding-for-deposit.patch +++ b/0077-tcg-optimize-add-constant-folding-for-deposit.patch @@ -41,6 +41,3 @@ index c8ae50b..35532a1 100644 CASE_OP_32_64(setcond): tmp = do_constant_folding_cond(op, args[1], args[2], args[3]); if (tmp != 2) { --- -1.7.12.1 - diff --git a/0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch b/0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch index b47b1f1..f411689 100644 --- a/0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch +++ b/0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch @@ -28,6 +28,3 @@ index d03ae05..33783ee 100644 * qemu_ld8u t0, t1, flags qemu_ld8s t0, t1, flags --- -1.7.12.1 - diff --git a/0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch b/0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch index 3cea914..33feaaf 100644 --- a/0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch +++ b/0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch @@ -52,6 +52,3 @@ index b356d76..ace63ba 100644 /* optional instructions */ #define TCG_TARGET_HAS_div2_i32 1 --- -1.7.12.1 - diff --git a/0080-tcg-ppc32-Implement-movcond32.patch b/0080-tcg-ppc32-Implement-movcond32.patch index 2877379..dc55aa3 100644 --- a/0080-tcg-ppc32-Implement-movcond32.patch +++ b/0080-tcg-ppc32-Implement-movcond32.patch @@ -132,6 +132,3 @@ index 177eea1..3259d89 100644 #define TCG_AREG0 TCG_REG_R27 --- -1.7.12.1 - diff --git a/0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch b/0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch index f84d719..56e5f0a 100644 --- a/0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch +++ b/0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch @@ -25,6 +25,3 @@ index baed3b4..608fc46 100644 #endif { -1 }, }; --- -1.7.12.1 - diff --git a/0082-tcg-sparc-Fix-ADDX-opcode.patch b/0082-tcg-sparc-Fix-ADDX-opcode.patch index af3a51a..7c46b9f 100644 --- a/0082-tcg-sparc-Fix-ADDX-opcode.patch +++ b/0082-tcg-sparc-Fix-ADDX-opcode.patch @@ -22,6 +22,3 @@ index 608fc46..0a19313 100644 #define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c)) #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a)) #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e)) --- -1.7.12.1 - diff --git a/0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch b/0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch index 3e7946c..6f1d3ad 100644 --- a/0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch +++ b/0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch @@ -40,6 +40,3 @@ index 5834766..871a68a 100644 if (code_gen_buffer_size > (512 * 1024 * 1024)) { code_gen_buffer_size = (512 * 1024 * 1024); } --- -1.7.12.1 - diff --git a/0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch b/0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch index a68474a..bc773ca 100644 --- a/0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch +++ b/0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch @@ -281,6 +281,3 @@ index 93421cd..16c4e1d 100644 s->current_frame_offset = (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1); --- -1.7.12.1 - diff --git a/0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch b/0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch index beaf45b..1df9038 100644 --- a/0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch +++ b/0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch @@ -962,6 +962,3 @@ index 23c2fda..d89c19b 100644 { -1 }, }; --- -1.7.12.1 - diff --git a/0086-tcg-sparc-Support-GUEST_BASE.patch b/0086-tcg-sparc-Support-GUEST_BASE.patch index 3e8a175..1a18244 100644 --- a/0086-tcg-sparc-Support-GUEST_BASE.patch +++ b/0086-tcg-sparc-Support-GUEST_BASE.patch @@ -108,6 +108,3 @@ index adca1d2..99e9f57 100644 #ifdef CONFIG_SOLARIS #define TCG_AREG0 TCG_REG_G2 #elif HOST_LONG_BITS == 64 --- -1.7.12.1 - diff --git a/0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch b/0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch index 336d7fe..cf5f3b0 100644 --- a/0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch +++ b/0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch @@ -46,6 +46,3 @@ index 99e9f57..ee154d0 100644 static inline void flush_icache_range(tcg_target_ulong start, tcg_target_ulong stop) --- -1.7.12.1 - diff --git a/0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch b/0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch index 15c4571..c69be8a 100644 --- a/0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch +++ b/0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch @@ -198,6 +198,3 @@ index ee154d0..6314ffb 100644 #endif #if TCG_TARGET_REG_BITS == 64 --- -1.7.12.1 - diff --git a/0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch b/0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch index 7ce69d1..7ced9e0 100644 --- a/0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch +++ b/0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch @@ -57,6 +57,3 @@ index e625aa3..be5c170 100644 case INDEX_op_mul_i64: c = ARITH_MULX; goto gen_arith; --- -1.7.12.1 - diff --git a/0090-tcg-sparc-Use-defines-for-temporaries.patch b/0090-tcg-sparc-Use-defines-for-temporaries.patch index c837d22..56e0c17 100644 --- a/0090-tcg-sparc-Use-defines-for-temporaries.patch +++ b/0090-tcg-sparc-Use-defines-for-temporaries.patch @@ -270,6 +270,3 @@ index be5c170..d401f8e 100644 tcg_add_target_add_op_defs(sparc_op_defs); } --- -1.7.12.1 - diff --git a/0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch b/0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch index 2bf9e95..20af5bb 100644 --- a/0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch +++ b/0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch @@ -39,6 +39,3 @@ index d401f8e..03c385a 100644 }; static const int tcg_target_call_iarg_regs[6] = { --- -1.7.12.1 - diff --git a/0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch b/0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch index 7b876c0..bcbecbf 100644 --- a/0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch +++ b/0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch @@ -74,6 +74,3 @@ index 03c385a..1db0c9d 100644 + *ptr = CALL | (disp & 0x3fffffff); + flush_icache_range(jmp_addr, jmp_addr + 4); +} --- -1.7.12.1 - diff --git a/0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch b/0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch index 167dc41..187ffec 100644 --- a/0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch +++ b/0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch @@ -55,6 +55,3 @@ index 1db0c9d..876da4f 100644 } #endif --- -1.7.12.1 - diff --git a/0094-target-alpha-Initialize-env-cpu_model_str.patch b/0094-target-alpha-Initialize-env-cpu_model_str.patch index 9734b0e..cf7272b 100644 --- a/0094-target-alpha-Initialize-env-cpu_model_str.patch +++ b/0094-target-alpha-Initialize-env-cpu_model_str.patch @@ -28,6 +28,3 @@ index 4a9011a..3f9aee1 100644 qemu_init_vcpu(env); return env; --- -1.7.12.1 - diff --git a/0095-tcg-mips-fix-MIPS32-R2-detection.patch b/0095-tcg-mips-fix-MIPS32-R2-detection.patch index e145e3b..5aa90c8 100644 --- a/0095-tcg-mips-fix-MIPS32-R2-detection.patch +++ b/0095-tcg-mips-fix-MIPS32-R2-detection.patch @@ -88,6 +88,3 @@ index d147e70..7020d65 100644 #define TCG_TARGET_HAS_bswap16_i32 1 #define TCG_TARGET_HAS_bswap32_i32 1 #define TCG_TARGET_HAS_rot_i32 1 --- -1.7.12.1 - diff --git a/0096-tcg-Adjust-descriptions-of-cond-opcodes.patch b/0096-tcg-Adjust-descriptions-of-cond-opcodes.patch index 64c62cb..bcef0e8 100644 --- a/0096-tcg-Adjust-descriptions-of-cond-opcodes.patch +++ b/0096-tcg-Adjust-descriptions-of-cond-opcodes.patch @@ -62,6 +62,3 @@ index 33783ee..27846f1 100644 Similar to setcond, except that the 64-bit values T1 and T2 are formed from two 32-bit arguments. The result is a 32-bit value. --- -1.7.12.1 - diff --git a/0097-tcg-i386-fix-build-with-march-i686.patch b/0097-tcg-i386-fix-build-with-march-i686.patch index a841086..d36642b 100644 --- a/0097-tcg-i386-fix-build-with-march-i686.patch +++ b/0097-tcg-i386-fix-build-with-march-i686.patch @@ -29,6 +29,3 @@ index 85c6b81..616ef23 100644 #if TCG_TARGET_REG_BITS == 32 { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } }, --- -1.7.12.1 - diff --git a/0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch b/0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch index dfc44fa..a6898b8 100644 --- a/0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch +++ b/0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch @@ -47,6 +47,3 @@ index 1f81da7..6516da0 100644 #define MAX_OPC_PARAM_OARGS 1 #define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS) --- -1.7.12.1 - diff --git a/0099-tci-Fix-for-AREG0-free-mode.patch b/0099-tci-Fix-for-AREG0-free-mode.patch index c67e4a3..dbe45ae 100644 --- a/0099-tci-Fix-for-AREG0-free-mode.patch +++ b/0099-tci-Fix-for-AREG0-free-mode.patch @@ -114,6 +114,3 @@ index ce8a988..a4f7b78 100644 tci_write_reg(TCG_REG_R0, tmp64); #endif break; --- -1.7.12.1 - diff --git a/0100-spice-abort-on-invalid-streaming-cmdline-params.patch b/0100-spice-abort-on-invalid-streaming-cmdline-params.patch index d73d347..1ee5c3a 100644 --- a/0100-spice-abort-on-invalid-streaming-cmdline-params.patch +++ b/0100-spice-abort-on-invalid-streaming-cmdline-params.patch @@ -36,6 +36,3 @@ index 4fc48f8..bb4f585 100644 static const char *compression_names[] = { [ SPICE_IMAGE_COMPRESS_OFF ] = "off", --- -1.7.12.1 - diff --git a/0101-spice-notify-spice-server-on-vm-start-stop.patch b/0101-spice-notify-spice-server-on-vm-start-stop.patch index 708bfe0..1527c4a 100644 --- a/0101-spice-notify-spice-server-on-vm-start-stop.patch +++ b/0101-spice-notify-spice-server-on-vm-start-stop.patch @@ -50,6 +50,3 @@ index bb4f585..a515c94 100644 g_free(x509_key_file); g_free(x509_cert_file); g_free(x509_cacert_file); --- -1.7.12.1 - diff --git a/0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch b/0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch index c599743..b0ccd8a 100644 --- a/0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch +++ b/0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch @@ -168,6 +168,3 @@ index 12e50b6..672d65e 100644 +void qemu_spice_display_stop(void); +#endif +int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd); --- -1.7.12.1 - diff --git a/0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch b/0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch index e8580c2..ad2da2f 100644 --- a/0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch +++ b/0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch @@ -88,6 +88,3 @@ index 1a7a773..851e869 100644 #else spice_server_migrate_end(spice_server, true); } else if (migration_has_failed(s)) { --- -1.7.12.1 - diff --git a/0104-spice-add-migrated-flag-to-spice-info.patch b/0104-spice-add-migrated-flag-to-spice-info.patch index 0247edd..eb7a997 100644 --- a/0104-spice-add-migrated-flag-to-spice-info.patch +++ b/0104-spice-add-migrated-flag-to-spice-info.patch @@ -92,6 +92,3 @@ index 851e869..ab069c5 100644 #else spice_server_migrate_end(spice_server, true); } else if (migration_has_failed(s)) { --- -1.7.12.1 - diff --git a/0105-spice-adding-seamless-migration-option-to-the-comman.patch b/0105-spice-adding-seamless-migration-option-to-the-comman.patch index 70eb7c0..9fdcb4d 100644 --- a/0105-spice-adding-seamless-migration-option-to-the-comman.patch +++ b/0105-spice-adding-seamless-migration-option-to-the-comman.patch @@ -74,6 +74,3 @@ index ab069c5..ba0d0bd 100644 if (0 != spice_server_init(spice_server, &core_interface)) { error_report("failed to initialize spice server"); exit(1); --- -1.7.12.1 - diff --git a/0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch b/0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch index 24ad9ff..a84a446 100644 --- a/0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch +++ b/0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch @@ -45,6 +45,3 @@ index dd7aa63..1af4fec 100644 STEXI @item -spice @var{option}[,@var{option}[,...]] @findex -spice --- -1.7.12.1 - diff --git a/0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch b/0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch index 7572299..f34e533 100644 --- a/0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch +++ b/0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch @@ -35,6 +35,3 @@ index 95bbc03..baf9bb4 100644 if (async == QXL_ASYNC) { cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO, QXL_IO_UPDATE_AREA_ASYNC); --- -1.7.12.1 - diff --git a/0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch b/0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch index 50dbee0..ba49852 100644 --- a/0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch +++ b/0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch @@ -322,6 +322,3 @@ index 672d65e..bcff114 100644 }; typedef struct QXLCookie { --- -1.7.12.1 - diff --git a/0109-configure-print-spice-protocol-and-spice-server-vers.patch b/0109-configure-print-spice-protocol-and-spice-server-vers.patch index 9e7f529..841c630 100644 --- a/0109-configure-print-spice-protocol-and-spice-server-vers.patch +++ b/0109-configure-print-spice-protocol-and-spice-server-vers.patch @@ -34,6 +34,3 @@ index b5cea26..d7a948f 100755 echo "rbd support $rbd" echo "xfsctl support $xfs" echo "nss used $smartcard_nss" --- -1.7.12.1 - diff --git a/0110-fix-doc-of-using-raw-values-with-sendkey.patch b/0110-fix-doc-of-using-raw-values-with-sendkey.patch index 9e59097..efde3ff 100644 --- a/0110-fix-doc-of-using-raw-values-with-sendkey.patch +++ b/0110-fix-doc-of-using-raw-values-with-sendkey.patch @@ -37,6 +37,3 @@ index 13f28cf..a72614d 100644 @example sendkey ctrl-alt-f1 @end example --- -1.7.12.1 - diff --git a/0111-qapi-Fix-potential-NULL-pointer-segfault.patch b/0111-qapi-Fix-potential-NULL-pointer-segfault.patch index 8f15921..a7de589 100644 --- a/0111-qapi-Fix-potential-NULL-pointer-segfault.patch +++ b/0111-qapi-Fix-potential-NULL-pointer-segfault.patch @@ -33,6 +33,3 @@ index 04ef7c4..5b15ee3 100644 visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err); if (!err) { switch ((*obj)->kind) { --- -1.7.12.1 - diff --git a/0112-json-parser-Fix-potential-NULL-pointer-segfault.patch b/0112-json-parser-Fix-potential-NULL-pointer-segfault.patch index 8198f24..2c2d4a3 100644 --- a/0112-json-parser-Fix-potential-NULL-pointer-segfault.patch +++ b/0112-json-parser-Fix-potential-NULL-pointer-segfault.patch @@ -35,6 +35,3 @@ index d42386d..9124649 100644 /* Initialize an object to default values */ #define QOBJECT_INIT(obj, qtype_type) \ --- -1.7.12.1 - diff --git a/0113-pcie-drop-version_id-field-for-live-migration.patch b/0113-pcie-drop-version_id-field-for-live-migration.patch index c3a469f..9c5aa3f 100644 --- a/0113-pcie-drop-version_id-field-for-live-migration.patch +++ b/0113-pcie-drop-version_id-field-for-live-migration.patch @@ -74,6 +74,3 @@ index b8ab0c7..4889194 100644 .size = sizeof(PCIDevice), \ .vmsd = &vmstate_pcie_device, \ .flags = VMS_STRUCT, \ --- -1.7.12.1 - diff --git a/0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch b/0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch index 80aad2b..d4bd386 100644 --- a/0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch +++ b/0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch @@ -35,6 +35,3 @@ index 3b6981c..b04c164 100644 } void pcie_aer_root_reset(PCIDevice *dev) --- -1.7.12.1 - diff --git a/0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch b/0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch index 4488d60..8c7098f 100644 --- a/0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch +++ b/0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch @@ -37,6 +37,3 @@ index fa65ce2..731a983 100644 snprintf(label, sizeof(label), "phdr #%d: %s", i, name); rom_add_blob_fixed(label, data, mem_size, addr); --- -1.7.12.1 - diff --git a/0116-lan9118-fix-multicast-filtering.patch b/0116-lan9118-fix-multicast-filtering.patch index 19cb229..d9b8664 100644 --- a/0116-lan9118-fix-multicast-filtering.patch +++ b/0116-lan9118-fix-multicast-filtering.patch @@ -32,6 +32,3 @@ index ff0a50b..ceaf96f 100644 if (hash & 0x20) { return (s->mac_hashh >> (hash & 0x1f)) & 1; } else { --- -1.7.12.1 - diff --git a/0117-MIPS-user-Fix-reset-CPU-state-initialization.patch b/0117-MIPS-user-Fix-reset-CPU-state-initialization.patch index e98d248..21d7371 100644 --- a/0117-MIPS-user-Fix-reset-CPU-state-initialization.patch +++ b/0117-MIPS-user-Fix-reset-CPU-state-initialization.patch @@ -191,6 +191,3 @@ index aba7935..4e04e97 100644 env->exception_index = EXCP_NONE; } --- -1.7.12.1 - diff --git a/0118-Add-MAINTAINERS-entry-for-leon3.patch b/0118-Add-MAINTAINERS-entry-for-leon3.patch index cbc0ff8..a69eeb4 100644 --- a/0118-Add-MAINTAINERS-entry-for-leon3.patch +++ b/0118-Add-MAINTAINERS-entry-for-leon3.patch @@ -29,6 +29,3 @@ index 6d864c1..61f8b45 100644 S390 Machines ------------- S390 Virtio --- -1.7.12.1 - diff --git a/0119-musicpal-Fix-flash-mapping.patch b/0119-musicpal-Fix-flash-mapping.patch index 9c95c49..881801c 100644 --- a/0119-musicpal-Fix-flash-mapping.patch +++ b/0119-musicpal-Fix-flash-mapping.patch @@ -37,6 +37,3 @@ index ad725b5..f305e21 100644 "musicpal.flash", flash_size, dinfo->bdrv, 0x10000, (flash_size + 0xffff) >> 16, --- -1.7.12.1 - diff --git a/0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch b/0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch index 40caa2c..42ee2c5 100644 --- a/0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch +++ b/0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch @@ -79,6 +79,3 @@ index badf1d8..90c71f9 100644 if (!kvm_has_sync_mmu()) { int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK); --- -1.7.12.1 - diff --git a/0121-hw-wm8750-Fix-potential-buffer-overflow.patch b/0121-hw-wm8750-Fix-potential-buffer-overflow.patch index 2b3acbe..db8b2be 100644 --- a/0121-hw-wm8750-Fix-potential-buffer-overflow.patch +++ b/0121-hw-wm8750-Fix-potential-buffer-overflow.patch @@ -38,6 +38,3 @@ index 11bcec3..44f138f 100644 } s->i2c_data[s->i2c_len ++] = data; if (s->i2c_len != 2) --- -1.7.12.1 - diff --git a/0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch b/0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch index c5fe15f..ec1c7c0 100644 --- a/0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch +++ b/0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch @@ -82,6 +82,3 @@ index 539b391..27753e2 100644 hw_error("Bad MBAR write offset 0x%x", (int)offset); } width = m5206_mbar_width[offset >> 2]; --- -1.7.12.1 - diff --git a/0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch b/0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch index 9764f22..144f951 100644 --- a/0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch +++ b/0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch @@ -1,8 +1,8 @@ From 6762c144443bca8fa97a389289bda7693bd4c8d4 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Thu, 7 Jun 2012 01:11:00 +0400 -Subject: [PATCH] use --libexecdir instead of ignoring it first and - reinventing it later +Subject: [PATCH] use --libexecdir instead of ignoring it first and reinventing + it later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -89,6 +89,3 @@ index 8874eff..d01f9dc 100755 echo "ARCH=$ARCH" >> $config_host_mak if test "$debug_tcg" = "yes" ; then --- -1.7.12.1 - diff --git a/0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch b/0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch index cff77f8..333a77a 100644 --- a/0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch +++ b/0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch @@ -38,6 +38,3 @@ index 398baf1..767da93 100644 } } --- -1.7.12.1 - diff --git a/0125-Add-ability-to-force-enable-disable-of-tools-build.patch b/0125-Add-ability-to-force-enable-disable-of-tools-build.patch index 35e05ee..b98e9a0 100644 --- a/0125-Add-ability-to-force-enable-disable-of-tools-build.patch +++ b/0125-Add-ability-to-force-enable-disable-of-tools-build.patch @@ -78,6 +78,3 @@ index d01f9dc..a8061c1 100755 fi # Mac OS X ships with a broken assembler --- -1.7.12.1 - diff --git a/0126-usb-controllers-do-not-need-to-check-for-babble-them.patch b/0126-usb-controllers-do-not-need-to-check-for-babble-them.patch index 2630139..69d43d1 100644 --- a/0126-usb-controllers-do-not-need-to-check-for-babble-them.patch +++ b/0126-usb-controllers-do-not-need-to-check-for-babble-them.patch @@ -53,6 +53,3 @@ index b0db921..c7c8786 100644 if ((td->ctrl & TD_CTRL_SPD) && len < max_len) { *int_mask |= 0x02; /* short packet: do not update QH */ --- -1.7.12.1 - diff --git a/0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch b/0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch index 1bbaed0..34a1a3c 100644 --- a/0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch +++ b/0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch @@ -32,6 +32,3 @@ index 2da38e7..be6d936 100644 } } else { ret = USB_RET_ASYNC; --- -1.7.12.1 - diff --git a/0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch b/0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch index 994e450..020f67f 100644 --- a/0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch +++ b/0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch @@ -49,6 +49,3 @@ index be6d936..fe431d0 100644 + + return NULL; +} --- -1.7.12.1 - diff --git a/0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch b/0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch index c264ca1..8826075 100644 --- a/0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch +++ b/0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch @@ -30,6 +30,3 @@ index fe431d0..b9f1f7a 100644 if (ret != USB_RET_NAK) { p->result = ret; usb_packet_set_state(p, USB_PACKET_COMPLETE); --- -1.7.12.1 - diff --git a/0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch b/0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch index ae5d4d3..1749750 100644 --- a/0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch +++ b/0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch @@ -119,6 +119,3 @@ index 9523247..e7c36f4 100644 break; default: --- -1.7.12.1 - diff --git a/0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch b/0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch index a0b0897..a1faa09 100644 --- a/0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch +++ b/0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch @@ -81,6 +81,3 @@ index e7c36f4..35eb441 100644 if (q->dev == NULL) { q->dev = ehci_find_device(q->ehci, devaddr); } --- -1.7.12.1 - diff --git a/0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch b/0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch index 020cb38..104037c 100644 --- a/0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch +++ b/0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch @@ -30,6 +30,3 @@ index 35eb441..78a248f 100644 * * EHCI project was started by Mark Burkley, with contributions by * Niels de Vos. David S. Ahern continued working on it. Kevin Wolf, --- -1.7.12.1 - diff --git a/0133-ehci-Properly-cleanup-packets-on-cancel.patch b/0133-ehci-Properly-cleanup-packets-on-cancel.patch index 1e20c4f..a1bf6e6 100644 --- a/0133-ehci-Properly-cleanup-packets-on-cancel.patch +++ b/0133-ehci-Properly-cleanup-packets-on-cancel.patch @@ -24,6 +24,3 @@ index 78a248f..4fe85c8 100644 } QTAILQ_REMOVE(&p->queue->packets, p, next); usb_packet_cleanup(&p->packet); --- -1.7.12.1 - diff --git a/0134-ehci-Properly-report-completed-but-not-yet-processed.patch b/0134-ehci-Properly-report-completed-but-not-yet-processed.patch index e70d469..5a7d08f 100644 --- a/0134-ehci-Properly-report-completed-but-not-yet-processed.patch +++ b/0134-ehci-Properly-report-completed-but-not-yet-processed.patch @@ -1,8 +1,8 @@ From c7251f2557d09ce4b8466eeccd0f3264c297c515 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 30 Aug 2012 15:18:24 +0200 -Subject: [PATCH] ehci: Properly report completed but not yet processed - packets to the guest +Subject: [PATCH] ehci: Properly report completed but not yet processed packets + to the guest Reported packets which have completed before being cancelled as such to the host. Note that the new code path this patch adds is untested since it I've @@ -47,6 +47,3 @@ index 4fe85c8..0a6c9ef 100644 QTAILQ_REMOVE(&p->queue->packets, p, next); usb_packet_cleanup(&p->packet); g_free(p); --- -1.7.12.1 - diff --git a/0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch b/0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch index f53bbe2..784c480 100644 --- a/0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch +++ b/0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch @@ -1,8 +1,7 @@ From b3950fe894e2b26f9dba0888af092cb43d01a466 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 31 Aug 2012 10:31:54 +0200 -Subject: [PATCH] ehci: check for EHCI_ASYNC_FINISHED first in - ehci_free_packet +Subject: [PATCH] ehci: check for EHCI_ASYNC_FINISHED first in ehci_free_packet Otherwise we'll see the packet free twice in the trace log even though it actually happens only once. @@ -45,6 +44,3 @@ index 0a6c9ef..23221d0 100644 QTAILQ_REMOVE(&p->queue->packets, p, next); usb_packet_cleanup(&p->packet); g_free(p); --- -1.7.12.1 - diff --git a/0136-ehci-trace-guest-bugs.patch b/0136-ehci-trace-guest-bugs.patch index 52c2f4a..295696d 100644 --- a/0136-ehci-trace-guest-bugs.patch +++ b/0136-ehci-trace-guest-bugs.patch @@ -104,6 +104,3 @@ index 8fcbc50..5112a47 100644 # hw/usb/hcd-uhci.c usb_uhci_reset(void) "=== RESET ===" --- -1.7.12.1 - diff --git a/0137-ehci-add-doorbell-trace-events.patch b/0137-ehci-add-doorbell-trace-events.patch index 33fb2a2..aac729c 100644 --- a/0137-ehci-add-doorbell-trace-events.patch +++ b/0137-ehci-add-doorbell-trace-events.patch @@ -46,6 +46,3 @@ index 5112a47..10bc04e 100644 # hw/usb/hcd-uhci.c usb_uhci_reset(void) "=== RESET ===" --- -1.7.12.1 - diff --git a/0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch b/0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch index 8a62ee7..a580d28 100644 --- a/0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch +++ b/0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch @@ -83,6 +83,3 @@ index 398f5e0..5a88268 100644 return USB_RET_PROCERR; } --- -1.7.12.1 - diff --git a/0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch b/0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch index b144ab4..d0ba725 100644 --- a/0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch +++ b/0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch @@ -115,6 +115,3 @@ index 5a88268..d87aca8 100644 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); break; case EHCI_ASYNC_FINISHED: --- -1.7.12.1 - diff --git a/0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch b/0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch index 74b2853..e94e747 100644 --- a/0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch +++ b/0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch @@ -52,6 +52,3 @@ index d87aca8..2534394 100644 goto out; } --- -1.7.12.1 - diff --git a/0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch b/0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch index 99c1351..287cee2 100644 --- a/0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch +++ b/0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch @@ -32,6 +32,3 @@ index 2534394..2f3e9c0 100644 ehci_set_state(q->ehci, q->async, EST_EXECUTING); break; } --- -1.7.12.1 - diff --git a/0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch b/0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch index f2723ac..ec5a34d 100644 --- a/0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch +++ b/0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch @@ -1,8 +1,7 @@ From 262c9bb1e59c2cd561dad1cf9d47c50f07af0e0f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 17 Aug 2012 17:27:08 +0200 -Subject: [PATCH] usb-redir: Never return USB_RET_NAK for async handled - packets +Subject: [PATCH] usb-redir: Never return USB_RET_NAK for async handled packets USB_RET_NAK is not a valid response for async handled packets (and will trigger an assert as such). @@ -42,6 +41,3 @@ index 10b4fbb..7f3719b 100644 case usb_redir_babble: return USB_RET_BABBLE; case usb_redir_ioerror: --- -1.7.12.1 - diff --git a/0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch b/0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch index 33f3ae9..612d892 100644 --- a/0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch +++ b/0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch @@ -179,6 +179,3 @@ index 7f3719b..5cc3334 100644 qemu_del_timer(dev->attach_timer); qemu_free_timer(dev->attach_timer); --- -1.7.12.1 - diff --git a/0144-usb-redir-Get-rid-of-async-struct-get-member.patch b/0144-usb-redir-Get-rid-of-async-struct-get-member.patch index 7ac41ee..531603e 100644 --- a/0144-usb-redir-Get-rid-of-async-struct-get-member.patch +++ b/0144-usb-redir-Get-rid-of-async-struct-get-member.patch @@ -71,6 +71,3 @@ index 5cc3334..2cae8c5 100644 dev->dev.data_buf[0] = alt_setting_status->alt; len = 1; } --- -1.7.12.1 - diff --git a/0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch b/0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch index eb581df..d291ead 100644 --- a/0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch +++ b/0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch @@ -104,6 +104,3 @@ index 2cae8c5..e4ef372 100644 if (aurb->packet) { aurb->packet->result = usbredir_handle_status(dev, interrupt_packet->status, len); --- -1.7.12.1 - diff --git a/0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch b/0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch index 18c7c1f..d56a1fb 100644 --- a/0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch +++ b/0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch @@ -36,6 +36,3 @@ index e4ef372..6593d50 100644 aurb->packet = p; aurb->packet_id = dev->packet_id; QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next); --- -1.7.12.1 - diff --git a/0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch b/0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch index f32e6cc..67fc09b 100644 --- a/0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch +++ b/0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch @@ -497,6 +497,3 @@ index 6593d50..fd1f8cc 100644 } } --- -1.7.12.1 - diff --git a/0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch b/0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch index 4c4e98b..185f4c9 100644 --- a/0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch +++ b/0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch @@ -32,6 +32,3 @@ index fd1f8cc..ee75217 100644 } } p->result = len; --- -1.7.12.1 - diff --git a/0149-Better-name-usb-braille-device.patch b/0149-Better-name-usb-braille-device.patch index 00c8599..ca00165 100644 --- a/0149-Better-name-usb-braille-device.patch +++ b/0149-Better-name-usb-braille-device.patch @@ -28,6 +28,3 @@ index 8aa6552..69b6e48 100644 [STR_SERIALNUMBER] = "1", }; --- -1.7.12.1 - diff --git a/0150-usb-audio-fix-usb-version.patch b/0150-usb-audio-fix-usb-version.patch index ceeb70d..277c60a 100644 --- a/0150-usb-audio-fix-usb-version.patch +++ b/0150-usb-audio-fix-usb-version.patch @@ -27,6 +27,3 @@ index 79b75fb..2594c78 100644 .bMaxPacketSize0 = 64, .bNumConfigurations = 1, .confs = (USBDescConfig[]) { --- -1.7.12.1 - diff --git a/0151-xhci-rip-out-background-transfer-code.patch b/0151-xhci-rip-out-background-transfer-code.patch index e728029..ce78b1b 100644 --- a/0151-xhci-rip-out-background-transfer-code.patch +++ b/0151-xhci-rip-out-background-transfer-code.patch @@ -322,6 +322,3 @@ index 3eb27fa..c0a2476 100644 break; } length = xhci_ring_chain_length(xhci, &epctx->ring); --- -1.7.12.1 - diff --git a/0152-xhci-drop-buffering.patch b/0152-xhci-drop-buffering.patch index af60c86..ce5bb91 100644 --- a/0152-xhci-drop-buffering.patch +++ b/0152-xhci-drop-buffering.patch @@ -381,6 +381,3 @@ index 10bc04e..c83d65e 100644 usb_xhci_xfer_async(void *xfer) "%p" usb_xhci_xfer_nak(void *xfer) "%p" usb_xhci_xfer_retry(void *xfer) "%p" --- -1.7.12.1 - diff --git a/0153-xhci-fix-runtime-write-tracepoint.patch b/0153-xhci-fix-runtime-write-tracepoint.patch index 133df2e..6f8475a 100644 --- a/0153-xhci-fix-runtime-write-tracepoint.patch +++ b/0153-xhci-fix-runtime-write-tracepoint.patch @@ -24,6 +24,3 @@ index 446d692..24b1f87 100644 switch (reg) { case 0x20: /* IMAN */ --- -1.7.12.1 - diff --git a/0154-xhci-allow-bytewise-capability-register-reads.patch b/0154-xhci-allow-bytewise-capability-register-reads.patch index 0870f14..9a70680 100644 --- a/0154-xhci-allow-bytewise-capability-register-reads.patch +++ b/0154-xhci-allow-bytewise-capability-register-reads.patch @@ -34,6 +34,3 @@ index 24b1f87..333df59 100644 .endianness = DEVICE_LITTLE_ENDIAN, }; --- -1.7.12.1 - diff --git a/0155-qxl-dont-update-invalid-area.patch b/0155-qxl-dont-update-invalid-area.patch index 902566d..243aa55 100644 --- a/0155-qxl-dont-update-invalid-area.patch +++ b/0155-qxl-dont-update-invalid-area.patch @@ -39,6 +39,3 @@ index 27f3779..038a8bb 100644 if (async == QXL_ASYNC) { cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO, QXL_IO_UPDATE_AREA_ASYNC); --- -1.7.12.1 - diff --git a/0156-usb-host-allow-emulated-non-async-control-requests-w.patch b/0156-usb-host-allow-emulated-non-async-control-requests-w.patch index 11fcb3f..e06f991 100644 --- a/0156-usb-host-allow-emulated-non-async-control-requests-w.patch +++ b/0156-usb-host-allow-emulated-non-async-control-requests-w.patch @@ -1,8 +1,8 @@ From e84037892a04dac64104b43d0a6342aee4c4e6f4 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 6 Sep 2012 12:03:41 +0200 -Subject: [PATCH] usb-host: allow emulated (non-async) control requests - without USBPacket +Subject: [PATCH] usb-host: allow emulated (non-async) control requests without + USBPacket xhci needs this for USB_REQ_SET_ADDRESS due to the way usb addressing is handled by the xhci hardware. @@ -35,6 +35,3 @@ index 8df9207..44f1a64 100644 if (length > sizeof(dev->data_buf)) { fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n", --- -1.7.12.1 - diff --git a/0157-qxl-better-cleanup-for-surface-destroy.patch b/0157-qxl-better-cleanup-for-surface-destroy.patch index b796173..69542b2 100644 --- a/0157-qxl-better-cleanup-for-surface-destroy.patch +++ b/0157-qxl-better-cleanup-for-surface-destroy.patch @@ -30,6 +30,3 @@ index 038a8bb..67f7100 100644 } } --- -1.7.12.1 - diff --git a/0158-ehci-switch-to-new-style-memory-ops.patch b/0158-ehci-switch-to-new-style-memory-ops.patch index 4932df4..fa7dea6 100644 --- a/0158-ehci-switch-to-new-style-memory-ops.patch +++ b/0158-ehci-switch-to-new-style-memory-ops.patch @@ -365,6 +365,3 @@ index c83d65e..cf05414 100644 usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d" usb_ehci_state(const char *schedule, const char *state) "%s schedule %s" usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x" --- -1.7.12.1 - diff --git a/0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch b/0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch index bd8d88b..bca784f 100644 --- a/0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch +++ b/0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch @@ -33,6 +33,3 @@ index f5ba8e1..54273d7 100644 ehci->usbsts_frindex -= 0x00004000; } else { ehci->usbsts_frindex = 0; --- -1.7.12.1 - diff --git a/0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch b/0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch index f0a4b00..630eeee 100644 --- a/0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch +++ b/0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch @@ -55,6 +55,3 @@ index 54273d7..017a01d 100644 ehci_update_frindex(ehci, 1); ehci_advance_periodic_state(ehci); ehci->last_run_ns += FRAME_TIMER_NS; --- -1.7.12.1 - diff --git a/0161-sheepdog-fix-savevm-and-loadvm.patch b/0161-sheepdog-fix-savevm-and-loadvm.patch index f85cc0b..ee2895d 100644 --- a/0161-sheepdog-fix-savevm-and-loadvm.patch +++ b/0161-sheepdog-fix-savevm-and-loadvm.patch @@ -36,6 +36,3 @@ index df4f441..e0753ee 100644 remaining -= data_len; } ret = size; --- -1.7.12.1 - diff --git a/0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch b/0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch index 62a21ce..45e4ea0 100644 --- a/0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch +++ b/0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch @@ -62,6 +62,3 @@ index d65ef3d..d6fb69c 100644 int i; for(i = 0; i < 11; i++) { s->io_buffer[2+i+(n*12)] = smart_attributes[n][i]; --- -1.7.12.1 - diff --git a/0163-block-curl-Fix-wrong-free-statement.patch b/0163-block-curl-Fix-wrong-free-statement.patch index a37ad7f..85e5b14 100644 --- a/0163-block-curl-Fix-wrong-free-statement.patch +++ b/0163-block-curl-Fix-wrong-free-statement.patch @@ -32,6 +32,3 @@ index e7c3634..c1074cd 100644 } static int64_t curl_getlength(BlockDriverState *bs) --- -1.7.12.1 - diff --git a/0164-vdi-Fix-warning-from-clang.patch b/0164-vdi-Fix-warning-from-clang.patch index c8e751d..4842cad 100644 --- a/0164-vdi-Fix-warning-from-clang.patch +++ b/0164-vdi-Fix-warning-from-clang.patch @@ -70,6 +70,3 @@ index c4f1529..550cf58 100644 if (image_type == VDI_TYPE_STATIC) { if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) { result = -errno; --- -1.7.12.1 - diff --git a/0165-block-fix-block-tray-status.patch b/0165-block-fix-block-tray-status.patch index 6db09b8..5476562 100644 --- a/0165-block-fix-block-tray-status.patch +++ b/0165-block-fix-block-tray-status.patch @@ -31,6 +31,3 @@ index 470bdcc..c754353 100644 /*throttling disk I/O limits*/ if (bs->io_limits_enabled) { bdrv_io_limits_disable(bs); --- -1.7.12.1 - diff --git a/0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch b/0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch index ad2d6b5..70c1d11 100644 --- a/0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch +++ b/0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch @@ -59,6 +59,3 @@ index 5ea3cad..68671bc 100644 ahci_reset_port(s, i); } } --- -1.7.12.1 - diff --git a/0167-Don-t-require-encryption-password-for-qemu-img-info-.patch b/0167-Don-t-require-encryption-password-for-qemu-img-info-.patch index 6b9d67f..f018cad 100644 --- a/0167-Don-t-require-encryption-password-for-qemu-img-info-.patch +++ b/0167-Don-t-require-encryption-password-for-qemu-img-info-.patch @@ -1,8 +1,7 @@ From 4812a358ff2d7442c33a517a6c80d7d3c301ec56 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 10 Sep 2012 12:11:31 +0100 -Subject: [PATCH] Don't require encryption password for 'qemu-img info' - command +Subject: [PATCH] Don't require encryption password for 'qemu-img info' command The encryption password is only required if I/O is going to be performed on a disk image. The 'qemu-img info' command merely @@ -116,6 +115,3 @@ index b41e670..0d208e8 100644 if (!bs) { ret = -1; goto out; --- -1.7.12.1 - diff --git a/0168-block-Don-t-forget-to-delete-temporary-file.patch b/0168-block-Don-t-forget-to-delete-temporary-file.patch index 90d07b9..0b86df0 100644 --- a/0168-block-Don-t-forget-to-delete-temporary-file.patch +++ b/0168-block-Don-t-forget-to-delete-temporary-file.patch @@ -31,6 +31,3 @@ index c754353..e78039b 100644 return -errno; } return 0; --- -1.7.12.1 - diff --git a/0169-hw-qxl-tracing-fixes.patch b/0169-hw-qxl-tracing-fixes.patch index 74c400f..d317b75 100644 --- a/0169-hw-qxl-tracing-fixes.patch +++ b/0169-hw-qxl-tracing-fixes.patch @@ -94,6 +94,3 @@ index cf05414..aa79836 100644 # hw/qxl-render.c qxl_render_blit_guest_primary_initialized(void) "" --- -1.7.12.1 - diff --git a/0170-configure-usbredir-fixes.patch b/0170-configure-usbredir-fixes.patch index cf87afa..924dc3c 100644 --- a/0170-configure-usbredir-fixes.patch +++ b/0170-configure-usbredir-fixes.patch @@ -31,6 +31,3 @@ index a8061c1..dcd8e7b 100755 else if test "$usb_redir" = "yes"; then feature_not_found "usb-redir" --- -1.7.12.1 - diff --git a/0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch b/0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch index de9f4ac..daec59a 100644 --- a/0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch +++ b/0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch @@ -99,6 +99,3 @@ index 017a01d..bc86460 100644 break; default: --- -1.7.12.1 - diff --git a/0172-ehci-Walk-async-schedule-before-and-after-migration.patch b/0172-ehci-Walk-async-schedule-before-and-after-migration.patch index 476e41e..4009d8f 100644 --- a/0172-ehci-Walk-async-schedule-before-and-after-migration.patch +++ b/0172-ehci-Walk-async-schedule-before-and-after-migration.patch @@ -65,6 +65,3 @@ index bc86460..6a5da84 100644 memory_region_init(&s->mem, "ehci", MMIO_SIZE); memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s, --- -1.7.12.1 - diff --git a/0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch b/0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch index 11125f2..e8d3495 100644 --- a/0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch +++ b/0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch @@ -58,6 +58,3 @@ index ee75217..ab8d79a 100644 usbredirparser_do_write(dev->parser); } --- -1.7.12.1 - diff --git a/0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch b/0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch index a135563..1f4df3a 100644 --- a/0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch +++ b/0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch @@ -42,6 +42,3 @@ index c7c8786..cdc8bc3 100644 uhci_fill_queue(s, &td); } link = curr_qh ? qh.link : td.link; --- -1.7.12.1 - diff --git a/0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch b/0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch index 365d586..4f909e2 100644 --- a/0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch +++ b/0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch @@ -32,6 +32,3 @@ index 025b374..5890d7a 100644 DEBUG_ARG("ack = %u", ack); DEBUG_ARG("seq = %u", seq); DEBUG_ARG("flags = %x", flags); --- -1.7.12.1 - diff --git a/0176-slirp-Fix-error-reported-by-static-code-analysis.patch b/0176-slirp-Fix-error-reported-by-static-code-analysis.patch index 7f2a90a..6ec5eb7 100644 --- a/0176-slirp-Fix-error-reported-by-static-code-analysis.patch +++ b/0176-slirp-Fix-error-reported-by-static-code-analysis.patch @@ -32,6 +32,3 @@ index 5890d7a..1542e43 100644 return; tlen = 0; m->m_data += IF_MAXLINKHDR; --- -1.7.12.1 - diff --git a/0177-slirp-improve-TFTP-performance.patch b/0177-slirp-improve-TFTP-performance.patch index 65dce5d..24011eb 100644 --- a/0177-slirp-improve-TFTP-performance.patch +++ b/0177-slirp-improve-TFTP-performance.patch @@ -101,6 +101,3 @@ index 72e5e91..9c364ea 100644 struct in_addr client_ip; uint16_t client_port; --- -1.7.12.1 - diff --git a/0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch b/0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch index 0a87572..356eebb 100644 --- a/0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch +++ b/0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch @@ -116,6 +116,3 @@ index 9c364ea..51704e4 100644 int timestamp; }; --- -1.7.12.1 - diff --git a/0179-slirp-Implement-TFTP-Blocksize-option.patch b/0179-slirp-Implement-TFTP-Blocksize-option.patch index 38ebba3..97eafe5 100644 --- a/0179-slirp-Implement-TFTP-Blocksize-option.patch +++ b/0179-slirp-Implement-TFTP-Blocksize-option.patch @@ -118,6 +118,3 @@ index c6a5df2..37b0387 100644 spt->block_nr = 0; tftp_send_next_block(spt, tp); } --- -1.7.12.1 - diff --git a/0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch b/0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch index 00cb718..214916c 100644 --- a/0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch +++ b/0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch @@ -58,6 +58,3 @@ index 3009bd5..5e0cad5 100644 enum { SRP_RSP_FLAG_RSPVALID = 1 << 0, --- -1.7.12.1 - diff --git a/0181-Spelling-fixes-in-comments-and-documentation.patch b/0181-Spelling-fixes-in-comments-and-documentation.patch index 5b696ed..299116b 100644 --- a/0181-Spelling-fixes-in-comments-and-documentation.patch +++ b/0181-Spelling-fixes-in-comments-and-documentation.patch @@ -178,6 +178,3 @@ index 6b42e35..360543b 100644 Only the formats @code{qcow2}, @code{qed} and @code{vdi} support consistency checks. --- -1.7.12.1 - diff --git a/0182-console-Clean-up-bytes-per-pixel-calculation.patch b/0182-console-Clean-up-bytes-per-pixel-calculation.patch index 7815a2d..45fde5f 100644 --- a/0182-console-Clean-up-bytes-per-pixel-calculation.patch +++ b/0182-console-Clean-up-bytes-per-pixel-calculation.patch @@ -46,6 +46,3 @@ index 3b5cabb..8b5e21d 100644 pf.rmask = 0x00007c00; pf.gmask = 0x000003E0; pf.bmask = 0x0000001F; --- -1.7.12.1 - diff --git a/0183-qapi-Fix-enumeration-typo-error.patch b/0183-qapi-Fix-enumeration-typo-error.patch index 8fc3e9f..a5cabb7 100644 --- a/0183-qapi-Fix-enumeration-typo-error.patch +++ b/0183-qapi-Fix-enumeration-typo-error.patch @@ -49,6 +49,3 @@ index 8ddde12..29dacb5 100644 # # @client: Mouse cursor position is determined by the client. # --- -1.7.12.1 - diff --git a/0184-kvm-Fix-warning-from-static-code-analysis.patch b/0184-kvm-Fix-warning-from-static-code-analysis.patch index 87ad81d..18d845b 100644 --- a/0184-kvm-Fix-warning-from-static-code-analysis.patch +++ b/0184-kvm-Fix-warning-from-static-code-analysis.patch @@ -44,6 +44,3 @@ index 90c71f9..08d6051 100644 } g_free(s); --- -1.7.12.1 - diff --git a/0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch b/0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch index 7fcc366..383fe8e 100644 --- a/0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch +++ b/0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch @@ -49,6 +49,3 @@ index 5a1173e..47977de 100644 return ret; } --- -1.7.12.1 - diff --git a/0186-net-notify-iothread-after-flushing-queue.patch b/0186-net-notify-iothread-after-flushing-queue.patch index b6a9f65..9dd44b0 100644 --- a/0186-net-notify-iothread-after-flushing-queue.patch +++ b/0186-net-notify-iothread-after-flushing-queue.patch @@ -100,6 +100,3 @@ index 9d44a9b..fc02b33 100644 +bool qemu_net_queue_flush(NetQueue *queue); #endif /* QEMU_NET_QUEUE_H */ --- -1.7.12.1 - diff --git a/0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch b/0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch index 9d61ff8..d9b13ef 100644 --- a/0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch +++ b/0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch @@ -46,6 +46,3 @@ index ae8a6c5..ec3a7c4 100644 } static void --- -1.7.12.1 - diff --git a/0188-xen-flush-queue-when-getting-an-event.patch b/0188-xen-flush-queue-when-getting-an-event.patch index 6c52eb4..25b1087 100644 --- a/0188-xen-flush-queue-when-getting-an-event.patch +++ b/0188-xen-flush-queue-when-getting-an-event.patch @@ -32,6 +32,3 @@ index 8b79bfb..cf7d559 100644 } static int net_free(struct XenDevice *xendev) --- -1.7.12.1 - diff --git a/0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch b/0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch index 4e2df82..a256edb 100644 --- a/0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch +++ b/0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch @@ -67,6 +67,3 @@ index 50d117e..5b23116 100644 } if (rfd_command & COMMAND_S) { /* S bit is set. */ --- -1.7.12.1 - diff --git a/0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch b/0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch index f94a29e..7393b14 100644 --- a/0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch +++ b/0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch @@ -60,6 +60,3 @@ index 76a8336..1303819 100644 } ssize_t qemu_sendv_packet_async(NetClientState *sender, --- -1.7.12.1 - diff --git a/0191-net-do-not-report-queued-packets-as-sent.patch b/0191-net-do-not-report-queued-packets-as-sent.patch index b6deca0..ee11193 100644 --- a/0191-net-do-not-report-queued-packets-as-sent.patch +++ b/0191-net-do-not-report-queued-packets-as-sent.patch @@ -98,6 +98,3 @@ index 6e64091..254f280 100644 } ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt); --- -1.7.12.1 - diff --git a/0192-net-add-netdev-options-to-man-page.patch b/0192-net-add-netdev-options-to-man-page.patch index b0272da..bb3f5cb 100644 --- a/0192-net-add-netdev-options-to-man-page.patch +++ b/0192-net-add-netdev-options-to-man-page.patch @@ -76,6 +76,3 @@ index 1af4fec..1021ab7 100644 @item -net vde[,vlan=@var{n}][,name=@var{name}][,sock=@var{socketpath}] [,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}] Connect VLAN @var{n} to PORT @var{n} of a vde switch running on host and listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname} --- -1.7.12.1 - diff --git a/0193-net-clean-up-usbnet_receive.patch b/0193-net-clean-up-usbnet_receive.patch index c92890e..01f2463 100644 --- a/0193-net-clean-up-usbnet_receive.patch +++ b/0193-net-clean-up-usbnet_receive.patch @@ -75,6 +75,3 @@ index c84892c..0b5cb71 100644 s->in_ptr = 0; return size; } --- -1.7.12.1 - diff --git a/0194-net-fix-usbnet_receive-packet-drops.patch b/0194-net-fix-usbnet_receive-packet-drops.patch index bbe1c76..c129091 100644 --- a/0194-net-fix-usbnet_receive-packet-drops.patch +++ b/0194-net-fix-usbnet_receive-packet-drops.patch @@ -76,6 +76,3 @@ index 0b5cb71..e4a4359 100644 if (is_rndis(s)) { struct rndis_packet_msg_type *msg; --- -1.7.12.1 - diff --git a/0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch b/0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch index 5cb7e1c..2a5f9bb 100644 --- a/0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch +++ b/0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch @@ -46,6 +46,3 @@ index ac157e3..650a8b4 100644 } static ssize_t net_hub_port_receive(NetClientState *nc, --- -1.7.12.1 - diff --git a/0196-net-asynchronous-send-receive-infrastructure-for-net.patch b/0196-net-asynchronous-send-receive-infrastructure-for-net.patch index 53f0722..3f1f1fc 100644 --- a/0196-net-asynchronous-send-receive-infrastructure-for-net.patch +++ b/0196-net-asynchronous-send-receive-infrastructure-for-net.patch @@ -128,6 +128,3 @@ index c172c24..54e32f0 100644 } static NetClientInfo net_socket_info = { --- -1.7.12.1 - diff --git a/0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch b/0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch index 9745eaa..81754e5 100644 --- a/0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch +++ b/0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch @@ -40,6 +40,3 @@ index 54e32f0..e5e4e8d 100644 } static void net_socket_send(void *opaque) --- -1.7.12.1 - diff --git a/0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch b/0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch index d318bf1..2cc4f59 100644 --- a/0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch +++ b/0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch @@ -92,6 +92,3 @@ index e5e4e8d..c3e55b8 100644 } static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size) --- -1.7.12.1 - diff --git a/0199-configure-fix-seccomp-check.patch b/0199-configure-fix-seccomp-check.patch index bf742c6..dd44ae1 100644 --- a/0199-configure-fix-seccomp-check.patch +++ b/0199-configure-fix-seccomp-check.patch @@ -40,6 +40,3 @@ index dcd8e7b..9e53cc2 100755 fi fi ########################################## --- -1.7.12.1 - diff --git a/0200-configure-properly-check-if-lrt-and-lm-is-needed.patch b/0200-configure-properly-check-if-lrt-and-lm-is-needed.patch index 2e9a949..a746373 100644 --- a/0200-configure-properly-check-if-lrt-and-lm-is-needed.patch +++ b/0200-configure-properly-check-if-lrt-and-lm-is-needed.patch @@ -75,6 +75,3 @@ index 9e53cc2..a1f256c 100755 fi if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \ --- -1.7.12.1 - diff --git a/0201-Revert-455aa1e08-and-c3767ed0eb.patch b/0201-Revert-455aa1e08-and-c3767ed0eb.patch index 5466652..3ec2dae 100644 --- a/0201-Revert-455aa1e08-and-c3767ed0eb.patch +++ b/0201-Revert-455aa1e08-and-c3767ed0eb.patch @@ -46,6 +46,3 @@ index 767da93..10d1504 100644 return len; } } --- -1.7.12.1 - diff --git a/0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch b/0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch index 74f8f39..a9caf4c 100644 --- a/0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch +++ b/0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch @@ -54,6 +54,3 @@ index 10d1504..7f0f895 100644 qemu_chr_generic_open(chr); } --- -1.7.12.1 - diff --git a/0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch b/0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch index cceb39c..dd7473a 100644 --- a/0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch +++ b/0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch @@ -47,6 +47,3 @@ index ad175db..3fdbbde 100644 qemu_put_ram_ptr(ptr); } len -= l; --- -1.7.12.1 - diff --git a/0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch b/0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch index d9001a5..291eba6 100644 --- a/0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch +++ b/0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch @@ -1,8 +1,8 @@ From 8daf993d3d75acea92ef5054c924c7d825ae812e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Wed, 19 Sep 2012 14:51:38 +0100 -Subject: [PATCH] arch_init.c: Improve '-soundhw help' for - non-HAS_AUDIO_CHOICE archs +Subject: [PATCH] arch_init.c: Improve '-soundhw help' for non-HAS_AUDIO_CHOICE + archs For architectures which don't set HAS_AUDIO_CHOICE, improve the '-soundhw help' message so that it doesn't simply print an empty @@ -38,6 +38,3 @@ index 47977de..f849f9b 100644 exit(!is_help_option(optarg)); } else { --- -1.7.12.1 - diff --git a/0205-xilinx_timer-Removed-comma-in-device-name.patch b/0205-xilinx_timer-Removed-comma-in-device-name.patch index 26b5d66..d225507 100644 --- a/0205-xilinx_timer-Removed-comma-in-device-name.patch +++ b/0205-xilinx_timer-Removed-comma-in-device-name.patch @@ -49,6 +49,3 @@ index b562bd0..053ba02 100644 .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(struct timerblock), .class_init = xilinx_timer_class_init, --- -1.7.12.1 - diff --git a/0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch b/0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch index e7b8ea1..c283e89 100644 --- a/0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch +++ b/0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch @@ -51,6 +51,3 @@ index 053ba02..c02e6ca 100644 xt->regs[R_TCSR] |= TCSR_TINT; if (xt->regs[R_TCSR] & TCSR_ARHT) --- -1.7.12.1 - diff --git a/0207-xilinx.h-Error-check-when-setting-links.patch b/0207-xilinx.h-Error-check-when-setting-links.patch index 924d91f..778d367 100644 --- a/0207-xilinx.h-Error-check-when-setting-links.patch +++ b/0207-xilinx.h-Error-check-when-setting-links.patch @@ -49,6 +49,3 @@ index df06a00..35d6681 100644 qdev_init_nofail(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); --- -1.7.12.1 - diff --git a/0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch b/0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch index 7c084bf..d966721 100644 --- a/0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch +++ b/0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch @@ -36,6 +36,3 @@ index c02e6ca..f410487 100644 xt->regs[R_TCSR] |= TCSR_TINT; if (xt->regs[R_TCSR] & TCSR_ARHT) --- -1.7.12.1 - diff --git a/0209-pflash_cfi01-fix-vendor-specific-extended-query.patch b/0209-pflash_cfi01-fix-vendor-specific-extended-query.patch index 40c0e51..76b03f8 100644 --- a/0209-pflash_cfi01-fix-vendor-specific-extended-query.patch +++ b/0209-pflash_cfi01-fix-vendor-specific-extended-query.patch @@ -44,6 +44,3 @@ index d1c7423..d56b51a 100644 return pfl; } --- -1.7.12.1 - diff --git a/0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch b/0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch index 17385e6..55066fd 100644 --- a/0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch +++ b/0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch @@ -31,6 +31,3 @@ index 61f8b45..25733fc 100644 Device Tree M: Peter Crosthwaite M: Alexander Graf --- -1.7.12.1 - diff --git a/0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch b/0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch index 856ed96..2d235aa 100644 --- a/0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch +++ b/0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch @@ -54,6 +54,3 @@ index 0b96165..ea16609 100644 default: return -1; } --- -1.7.12.1 - diff --git a/0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch b/0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch index d2d4b2d..171153a 100644 --- a/0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch +++ b/0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch @@ -34,6 +34,3 @@ index ea16609..fb001b9 100644 iscsilun->events = ev; } --- -1.7.12.1 - diff --git a/0213-scsi-disk-introduce-check_lba_range.patch b/0213-scsi-disk-introduce-check_lba_range.patch index 567728d..db8f050 100644 --- a/0213-scsi-disk-introduce-check_lba_range.patch +++ b/0213-scsi-disk-introduce-check_lba_range.patch @@ -77,6 +77,3 @@ index 1585683..3959603 100644 goto illegal_lba; } r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512); --- -1.7.12.1 - diff --git a/0214-scsi-disk-fix-check-for-out-of-range-LBA.patch b/0214-scsi-disk-fix-check-for-out-of-range-LBA.patch index 9deef86..f55ccd7 100644 --- a/0214-scsi-disk-fix-check-for-out-of-range-LBA.patch +++ b/0214-scsi-disk-fix-check-for-out-of-range-LBA.patch @@ -33,6 +33,3 @@ index 3959603..d621852 100644 } typedef struct UnmapCBData { --- -1.7.12.1 - diff --git a/0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch b/0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch index 840be83..659b920 100644 --- a/0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch +++ b/0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch @@ -38,6 +38,3 @@ index d621852..7ed1bde 100644 if (buflen > 36) { outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */ --- -1.7.12.1 - diff --git a/0216-audio-Fix-warning-from-static-code-analysis.patch b/0216-audio-Fix-warning-from-static-code-analysis.patch index d25383c..dfe9886 100644 --- a/0216-audio-Fix-warning-from-static-code-analysis.patch +++ b/0216-audio-Fix-warning-from-static-code-analysis.patch @@ -42,6 +42,3 @@ index 519432a..16f7880 100644 if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) { audio_print_settings (as); goto fail; --- -1.7.12.1 - diff --git a/0217-qemu-ga-Remove-unreachable-code-after-g_error.patch b/0217-qemu-ga-Remove-unreachable-code-after-g_error.patch index 5b64003..922fff9 100644 --- a/0217-qemu-ga-Remove-unreachable-code-after-g_error.patch +++ b/0217-qemu-ga-Remove-unreachable-code-after-g_error.patch @@ -35,6 +35,3 @@ index 7623079..b747470 100644 } return true; --- -1.7.12.1 - diff --git a/0218-qemu-sockets-Fix-potential-memory-leak.patch b/0218-qemu-sockets-Fix-potential-memory-leak.patch index 35d9a44..f48ad0b 100644 --- a/0218-qemu-sockets-Fix-potential-memory-leak.patch +++ b/0218-qemu-sockets-Fix-potential-memory-leak.patch @@ -27,6 +27,3 @@ index 361d890..037775b 100644 } /* create socket */ --- -1.7.12.1 - diff --git a/0219-cadence_uart-Fix-buffer-overflow.patch b/0219-cadence_uart-Fix-buffer-overflow.patch index 3dbf127..027dc64 100644 --- a/0219-cadence_uart-Fix-buffer-overflow.patch +++ b/0219-cadence_uart-Fix-buffer-overflow.patch @@ -30,6 +30,3 @@ index d98e531..f8afc4e 100644 return 0; } else if (offset == R_TX_RX) { uart_read_rx_fifo(s, &c); --- -1.7.12.1 - diff --git a/0220-lm4549-Fix-buffer-overflow.patch b/0220-lm4549-Fix-buffer-overflow.patch index 656c9aa..26e834c 100644 --- a/0220-lm4549-Fix-buffer-overflow.patch +++ b/0220-lm4549-Fix-buffer-overflow.patch @@ -42,6 +42,3 @@ index 80b3ec4..e0137d5 100644 DPRINTF("write_sample Buffer full\n"); return 0; } --- -1.7.12.1 - diff --git a/0221-ioh3420-Remove-unreachable-code.patch b/0221-ioh3420-Remove-unreachable-code.patch index e465486..99413a9 100644 --- a/0221-ioh3420-Remove-unreachable-code.patch +++ b/0221-ioh3420-Remove-unreachable-code.patch @@ -28,6 +28,3 @@ index 94a537c..4d31473 100644 } pcie_cap_root_init(d); rc = pcie_aer_init(d, IOH_EP_AER_OFFSET); --- -1.7.12.1 - diff --git a/0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch b/0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch index ef3cecd..aad88ee 100644 --- a/0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch +++ b/0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch @@ -60,6 +60,3 @@ index d56b51a..ac503cf 100644 default: /* Should never happen */ DPRINTF("%s: invalid write state\n", __func__); --- -1.7.12.1 - diff --git a/0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch b/0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch index 9f29c5e..c6ef610 100644 --- a/0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch +++ b/0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch @@ -85,6 +85,3 @@ index c681c33..49d7a52 100644 break; #endif #if defined(CONFIG_SDL) --- -1.7.12.1 - diff --git a/0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch b/0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch index 523d5f4..b95d4ee 100644 --- a/0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch +++ b/0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch @@ -31,6 +31,3 @@ index 8b5e21d..314f5a5 100644 } } else { if (s->nb_esc_params < MAX_ESC_PARAMS) --- -1.7.12.1 - diff --git a/0225-linux-user-Remove-redundant-null-check-and-replace-f.patch b/0225-linux-user-Remove-redundant-null-check-and-replace-f.patch index acb18c0..57d4f6c 100644 --- a/0225-linux-user-Remove-redundant-null-check-and-replace-f.patch +++ b/0225-linux-user-Remove-redundant-null-check-and-replace-f.patch @@ -37,6 +37,3 @@ index 6257a04..471d060 100644 return ret; } --- -1.7.12.1 - diff --git a/0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch b/0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch index e3cb65f..49d90a3 100644 --- a/0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch +++ b/0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch @@ -63,6 +63,3 @@ index e5c2bcd..15d9e4e 100644 #endif /* Error handling. */ --- -1.7.12.1 - diff --git a/0227-w32-Always-use-standard-instead-of-native-format-str.patch b/0227-w32-Always-use-standard-instead-of-native-format-str.patch index 91b7bba..5ef8430 100644 --- a/0227-w32-Always-use-standard-instead-of-native-format-str.patch +++ b/0227-w32-Always-use-standard-instead-of-native-format-str.patch @@ -47,6 +47,3 @@ index 07ba1f8..c734a71 100644 # endif #if defined(_WIN32) #define GCC_WEAK __attribute__((weak)) --- -1.7.12.1 - diff --git a/0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch b/0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch index 16473ea..64815ea 100644 --- a/0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch +++ b/0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch @@ -76,6 +76,3 @@ index b3e451b..8ba466d 100644 static inline void os_setup_signal_handling(void) {} static inline void os_daemonize(void) {} static inline void os_setup_post(void) {} --- -1.7.12.1 - diff --git a/0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch b/0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch index 19bbd20..19c876e 100644 --- a/0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch +++ b/0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch @@ -32,6 +32,3 @@ index 4a5266e..9ba3503 100644 dinfo->devaddr = devaddr; dinfo->type = type; dinfo->bus = bus_id; --- -1.7.12.1 - diff --git a/0230-block-correctly-set-the-keep_read_only-flag.patch b/0230-block-correctly-set-the-keep_read_only-flag.patch index ec1affa..95bde04 100644 --- a/0230-block-correctly-set-the-keep_read_only-flag.patch +++ b/0230-block-correctly-set-the-keep_read_only-flag.patch @@ -99,6 +99,3 @@ index 2e2be11..4d919c2 100644 #define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH) --- -1.7.12.1 - diff --git a/0231-configure-Allow-builds-without-any-system-or-user-em.patch b/0231-configure-Allow-builds-without-any-system-or-user-em.patch index d40c6dc..e7129bf 100644 --- a/0231-configure-Allow-builds-without-any-system-or-user-em.patch +++ b/0231-configure-Allow-builds-without-any-system-or-user-em.patch @@ -54,6 +54,3 @@ index a1f256c..f528146 100755 # see if system emulation was really requested case " $target_list " in *"-softmmu "*) softmmu=yes --- -1.7.12.1 - diff --git a/0232-Refactor-inet_connect_opts-function.patch b/0232-Refactor-inet_connect_opts-function.patch index bd8702f..8490f3a 100644 --- a/0232-Refactor-inet_connect_opts-function.patch +++ b/0232-Refactor-inet_connect_opts-function.patch @@ -202,6 +202,3 @@ index 037775b..22797bf 100644 } int inet_dgram_opts(QemuOpts *opts) --- -1.7.12.1 - diff --git a/0233-Separate-inet_connect-into-inet_connect-blocking-and.patch b/0233-Separate-inet_connect-into-inet_connect-blocking-and.patch index e017ef0..5ae4a00 100644 --- a/0233-Separate-inet_connect-into-inet_connect-blocking-and.patch +++ b/0233-Separate-inet_connect-into-inet_connect-blocking-and.patch @@ -183,6 +183,3 @@ index 385e345..01b2daf 100644 if (-1 == vs->lsock) { g_free(vs->display); vs->display = NULL; --- -1.7.12.1 - diff --git a/0234-Fix-address-handling-in-inet_nonblocking_connect.patch b/0234-Fix-address-handling-in-inet_nonblocking_connect.patch index 9e64c16..72eb695 100644 --- a/0234-Fix-address-handling-in-inet_nonblocking_connect.patch +++ b/0234-Fix-address-handling-in-inet_nonblocking_connect.patch @@ -364,6 +364,3 @@ index 80696aa..3e8aee9 100644 int inet_dgram_opts(QemuOpts *opts); const char *inet_strfamily(int family); --- -1.7.12.1 - diff --git a/0235-Clear-handler-only-for-valid-fd.patch b/0235-Clear-handler-only-for-valid-fd.patch index 3ddcd80..18e8ac7 100644 --- a/0235-Clear-handler-only-for-valid-fd.patch +++ b/0235-Clear-handler-only-for-valid-fd.patch @@ -27,6 +27,3 @@ index 1edeec5..22a05c4 100644 if (s->file) { DPRINTF("closing file\n"); --- -1.7.12.1 - diff --git a/0236-pl190-fix-read-of-VECTADDR.patch b/0236-pl190-fix-read-of-VECTADDR.patch index c306cb5..f9072f8 100644 --- a/0236-pl190-fix-read-of-VECTADDR.patch +++ b/0236-pl190-fix-read-of-VECTADDR.patch @@ -46,6 +46,3 @@ index cb50afb..7332f4d 100644 /* Reading this value with no pending interrupts is undefined. We return the default address. */ if (i == PL190_NUM_PRIO) --- -1.7.12.1 - diff --git a/0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch b/0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch index 2f3f36d..56ea7e2 100644 --- a/0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch +++ b/0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch @@ -1,8 +1,8 @@ From f4a5b8185d067430cd605a740af654cd1cd2e2aa Mon Sep 17 00:00:00 2001 From: Meador Inge Date: Wed, 26 Sep 2012 16:46:28 +0100 -Subject: [PATCH] hw/armv7m_nvic: Correctly register GIC region when setting - up NVIC +Subject: [PATCH] hw/armv7m_nvic: Correctly register GIC region when setting up + NVIC When setting up the NVIC memory regions the memory range 0x100..0xcff is aliased to an IO memory region that belongs @@ -35,6 +35,3 @@ index 6a0832e..5c09116 100644 /* Map the whole thing into system memory at the location required * by the v7M architecture. */ --- -1.7.12.1 - diff --git a/0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch b/0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch index 4fd2f11..088dcc5 100644 --- a/0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch +++ b/0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch @@ -51,6 +51,3 @@ index b615844..454c2bb 100644 /* VE_NORFLASH1: not modelled */ sram_size = 0x2000000; --- -1.7.12.1 - diff --git a/0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch b/0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch index 772314f..856d75b 100644 --- a/0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch +++ b/0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch @@ -31,6 +31,3 @@ index 6790180..acb9369 100644 break; } break; --- -1.7.12.1 - diff --git a/0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch b/0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch index 37e5c3a..31a8f10 100644 --- a/0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch +++ b/0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch @@ -39,6 +39,3 @@ index b29256a..91497e8 100644 } } --- -1.7.12.1 - diff --git a/0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch b/0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch index 7edb0b2..8653846 100644 --- a/0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch +++ b/0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch @@ -61,6 +61,3 @@ index abd847f..38098f7 100644 if ((opcode <= MAX_HCALL_OPCODE) && ((opcode & 0x3) == 0)) { spapr_hcall_fn fn = papr_hypercall_table[opcode / 4]; --- -1.7.12.1 - diff --git a/0242-update-VERSION-for-v1.2.1.patch b/0242-update-VERSION-for-v1.2.1.patch index 5a2045d..9bf36cc 100644 --- a/0242-update-VERSION-for-v1.2.1.patch +++ b/0242-update-VERSION-for-v1.2.1.patch @@ -15,6 +15,3 @@ index 26aaba0..6085e94 100644 @@ -1 +1 @@ -1.2.0 +1.2.1 --- -1.7.12.1 - diff --git a/0301-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch b/0301-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch new file mode 100644 index 0000000..dc0ed3e --- /dev/null +++ b/0301-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch @@ -0,0 +1,35 @@ +From abd9b89fe95879eb73ff4728397de6a390464de3 Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Wed, 17 Oct 2012 19:09:25 +0200 +Subject: [PATCH] configure: Fix CONFIG_QEMU_HELPERDIR generation + +We need to evaluate $libexecdir in configure, otherwise we literally end +up with "${prefix}/libexec" instead of the absolute path as +CONFIG_QEMU_HELPERDIR. + +Signed-off-by: Jan Kiszka +Signed-off-by: Aurelien Jarno +(cherry picked from commit 38f419f35225decdbaea9fe1fd00218f8924ce84) + +Conflicts: + + configure + +Signed-off-by: Michael Roth +--- + configure | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure b/configure +index f528146..2de0900 100755 +--- a/configure ++++ b/configure +@@ -3201,7 +3201,7 @@ echo "sysconfdir=$sysconfdir" >> $config_host_mak + echo "qemu_confdir=$qemu_confdir" >> $config_host_mak + echo "qemu_datadir=$qemu_datadir" >> $config_host_mak + echo "qemu_docdir=$qemu_docdir" >> $config_host_mak +-echo "CONFIG_QEMU_HELPERDIR=\"$libexecdir\"" >> $config_host_mak ++echo "CONFIG_QEMU_HELPERDIR=\"`eval echo $libexecdir`\"" >> $config_host_mak + + echo "ARCH=$ARCH" >> $config_host_mak + if test "$debug_tcg" = "yes" ; then diff --git a/0302-fix-CONFIG_QEMU_HELPERDIR-generation-again.patch b/0302-fix-CONFIG_QEMU_HELPERDIR-generation-again.patch new file mode 100644 index 0000000..6345999 --- /dev/null +++ b/0302-fix-CONFIG_QEMU_HELPERDIR-generation-again.patch @@ -0,0 +1,37 @@ +From 6cfdf00d58feb60e60a4844dc073a5995e6c08d5 Mon Sep 17 00:00:00 2001 +From: Michael Tokarev +Date: Sun, 21 Oct 2012 22:52:54 +0400 +Subject: [PATCH] fix CONFIG_QEMU_HELPERDIR generation again + +commit 38f419f35225 fixed a breakage with CONFIG_QEMU_HELPERDIR +which has been introduced by 8bf188aa18ef7a8. But while techinically +that fix has been correct, all other similar variables are handled +differently. Make it consistent, and let scripts/create_config +expand and capitalize the variable properly like for all other +qemu_*dir variables. + +Signed-off-by: Michael Tokarev +(cherry picked from commit f354b1a1ee7a1c72d51b42808724a2b10eec315f) + +Conflicts: + + configure + +Signed-off-by: Michael Roth +--- + configure | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure b/configure +index 2de0900..4d11fe3 100755 +--- a/configure ++++ b/configure +@@ -3201,7 +3201,7 @@ echo "sysconfdir=$sysconfdir" >> $config_host_mak + echo "qemu_confdir=$qemu_confdir" >> $config_host_mak + echo "qemu_datadir=$qemu_datadir" >> $config_host_mak + echo "qemu_docdir=$qemu_docdir" >> $config_host_mak +-echo "CONFIG_QEMU_HELPERDIR=\"`eval echo $libexecdir`\"" >> $config_host_mak ++echo "qemu_helperdir=$libexecdir" >> $config_host_mak + + echo "ARCH=$ARCH" >> $config_host_mak + if test "$debug_tcg" = "yes" ; then diff --git a/0303-ui-vnc-Only-report-use-TIGHT_PNG-encoding-if-enabled.patch b/0303-ui-vnc-Only-report-use-TIGHT_PNG-encoding-if-enabled.patch new file mode 100644 index 0000000..b31d4b1 --- /dev/null +++ b/0303-ui-vnc-Only-report-use-TIGHT_PNG-encoding-if-enabled.patch @@ -0,0 +1,39 @@ +From c441420055790934d7f344800a46c7ae644002a4 Mon Sep 17 00:00:00 2001 +From: Joel Martin +Date: Wed, 16 May 2012 12:54:25 +0000 +Subject: [PATCH] ui/vnc: Only report/use TIGHT_PNG encoding if enabled. + +If TIGHT_PNG is not enabled by the --enable-vnc-png configure flag +then do not report to the client that it is supported. + +Also, since TIGHT_PNG is the same as the TIGHT encoding but with the +filter/copy replaced with PNG data, adding it to the supported +encodings list when it is disabled will cause the TIGHT encoding to be +used even though the client requested TIGHT_PNG. + +Signed-off-by: Joel Martin +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit fe3e7f2dc05225cdd2ba40defcd4e2581bebc5e0) + +Signed-off-by: Michael Roth +--- + ui/vnc.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ui/vnc.c b/ui/vnc.c +index 01b2daf..18ec101 100644 +--- a/ui/vnc.c ++++ b/ui/vnc.c +@@ -1802,10 +1802,12 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) + vs->features |= VNC_FEATURE_TIGHT_MASK; + vs->vnc_encoding = enc; + break; ++#ifdef CONFIG_VNC_PNG + case VNC_ENCODING_TIGHT_PNG: + vs->features |= VNC_FEATURE_TIGHT_PNG_MASK; + vs->vnc_encoding = enc; + break; ++#endif + case VNC_ENCODING_ZLIB: + vs->features |= VNC_FEATURE_ZLIB_MASK; + vs->vnc_encoding = enc; diff --git a/0304-vnc-fix-info-vnc-with-vnc-.-reverse-on.patch b/0304-vnc-fix-info-vnc-with-vnc-.-reverse-on.patch new file mode 100644 index 0000000..b14a049 --- /dev/null +++ b/0304-vnc-fix-info-vnc-with-vnc-.-reverse-on.patch @@ -0,0 +1,51 @@ +From 07a824f03fe1e820b5a0f19c380b19595ac0caa9 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 10 Oct 2012 14:30:58 +0200 +Subject: [PATCH] vnc: fix "info vnc" with "-vnc ..., reverse=on" + +When reverse connection is in use, there is no active VNC server +socket. Because of this, getsockopt(-1, ...) is attempted and +the following error is emitted: + + $ socat TCP-LISTEN:5900,reuseaddr TCP-LISTEN:5901,reuseaddr & + $ x86_64-softmmu/qemu-system-x86_64 -vnc localhost:5900,reverse -monitor stdio + QEMU 1.2.50 monitor - type 'help' for more information + (qemu) info vnc + An undefined error has occurred + +Because however the host, family, service and auth fields are +optional, we can just exit if there is no active server socket. + + $ x86_64-softmmu/qemu-system-x86_64 -vnc localhost:5900,reverse -monitor stdio + QEMU 1.2.50 monitor - type 'help' for more information + (qemu) info vnc + Server: + Client: + address: 127.0.0.1:5900 + x509_dname: none + username: none + +Signed-off-by: Paolo Bonzini +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 417b0b88904fe1dd8c41bff8092dfbab0134d9cb) + +Signed-off-by: Michael Roth +--- + ui/vnc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/ui/vnc.c b/ui/vnc.c +index 18ec101..66ae930 100644 +--- a/ui/vnc.c ++++ b/ui/vnc.c +@@ -372,6 +372,10 @@ VncInfo *qmp_query_vnc(Error **errp) + } + } + ++ if (vnc_display->lsock == -1) { ++ return info; ++ } ++ + if (getsockname(vnc_display->lsock, (struct sockaddr *)&sa, + &salen) == -1) { + error_set(errp, QERR_UNDEFINED_ERROR); diff --git a/0305-uhci-Raise-interrupt-when-requested-even-for-non-act.patch b/0305-uhci-Raise-interrupt-when-requested-even-for-non-act.patch new file mode 100644 index 0000000..880e7eb --- /dev/null +++ b/0305-uhci-Raise-interrupt-when-requested-even-for-non-act.patch @@ -0,0 +1,48 @@ +From 7fdcb0738e43e49ac3081cc28212c1b7985f8bae Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 10 Oct 2012 15:50:36 +0200 +Subject: [PATCH] uhci: Raise interrupt when requested even for non active tds + +According to the spec we must raise an interrupt when one is requested +even for non active tds. + +Linux depends on this, for bulk transfers it runs an inactivity timer +to work around a bug in early uhci revisions, when we take longer then +200 ms to process a packet, this timer goes of, and as part of the +handling Linux then unlinks the qh, and relinks it after the frindex +has increased by atleast 1, the problem is Linux only checks for the +frindex increases on an interrupt, and we don't send that, causing +the qh to go inactive for more then 32 frames, at which point we +consider the packet cancelled. + +Signed-off-by: Hans de Goede +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 883bca776daa43111e9c39008f0038f7c62ae723) + +Signed-off-by: Michael Roth +--- + hw/usb/hcd-uhci.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c +index cdc8bc3..c2f08e3 100644 +--- a/hw/usb/hcd-uhci.c ++++ b/hw/usb/hcd-uhci.c +@@ -826,8 +826,16 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, + USBEndpoint *ep; + + /* Is active ? */ +- if (!(td->ctrl & TD_CTRL_ACTIVE)) ++ if (!(td->ctrl & TD_CTRL_ACTIVE)) { ++ /* ++ * ehci11d spec page 22: "Even if the Active bit in the TD is already ++ * cleared when the TD is fetched ... an IOC interrupt is generated" ++ */ ++ if (td->ctrl & TD_CTRL_IOC) { ++ *int_mask |= 0x01; ++ } + return TD_RESULT_NEXT_QH; ++ } + + async = uhci_async_find_td(s, addr, td); + if (async) { diff --git a/0306-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch b/0306-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch new file mode 100644 index 0000000..52ee853 --- /dev/null +++ b/0306-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch @@ -0,0 +1,38 @@ +From d03ab137143aeae21ab7bb4e8cab72e1f49b8309 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Sun, 7 Oct 2012 17:03:35 +0200 +Subject: [PATCH] hw/qxl: qxl_dirty_surfaces: use uintptr_t + +As suggested by Paolo Bonzini, to avoid possible integer overflow issues. + +Signed-off-by: Alon Levy +Signed-off-by: Gerd Hoffmann +(cherry picked from commit c5825ac6c861bfe1a4adfa27517931b56079e298) + +Signed-off-by: Michael Roth +--- + hw/qxl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 59bf822..89e9ad9 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -1703,7 +1703,7 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata) + + static void qxl_dirty_surfaces(PCIQXLDevice *qxl) + { +- intptr_t vram_start; ++ uintptr_t vram_start; + int i; + + if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) { +@@ -1714,7 +1714,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) + qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset, + qxl->shadow_rom.surface0_area_size); + +- vram_start = (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); ++ vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); + + /* dirty the off-screen surfaces */ + for (i = 0; i < NUM_SURFACES; i++) { diff --git a/0307-qxl-always-update-displaysurface-on-resize.patch b/0307-qxl-always-update-displaysurface-on-resize.patch new file mode 100644 index 0000000..f719f87 --- /dev/null +++ b/0307-qxl-always-update-displaysurface-on-resize.patch @@ -0,0 +1,44 @@ +From 5100d7f2beedd5248337f956c74aee4300a00915 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 14 Sep 2012 22:09:23 +0200 +Subject: [PATCH] qxl: always update displaysurface on resize + +Don't try to be clever and skip displaysurface reinitialization in case +the size hasn't changed. Other parameters might have changed +nevertheless, for example depth or stride, resulting in rendering being +broken then. + +Trigger: boot linux guest with vesafb, start X11, make sure both vesafb +and X11 use the display same resolution. Then watch X11 screen being +upside down. + +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 0ec8df3974d2a4ff95b5fd4785b9bd3def7252f3) + +Signed-off-by: Michael Roth +--- + hw/qxl-render.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/hw/qxl-render.c b/hw/qxl-render.c +index e2e3fe2..b66c168 100644 +--- a/hw/qxl-render.c ++++ b/hw/qxl-render.c +@@ -99,7 +99,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) + { + VGACommonState *vga = &qxl->vga; + int i; +- DisplaySurface *surface = vga->ds->surface; + + if (qxl->guest_primary.resized) { + qxl->guest_primary.resized = 0; +@@ -112,9 +111,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) + qxl->guest_primary.qxl_stride, + qxl->guest_primary.bytes_pp, + qxl->guest_primary.bits_pp); +- } +- if (surface->width != qxl->guest_primary.surface.width || +- surface->height != qxl->guest_primary.surface.height) { + if (qxl->guest_primary.qxl_stride > 0) { + qemu_free_displaysurface(vga->ds); + qemu_create_displaysurface_from(qxl->guest_primary.surface.width, diff --git a/0308-rtc-fix-overflow-in-mktimegm.patch b/0308-rtc-fix-overflow-in-mktimegm.patch new file mode 100644 index 0000000..91254b1 --- /dev/null +++ b/0308-rtc-fix-overflow-in-mktimegm.patch @@ -0,0 +1,97 @@ +From 6dfc8874df8648e37f19f099cb8c2efee19bcee3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 1 Oct 2012 14:22:06 +0200 +Subject: [PATCH] rtc: fix overflow in mktimegm + +When setting a date in 1980, Linux is actually disregarding the century +byte and setting the year to 2080. This causes a year-2038 overflow +in mktimegm. Fix this by doing the days-to-seconds computation in +64-bit math. + +Reported-by: Lucas Meneghel Rodrigues +Signed-off-by: Paolo Bonzini +Signed-off-by: Anthony Liguori +(cherry picked from commit b6db4aca20e9af4f62c9c9e08b9b9672a6ed3390) + +Signed-off-by: Michael Roth +--- + cutils.c | 2 +- + tests/rtc-test.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 46 insertions(+), 1 deletion(-) + +diff --git a/cutils.c b/cutils.c +index 8ef648f..8edd8fa 100644 +--- a/cutils.c ++++ b/cutils.c +@@ -115,7 +115,7 @@ time_t mktimegm(struct tm *tm) + m += 12; + y--; + } +- t = 86400 * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + ++ t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + + y / 400 - 719469); + t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; + return t; +diff --git a/tests/rtc-test.c b/tests/rtc-test.c +index f23ac3a..2b9aa63 100644 +--- a/tests/rtc-test.c ++++ b/tests/rtc-test.c +@@ -179,6 +179,50 @@ static void check_time(int wiggle) + + static int wiggle = 2; + ++static void set_year(void) ++{ ++ /* Set BCD mode */ ++ cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_DM); ++ cmos_write(RTC_REG_A, 0x76); ++ cmos_write(RTC_YEAR, 0x11); ++ cmos_write(RTC_MONTH, 0x02); ++ cmos_write(RTC_DAY_OF_MONTH, 0x02); ++ cmos_write(RTC_HOURS, 0x02); ++ cmos_write(RTC_MINUTES, 0x04); ++ cmos_write(RTC_SECONDS, 0x58); ++ cmos_write(RTC_REG_A, 0x26); ++ ++ g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); ++ g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); ++ g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11); ++ ++ /* Set a date in 2080 to ensure there is no year-2038 overflow. */ ++ cmos_write(RTC_REG_A, 0x76); ++ cmos_write(RTC_YEAR, 0x80); ++ cmos_write(RTC_REG_A, 0x26); ++ ++ g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); ++ g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); ++ g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x80); ++ ++ cmos_write(RTC_REG_A, 0x76); ++ cmos_write(RTC_YEAR, 0x11); ++ cmos_write(RTC_REG_A, 0x26); ++ ++ g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); ++ g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); ++ g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); ++ g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11); ++} ++ + static void bcd_check_time(void) + { + /* Set BCD mode */ +@@ -269,6 +313,7 @@ int main(int argc, char **argv) + qtest_add_func("/rtc/bcd/check-time", bcd_check_time); + qtest_add_func("/rtc/dec/check-time", dec_check_time); + qtest_add_func("/rtc/alarm-time", alarm_time); ++ qtest_add_func("/rtc/set-year", set_year); + qtest_add_func("/rtc/fuzz-registers", fuzz_registers); + ret = g_test_run(); + diff --git a/0309-hw-Fix-return-value-check-for-bdrv_read-bdrv_write.patch b/0309-hw-Fix-return-value-check-for-bdrv_read-bdrv_write.patch new file mode 100644 index 0000000..262bc39 --- /dev/null +++ b/0309-hw-Fix-return-value-check-for-bdrv_read-bdrv_write.patch @@ -0,0 +1,198 @@ +From 4c9e1e2839d81b65a1b4a3a150c793d577e4ce70 Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Sun, 23 Sep 2012 08:51:01 +0200 +Subject: [PATCH] hw: Fix return value check for bdrv_read, bdrv_write + +Those functions return -errno in case of an error. +The old code would typically only detect EPERM (1) errors. + +Signed-off-by: Stefan Weil +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 7a608f562ebd91e811ed0b725e528c894e4f19c4) + +Signed-off-by: Michael Roth +--- + hw/nand.c | 34 ++++++++++++++++++++++------------ + hw/onenand.c | 2 +- + hw/sd.c | 16 +++++++++------- + 3 files changed, 32 insertions(+), 20 deletions(-) + +diff --git a/hw/nand.c b/hw/nand.c +index e9501ae..01f3ada 100644 +--- a/hw/nand.c ++++ b/hw/nand.c +@@ -654,7 +654,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) + sector = SECTOR(s->addr); + off = (s->addr & PAGE_MASK) + s->offset; + soff = SECTOR_OFFSET(s->addr); +- if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) { ++ if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) < 0) { + printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); + return; + } +@@ -666,21 +666,23 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) + MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE)); + } + +- if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) ++ if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) < 0) { + printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); ++ } + } else { + off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset; + sector = off >> 9; + soff = off & 0x1ff; +- if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) { ++ if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) < 0) { + printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); + return; + } + + mem_and(iobuf + soff, s->io, s->iolen); + +- if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) ++ if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) < 0) { + printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); ++ } + } + s->offset = 0; + } +@@ -704,31 +706,37 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s) + i = SECTOR(addr); + page = SECTOR(addr + (ADDR_SHIFT + s->erase_shift)); + for (; i < page; i ++) +- if (bdrv_write(s->bdrv, i, iobuf, 1) == -1) ++ if (bdrv_write(s->bdrv, i, iobuf, 1) < 0) { + printf("%s: write error in sector %" PRIu64 "\n", __func__, i); ++ } + } else { + addr = PAGE_START(addr); + page = addr >> 9; +- if (bdrv_read(s->bdrv, page, iobuf, 1) == -1) ++ if (bdrv_read(s->bdrv, page, iobuf, 1) < 0) { + printf("%s: read error in sector %" PRIu64 "\n", __func__, page); ++ } + memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1); +- if (bdrv_write(s->bdrv, page, iobuf, 1) == -1) ++ if (bdrv_write(s->bdrv, page, iobuf, 1) < 0) { + printf("%s: write error in sector %" PRIu64 "\n", __func__, page); ++ } + + memset(iobuf, 0xff, 0x200); + i = (addr & ~0x1ff) + 0x200; + for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200; + i < addr; i += 0x200) +- if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) == -1) ++ if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) < 0) { + printf("%s: write error in sector %" PRIu64 "\n", + __func__, i >> 9); ++ } + + page = i >> 9; +- if (bdrv_read(s->bdrv, page, iobuf, 1) == -1) ++ if (bdrv_read(s->bdrv, page, iobuf, 1) < 0) { + printf("%s: read error in sector %" PRIu64 "\n", __func__, page); ++ } + memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1); +- if (bdrv_write(s->bdrv, page, iobuf, 1) == -1) ++ if (bdrv_write(s->bdrv, page, iobuf, 1) < 0) { + printf("%s: write error in sector %" PRIu64 "\n", __func__, page); ++ } + } + } + +@@ -740,18 +748,20 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, + + if (s->bdrv) { + if (s->mem_oob) { +- if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) == -1) ++ if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) < 0) { + printf("%s: read error in sector %" PRIu64 "\n", + __func__, SECTOR(addr)); ++ } + memcpy(s->io + SECTOR_OFFSET(s->addr) + PAGE_SIZE, + s->storage + (PAGE(s->addr) << OOB_SHIFT), + OOB_SIZE); + s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset; + } else { + if (bdrv_read(s->bdrv, PAGE_START(addr) >> 9, +- s->io, (PAGE_SECTORS + 2)) == -1) ++ s->io, (PAGE_SECTORS + 2)) < 0) { + printf("%s: read error in sector %" PRIu64 "\n", + __func__, PAGE_START(addr) >> 9); ++ } + s->ioaddr = s->io + (PAGE_START(addr) & 0x1ff) + offset; + } + } else { +diff --git a/hw/onenand.c b/hw/onenand.c +index db6af68..0f7b755 100644 +--- a/hw/onenand.c ++++ b/hw/onenand.c +@@ -351,7 +351,7 @@ static inline int onenand_erase(OneNANDState *s, int sec, int num) + for (; num > 0; num--, sec++) { + if (s->bdrv_cur) { + int erasesec = s->secs_cur + (sec >> 5); +- if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1)) { ++ if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1) < 0) { + goto fail; + } + if (bdrv_read(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) { +diff --git a/hw/sd.c b/hw/sd.c +index ec26407..297580a 100644 +--- a/hw/sd.c ++++ b/hw/sd.c +@@ -1407,7 +1407,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len) + + DPRINTF("sd_blk_read: addr = 0x%08llx, len = %d\n", + (unsigned long long) addr, len); +- if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { ++ if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) < 0) { + fprintf(stderr, "sd_blk_read: read error on host side\n"); + return; + } +@@ -1415,7 +1415,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len) + if (end > (addr & ~511) + 512) { + memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511)); + +- if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { ++ if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) < 0) { + fprintf(stderr, "sd_blk_read: read error on host side\n"); + return; + } +@@ -1429,29 +1429,31 @@ static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len) + uint64_t end = addr + len; + + if ((addr & 511) || len < 512) +- if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { ++ if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) < 0) { + fprintf(stderr, "sd_blk_write: read error on host side\n"); + return; + } + + if (end > (addr & ~511) + 512) { + memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511)); +- if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { ++ if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) { + fprintf(stderr, "sd_blk_write: write error on host side\n"); + return; + } + +- if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { ++ if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) < 0) { + fprintf(stderr, "sd_blk_write: read error on host side\n"); + return; + } + memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511); +- if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1) ++ if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) < 0) { + fprintf(stderr, "sd_blk_write: write error on host side\n"); ++ } + } else { + memcpy(sd->buf + (addr & 511), sd->data, len); +- if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) ++ if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) { + fprintf(stderr, "sd_blk_write: write error on host side\n"); ++ } + } + } + diff --git a/0310-target-i386-Allow-tsc-frequency-to-be-larger-then-2..patch b/0310-target-i386-Allow-tsc-frequency-to-be-larger-then-2..patch new file mode 100644 index 0000000..661749f --- /dev/null +++ b/0310-target-i386-Allow-tsc-frequency-to-be-larger-then-2..patch @@ -0,0 +1,30 @@ +From 4c512ed2aa98b5219b84fa98e8b3ac9ef0128436 Mon Sep 17 00:00:00 2001 +From: Don Slutz +Date: Fri, 21 Sep 2012 20:13:13 -0400 +Subject: [PATCH] target-i386: Allow tsc-frequency to be larger then 2.147G + +The check using INT_MAX (2147483647) is wrong in this case. + +Signed-off-by: Fred Oliveira +Signed-off-by: Don Slutz +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 2e84849aa2cc7f220d3b3668f5f7e3c57bb1b590) + +Signed-off-by: Michael Roth +--- + target-i386/cpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target-i386/cpu.c b/target-i386/cpu.c +index 423e009..cbc172e 100644 +--- a/target-i386/cpu.c ++++ b/target-i386/cpu.c +@@ -846,7 +846,7 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque, + { + X86CPU *cpu = X86_CPU(obj); + const int64_t min = 0; +- const int64_t max = INT_MAX; ++ const int64_t max = INT64_MAX; + int64_t value; + + visit_type_int(v, &value, name, errp); diff --git a/0311-e1000-drop-check_rxov-always-treat-RX-ring-with-RDH-.patch b/0311-e1000-drop-check_rxov-always-treat-RX-ring-with-RDH-.patch new file mode 100644 index 0000000..327854c --- /dev/null +++ b/0311-e1000-drop-check_rxov-always-treat-RX-ring-with-RDH-.patch @@ -0,0 +1,62 @@ +From 0b8f2583c9cd2b06b422c80ceec6a7f2641fc4e0 Mon Sep 17 00:00:00 2001 +From: Dmitry Fleytman +Date: Fri, 19 Oct 2012 07:56:55 +0200 +Subject: [PATCH] e1000: drop check_rxov, always treat RX ring with RDH == RDT + as empty + +Real HW always treats RX ring with RDH == RDT as empty. +Emulation is supposed to behave the same. + +Reported-by: Chris Webb +Reported-by: Richard Davies +Signed-off-by: Dmitry Fleytman +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit e5b8b0d4ba29fe1268ba049519a1b0cf8552a21a) + +Signed-off-by: Michael Roth +--- + hw/e1000.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/hw/e1000.c b/hw/e1000.c +index ec3a7c4..4d4ac32 100644 +--- a/hw/e1000.c ++++ b/hw/e1000.c +@@ -92,7 +92,6 @@ typedef struct E1000State_st { + + uint32_t rxbuf_size; + uint32_t rxbuf_min_shift; +- int check_rxov; + struct e1000_tx { + unsigned char header[256]; + unsigned char vlan_header[4]; +@@ -741,11 +740,11 @@ static bool e1000_has_rxbufs(E1000State *s, size_t total_size) + int bufs; + /* Fast-path short packets */ + if (total_size <= s->rxbuf_size) { +- return s->mac_reg[RDH] != s->mac_reg[RDT] || !s->check_rxov; ++ return s->mac_reg[RDH] != s->mac_reg[RDT]; + } + if (s->mac_reg[RDH] < s->mac_reg[RDT]) { + bufs = s->mac_reg[RDT] - s->mac_reg[RDH]; +- } else if (s->mac_reg[RDH] > s->mac_reg[RDT] || !s->check_rxov) { ++ } else if (s->mac_reg[RDH] > s->mac_reg[RDT]) { + bufs = s->mac_reg[RDLEN] / sizeof(struct e1000_rx_desc) + + s->mac_reg[RDT] - s->mac_reg[RDH]; + } else { +@@ -848,7 +847,6 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size) + + if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) + s->mac_reg[RDH] = 0; +- s->check_rxov = 1; + /* see comment in start_xmit; same here */ + if (s->mac_reg[RDH] == rdh_start) { + DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n", +@@ -925,7 +923,6 @@ mac_writereg(E1000State *s, int index, uint32_t val) + static void + set_rdt(E1000State *s, int index, uint32_t val) + { +- s->check_rxov = 0; + s->mac_reg[index] = val & 0xffff; + if (e1000_has_rxbufs(s, 1)) { + qemu_flush_queued_packets(&s->nic->nc); diff --git a/0312-memory-fix-rendering-of-a-region-obscured-by-another.patch b/0312-memory-fix-rendering-of-a-region-obscured-by-another.patch new file mode 100644 index 0000000..e423b4c --- /dev/null +++ b/0312-memory-fix-rendering-of-a-region-obscured-by-another.patch @@ -0,0 +1,54 @@ +From 4d172af076079d753cb666af31d93ed9a7b452ff Mon Sep 17 00:00:00 2001 +From: Avi Kivity +Date: Mon, 29 Oct 2012 18:22:36 +0200 +Subject: [PATCH] memory: fix rendering of a region obscured by another + +The memory core drops regions that are hidden by another region (for example, +during BAR sizing), but it doesn't do so correctly if the lower address of the +existing range is below the lower address of the new range. + +Example (qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta + -append "console=ttyS0" -nographic -vga cirrus): + +Existing range: 10000000-107fffff +New range: 100a0000-100bffff + +Correct behaviour: drop new range +Incorrect behaviour: add new range + +Fix by taking this case into account (previously we only considered +equal lower boundaries). + +Tested-by: Aurelien Jarno +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori +(cherry picked from commit d26a8caea3f160782841efb87b5e8bea606b512b) + +Signed-off-by: Michael Roth +--- + memory.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/memory.c b/memory.c +index d528d1f..7144020 100644 +--- a/memory.c ++++ b/memory.c +@@ -538,12 +538,12 @@ static void render_memory_region(FlatView *view, + offset_in_region += int128_get64(now); + int128_subfrom(&remain, now); + } +- if (int128_eq(base, view->ranges[i].addr.start)) { +- now = int128_min(remain, view->ranges[i].addr.size); +- int128_addto(&base, now); +- offset_in_region += int128_get64(now); +- int128_subfrom(&remain, now); +- } ++ now = int128_sub(int128_min(int128_add(base, remain), ++ addrrange_end(view->ranges[i].addr)), ++ base); ++ int128_addto(&base, now); ++ offset_in_region += int128_get64(now); ++ int128_subfrom(&remain, now); + } + if (int128_nz(remain)) { + fr.mr = mr; diff --git a/0313-s390x-fix-initrd-in-virtio-machine.patch b/0313-s390x-fix-initrd-in-virtio-machine.patch new file mode 100644 index 0000000..4cf28c7 --- /dev/null +++ b/0313-s390x-fix-initrd-in-virtio-machine.patch @@ -0,0 +1,34 @@ +From a89b91d1d8a0bf914c44deaca4f743de6971bdc7 Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Wed, 19 Sep 2012 17:24:46 +0200 +Subject: [PATCH] s390x: fix -initrd in virtio machine + +When using -initrd in the virtio machine, we need to indicate the initrd +start and size inside the kernel image. These parameters need to be stored +in native endianness. + +Signed-off-by: Alexander Graf +Acked-by: Richard Henderson +Acked-by: Christian Borntraeger +(cherry picked from commit 235a3f0bed3584fe65079ffa07c7a842971f261e) + +Signed-off-by: Michael Roth +--- + hw/s390-virtio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c +index 47eed35..12ae612 100644 +--- a/hw/s390-virtio.c ++++ b/hw/s390-virtio.c +@@ -284,8 +284,8 @@ static void s390_init(ram_addr_t my_ram_size, + } + + /* we have to overwrite values in the kernel image, which are "rom" */ +- memcpy(rom_ptr(INITRD_PARM_START), &initrd_offset, 8); +- memcpy(rom_ptr(INITRD_PARM_SIZE), &initrd_size, 8); ++ stq_p(rom_ptr(INITRD_PARM_START), initrd_offset); ++ stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size); + } + + if (rom_ptr(KERN_PARM_AREA)) { diff --git a/0314-PPC-Bamboo-Fix-memory-size-DT-property.patch b/0314-PPC-Bamboo-Fix-memory-size-DT-property.patch new file mode 100644 index 0000000..68dbe62 --- /dev/null +++ b/0314-PPC-Bamboo-Fix-memory-size-DT-property.patch @@ -0,0 +1,30 @@ +From ef7b114db1a56aaa69cb872ea0212a8cbe5c438d Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Sat, 6 Oct 2012 02:02:05 +0200 +Subject: [PATCH] PPC: Bamboo: Fix memory size DT property + +Device tree properties need to be specified in big endian. Fix the +bamboo memory size property accordingly. + +Signed-off-by: Alexander Graf +CC: qemu-stable@nongnu.org +(cherry picked from commit 5232fa59b17b45c04bd24e0d38224964816bf391) + +Signed-off-by: Michael Roth +--- + hw/ppc440_bamboo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c +index c198071..9286438 100644 +--- a/hw/ppc440_bamboo.c ++++ b/hw/ppc440_bamboo.c +@@ -59,7 +59,7 @@ static int bamboo_load_device_tree(target_phys_addr_t addr, + { + int ret = -1; + #ifdef CONFIG_FDT +- uint32_t mem_reg_property[] = { 0, 0, ramsize }; ++ uint32_t mem_reg_property[] = { 0, 0, cpu_to_be32(ramsize) }; + char *filename; + int fdt_size; + void *fdt; diff --git a/0315-target-sparc64-disable-VGA-cirrus.patch b/0315-target-sparc64-disable-VGA-cirrus.patch new file mode 100644 index 0000000..e69a856 --- /dev/null +++ b/0315-target-sparc64-disable-VGA-cirrus.patch @@ -0,0 +1,34 @@ +From d88afebe37fbaf40a5f43c1c82609abc69a629b3 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Mon, 22 Oct 2012 00:50:58 +0200 +Subject: [PATCH] target-sparc64: disable VGA cirrus + +OpenBIOS on sparc64 only support Standard VGA and not Cirrus VGA. Don't +build Cirrus VGA support so that it can't be selected. + +This fixes the breakage introduced by commit f2898771. + +Reported-by: Richard Henderson +Cc: Blue Swirl +Signed-off-by: Aurelien Jarno +Tested-by: Richard Henderson +Signed-off-by: Blue Swirl +(cherry picked from commit 0356404b0f1da939657cad1efeb556745cd430d5) + +Signed-off-by: Michael Roth +--- + default-configs/sparc64-softmmu.mak | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak +index c9a36c1..03e8b42 100644 +--- a/default-configs/sparc64-softmmu.mak ++++ b/default-configs/sparc64-softmmu.mak +@@ -6,7 +6,6 @@ CONFIG_M48T59=y + CONFIG_PTIMER=y + CONFIG_VGA=y + CONFIG_VGA_PCI=y +-CONFIG_VGA_CIRRUS=y + CONFIG_SERIAL=y + CONFIG_PARALLEL=y + CONFIG_PCKBD=y diff --git a/0316-xhci-fix-usb-name-in-caps.patch b/0316-xhci-fix-usb-name-in-caps.patch new file mode 100644 index 0000000..217e882 --- /dev/null +++ b/0316-xhci-fix-usb-name-in-caps.patch @@ -0,0 +1,37 @@ +From 57f23d23f079eaea5605e636ba3fa5d1bd2fe377 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 24 Oct 2012 16:19:21 +0200 +Subject: [PATCH] xhci: fix usb name in caps + +Used to be "UTB" not "USB". + +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 0ebfb144e8ad3f2da436d630fdcc5aa9ab646341) + +Signed-off-by: Michael Roth +--- + hw/usb/hcd-xhci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 333df59..30cb0d5 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -2098,7 +2098,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) + ret = 0x02000402; /* USB 2.0 */ + break; + case 0x24: /* Supported Protocol:04 */ +- ret = 0x20425455; /* "USB " */ ++ ret = 0x20425355; /* "USB " */ + break; + case 0x28: /* Supported Protocol:08 */ + ret = 0x00000001 | (USB2_PORTS<<8); +@@ -2110,7 +2110,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) + ret = 0x03000002; /* USB 3.0 */ + break; + case 0x34: /* Supported Protocol:04 */ +- ret = 0x20425455; /* "USB " */ ++ ret = 0x20425355; /* "USB " */ + break; + case 0x38: /* Supported Protocol:08 */ + ret = 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8); diff --git a/0317-tools-initialize-main-loop-before-block-layer.patch b/0317-tools-initialize-main-loop-before-block-layer.patch new file mode 100644 index 0000000..1891c33 --- /dev/null +++ b/0317-tools-initialize-main-loop-before-block-layer.patch @@ -0,0 +1,54 @@ +From cea4225aa439953117384764cb5c0b3c3fc325d4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Sat, 3 Nov 2012 18:10:17 +0100 +Subject: [PATCH] tools: initialize main loop before block layer + +Tools were broken because they initialized the block layer while +qemu_aio_context was still NULL. + +Reported-by: malc +Signed-off-by: Paolo Bonzini +Signed-off-by: malc +(cherry picked from commit 2592c59a66d456fe98fe96cb5787b356c40ee66f) + +Signed-off-by: Michael Roth +--- + qemu-img.c | 3 +-- + qemu-io.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/qemu-img.c b/qemu-img.c +index 7615e91..c90ae4a 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -1698,14 +1698,13 @@ int main(int argc, char **argv) + + error_set_progname(argv[0]); + ++ qemu_init_main_loop(); + bdrv_init(); + if (argc < 2) + help(); + cmdname = argv[1]; + argc--; argv++; + +- qemu_init_main_loop(); +- + /* find the command */ + for(cmd = img_cmds; cmd->name != NULL; cmd++) { + if (!strcmp(cmdname, cmd->name)) { +diff --git a/qemu-io.c b/qemu-io.c +index d0f4fb7..1ad7d3a 100644 +--- a/qemu-io.c ++++ b/qemu-io.c +@@ -1892,9 +1892,8 @@ int main(int argc, char **argv) + exit(1); + } + +- bdrv_init(); +- + qemu_init_main_loop(); ++ bdrv_init(); + + /* initialize commands */ + quit_init(); diff --git a/0318-m68k-Return-semihosting-errno-values-correctly.patch b/0318-m68k-Return-semihosting-errno-values-correctly.patch new file mode 100644 index 0000000..a3b8a01 --- /dev/null +++ b/0318-m68k-Return-semihosting-errno-values-correctly.patch @@ -0,0 +1,36 @@ +From 85c9ce8e19f0a652e121144f6b6c21d618325363 Mon Sep 17 00:00:00 2001 +From: Meador Inge +Date: Mon, 29 Oct 2012 12:05:09 +0000 +Subject: [PATCH] m68k: Return semihosting errno values correctly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixing a simple typo, s/errno/err/, that caused +the error status from GDB semihosted system calls +to be returned incorrectly. + +Signed-off-by: Meador Inge +Reviewed-by: Andreas Färber +Signed-off-by: Peter Maydell +Signed-off-by: Blue Swirl +(cherry picked from commit aed91c1bff5e568c7b0fbd0e1e7e2f9e62409e73) + +Signed-off-by: Michael Roth +--- + target-m68k/m68k-semi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c +index 3bb30cd..fed44ea 100644 +--- a/target-m68k/m68k-semi.c ++++ b/target-m68k/m68k-semi.c +@@ -150,7 +150,7 @@ static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err) + } + /* FIXME - handle put_user() failure */ + put_user_u32(ret, args); +- put_user_u32(errno, args + 4); ++ put_user_u32(err, args + 4); + } + + #define ARG(n) \ diff --git a/0319-nbd-fixes-to-read-only-handling.patch b/0319-nbd-fixes-to-read-only-handling.patch new file mode 100644 index 0000000..81e0ffd --- /dev/null +++ b/0319-nbd-fixes-to-read-only-handling.patch @@ -0,0 +1,59 @@ +From bcbf10c15f43cfc079622c25ef282688965a7128 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 13 Nov 2012 10:34:17 +0100 +Subject: [PATCH] nbd: fixes to read-only handling + +We do not need BLKROSET if the kernel supports setting flags. +Also, always do BLKROSET even for a read-write export, otherwise +the read-only state remains "sticky" after the invocation of +"qemu-nbd -r". + +Signed-off-by: Paolo Bonzini +(cherry picked from commit c8969eded252058e90e91f12f75f32aceae46ec9) + +Signed-off-by: Michael Roth +--- + nbd.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/nbd.c b/nbd.c +index 206f75c..19f6cd8 100644 +--- a/nbd.c ++++ b/nbd.c +@@ -399,24 +399,23 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize) + return -serrno; + } + +- if (flags & NBD_FLAG_READ_ONLY) { +- int read_only = 1; +- TRACE("Setting readonly attribute"); +- +- if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { ++ if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) { ++ if (errno == ENOTTY) { ++ int read_only = (flags & NBD_FLAG_READ_ONLY) != 0; ++ TRACE("Setting readonly attribute"); ++ ++ if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { ++ int serrno = errno; ++ LOG("Failed setting read-only attribute"); ++ return -serrno; ++ } ++ } else { + int serrno = errno; +- LOG("Failed setting read-only attribute"); ++ LOG("Failed setting flags"); + return -serrno; + } + } + +- if (ioctl(fd, NBD_SET_FLAGS, flags) < 0 +- && errno != ENOTTY) { +- int serrno = errno; +- LOG("Failed setting flags"); +- return -serrno; +- } +- + TRACE("Negotiation ended"); + + return 0; diff --git a/0320-mips-malta-fix-CBUS-UART-interrupt-pin.patch b/0320-mips-malta-fix-CBUS-UART-interrupt-pin.patch new file mode 100644 index 0000000..a8119d1 --- /dev/null +++ b/0320-mips-malta-fix-CBUS-UART-interrupt-pin.patch @@ -0,0 +1,38 @@ +From e6cd59a324a330fe7fd50f3b91df4f34ad2ea111 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Wed, 14 Nov 2012 15:04:42 +0100 +Subject: [PATCH] mips/malta: fix CBUS UART interrupt pin + +According to the MIPS Malta Developement Platform User's Manual, the +i8259 interrupt controller is supposed to be connected to the hardware +IRQ0, and the CBUS UART to the hardware interrupt 2. + +In QEMU they are both connected to hardware interrupt 0, the CBUS UART +interrupt being wrong. This patch fixes that. It should be noted that +the irq array in QEMU includes the software interrupts, hence +env->irq[2] is the first hardware interrupt. + +Cc: Ralf Baechle +Reviewed-by: Eric Johnson +Signed-off-by: Aurelien Jarno +(cherry picked from commit 68d001928b151a0c50f367c0bdca645b3d5e9ed3) + +Signed-off-by: Michael Roth +--- + hw/mips_malta.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/mips_malta.c b/hw/mips_malta.c +index ad23f26..9289a28 100644 +--- a/hw/mips_malta.c ++++ b/hw/mips_malta.c +@@ -860,7 +860,8 @@ void mips_malta_init (ram_addr_t ram_size, + be = 0; + #endif + /* FPGA */ +- malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[2], serial_hds[2]); ++ /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */ ++ malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[4], serial_hds[2]); + + /* Load firmware in flash / BIOS. */ + dinfo = drive_get(IF_PFLASH, 0, fl_idx); diff --git a/0321-target-mips-fix-wrong-microMIPS-opcode-encoding.patch b/0321-target-mips-fix-wrong-microMIPS-opcode-encoding.patch new file mode 100644 index 0000000..b6a87dd --- /dev/null +++ b/0321-target-mips-fix-wrong-microMIPS-opcode-encoding.patch @@ -0,0 +1,35 @@ +From 7575e5a249f1bc38ee9498f2663771b1ccd7702e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=99=B3=E9=9F=8B=E4=BB=BB=20=28Wei-Ren=20Chen=29?= + +Date: Wed, 14 Nov 2012 10:49:55 +0800 +Subject: [PATCH] target-mips: fix wrong microMIPS opcode encoding + +While reading microMIPS decoding, I found a possible wrong opcode +encoding. According to [1] page 166, the bits 13..12 for MULTU is +0x01 rather than 0x00. Please review, thanks. + +[1] MIPS Architecture for Programmers VolumeIV-e: The MIPS DSP + Application-Specific Extension to the microMIPS32 Architecture + +Signed-off-by: Chen Wei-Ren +Signed-off-by: Aurelien Jarno +(cherry picked from commit 6801038bc52d61f81ac8a25fbe392f1bad982887) + +Signed-off-by: Michael Roth +--- + target-mips/translate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target-mips/translate.c b/target-mips/translate.c +index 4e04e97..49907bb 100644 +--- a/target-mips/translate.c ++++ b/target-mips/translate.c +@@ -9486,7 +9486,7 @@ enum { + + /* bits 13..12 for 0x32 */ + MULT_ACC = 0x0, +- MULTU_ACC = 0x0, ++ MULTU_ACC = 0x1, + + /* bits 15..12 for 0x2c */ + SEB = 0x2, diff --git a/0322-tcg-arm-fix-TLB-access-in-qemu-ld-st-ops.patch b/0322-tcg-arm-fix-TLB-access-in-qemu-ld-st-ops.patch new file mode 100644 index 0000000..0544bce --- /dev/null +++ b/0322-tcg-arm-fix-TLB-access-in-qemu-ld-st-ops.patch @@ -0,0 +1,166 @@ +From 7482be857b0d55189020bef699b65903be9c256a Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 9 Oct 2012 21:53:11 +0200 +Subject: [PATCH] tcg/arm: fix TLB access in qemu-ld/st ops + +The TCG arm backend considers likely that the offset to the TLB +entries does not exceed 12 bits for mem_index = 0. In practice this is +not true for at least the MIPS target. + +The current patch fixes that by loading the bits 23-12 with a separate +instruction, and using loads with address writeback, independently of +the value of mem_idx. In total this allow a 24-bit offset, which is a +lot more than needed. + +Cc: Andrzej Zaborowski +Cc: Peter Maydell +Cc: qemu-stable@nongnu.org +Signed-off-by: Aurelien Jarno +(cherry picked from commit d17bd1d8cc27f8c1a24c65f555a77a661c332b7f) + +Signed-off-by: Michael Roth +--- + tcg/arm/tcg-target.c | 78 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 42 insertions(+), 36 deletions(-) + +diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c +index aed3b53..fbad716 100644 +--- a/tcg/arm/tcg-target.c ++++ b/tcg/arm/tcg-target.c +@@ -630,6 +630,22 @@ static inline void tcg_out_ld32_12(TCGContext *s, int cond, + (rn << 16) | (rd << 12) | ((-im) & 0xfff)); + } + ++/* Offset pre-increment with base writeback. */ ++static inline void tcg_out_ld32_12wb(TCGContext *s, int cond, ++ int rd, int rn, tcg_target_long im) ++{ ++ /* ldr with writeback and both register equals is UNPREDICTABLE */ ++ assert(rd != rn); ++ ++ if (im >= 0) { ++ tcg_out32(s, (cond << 28) | 0x05b00000 | ++ (rn << 16) | (rd << 12) | (im & 0xfff)); ++ } else { ++ tcg_out32(s, (cond << 28) | 0x05300000 | ++ (rn << 16) | (rd << 12) | ((-im) & 0xfff)); ++ } ++} ++ + static inline void tcg_out_st32_12(TCGContext *s, int cond, + int rd, int rn, tcg_target_long im) + { +@@ -1062,7 +1078,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) + { + int addr_reg, data_reg, data_reg2, bswap; + #ifdef CONFIG_SOFTMMU +- int mem_index, s_bits; ++ int mem_index, s_bits, tlb_offset; + TCGReg argreg; + # if TARGET_LONG_BITS == 64 + int addr_reg2; +@@ -1102,19 +1118,15 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) + TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1); + tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_AREG0, + TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); +- /* In the +- * ldr r1 [r0, #(offsetof(CPUArchState, tlb_table[mem_index][0].addr_read))] +- * below, the offset is likely to exceed 12 bits if mem_index != 0 and +- * not exceed otherwise, so use an +- * add r0, r0, #(mem_index * sizeof *CPUArchState.tlb_table) +- * before. +- */ +- if (mem_index) ++ /* We assume that the offset is contained within 20 bits. */ ++ tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read); ++ assert(tlb_offset & ~0xfffff == 0); ++ if (tlb_offset > 0xfff) { + tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0, +- (mem_index << (TLB_SHIFT & 1)) | +- ((16 - (TLB_SHIFT >> 1)) << 8)); +- tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0, +- offsetof(CPUArchState, tlb_table[0][0].addr_read)); ++ 0xa00 | (tlb_offset >> 12)); ++ tlb_offset &= 0xfff; ++ } ++ tcg_out_ld32_12wb(s, COND_AL, TCG_REG_R1, TCG_REG_R0, tlb_offset); + tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1, + TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); + /* Check alignment. */ +@@ -1122,15 +1134,14 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) + tcg_out_dat_imm(s, COND_EQ, ARITH_TST, + 0, addr_reg, (1 << s_bits) - 1); + # if TARGET_LONG_BITS == 64 +- /* XXX: possibly we could use a block data load or writeback in +- * the first access. */ +- tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, +- offsetof(CPUArchState, tlb_table[0][0].addr_read) + 4); ++ /* XXX: possibly we could use a block data load in the first access. */ ++ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, 4); + tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, + TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0)); + # endif + tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, +- offsetof(CPUArchState, tlb_table[0][0].addend)); ++ offsetof(CPUTLBEntry, addend) ++ - offsetof(CPUTLBEntry, addr_read)); + + switch (opc) { + case 0: +@@ -1288,7 +1299,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) + { + int addr_reg, data_reg, data_reg2, bswap; + #ifdef CONFIG_SOFTMMU +- int mem_index, s_bits; ++ int mem_index, s_bits, tlb_offset; + TCGReg argreg; + # if TARGET_LONG_BITS == 64 + int addr_reg2; +@@ -1325,19 +1336,15 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) + TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1); + tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0, + TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); +- /* In the +- * ldr r1 [r0, #(offsetof(CPUArchState, tlb_table[mem_index][0].addr_write))] +- * below, the offset is likely to exceed 12 bits if mem_index != 0 and +- * not exceed otherwise, so use an +- * add r0, r0, #(mem_index * sizeof *CPUArchState.tlb_table) +- * before. +- */ +- if (mem_index) ++ /* We assume that the offset is contained within 20 bits. */ ++ tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write); ++ assert(tlb_offset & ~0xfffff == 0); ++ if (tlb_offset > 0xfff) { + tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0, +- (mem_index << (TLB_SHIFT & 1)) | +- ((16 - (TLB_SHIFT >> 1)) << 8)); +- tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0, +- offsetof(CPUArchState, tlb_table[0][0].addr_write)); ++ 0xa00 | (tlb_offset >> 12)); ++ tlb_offset &= 0xfff; ++ } ++ tcg_out_ld32_12wb(s, COND_AL, TCG_REG_R1, TCG_REG_R0, tlb_offset); + tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1, + TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); + /* Check alignment. */ +@@ -1345,15 +1352,14 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) + tcg_out_dat_imm(s, COND_EQ, ARITH_TST, + 0, addr_reg, (1 << s_bits) - 1); + # if TARGET_LONG_BITS == 64 +- /* XXX: possibly we could use a block data load or writeback in +- * the first access. */ +- tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, +- offsetof(CPUArchState, tlb_table[0][0].addr_write) + 4); ++ /* XXX: possibly we could use a block data load in the first access. */ ++ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, 4); + tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, + TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0)); + # endif + tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, +- offsetof(CPUArchState, tlb_table[0][0].addend)); ++ offsetof(CPUTLBEntry, addend) ++ - offsetof(CPUTLBEntry, addr_write)); + + switch (opc) { + case 0: diff --git a/0323-tcg-arm-fix-cross-endian-qemu_st16.patch b/0323-tcg-arm-fix-cross-endian-qemu_st16.patch new file mode 100644 index 0000000..94e536d --- /dev/null +++ b/0323-tcg-arm-fix-cross-endian-qemu_st16.patch @@ -0,0 +1,74 @@ +From c6f924c195da25e7211db91abfe0f2942d631509 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 9 Oct 2012 21:53:11 +0200 +Subject: [PATCH] tcg/arm: fix cross-endian qemu_st16 + +The bswap16 TCG opcode assumes that the high bytes of the temp equal +to 0 before calling it. The ARM backend implementation takes this +assumption to slightly optimize the generated code. + +The same implementation is called for implementing the cross-endian +qemu_st16 opcode, where this assumption is not true anymore. One way to +fix that would be to zero the high bytes before calling it. Given the +store instruction just ignore them, it is possible to provide a slightly +more optimized version. With ARMv6+ the rev16 instruction does the work +correctly. For lower ARM versions the patch provides a version which +behaves correctly with non-zero high bytes, but fill them with junk. + +Cc: Andrzej Zaborowski +Cc: Peter Maydell +Cc: qemu-stable@nongnu.org +Reviewed-by: Peter Maydell +Signed-off-by: Aurelien Jarno +(cherry picked from commit 7aab08aa786e3a8838beac758ee61c5000144937) + +Signed-off-by: Michael Roth +--- + tcg/arm/tcg-target.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c +index fbad716..83aa856 100644 +--- a/tcg/arm/tcg-target.c ++++ b/tcg/arm/tcg-target.c +@@ -602,6 +602,22 @@ static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn) + } + } + ++/* swap the two low bytes assuming that the two high input bytes and the ++ two high output bit can hold any value. */ ++static inline void tcg_out_bswap16st(TCGContext *s, int cond, int rd, int rn) ++{ ++ if (use_armv6_instructions) { ++ /* rev16 */ ++ tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn); ++ } else { ++ tcg_out_dat_reg(s, cond, ARITH_MOV, ++ TCG_REG_R8, 0, rn, SHIFT_IMM_LSR(8)); ++ tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_R8, TCG_REG_R8, 0xff); ++ tcg_out_dat_reg(s, cond, ARITH_ORR, ++ rd, TCG_REG_R8, rn, SHIFT_IMM_LSL(8)); ++ } ++} ++ + static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn) + { + if (use_armv6_instructions) { +@@ -1367,7 +1383,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) + break; + case 1: + if (bswap) { +- tcg_out_bswap16(s, COND_EQ, TCG_REG_R0, data_reg); ++ tcg_out_bswap16st(s, COND_EQ, TCG_REG_R0, data_reg); + tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1); + } else { + tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1); +@@ -1453,7 +1469,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) + break; + case 1: + if (bswap) { +- tcg_out_bswap16(s, COND_AL, TCG_REG_R0, data_reg); ++ tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, data_reg); + tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0); + } else { + tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0); diff --git a/0324-target-openrisc-remove-conflicting-definitions-from-.patch b/0324-target-openrisc-remove-conflicting-definitions-from-.patch new file mode 100644 index 0000000..ad5930c --- /dev/null +++ b/0324-target-openrisc-remove-conflicting-definitions-from-.patch @@ -0,0 +1,49 @@ +From 1a51e9b66a61238e56668d647a74a6ceeeeaa727 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Tue, 9 Oct 2012 21:53:12 +0200 +Subject: [PATCH] target-openrisc: remove conflicting definitions from cpu.h + +On an ARM host, the registers definitions from cpu.h clash +with /usr/include/sys/ucontext.h. As there are unused, just remove +them. + +Cc: Jia Liu +Cc: qemu-stable@nongnu.org +Reviewed-by: Peter Maydell +Signed-off-by: Aurelien Jarno +(cherry picked from commit 44e04d3b945ba6f5cc87e65192081da4783f73fa) + +Signed-off-by: Michael Roth +--- + target-openrisc/cpu.h | 18 ------------------ + 1 file changed, 18 deletions(-) + +diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h +index de21a87..244788c 100644 +--- a/target-openrisc/cpu.h ++++ b/target-openrisc/cpu.h +@@ -89,24 +89,6 @@ enum { + /* Interrupt */ + #define NR_IRQS 32 + +-/* Registers */ +-enum { +- R0 = 0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, +- R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, +- R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, +- R31 +-}; +- +-/* Register aliases */ +-enum { +- R_ZERO = R0, +- R_SP = R1, +- R_FP = R2, +- R_LR = R9, +- R_RV = R11, +- R_RVH = R12 +-}; +- + /* Unit presece register */ + enum { + UPR_UP = (1 << 0), diff --git a/0325-configure-avoid-compiler-warning-in-pipe2-detection.patch b/0325-configure-avoid-compiler-warning-in-pipe2-detection.patch new file mode 100644 index 0000000..8803ca3 --- /dev/null +++ b/0325-configure-avoid-compiler-warning-in-pipe2-detection.patch @@ -0,0 +1,35 @@ +From b61abbc18c7ba7cfb58a0d3a51fb377f4a5af5e4 Mon Sep 17 00:00:00 2001 +From: Bruce Rogers +Date: Mon, 20 Aug 2012 12:45:08 -0600 +Subject: [PATCH] configure: avoid compiler warning in pipe2 detection + +When building qemu-kvm for openSUSE:Factory, I am getting a +warning in the pipe2 detection performed by configure, which +prevents using --enable-werror. + +Change detection code to use return value of pipe2. + +Signed-off-by: Bruce Rogers +Reviewed-by: Peter Maydell +Signed-off-by: Blue Swirl +(cherry picked from commit 9bca81624ef9299b9a06013fd29cd6899079aab4) + +Signed-off-by: Michael Roth +--- + configure | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/configure b/configure +index 4d11fe3..9129433 100755 +--- a/configure ++++ b/configure +@@ -2399,8 +2399,7 @@ cat > $TMPC << EOF + int main(void) + { + int pipefd[2]; +- pipe2(pipefd, O_CLOEXEC); +- return 0; ++ return pipe2(pipefd, O_CLOEXEC); + } + EOF + if compile_prog "" "" ; then diff --git a/0326-qcow2-Fix-refcount-table-size-calculation.patch b/0326-qcow2-Fix-refcount-table-size-calculation.patch new file mode 100644 index 0000000..5af0b5e --- /dev/null +++ b/0326-qcow2-Fix-refcount-table-size-calculation.patch @@ -0,0 +1,33 @@ +From 1687a813ebbb6915be5c103ba99221d11db5647f Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 26 Oct 2012 16:33:32 +0200 +Subject: [PATCH] qcow2: Fix refcount table size calculation + +A missing factor for the refcount table entry size in the calculation +could mean that too little memory was allocated for the in-memory +representation of the table, resulting in a buffer overflow. + +Signed-off-by: Kevin Wolf +Reviewed-by: Michael Tokarev +Tested-by: Michael Tokarev +(cherry picked from commit a3548077062dd9dc2701ebffd931ba6eaef40bec) + +Signed-off-by: Michael Roth +--- + block/qcow2-refcount.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c +index 5e3f915..96224d1 100644 +--- a/block/qcow2-refcount.c ++++ b/block/qcow2-refcount.c +@@ -301,7 +301,8 @@ static int alloc_refcount_block(BlockDriverState *bs, + uint64_t last_table_size; + uint64_t blocks_clusters; + do { +- uint64_t table_clusters = size_to_clusters(s, table_size); ++ uint64_t table_clusters = ++ size_to_clusters(s, table_size * sizeof(uint64_t)); + blocks_clusters = 1 + + ((table_clusters + refcount_block_clusters - 1) + / refcount_block_clusters); diff --git a/0327-tci-Fix-type-of-tci_read_label.patch b/0327-tci-Fix-type-of-tci_read_label.patch new file mode 100644 index 0000000..469304a --- /dev/null +++ b/0327-tci-Fix-type-of-tci_read_label.patch @@ -0,0 +1,36 @@ +From e261b15047dbc9f8309f4e6b94b84f530402edc2 Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Mon, 19 Nov 2012 12:43:14 -0800 +Subject: [PATCH] tci: Fix type of tci_read_label + +Fixes the pointer truncation that was occurring for branches. + +Cc: Stefan Weil +Cc: Blue Swirl +Signed-off-by: Richard Henderson +Reviewed-by: Stefan Weil +Tested-by: Stefan Weil +Signed-off-by: Blue Swirl +(cherry picked from commit c6c5063c7a5bb1d3fe6b9931a1ec15294e39b8b1) + +Signed-off-by: Michael Roth +--- + tci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tci.c b/tci.c +index a4f7b78..bb456d2 100644 +--- a/tci.c ++++ b/tci.c +@@ -338,9 +338,9 @@ static uint64_t tci_read_ri64(uint8_t **tb_ptr) + } + #endif + +-static target_ulong tci_read_label(uint8_t **tb_ptr) ++static tcg_target_ulong tci_read_label(uint8_t **tb_ptr) + { +- target_ulong label = tci_read_i(tb_ptr); ++ tcg_target_ulong label = tci_read_i(tb_ptr); + assert(label != 0); + return label; + } diff --git a/0328-block-Fix-regression-for-MinGW-assertion-caused-by-s.patch b/0328-block-Fix-regression-for-MinGW-assertion-caused-by-s.patch new file mode 100644 index 0000000..5a542aa --- /dev/null +++ b/0328-block-Fix-regression-for-MinGW-assertion-caused-by-s.patch @@ -0,0 +1,38 @@ +From 9eeac8cebac645531dd0b9d79710bea732e76c40 Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Thu, 22 Nov 2012 07:25:48 +0100 +Subject: [PATCH] block: Fix regression for MinGW (assertion caused by short + string) + +The local string tmp_filename is passed to function get_tmp_filename +which expects a string with minimum size MAX_PATH for w32 hosts. + +MAX_PATH is 260 and PATH_MAX is 259, so tmp_filename was too short. + +Commit eba25057b9a5e19d10ace2bc7716667a31297169 introduced this +regression. + +Signed-off-by: Stefan Weil +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Blue Swirl +(cherry picked from commit 89c9bc3d147fdaa932db99b0463b4af1d3e7cda1) + +Signed-off-by: Michael Roth +--- + block.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/block.c b/block.c +index 4c0e7f5..e49a999 100644 +--- a/block.c ++++ b/block.c +@@ -739,7 +739,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, + BlockDriver *drv) + { + int ret; +- char tmp_filename[PATH_MAX]; ++ /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ ++ char tmp_filename[PATH_MAX + 1]; + + if (flags & BDRV_O_SNAPSHOT) { + BlockDriverState *bs1; diff --git a/0329-qom-dynamic_cast-of-NULL-is-always-NULL.patch b/0329-qom-dynamic_cast-of-NULL-is-always-NULL.patch new file mode 100644 index 0000000..315e226 --- /dev/null +++ b/0329-qom-dynamic_cast-of-NULL-is-always-NULL.patch @@ -0,0 +1,41 @@ +From 6ec7c05b9b753df2058dda52b10b6943a5626036 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 23 Nov 2012 16:56:17 +0100 +Subject: [PATCH] qom: dynamic_cast of NULL is always NULL + +Trying to cast a NULL value will cause a crash. Returning +NULL is also sensible, and it is also what the type-unsafe +DO_UPCAST macro does. + +Reported-by: Markus Armbruster +Signed-off-by: Paolo Bonzini +Signed-off-by: Anthony Liguori +(cherry picked from commit b7f43fe46029d8fd0594cd599fa2599dcce0f553) + +Signed-off-by: Michael Roth +--- + qom/object.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/qom/object.c b/qom/object.c +index e3e9242..f33e84d 100644 +--- a/qom/object.c ++++ b/qom/object.c +@@ -417,7 +417,7 @@ void object_delete(Object *obj) + + Object *object_dynamic_cast(Object *obj, const char *typename) + { +- if (object_class_dynamic_cast(object_get_class(obj), typename)) { ++ if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { + return obj; + } + +@@ -430,7 +430,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename) + + inst = object_dynamic_cast(obj, typename); + +- if (!inst) { ++ if (!inst && obj) { + fprintf(stderr, "Object %p is not an instance of type %s\n", + obj, typename); + abort(); diff --git a/0330-hmp-do-not-crash-on-invalid-SCSI-hotplug.patch b/0330-hmp-do-not-crash-on-invalid-SCSI-hotplug.patch new file mode 100644 index 0000000..49cc9ac --- /dev/null +++ b/0330-hmp-do-not-crash-on-invalid-SCSI-hotplug.patch @@ -0,0 +1,43 @@ +From 7c0aea40a3318d914d791f23a85d0c488cae60fe Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 23 Nov 2012 16:56:18 +0100 +Subject: [PATCH] hmp: do not crash on invalid SCSI hotplug + +Commit 0d93692 (qdev: Convert busses to QEMU Object Model, 2012-05-02) +removed a check on the type of the bus where a SCSI disk is hotplugged. +However, hot-plugging to the wrong kind of device now causes a crash +due to either a NULL pointer dereference (avoided by the previous patch) +or a failed QOM cast. + +Instead, in this case we need to use object_dynamic_cast and check for +the result, similar to what was done before that commit. + +Reported-by: Markus Armbruster +Signed-off-by: Paolo Bonzini +Signed-off-by: Anthony Liguori +(cherry picked from commit b5007bcc9729acd995518c52eb1038c4d8416b5d) + +Signed-off-by: Michael Roth +--- + hw/pci-hotplug.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c +index e7fb780..0ca5546 100644 +--- a/hw/pci-hotplug.c ++++ b/hw/pci-hotplug.c +@@ -80,7 +80,13 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, + SCSIBus *scsibus; + SCSIDevice *scsidev; + +- scsibus = SCSI_BUS(QLIST_FIRST(&adapter->child_bus)); ++ scsibus = (SCSIBus *) ++ object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)), ++ TYPE_SCSI_BUS); ++ if (!scsibus) { ++ error_report("Device is not a SCSI adapter"); ++ return -1; ++ } + + /* + * drive_init() tries to find a default for dinfo->unit. Doesn't diff --git a/0331-PPC-Fix-missing-TRACE-exception.patch b/0331-PPC-Fix-missing-TRACE-exception.patch new file mode 100644 index 0000000..ee2ce29 --- /dev/null +++ b/0331-PPC-Fix-missing-TRACE-exception.patch @@ -0,0 +1,82 @@ +From 1e597afb2b3581ddcda1eeac81475452520ae43f Mon Sep 17 00:00:00 2001 +From: Julio Guerra +Date: Fri, 19 Oct 2012 00:17:13 +0000 +Subject: [PATCH] PPC: Fix missing TRACE exception + +This patch fixes bug 1031698 : +https://bugs.launchpad.net/qemu/+bug/1031698 + +If we look at the (truncated) translation of the conditional branch +instruction in the test submitted in the bug post, the call to the +exception helper is missing in the "bne-false" chunk of translated +code : + +IN: +bne- 0x1800278 + +OUT: +0xb544236d: jne 0xb5442396 + +0xb5442373: mov %ebp,(%esp) +0xb5442376: mov $0x44,%ebx +0xb544237b: mov %ebx,0x4(%esp) +0xb544237f: mov $0x1800278,%ebx +0xb5442384: mov %ebx,0x25c(%ebp) +0xb544238a: call 0x827475a + ^^^^^^^^^^^^^^^^^^ + +0xb5442396: mov %ebp,(%esp) +0xb5442399: mov $0x44,%ebx +0xb544239e: mov %ebx,0x4(%esp) +0xb54423a2: mov $0x1800270,%ebx +0xb54423a7: mov %ebx,0x25c(%ebp) + +Indeed, gen_exception(ctx, excp) called by gen_goto_tb (called by +gen_bcond) changes ctx->exception's value to excp's : + +gen_bcond() +{ + gen_goto_tb(ctx, 0, ctx->nip + li - 4); + /* ctx->exception value is POWERPC_EXCP_BRANCH */ + + gen_goto_tb(ctx, 1, ctx->nip); + /* ctx->exception now value is POWERPC_EXCP_TRACE */ +} + +Making the following gen_goto_tb()'s test false during the second call : + +if ((ctx->singlestep_enabled & + (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) && + ctx->exception == POWERPC_EXCP_BRANCH /* false...*/) { + target_ulong tmp = ctx->nip; + ctx->nip = dest; + /* ... and this is the missing call */ + gen_exception(ctx, POWERPC_EXCP_TRACE); + ctx->nip = tmp; +} + +So the patch simply adds the missing matching case, fixing our problem. + +Signed-off-by: Julio Guerra +Signed-off-by: Alexander Graf +(cherry picked from commit f0cc4aa8450376ca2aee3ebb09db71f9f2ff333b) + +Signed-off-by: Michael Roth +--- + target-ppc/translate.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/target-ppc/translate.c b/target-ppc/translate.c +index ac915cc..3c49ca9 100644 +--- a/target-ppc/translate.c ++++ b/target-ppc/translate.c +@@ -3466,7 +3466,8 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) + if (unlikely(ctx->singlestep_enabled)) { + if ((ctx->singlestep_enabled & + (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) && +- ctx->exception == POWERPC_EXCP_BRANCH) { ++ (ctx->exception == POWERPC_EXCP_BRANCH || ++ ctx->exception == POWERPC_EXCP_TRACE)) { + target_ulong tmp = ctx->nip; + ctx->nip = dest; + gen_exception(ctx, POWERPC_EXCP_TRACE); diff --git a/0332-qom-fix-refcount-of-non-heap-allocated-objects.patch b/0332-qom-fix-refcount-of-non-heap-allocated-objects.patch new file mode 100644 index 0000000..bbc9585 --- /dev/null +++ b/0332-qom-fix-refcount-of-non-heap-allocated-objects.patch @@ -0,0 +1,47 @@ +From 3f7b149e9d80fee4274dfaf46eb7989420a9f046 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 23 Nov 2012 09:47:12 +0100 +Subject: [PATCH] qom: fix refcount of non-heap-allocated objects +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The reference count for embedded objects is always one too low, because +object_initialize_with_type returns with zero references to the object. +This causes premature finalization of the object (or an assertion failure) +after calling object_ref to add an extra reference and object_unref to +remove it. + +The fix is to move the initial object_ref call from object_new_with_type +to object_initialize_with_type. + +Acked-by: Andreas Färber +Signed-off-by: Paolo Bonzini +Signed-off-by: Anthony Liguori +(cherry picked from commit 764b63125a77dab54ed405d493452a4e05679c2e) + +Signed-off-by: Michael Roth +--- + qom/object.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/qom/object.c b/qom/object.c +index f33e84d..5499318 100644 +--- a/qom/object.c ++++ b/qom/object.c +@@ -307,6 +307,7 @@ void object_initialize_with_type(void *data, TypeImpl *type) + + memset(obj, 0, type->instance_size); + obj->class = type->class; ++ object_ref(obj); + QTAILQ_INIT(&obj->properties); + object_init_with_type(obj, type); + } +@@ -395,7 +396,6 @@ Object *object_new_with_type(Type type) + + obj = g_malloc(type->instance_size); + object_initialize_with_type(obj, type); +- object_ref(obj); + + return obj; + } diff --git a/0333-qapi-handle-visitor-type_size-in-QapiDeallocVisitor.patch b/0333-qapi-handle-visitor-type_size-in-QapiDeallocVisitor.patch new file mode 100644 index 0000000..93a5ce7 --- /dev/null +++ b/0333-qapi-handle-visitor-type_size-in-QapiDeallocVisitor.patch @@ -0,0 +1,54 @@ +From 0e647462940092c7af035c69613c799fd65bd0cb Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Mon, 26 Nov 2012 13:10:12 +0100 +Subject: [PATCH] qapi: handle visitor->type_size() in QapiDeallocVisitor +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +visit_type_size() requires either visitor->type_size() or +visitor_uint64() to be implemented, otherwise a NULL function pointer is +invoked. + +It is possible to trigger this crash as follows: + + $ qemu-system-x86_64 -netdev tap,sndbuf=0,id=netdev0 \ + -device virtio-blk-pci,netdev=netdev0 + +The 'sndbuf' option has type "size". + +Reviewed-by: Andreas Färber +Reviewed-by: Michael Roth +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Anthony Liguori +(cherry picked from commit 0c26f2eca40d6c65ea9edc62a10e510dc7f65cc8) + +Signed-off-by: Michael Roth +--- + qapi/qapi-dealloc-visitor.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c +index a154523..a07b171 100644 +--- a/qapi/qapi-dealloc-visitor.c ++++ b/qapi/qapi-dealloc-visitor.c +@@ -132,6 +132,11 @@ static void qapi_dealloc_type_number(Visitor *v, double *obj, const char *name, + { + } + ++static void qapi_dealloc_type_size(Visitor *v, size_t *obj, const char *name, ++ Error **errp) ++{ ++} ++ + static void qapi_dealloc_type_enum(Visitor *v, int *obj, const char *strings[], + const char *kind, const char *name, + Error **errp) +@@ -164,6 +169,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void) + v->visitor.type_bool = qapi_dealloc_type_bool; + v->visitor.type_str = qapi_dealloc_type_str; + v->visitor.type_number = qapi_dealloc_type_number; ++ v->visitor.type_size = qapi_dealloc_type_size; + + QTAILQ_INIT(&v->stack); + diff --git a/0334-qapi-fix-qapi_dealloc_type_size-parameter-type.patch b/0334-qapi-fix-qapi_dealloc_type_size-parameter-type.patch new file mode 100644 index 0000000..3ac013a --- /dev/null +++ b/0334-qapi-fix-qapi_dealloc_type_size-parameter-type.patch @@ -0,0 +1,33 @@ +From 191a171e02de164ae03e0f90a6cdead6e2bd029f Mon Sep 17 00:00:00 2001 +From: Bruce Rogers +Date: Tue, 27 Nov 2012 13:11:25 -0700 +Subject: [PATCH] qapi: fix qapi_dealloc_type_size parameter type + +The second parameter to qapi_dealloc_type_size should be a uint64_t *, +not a size_t *. This was causing our 32 bit x86 build to fail, since +warnings are treated as errors. + +Signed-off-by: Bruce Rogers +Reviewed-by: Michael Roth +Reviewed-by: Stefan Weil +Signed-off-by: Luiz Capitulino +(cherry picked from commit 1d16252652688a775b244fffa1b9ac9b719ceffc) + +Signed-off-by: Michael Roth +--- + qapi/qapi-dealloc-visitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c +index a07b171..75214e7 100644 +--- a/qapi/qapi-dealloc-visitor.c ++++ b/qapi/qapi-dealloc-visitor.c +@@ -132,7 +132,7 @@ static void qapi_dealloc_type_number(Visitor *v, double *obj, const char *name, + { + } + +-static void qapi_dealloc_type_size(Visitor *v, size_t *obj, const char *name, ++static void qapi_dealloc_type_size(Visitor *v, uint64_t *obj, const char *name, + Error **errp) + { + } diff --git a/0335-iscsi-fix-segfault-in-url-parsing.patch b/0335-iscsi-fix-segfault-in-url-parsing.patch new file mode 100644 index 0000000..325a1a8 --- /dev/null +++ b/0335-iscsi-fix-segfault-in-url-parsing.patch @@ -0,0 +1,31 @@ +From 09d790ef3ff7aa8d19a7f5e82bac04e101887ca4 Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Thu, 15 Nov 2012 15:42:06 +0100 +Subject: [PATCH] iscsi: fix segfault in url parsing + +If an invalid URL is specified iscsi_get_error(iscsi) is called +with iscsi == NULL. + +Signed-off-by: Peter Lieven +Signed-off-by: Paolo Bonzini +(cherry picked from commit 8da1e18b0cf46b6c95c88bbad1cc50d6dd1bef4b) + +Signed-off-by: Michael Roth +--- + block/iscsi.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/block/iscsi.c b/block/iscsi.c +index fb001b9..817196a 100644 +--- a/block/iscsi.c ++++ b/block/iscsi.c +@@ -951,8 +951,7 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags) + + iscsi_url = iscsi_parse_full_url(iscsi, filename); + if (iscsi_url == NULL) { +- error_report("Failed to parse URL : %s %s", filename, +- iscsi_get_error(iscsi)); ++ error_report("Failed to parse URL : %s", filename); + ret = -EINVAL; + goto out; + } diff --git a/0336-iscsi-fix-deadlock-during-login.patch b/0336-iscsi-fix-deadlock-during-login.patch new file mode 100644 index 0000000..ae9d69a --- /dev/null +++ b/0336-iscsi-fix-deadlock-during-login.patch @@ -0,0 +1,330 @@ +From e450cd0c7256039a42167621ff8125067feca6ad Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Sat, 17 Nov 2012 14:37:39 +0100 +Subject: [PATCH] iscsi: fix deadlock during login + +If the connection is interrupted before the first login is successfully +completed qemu-kvm is waiting forever in qemu_aio_wait(). + +This is fixed by performing an sync login to the target. If the +connection breaks after the first successful login errors are +handled internally by libiscsi. + +Signed-off-by: Peter Lieven +Signed-off-by: Paolo Bonzini +(cherry picked from commit e829b0bb054ed3389e5b22dad61875e51674e629) + +Signed-off-by: Michael Roth +--- + block/iscsi.c | 251 ++++++++++++++++------------------------------------------ + 1 file changed, 70 insertions(+), 181 deletions(-) + +diff --git a/block/iscsi.c b/block/iscsi.c +index 817196a..1836c71 100644 +--- a/block/iscsi.c ++++ b/block/iscsi.c +@@ -65,13 +65,6 @@ typedef struct IscsiAIOCB { + #endif + } IscsiAIOCB; + +-struct IscsiTask { +- IscsiLun *iscsilun; +- BlockDriverState *bs; +- int status; +- int complete; +-}; +- + static void + iscsi_bh_cb(void *p) + { +@@ -384,7 +377,7 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num, + *(uint16_t *)&acb->task->cdb[7] = htons(num_sectors); + break; + } +- ++ + if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task, + iscsi_aio_read16_cb, + NULL, +@@ -669,163 +662,6 @@ iscsi_getlength(BlockDriverState *bs) + return len; + } + +-static void +-iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status, +- void *command_data, void *opaque) +-{ +- struct IscsiTask *itask = opaque; +- struct scsi_readcapacity16 *rc16; +- struct scsi_task *task = command_data; +- +- if (status != 0) { +- error_report("iSCSI: Failed to read capacity of iSCSI lun. %s", +- iscsi_get_error(iscsi)); +- itask->status = 1; +- itask->complete = 1; +- scsi_free_scsi_task(task); +- return; +- } +- +- rc16 = scsi_datain_unmarshall(task); +- if (rc16 == NULL) { +- error_report("iSCSI: Failed to unmarshall readcapacity16 data."); +- itask->status = 1; +- itask->complete = 1; +- scsi_free_scsi_task(task); +- return; +- } +- +- itask->iscsilun->block_size = rc16->block_length; +- itask->iscsilun->num_blocks = rc16->returned_lba + 1; +- itask->bs->total_sectors = itask->iscsilun->num_blocks * +- itask->iscsilun->block_size / BDRV_SECTOR_SIZE ; +- +- itask->status = 0; +- itask->complete = 1; +- scsi_free_scsi_task(task); +-} +- +-static void +-iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status, +- void *command_data, void *opaque) +-{ +- struct IscsiTask *itask = opaque; +- struct scsi_readcapacity10 *rc10; +- struct scsi_task *task = command_data; +- +- if (status != 0) { +- error_report("iSCSI: Failed to read capacity of iSCSI lun. %s", +- iscsi_get_error(iscsi)); +- itask->status = 1; +- itask->complete = 1; +- scsi_free_scsi_task(task); +- return; +- } +- +- rc10 = scsi_datain_unmarshall(task); +- if (rc10 == NULL) { +- error_report("iSCSI: Failed to unmarshall readcapacity10 data."); +- itask->status = 1; +- itask->complete = 1; +- scsi_free_scsi_task(task); +- return; +- } +- +- itask->iscsilun->block_size = rc10->block_size; +- if (rc10->lba == 0) { +- /* blank disk loaded */ +- itask->iscsilun->num_blocks = 0; +- } else { +- itask->iscsilun->num_blocks = rc10->lba + 1; +- } +- itask->bs->total_sectors = itask->iscsilun->num_blocks * +- itask->iscsilun->block_size / BDRV_SECTOR_SIZE ; +- +- itask->status = 0; +- itask->complete = 1; +- scsi_free_scsi_task(task); +-} +- +-static void +-iscsi_inquiry_cb(struct iscsi_context *iscsi, int status, void *command_data, +- void *opaque) +-{ +- struct IscsiTask *itask = opaque; +- struct scsi_task *task = command_data; +- struct scsi_inquiry_standard *inq; +- +- if (status != 0) { +- itask->status = 1; +- itask->complete = 1; +- scsi_free_scsi_task(task); +- return; +- } +- +- inq = scsi_datain_unmarshall(task); +- if (inq == NULL) { +- error_report("iSCSI: Failed to unmarshall inquiry data."); +- itask->status = 1; +- itask->complete = 1; +- scsi_free_scsi_task(task); +- return; +- } +- +- itask->iscsilun->type = inq->periperal_device_type; +- +- scsi_free_scsi_task(task); +- +- switch (itask->iscsilun->type) { +- case TYPE_DISK: +- task = iscsi_readcapacity16_task(iscsi, itask->iscsilun->lun, +- iscsi_readcapacity16_cb, opaque); +- if (task == NULL) { +- error_report("iSCSI: failed to send readcapacity16 command."); +- itask->status = 1; +- itask->complete = 1; +- return; +- } +- break; +- case TYPE_ROM: +- task = iscsi_readcapacity10_task(iscsi, itask->iscsilun->lun, +- 0, 0, +- iscsi_readcapacity10_cb, opaque); +- if (task == NULL) { +- error_report("iSCSI: failed to send readcapacity16 command."); +- itask->status = 1; +- itask->complete = 1; +- return; +- } +- break; +- default: +- itask->status = 0; +- itask->complete = 1; +- } +-} +- +-static void +-iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data, +- void *opaque) +-{ +- struct IscsiTask *itask = opaque; +- struct scsi_task *task; +- +- if (status != 0) { +- itask->status = 1; +- itask->complete = 1; +- return; +- } +- +- task = iscsi_inquiry_task(iscsi, itask->iscsilun->lun, +- 0, 0, 36, +- iscsi_inquiry_cb, opaque); +- if (task == NULL) { +- error_report("iSCSI: failed to send inquiry command."); +- itask->status = 1; +- itask->complete = 1; +- return; +- } +-} +- + static int parse_chap(struct iscsi_context *iscsi, const char *target) + { + QemuOptsList *list; +@@ -938,7 +774,10 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags) + IscsiLun *iscsilun = bs->opaque; + struct iscsi_context *iscsi = NULL; + struct iscsi_url *iscsi_url = NULL; +- struct IscsiTask task; ++ struct scsi_task *task = NULL; ++ struct scsi_inquiry_standard *inq = NULL; ++ struct scsi_readcapacity10 *rc10 = NULL; ++ struct scsi_readcapacity16 *rc16 = NULL; + char *initiator_name = NULL; + int ret; + +@@ -1001,33 +840,80 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags) + /* check if we got HEADER_DIGEST via the options */ + parse_header_digest(iscsi, iscsi_url->target); + +- task.iscsilun = iscsilun; +- task.status = 0; +- task.complete = 0; +- task.bs = bs; ++ if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { ++ error_report("iSCSI: Failed to connect to LUN : %s", ++ iscsi_get_error(iscsi)); ++ ret = -EINVAL; ++ goto out; ++ } + + iscsilun->iscsi = iscsi; + iscsilun->lun = iscsi_url->lun; + +- if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun, +- iscsi_connect_cb, &task) +- != 0) { +- error_report("iSCSI: Failed to start async connect."); ++ task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36); ++ ++ if (task == NULL || task->status != SCSI_STATUS_GOOD) { ++ error_report("iSCSI: failed to send inquiry command."); + ret = -EINVAL; + goto out; + } + +- while (!task.complete) { +- iscsi_set_events(iscsilun); +- qemu_aio_wait(); +- } +- if (task.status != 0) { +- error_report("iSCSI: Failed to connect to LUN : %s", +- iscsi_get_error(iscsi)); ++ inq = scsi_datain_unmarshall(task); ++ if (inq == NULL) { ++ error_report("iSCSI: Failed to unmarshall inquiry data."); + ret = -EINVAL; + goto out; + } + ++ iscsilun->type = inq->periperal_device_type; ++ ++ scsi_free_scsi_task(task); ++ ++ switch (iscsilun->type) { ++ case TYPE_DISK: ++ task = iscsi_readcapacity16_sync(iscsi, iscsilun->lun); ++ if (task == NULL || task->status != SCSI_STATUS_GOOD) { ++ error_report("iSCSI: failed to send readcapacity16 command."); ++ ret = -EINVAL; ++ goto out; ++ } ++ rc16 = scsi_datain_unmarshall(task); ++ if (rc16 == NULL) { ++ error_report("iSCSI: Failed to unmarshall readcapacity16 data."); ++ ret = -EINVAL; ++ goto out; ++ } ++ iscsilun->block_size = rc16->block_length; ++ iscsilun->num_blocks = rc16->returned_lba + 1; ++ break; ++ case TYPE_ROM: ++ task = iscsi_readcapacity10_sync(iscsi, iscsilun->lun, 0, 0); ++ if (task == NULL || task->status != SCSI_STATUS_GOOD) { ++ error_report("iSCSI: failed to send readcapacity10 command."); ++ ret = -EINVAL; ++ goto out; ++ } ++ rc10 = scsi_datain_unmarshall(task); ++ if (rc10 == NULL) { ++ error_report("iSCSI: Failed to unmarshall readcapacity10 data."); ++ ret = -EINVAL; ++ goto out; ++ } ++ iscsilun->block_size = rc10->block_size; ++ if (rc10->lba == 0) { ++ /* blank disk loaded */ ++ iscsilun->num_blocks = 0; ++ } else { ++ iscsilun->num_blocks = rc10->lba + 1; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ bs->total_sectors = iscsilun->num_blocks * ++ iscsilun->block_size / BDRV_SECTOR_SIZE ; ++ + /* Medium changer or tape. We dont have any emulation for this so this must + * be sg ioctl compatible. We force it to be sg, otherwise qemu will try + * to read from the device to guess the image format. +@@ -1046,6 +932,9 @@ out: + if (iscsi_url != NULL) { + iscsi_destroy_url(iscsi_url); + } ++ if (task != NULL) { ++ scsi_free_scsi_task(task); ++ } + + if (ret) { + if (iscsi != NULL) { diff --git a/0337-iscsi-do-not-assume-device-is-zero-initialized.patch b/0337-iscsi-do-not-assume-device-is-zero-initialized.patch new file mode 100644 index 0000000..f4a8177 --- /dev/null +++ b/0337-iscsi-do-not-assume-device-is-zero-initialized.patch @@ -0,0 +1,41 @@ +From b360ba5cd93cbc30940538ce038b856ed8f72dd3 Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Sat, 17 Nov 2012 16:20:28 +0100 +Subject: [PATCH] iscsi: do not assume device is zero initialized + +Without any complex checks we can't assume that an +iscsi target is initialized to zero. + +Signed-off-by: Peter Lieven +Signed-off-by: Paolo Bonzini +(cherry picked from commit f807ecd5741325fe0d281199ff22cdda0acb6a7a) + +Signed-off-by: Michael Roth +--- + block/iscsi.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/block/iscsi.c b/block/iscsi.c +index 1836c71..11fd37e 100644 +--- a/block/iscsi.c ++++ b/block/iscsi.c +@@ -955,6 +955,11 @@ static void iscsi_close(BlockDriverState *bs) + memset(iscsilun, 0, sizeof(IscsiLun)); + } + ++static int iscsi_has_zero_init(BlockDriverState *bs) ++{ ++ return 0; ++} ++ + static BlockDriver bdrv_iscsi = { + .format_name = "iscsi", + .protocol_name = "iscsi", +@@ -970,6 +975,7 @@ static BlockDriver bdrv_iscsi = { + .bdrv_aio_flush = iscsi_aio_flush, + + .bdrv_aio_discard = iscsi_aio_discard, ++ .bdrv_has_zero_init = iscsi_has_zero_init, + + #ifdef __linux__ + .bdrv_ioctl = iscsi_ioctl, diff --git a/0338-virtio-scsi-Fix-some-endian-bugs-with-virtio-scsi.patch b/0338-virtio-scsi-Fix-some-endian-bugs-with-virtio-scsi.patch new file mode 100644 index 0000000..f07e36b --- /dev/null +++ b/0338-virtio-scsi-Fix-some-endian-bugs-with-virtio-scsi.patch @@ -0,0 +1,54 @@ +From 6f364e7d71769eeb134ebaa4c6cc5ffd214768d9 Mon Sep 17 00:00:00 2001 +From: David Gibson +Date: Fri, 23 Nov 2012 16:08:44 +1100 +Subject: [PATCH] virtio-scsi: Fix some endian bugs with virtio-scsi + +The virtio-scsi specification does not specify the correct endianness for +fields in the request structure. It's therefore best to assume that it is +"guest native" endian since that's the (stupid and poorly defined) norm in +virtio. + +However, the qemu device for virtio-scsi has no byteswaps at all, and so +will break if the guest has different endianness from the host. This patch +fixes it by adding tswap() calls for the sense_len and resid fields in +the request structure. In theory status_qualifier needs swaps as well, +but that field is never actually touched. The tag field is a uint64_t, but +since its value is completely arbitrary, it might as well be uint8_t[8] +and so it does not need swapping. + +Cc: Paolo Bonzini +Cc: Paul 'Rusty' Russell +Signed-off-by: David Gibson +Signed-off-by: Paolo Bonzini +(cherry picked from commit 474ee55a18765e7de8f0b2cc00db5d26286bb24d) + +Signed-off-by: Michael Roth +--- + hw/virtio-scsi.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c +index c1b47a8..c6d5290 100644 +--- a/hw/virtio-scsi.c ++++ b/hw/virtio-scsi.c +@@ -424,15 +424,17 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status, + size_t resid) + { + VirtIOSCSIReq *req = r->hba_private; ++ uint32_t sense_len; + + req->resp.cmd->response = VIRTIO_SCSI_S_OK; + req->resp.cmd->status = status; + if (req->resp.cmd->status == GOOD) { +- req->resp.cmd->resid = resid; ++ req->resp.cmd->resid = tswap32(resid); + } else { + req->resp.cmd->resid = 0; +- req->resp.cmd->sense_len = +- scsi_req_get_sense(r, req->resp.cmd->sense, VIRTIO_SCSI_SENSE_SIZE); ++ sense_len = scsi_req_get_sense(r, req->resp.cmd->sense, ++ VIRTIO_SCSI_SENSE_SIZE); ++ req->resp.cmd->sense_len = tswap32(sense_len); + } + virtio_scsi_complete_req(req); + } diff --git a/0339-virtio-scsi-Fix-subtle-guest-endian-bug.patch b/0339-virtio-scsi-Fix-subtle-guest-endian-bug.patch new file mode 100644 index 0000000..ecbc7d4 --- /dev/null +++ b/0339-virtio-scsi-Fix-subtle-guest-endian-bug.patch @@ -0,0 +1,43 @@ +From f42859e8791c5dc1c8b2a3e3499310d38e302fb4 Mon Sep 17 00:00:00 2001 +From: David Gibson +Date: Mon, 26 Nov 2012 12:33:52 +1100 +Subject: [PATCH] virtio-scsi: Fix subtle (guest) endian bug + +The virtio-scsi config space is, by specification, in guest endian (which +is ill-defined, but there you go). In virtio_scsi_get_config() we set up +all the fields in there, using stl_raw(). Which is a problem for the +max_channel and max_target fields, which are 16-bit, not 32-bit. For +little-endian targets we get away with it by accident, since the first +two bytes will still be correct, and the extra two bytes written (with +zeroes) will be overwritten correctly by the next store. + +But for big-endian guests, this means the max_target field ends up as zero, +which means the guest will only recognize a single disk on the virtio-scsi +bus. This patch fixes the problem. + +Cc: Paolo Bonzini +Cc: Paul 'Rusty' Russell +Signed-off-by: David Gibson +Signed-off-by: Paolo Bonzini +(cherry picked from commit 863d1050c96cff91dd478767c0da9cc288575919) + +Signed-off-by: Michael Roth +--- + hw/virtio-scsi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c +index c6d5290..5fcbdd8 100644 +--- a/hw/virtio-scsi.c ++++ b/hw/virtio-scsi.c +@@ -534,8 +534,8 @@ static void virtio_scsi_get_config(VirtIODevice *vdev, + stl_raw(&scsiconf->event_info_size, sizeof(VirtIOSCSIEvent)); + stl_raw(&scsiconf->sense_size, s->sense_size); + stl_raw(&scsiconf->cdb_size, s->cdb_size); +- stl_raw(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL); +- stl_raw(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET); ++ stw_raw(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL); ++ stw_raw(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET); + stl_raw(&scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN); + } + diff --git a/0340-qxl-reload-memslots-after-migration-when-qxl-is-in-U.patch b/0340-qxl-reload-memslots-after-migration-when-qxl-is-in-U.patch new file mode 100644 index 0000000..8d970f4 --- /dev/null +++ b/0340-qxl-reload-memslots-after-migration-when-qxl-is-in-U.patch @@ -0,0 +1,33 @@ +From 358b29311255c2277ec4d0ca1eefd29882dee006 Mon Sep 17 00:00:00 2001 +From: Yonit Halperin +Date: Wed, 28 Nov 2012 10:08:22 -0500 +Subject: [PATCH] qxl: reload memslots after migration, when qxl is in + UNDEFINED mode + +The devram memslot stays active when qxl enters UNDEFINED mode (i.e, no +primary surface). If migration has occurred while the device is in +UNDEFINED stae, the memslots have to be reloaded at the destination. + +Fixes rhbz#874574 + +Signed-off-by: Yonit Halperin +Signed-off-by: Gerd Hoffmann +(cherry picked from commit fa98efe932d93a15ffa867f3b05149c8d1fc7c28) + +Signed-off-by: Michael Roth +--- + hw/qxl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 89e9ad9..e7e9dd9 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -2042,6 +2042,7 @@ static int qxl_post_load(void *opaque, int version) + + switch (newmode) { + case QXL_MODE_UNDEFINED: ++ qxl_create_memslots(d); + break; + case QXL_MODE_VGA: + qxl_create_memslots(d); diff --git a/0341-usb-fail-usbdevice_create-when-there-is-no-USB-bus.patch b/0341-usb-fail-usbdevice_create-when-there-is-no-USB-bus.patch new file mode 100644 index 0000000..b984928 --- /dev/null +++ b/0341-usb-fail-usbdevice_create-when-there-is-no-USB-bus.patch @@ -0,0 +1,44 @@ +From cf0ad23ce4dc68d0617b01cc5eefdd133f87cafc Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Sun, 25 Nov 2012 16:49:15 +0100 +Subject: [PATCH] usb: fail usbdevice_create() when there is no USB bus + +Report an error instead of segfaulting when attaching a USB device to a +machine with no USB busses: + + $ qemu-system-arm -machine vexpress-a9 \ + -sd Fedora-17-armhfp-vexpress-mmcblk0.img \ + -kernel vmlinuz-3.4.2-3.fc17.armv7hl \ + -initrd initramfs-3.4.2-3.fc17.armv7hl.img \ + -usbdevice disk:format=raw:test.img + +Note that the vexpress-a9 machine does not have a USB host controller. + +Reported-by: David Abdurachmanov +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Gerd Hoffmann +(cherry picked from commit c128d6a6d785eb9235a4f6dbd52f405ab8c60bee) + +Signed-off-by: Michael Roth +--- + hw/usb/bus.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/hw/usb/bus.c b/hw/usb/bus.c +index b649360..1f73a52 100644 +--- a/hw/usb/bus.c ++++ b/hw/usb/bus.c +@@ -585,6 +585,13 @@ USBDevice *usbdevice_create(const char *cmdline) + return NULL; + } + ++ if (!bus) { ++ error_report("Error: no usb bus to attach usbdevice %s, " ++ "please try -machine usb=on and check that " ++ "the machine model supports USB", driver); ++ return NULL; ++ } ++ + if (!f->usbdevice_init) { + if (*params) { + error_report("usbdevice %s accepts no params", driver); diff --git a/0342-stream-fix-ratelimit_set_speed.patch b/0342-stream-fix-ratelimit_set_speed.patch new file mode 100644 index 0000000..c072227 --- /dev/null +++ b/0342-stream-fix-ratelimit_set_speed.patch @@ -0,0 +1,30 @@ +From e56a0d717b356c4e847c1c5cf537c1382a1597ec Mon Sep 17 00:00:00 2001 +From: Dietmar Maurer +Date: Wed, 24 Oct 2012 12:10:47 +0200 +Subject: [PATCH] stream: fix ratelimit_set_speed + +The formula to compute slice_quota was wrong since commit 6ef228fc. + +Signed-off-by: Dietmar Maurer +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit e3980e28bb888bf643054770452998d1b4319609) + +Signed-off-by: Michael Roth +--- + include/qemu/ratelimit.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/qemu/ratelimit.h b/include/qemu/ratelimit.h +index c6ac281..d1610f1 100644 +--- a/include/qemu/ratelimit.h ++++ b/include/qemu/ratelimit.h +@@ -42,7 +42,7 @@ static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed, + uint64_t slice_ns) + { + limit->slice_ns = slice_ns; +- limit->slice_quota = ((double)speed * 1000000000ULL) / slice_ns; ++ limit->slice_quota = ((double)speed * slice_ns)/1000000000ULL; + } + + #endif diff --git a/0343-e1000-Discard-packets-that-are-too-long-if-SBP-and-L.patch b/0343-e1000-Discard-packets-that-are-too-long-if-SBP-and-L.patch new file mode 100644 index 0000000..203027d --- /dev/null +++ b/0343-e1000-Discard-packets-that-are-too-long-if-SBP-and-L.patch @@ -0,0 +1,46 @@ +From 55c6a5611acc88b9c97fff3324fc743fafc6d0c7 Mon Sep 17 00:00:00 2001 +From: Michael Contreras +Date: Sun, 2 Dec 2012 20:11:22 -0800 +Subject: [PATCH] e1000: Discard packets that are too long if !SBP and !LPE + +The e1000_receive function for the e1000 needs to discard packets longer than +1522 bytes if the SBP and LPE flags are disabled. The linux driver assumes +this behavior and allocates memory based on this assumption. + +Signed-off-by: Michael Contreras +Signed-off-by: Anthony Liguori +(cherry picked from commit b0d9ffcd0251161c7c92f94804dcf599dfa3edeb) + +Signed-off-by: Michael Roth +--- + hw/e1000.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/hw/e1000.c b/hw/e1000.c +index 4d4ac32..b1d8508 100644 +--- a/hw/e1000.c ++++ b/hw/e1000.c +@@ -59,6 +59,9 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL); + #define PNPMMIO_SIZE 0x20000 + #define MIN_BUF_SIZE 60 /* Min. octets in an ethernet frame sans FCS */ + ++/* this is the size past which hardware will drop packets when setting LPE=0 */ ++#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 ++ + /* + * HW models: + * E1000_DEV_ID_82540EM works with Windows and Linux +@@ -795,6 +798,13 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size) + size = sizeof(min_buf); + } + ++ /* Discard oversized packets if !LPE and !SBP. */ ++ if (size > MAXIMUM_ETHERNET_VLAN_SIZE ++ && !(s->mac_reg[RCTL] & E1000_RCTL_LPE) ++ && !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) { ++ return size; ++ } ++ + if (!receive_filter(s, buf, size)) + return size; + diff --git a/0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch b/0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch deleted file mode 100644 index 0df1449..0000000 --- a/0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch +++ /dev/null @@ -1,57 +0,0 @@ -From e999fe6e315c5d6f6e8b5d4c689787fc46f10575 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 21:57:47 +0100 -Subject: [PATCH] char: Split out tcp socket close code in a separate function - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 25 ++++++++++++++++--------- - 1 file changed, 16 insertions(+), 9 deletions(-) - -diff --git a/qemu-char.c b/qemu-char.c -index b082bae..a1fdf88 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -2141,6 +2141,21 @@ typedef struct { - - static void tcp_chr_accept(void *opaque); - -+static void tcp_closed(void *opaque) -+{ -+ CharDriverState *chr = opaque; -+ TCPCharDriver *s = chr->opaque; -+ -+ s->connected = 0; -+ if (s->listen_fd >= 0) { -+ qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); -+ } -+ qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); -+ closesocket(s->fd); -+ s->fd = -1; -+ qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -+} -+ - static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - TCPCharDriver *s = chr->opaque; -@@ -2299,15 +2314,7 @@ static void tcp_chr_read(void *opaque) - len = s->max_size; - size = tcp_chr_recv(chr, (void *)buf, len); - if (size == 0) { -- /* connection closed */ -- s->connected = 0; -- if (s->listen_fd >= 0) { -- qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); -- } -- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); -- closesocket(s->fd); -- s->fd = -1; -- qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -+ tcp_closed(chr); - } else if (size > 0) { - if (s->do_telnetopt) - tcp_chr_process_IAC_bytes(chr, s, buf, &size); --- -1.7.12.1 - diff --git a/0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch b/0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch deleted file mode 100644 index 58d0b4a..0000000 --- a/0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch +++ /dev/null @@ -1,962 +0,0 @@ -From 5f3ba69a09688b40a4648e8818e4878ae20fc2f6 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 20:31:45 +0100 -Subject: [PATCH] char: Add a QemuChrHandlers struct to initialise chardev - handlers - -Instead of passing each handler in the qemu_add_handlers() function, -create a struct of handlers that can be passed to the function instead. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - gdbstub.c | 9 +++++++-- - hw/cadence_uart.c | 9 +++++++-- - hw/ccid-card-passthru.c | 11 +++++++---- - hw/debugcon.c | 2 +- - hw/escc.c | 9 +++++++-- - hw/etraxfs_ser.c | 13 +++++++++---- - hw/exynos4210_uart.c | 9 +++++++-- - hw/grlib_apbuart.c | 12 +++++++----- - hw/imx_serial.c | 9 +++++++-- - hw/ivshmem.c | 28 ++++++++++++++++++++++------ - hw/lm32_juart.c | 8 +++++++- - hw/lm32_uart.c | 8 +++++++- - hw/mcf_uart.c | 9 +++++++-- - hw/milkymist-uart.c | 8 +++++++- - hw/pl011.c | 9 +++++++-- - hw/pxa2xx.c | 13 +++++++++---- - hw/qdev-properties.c | 2 +- - hw/serial.c | 9 +++++++-- - hw/sh_serial.c | 12 +++++++++--- - hw/spapr_vty.c | 8 ++++++-- - hw/strongarm.c | 12 +++++++----- - hw/usb/dev-serial.c | 9 +++++++-- - hw/usb/redirect.c | 9 +++++++-- - hw/virtio-console.c | 9 +++++++-- - hw/xen_console.c | 16 +++++++++++----- - hw/xilinx_uartlite.c | 11 +++++++++-- - monitor.c | 18 ++++++++++++++---- - net/slirp.c | 8 ++++++-- - qemu-char.c | 32 ++++++++++++++++++++++---------- - qemu-char.h | 13 +++++++++---- - qtest.c | 9 ++++++++- - 31 files changed, 255 insertions(+), 88 deletions(-) - -diff --git a/gdbstub.c b/gdbstub.c -index a91709f..b905c15 100644 ---- a/gdbstub.c -+++ b/gdbstub.c -@@ -2965,6 +2965,12 @@ static void gdb_sigterm_handler(int signal) - } - #endif - -+static const QemuChrHandlers gdb_handlers = { -+ .fd_can_read = gdb_chr_can_receive, -+ .fd_read = gdb_chr_receive, -+ .fd_event = gdb_chr_event, -+}; -+ - int gdbserver_start(const char *device) - { - GDBState *s; -@@ -2994,8 +3000,7 @@ int gdbserver_start(const char *device) - if (!chr) - return -1; - -- qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive, -- gdb_chr_event, NULL); -+ qemu_chr_add_handlers(chr, &gdb_handlers, NULL); - } - - s = gdbserver_state; -diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c -index f8afc4e..c9d3b21 100644 ---- a/hw/cadence_uart.c -+++ b/hw/cadence_uart.c -@@ -435,6 +435,12 @@ static void cadence_uart_reset(UartState *s) - s->rx_wpos = 0; - } - -+static const QemuChrHandlers cadence_uart_handlers = { -+ .fd_can_read = uart_can_receive, -+ .fd_read = uart_receive, -+ .fd_event = uart_event, -+}; -+ - static int cadence_uart_init(SysBusDevice *dev) - { - UartState *s = FROM_SYSBUS(UartState, dev); -@@ -456,8 +462,7 @@ static int cadence_uart_init(SysBusDevice *dev) - cadence_uart_reset(s); - - if (s->chr) { -- qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive, -- uart_event, s); -+ qemu_chr_add_handlers(s->chr, &cadence_uart_handlers, s); - } - - return 0; -diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c -index bd6c777..fb32107 100644 ---- a/hw/ccid-card-passthru.c -+++ b/hw/ccid-card-passthru.c -@@ -274,6 +274,12 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len) - return card->atr; - } - -+static const QemuChrHandlers passthru_handlers = { -+ .fd_can_read = ccid_card_vscard_can_read, -+ .fd_read = ccid_card_vscard_read, -+ .fd_event = ccid_card_vscard_event, -+}; -+ - static int passthru_initfn(CCIDCardState *base) - { - PassthruState *card = DO_UPCAST(PassthruState, base, base); -@@ -282,10 +288,7 @@ static int passthru_initfn(CCIDCardState *base) - card->vscard_in_hdr = 0; - if (card->cs) { - DPRINTF(card, D_INFO, "initing chardev\n"); -- qemu_chr_add_handlers(card->cs, -- ccid_card_vscard_can_read, -- ccid_card_vscard_read, -- ccid_card_vscard_event, card); -+ qemu_chr_add_handlers(card->cs, &passthru_handlers, card); - ccid_card_vscard_send_init(card); - } else { - error_report("missing chardev"); -diff --git a/hw/debugcon.c b/hw/debugcon.c -index 14ab326..7887fd2 100644 ---- a/hw/debugcon.c -+++ b/hw/debugcon.c -@@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s) - exit(1); - } - -- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s); -+ qemu_chr_add_handlers(s->chr, NULL, s); - } - - static int debugcon_isa_initfn(ISADevice *dev) -diff --git a/hw/escc.c b/hw/escc.c -index e1f5e73..ff9d8b1 100644 ---- a/hw/escc.c -+++ b/hw/escc.c -@@ -867,6 +867,12 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, - sysbus_mmio_map(s, 0, base); - } - -+static const QemuChrHandlers serial_handlers = { -+ .fd_can_read = serial_can_receive, -+ .fd_read = serial_receive1, -+ .fd_event = serial_event, -+}; -+ - static int escc_init1(SysBusDevice *dev) - { - SerialState *s = FROM_SYSBUS(SerialState, dev); -@@ -879,8 +885,7 @@ static int escc_init1(SysBusDevice *dev) - s->chn[i].chn = 1 - i; - s->chn[i].clock = s->frequency / 2; - if (s->chn[i].chr) { -- qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, -- serial_receive1, serial_event, &s->chn[i]); -+ qemu_chr_add_handlers(s->chn[i].chr, &serial_handlers, &s->chn[i]); - } - } - s->chn[0].otherchn = &s->chn[1]; -diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c -index 5f16b17..f2571c2 100644 ---- a/hw/etraxfs_ser.c -+++ b/hw/etraxfs_ser.c -@@ -208,6 +208,12 @@ static void etraxfs_ser_reset(DeviceState *d) - - } - -+static const QemuChrHandlers serial_handlers = { -+ .fd_can_read = serial_can_receive, -+ .fd_read = serial_receive, -+ .fd_event = serial_event, -+}; -+ - static int etraxfs_ser_init(SysBusDevice *dev) - { - struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev); -@@ -217,10 +223,9 @@ static int etraxfs_ser_init(SysBusDevice *dev) - sysbus_init_mmio(dev, &s->mmio); - - s->chr = qemu_char_get_next_serial(); -- if (s->chr) -- qemu_chr_add_handlers(s->chr, -- serial_can_receive, serial_receive, -- serial_event, s); -+ if (s->chr) { -+ qemu_chr_add_handlers(s->chr, &serial_handlers, s); -+ } - return 0; - } - -diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c -index ccc4780..fefe400 100644 ---- a/hw/exynos4210_uart.c -+++ b/hw/exynos4210_uart.c -@@ -625,6 +625,12 @@ DeviceState *exynos4210_uart_create(target_phys_addr_t addr, - return dev; - } - -+static const QemuChrHandlers exynos4210_handlers = { -+ .fd_can_read = exynos4210_uart_can_receive, -+ .fd_read = exynos4210_uart_receive, -+ .fd_event = exynos4210_uart_event, -+}; -+ - static int exynos4210_uart_init(SysBusDevice *dev) - { - Exynos4210UartState *s = FROM_SYSBUS(Exynos4210UartState, dev); -@@ -636,8 +642,7 @@ static int exynos4210_uart_init(SysBusDevice *dev) - - sysbus_init_irq(dev, &s->irq); - -- qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive, -- exynos4210_uart_receive, exynos4210_uart_event, s); -+ qemu_chr_add_handlers(s->chr, &exynos4210_handlers, s); - - return 0; - } -diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c -index 73fc989..fd77d52 100644 ---- a/hw/grlib_apbuart.c -+++ b/hw/grlib_apbuart.c -@@ -222,15 +222,17 @@ static const MemoryRegionOps grlib_apbuart_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers grlib_handlers = { -+ .fd_can_read = grlib_apbuart_can_receive, -+ .fd_read = grlib_apbuart_receive, -+ .fd_event = grlib_apbuart_event, -+}; -+ - static int grlib_apbuart_init(SysBusDevice *dev) - { - UART *uart = FROM_SYSBUS(typeof(*uart), dev); - -- qemu_chr_add_handlers(uart->chr, -- grlib_apbuart_can_receive, -- grlib_apbuart_receive, -- grlib_apbuart_event, -- uart); -+ qemu_chr_add_handlers(uart->chr, &grlib_handlers, uart); - - sysbus_init_irq(dev, &uart->irq); - -diff --git a/hw/imx_serial.c b/hw/imx_serial.c -index d4eae43..f2304d2 100644 ---- a/hw/imx_serial.c -+++ b/hw/imx_serial.c -@@ -381,6 +381,12 @@ static const struct MemoryRegionOps imx_serial_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers imx_handlers = { -+ .fd_can_read = imx_can_receive, -+ .fd_read = imx_receive, -+ .fd_event = imx_event, -+}; -+ - static int imx_serial_init(SysBusDevice *dev) - { - IMXSerialState *s = FROM_SYSBUS(IMXSerialState, dev); -@@ -391,8 +397,7 @@ static int imx_serial_init(SysBusDevice *dev) - sysbus_init_irq(dev, &s->irq); - - if (s->chr) { -- qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive, -- imx_event, s); -+ qemu_chr_add_handlers(s->chr, &imx_handlers, s); - } else { - DPRINTF("No char dev for uart at 0x%lx\n", - (unsigned long)s->iomem.ram_addr); -diff --git a/hw/ivshmem.c b/hw/ivshmem.c -index 62fe53a..e90f691 100644 ---- a/hw/ivshmem.c -+++ b/hw/ivshmem.c -@@ -273,6 +273,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) { - msix_notify(pdev, entry->vector); - } - -+static const QemuChrHandlers ivshmem_handlers = { -+ .fd_can_read = ivshmem_can_receive, -+ .fd_read = ivshmem_receive, -+ .fd_event = ivshmem_event, -+}; -+ -+static const QemuChrHandlers ivshmem_msi_handlers = { -+ .fd_can_read = ivshmem_can_receive, -+ .fd_read = fake_irqfd, -+ .fd_event = ivshmem_event, -+}; -+ - static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *n, - int vector) - { -@@ -293,11 +305,10 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier * - s->eventfd_table[vector].pdev = &s->dev; - s->eventfd_table[vector].vector = vector; - -- qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd, -- ivshmem_event, &s->eventfd_table[vector]); -+ qemu_chr_add_handlers(chr, &ivshmem_msi_handlers, -+ &s->eventfd_table[vector]); - } else { -- qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive, -- ivshmem_event, s); -+ qemu_chr_add_handlers(chr, &ivshmem_handlers, s); - } - - return chr; -@@ -634,6 +645,12 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address, - msix_write_config(pci_dev, address, val, len); - } - -+static const QemuChrHandlers ivshmem_server_handlers = { -+ .fd_can_read = ivshmem_can_receive, -+ .fd_read = ivshmem_read, -+ .fd_event = ivshmem_event, -+}; -+ - static int pci_ivshmem_init(PCIDevice *dev) - { - IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); -@@ -720,8 +737,7 @@ static int pci_ivshmem_init(PCIDevice *dev) - - s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *)); - -- qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read, -- ivshmem_event, s); -+ qemu_chr_add_handlers(s->server_chr, &ivshmem_server_handlers, s); - } else { - /* just map the file immediately, we're not using a server */ - int fd; -diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c -index f07ed39..d4daeb8 100644 ---- a/hw/lm32_juart.c -+++ b/hw/lm32_juart.c -@@ -110,13 +110,19 @@ static void juart_reset(DeviceState *d) - s->jrx = 0; - } - -+static const QemuChrHandlers juart_handlers = { -+ .fd_can_read = juart_can_rx, -+ .fd_read = juart_rx, -+ .fd_event = juart_event, -+}; -+ - static int lm32_juart_init(SysBusDevice *dev) - { - LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev); - - s->chr = qemu_char_get_next_serial(); - if (s->chr) { -- qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s); -+ qemu_chr_add_handlers(s->chr, &juart_handlers, s); - } - - return 0; -diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c -index 57066e2..4ea130b 100644 ---- a/hw/lm32_uart.c -+++ b/hw/lm32_uart.c -@@ -243,6 +243,12 @@ static void uart_reset(DeviceState *d) - s->regs[R_LSR] = LSR_THRE | LSR_TEMT; - } - -+static const QemuChrHandlers uart_handlers = { -+ .fd_can_read = uart_can_rx, -+ .fd_read = uart_rx, -+ .fd_event = uart_event, -+}; -+ - static int lm32_uart_init(SysBusDevice *dev) - { - LM32UartState *s = FROM_SYSBUS(typeof(*s), dev); -@@ -254,7 +260,7 @@ static int lm32_uart_init(SysBusDevice *dev) - - s->chr = qemu_char_get_next_serial(); - if (s->chr) { -- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); -+ qemu_chr_add_handlers(s->chr, &uart_handlers, s); - } - - return 0; -diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c -index ec6a87f..f52fb96 100644 ---- a/hw/mcf_uart.c -+++ b/hw/mcf_uart.c -@@ -272,6 +272,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size) - mcf_uart_push_byte(s, buf[0]); - } - -+static const QemuChrHandlers mcf_uart_handlers = { -+ .fd_can_read = mcf_uart_can_receive, -+ .fd_read = mcf_uart_receive, -+ .fd_event = mcf_uart_event, -+}; -+ - void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) - { - mcf_uart_state *s; -@@ -280,8 +286,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) - s->chr = chr; - s->irq = irq; - if (chr) { -- qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive, -- mcf_uart_event, s); -+ qemu_chr_add_handlers(chr, &mcf_uart_handlers, s); - } - mcf_uart_reset(s); - return s; -diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c -index 291fe3c..2dcb41c 100644 ---- a/hw/milkymist-uart.c -+++ b/hw/milkymist-uart.c -@@ -189,6 +189,12 @@ static void milkymist_uart_reset(DeviceState *d) - s->regs[R_STAT] = STAT_THRE; - } - -+static const QemuChrHandlers uart_handlers = { -+ .fd_can_read = uart_can_rx, -+ .fd_read = uart_rx, -+ .fd_event = uart_event, -+}; -+ - static int milkymist_uart_init(SysBusDevice *dev) - { - MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev); -@@ -201,7 +207,7 @@ static int milkymist_uart_init(SysBusDevice *dev) - - s->chr = qemu_char_get_next_serial(); - if (s->chr) { -- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); -+ qemu_chr_add_handlers(s->chr, &uart_handlers, s); - } - - return 0; -diff --git a/hw/pl011.c b/hw/pl011.c -index 3245702..0d620f8 100644 ---- a/hw/pl011.c -+++ b/hw/pl011.c -@@ -258,6 +258,12 @@ static const VMStateDescription vmstate_pl011 = { - } - }; - -+static const QemuChrHandlers pl011_handlers = { -+ .fd_can_read = pl011_can_receive, -+ .fd_read = pl011_receive, -+ .fd_event = pl011_event, -+}; -+ - static int pl011_init(SysBusDevice *dev, const unsigned char *id) - { - pl011_state *s = FROM_SYSBUS(pl011_state, dev); -@@ -273,8 +279,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id) - s->cr = 0x300; - s->flags = 0x90; - if (s->chr) { -- qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, -- pl011_event, s); -+ qemu_chr_add_handlers(s->chr, &pl011_handlers, s); - } - vmstate_register(&dev->qdev, -1, &vmstate_pl011, s); - return 0; -diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c -index d5f1420..0b308cf 100644 ---- a/hw/pxa2xx.c -+++ b/hw/pxa2xx.c -@@ -1962,6 +1962,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id) - return 0; - } - -+static const QemuChrHandlers pxa2xx_handlers = { -+ .fd_can_read = pxa2xx_fir_is_empty, -+ .fd_read = pxa2xx_fir_rx, -+ .fd_event = pxa2xx_fir_event, -+}; -+ - static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, - target_phys_addr_t base, - qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma, -@@ -1980,10 +1986,9 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, - memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000); - memory_region_add_subregion(sysmem, base, &s->iomem); - -- if (chr) -- qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty, -- pxa2xx_fir_rx, pxa2xx_fir_event, s); -- -+ if (chr) { -+ qemu_chr_add_handlers(chr, &pxa2xx_handlers, s); -+ } - register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save, - pxa2xx_fir_load, s); - -diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c -index 8aca0d4..677c665 100644 ---- a/hw/qdev-properties.c -+++ b/hw/qdev-properties.c -@@ -549,7 +549,7 @@ static void release_chr(Object *obj, const char *name, void *opaque) - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); - - if (*ptr) { -- qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); -+ qemu_chr_add_handlers(*ptr, NULL, NULL); - } - } - -diff --git a/hw/serial.c b/hw/serial.c -index a421d1e..056d823 100644 ---- a/hw/serial.c -+++ b/hw/serial.c -@@ -736,6 +736,12 @@ static void serial_reset(void *opaque) - qemu_irq_lower(s->irq); - } - -+static const QemuChrHandlers serial_handlers = { -+ .fd_can_read = serial_can_receive1, -+ .fd_read = serial_receive1, -+ .fd_event = serial_event, -+}; -+ - static void serial_init_core(SerialState *s) - { - if (!s->chr) { -@@ -750,8 +756,7 @@ static void serial_init_core(SerialState *s) - - qemu_register_reset(serial_reset, s); - -- qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1, -- serial_event, s); -+ qemu_chr_add_handlers(s->chr, &serial_handlers, s); - } - - /* Change the main reference oscillator frequency. */ -diff --git a/hw/sh_serial.c b/hw/sh_serial.c -index 1d1883d..ce1c765 100644 ---- a/hw/sh_serial.c -+++ b/hw/sh_serial.c -@@ -352,6 +352,12 @@ static const MemoryRegionOps sh_serial_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers sh_serial_handlers = { -+ .fd_can_read = sh_serial_can_receive1, -+ .fd_read = sh_serial_receive1, -+ .fd_event = sh_serial_event, -+}; -+ - void sh_serial_init(MemoryRegion *sysmem, - target_phys_addr_t base, int feat, - uint32_t freq, CharDriverState *chr, -@@ -396,9 +402,9 @@ void sh_serial_init(MemoryRegion *sysmem, - - s->chr = chr; - -- if (chr) -- qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, -- sh_serial_event, s); -+ if (chr) { -+ qemu_chr_add_handlers(chr, &sh_serial_handlers, s); -+ } - - s->eri = eri_source; - s->rxi = rxi_source; -diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c -index 5da17a3..6c2ada1 100644 ---- a/hw/spapr_vty.c -+++ b/hw/spapr_vty.c -@@ -54,6 +54,11 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len) - qemu_chr_fe_write(dev->chardev, buf, len); - } - -+static const QemuChrHandlers vty_handlers = { -+ .fd_can_read = vty_can_receive, -+ .fd_read = vty_receive, -+}; -+ - static int spapr_vty_init(VIOsPAPRDevice *sdev) - { - VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev; -@@ -63,8 +68,7 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev) - exit(1); - } - -- qemu_chr_add_handlers(dev->chardev, vty_can_receive, -- vty_receive, NULL, dev); -+ qemu_chr_add_handlers(dev->chardev, &vty_handlers, dev); - - return 0; - } -diff --git a/hw/strongarm.c b/hw/strongarm.c -index 7150eeb..594cf31 100644 ---- a/hw/strongarm.c -+++ b/hw/strongarm.c -@@ -1199,6 +1199,12 @@ static const MemoryRegionOps strongarm_uart_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers strongarm_uart_handlers = { -+ .fd_can_read = strongarm_uart_can_receive, -+ .fd_read = strongarm_uart_receive, -+ .fd_event = strongarm_uart_event, -+}; -+ - static int strongarm_uart_init(SysBusDevice *dev) - { - StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev); -@@ -1211,11 +1217,7 @@ static int strongarm_uart_init(SysBusDevice *dev) - s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s); - - if (s->chr) { -- qemu_chr_add_handlers(s->chr, -- strongarm_uart_can_receive, -- strongarm_uart_receive, -- strongarm_uart_event, -- s); -+ qemu_chr_add_handlers(s->chr, &strongarm_uart_handlers, s); - } - - return 0; -diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c -index 69b6e48..0ddfab6 100644 ---- a/hw/usb/dev-serial.c -+++ b/hw/usb/dev-serial.c -@@ -475,6 +475,12 @@ static void usb_serial_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers usb_serial_handlers = { -+ .fd_can_read = usb_serial_can_read, -+ .fd_read = usb_serial_read, -+ .fd_event = usb_serial_event, -+}; -+ - static int usb_serial_initfn(USBDevice *dev) - { - USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev); -@@ -487,8 +493,7 @@ static int usb_serial_initfn(USBDevice *dev) - return -1; - } - -- qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read, -- usb_serial_event, s); -+ qemu_chr_add_handlers(s->cs, &usb_serial_handlers, s); - usb_serial_handle_reset(dev); - return 0; - } -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index ab8d79a..8b22c80 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -867,6 +867,12 @@ static void usbredir_chardev_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers usbredir_chr_handlers = { -+ .fd_can_read = usbredir_chardev_can_read, -+ .fd_read = usbredir_chardev_read, -+ .fd_event = usbredir_chardev_event, -+}; -+ - /* - * init + destroy - */ -@@ -905,8 +911,7 @@ static int usbredir_initfn(USBDevice *udev) - - /* Let the backend know we are ready */ - qemu_chr_fe_open(dev->cs); -- qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read, -- usbredir_chardev_read, usbredir_chardev_event, dev); -+ qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev); - - add_boot_device_path(dev->bootindex, &udev->qdev, NULL); - return 0; -diff --git a/hw/virtio-console.c b/hw/virtio-console.c -index cffee3d..066590c 100644 ---- a/hw/virtio-console.c -+++ b/hw/virtio-console.c -@@ -106,6 +106,12 @@ static void chr_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers chr_handlers = { -+ .fd_can_read = chr_can_read, -+ .fd_read = chr_read, -+ .fd_event = chr_event, -+}; -+ - static int virtconsole_initfn(VirtIOSerialPort *port) - { - VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -@@ -117,8 +123,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port) - } - - if (vcon->chr) { -- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -- vcon); -+ qemu_chr_add_handlers(vcon->chr, &chr_handlers, vcon); - } - - return 0; -diff --git a/hw/xen_console.c b/hw/xen_console.c -index 9426d73..e9fcadc 100644 ---- a/hw/xen_console.c -+++ b/hw/xen_console.c -@@ -211,6 +211,11 @@ out: - return ret; - } - -+static const QemuChrHandlers xencons_handlers = { -+ .fd_can_read = xencons_can_receive, -+ .fd_read = xencons_receive, -+}; -+ - static int con_initialise(struct XenDevice *xendev) - { - struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); -@@ -231,9 +236,9 @@ static int con_initialise(struct XenDevice *xendev) - return -1; - - xen_be_bind_evtchn(&con->xendev); -- if (con->chr) -- qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive, -- NULL, con); -+ if (con->chr) { -+ qemu_chr_add_handlers(con->chr, &xencons_handlers, con); -+ } - - xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n", - con->ring_ref, -@@ -250,8 +255,9 @@ static void con_disconnect(struct XenDevice *xendev) - if (!xendev->dev) { - return; - } -- if (con->chr) -- qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL); -+ if (con->chr) { -+ qemu_chr_add_handlers(con->chr, NULL, NULL); -+ } - xen_be_unbind_evtchn(&con->xendev); - - if (con->sring) { -diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c -index d0f32db..33f0cd5 100644 ---- a/hw/xilinx_uartlite.c -+++ b/hw/xilinx_uartlite.c -@@ -195,6 +195,12 @@ static void uart_event(void *opaque, int event) - - } - -+static const QemuChrHandlers uart_handlers = { -+ .fd_can_read = uart_can_rx, -+ .fd_read = uart_rx, -+ .fd_event = uart_event, -+}; -+ - static int xilinx_uartlite_init(SysBusDevice *dev) - { - struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev); -@@ -207,8 +213,9 @@ static int xilinx_uartlite_init(SysBusDevice *dev) - sysbus_init_mmio(dev, &s->mmio); - - s->chr = qemu_char_get_next_serial(); -- if (s->chr) -- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); -+ if (s->chr) { -+ qemu_chr_add_handlers(s->chr, &uart_handlers, s); -+ } - return 0; - } - -diff --git a/monitor.c b/monitor.c -index f45cf92..99eee98 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -4942,6 +4942,18 @@ static void sortcmdlist(void) - * End: - */ - -+static const QemuChrHandlers monitor_handlers = { -+ .fd_can_read = monitor_can_read, -+ .fd_read = monitor_read, -+ .fd_event = monitor_event, -+}; -+ -+static const QemuChrHandlers monitor_control_handlers = { -+ .fd_can_read = monitor_can_read, -+ .fd_read = monitor_control_read, -+ .fd_event = monitor_control_event, -+}; -+ - void monitor_init(CharDriverState *chr, int flags) - { - static int is_first_init = 1; -@@ -4965,14 +4977,12 @@ void monitor_init(CharDriverState *chr, int flags) - if (monitor_ctrl_mode(mon)) { - mon->mc = g_malloc0(sizeof(MonitorControl)); - /* Control mode requires special handlers */ -- qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read, -- monitor_control_event, mon); -+ qemu_chr_add_handlers(chr, &monitor_control_handlers, mon); - qemu_chr_fe_set_echo(chr, true); - - json_message_parser_init(&mon->mc->parser, handle_qmp_command); - } else { -- qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, -- monitor_event, mon); -+ qemu_chr_add_handlers(chr, &monitor_handlers, mon); - } - - QLIST_INSERT_HEAD(&mon_list, mon, entry); -diff --git a/net/slirp.c b/net/slirp.c -index 8db66ea..63542cb 100644 ---- a/net/slirp.c -+++ b/net/slirp.c -@@ -593,6 +593,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size) - slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size); - } - -+static const QemuChrHandlers guestfwd_handlers = { -+ .fd_can_read = guestfwd_can_read, -+ .fd_read = guestfwd_read, -+}; -+ - static int slirp_guestfwd(SlirpState *s, const char *config_str, - int legacy_format) - { -@@ -658,8 +663,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, - fwd->port = port; - fwd->slirp = s->slirp; - -- qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read, -- NULL, fwd); -+ qemu_chr_add_handlers(fwd->hd, &guestfwd_handlers, fwd); - } - return 0; - -diff --git a/qemu-char.c b/qemu-char.c -index a1fdf88..bd443db 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -192,19 +192,26 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) - va_end(ap); - } - -+static const QemuChrHandlers null_handlers = { -+ /* All handlers are initialised to NULL */ -+}; -+ - void qemu_chr_add_handlers(CharDriverState *s, -- IOCanReadHandler *fd_can_read, -- IOReadHandler *fd_read, -- IOEventHandler *fd_event, -- void *opaque) -+ const QemuChrHandlers *handlers, void *opaque) - { -- if (!opaque && !fd_can_read && !fd_read && !fd_event) { -+ if (!s) { -+ return; -+ } -+ if (!opaque && !handlers) { - /* chr driver being released. */ - ++s->avail_connections; - } -- s->chr_can_read = fd_can_read; -- s->chr_read = fd_read; -- s->chr_event = fd_event; -+ if (!handlers) { -+ handlers = &null_handlers; -+ } -+ s->chr_can_read = handlers->fd_can_read; -+ s->chr_read = handlers->fd_read; -+ s->chr_event = handlers->fd_event; - s->handler_opaque = opaque; - if (s->chr_update_read_handler) - s->chr_update_read_handler(s); -@@ -442,6 +449,12 @@ static void mux_chr_event(void *opaque, int event) - mux_chr_send_event(d, i, event); - } - -+static const QemuChrHandlers mux_chr_handlers = { -+ .fd_can_read = mux_chr_can_read, -+ .fd_read = mux_chr_read, -+ .fd_event = mux_chr_event, -+}; -+ - static void mux_chr_update_read_handler(CharDriverState *chr) - { - MuxDriver *d = chr->opaque; -@@ -456,8 +469,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr) - d->chr_event[d->mux_cnt] = chr->chr_event; - /* Fix up the real driver with mux routines */ - if (d->mux_cnt == 0) { -- qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read, -- mux_chr_event, chr); -+ qemu_chr_add_handlers(d->drv, &mux_chr_handlers, chr); - } - if (d->focus != -1) { - mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); -diff --git a/qemu-char.h b/qemu-char.h -index 486644b..dfa8c2d 100644 ---- a/qemu-char.h -+++ b/qemu-char.h -@@ -222,10 +222,15 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); - */ - void qemu_chr_be_event(CharDriverState *s, int event); - --void qemu_chr_add_handlers(CharDriverState *s, -- IOCanReadHandler *fd_can_read, -- IOReadHandler *fd_read, -- IOEventHandler *fd_event, -+ -+typedef struct QemuChrHandlers { -+ IOCanReadHandler *fd_can_read; -+ IOReadHandler *fd_read; -+ IOHandler *fd_write_unblocked; -+ IOEventHandler *fd_event; -+} QemuChrHandlers; -+ -+void qemu_chr_add_handlers(CharDriverState *s, const QemuChrHandlers *handlers, - void *opaque); - - void qemu_chr_generic_open(CharDriverState *s); -diff --git a/qtest.c b/qtest.c -index fbfab4e..4ab5b69 100644 ---- a/qtest.c -+++ b/qtest.c -@@ -416,6 +416,13 @@ static void qtest_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers test_handlers = { -+ .fd_can_read = qtest_can_read, -+ .fd_read = qtest_read, -+ .fd_event = qtest_event, -+}; -+ -+ - int qtest_init(void) - { - CharDriverState *chr; -@@ -425,7 +432,7 @@ int qtest_init(void) - configure_icount("0"); - chr = qemu_chr_new("qtest", qtest_chrdev, NULL); - -- qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr); -+ qemu_chr_add_handlers(chr, &test_handlers, chr); - qemu_chr_fe_set_echo(chr, true); - - inbuf = g_string_new(""); --- -1.7.12.1 - diff --git a/0401-update-VERSION-for-v1.2.2.patch b/0401-update-VERSION-for-v1.2.2.patch new file mode 100644 index 0000000..0fde5c3 --- /dev/null +++ b/0401-update-VERSION-for-v1.2.2.patch @@ -0,0 +1,17 @@ +From 91d2b5a0faa030cb437fbe99e94bb0720b03b44b Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Tue, 11 Dec 2012 15:09:44 -0600 +Subject: [PATCH] update VERSION for v1.2.2 + +Signed-off-by: Michael Roth +--- + VERSION | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/VERSION b/VERSION +index 6085e94..23aa839 100644 +--- a/VERSION ++++ b/VERSION +@@ -1 +1 @@ +-1.2.1 ++1.2.2 diff --git a/0402-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch b/0402-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch new file mode 100644 index 0000000..7f45cd7 --- /dev/null +++ b/0402-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch @@ -0,0 +1,54 @@ +From d33363c7732da489e69312949741181a59766bb2 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 21:57:47 +0100 +Subject: [PATCH] char: Split out tcp socket close code in a separate function + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + qemu-char.c | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +diff --git a/qemu-char.c b/qemu-char.c +index b082bae..a1fdf88 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -2141,6 +2141,21 @@ typedef struct { + + static void tcp_chr_accept(void *opaque); + ++static void tcp_closed(void *opaque) ++{ ++ CharDriverState *chr = opaque; ++ TCPCharDriver *s = chr->opaque; ++ ++ s->connected = 0; ++ if (s->listen_fd >= 0) { ++ qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); ++ } ++ qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); ++ closesocket(s->fd); ++ s->fd = -1; ++ qemu_chr_be_event(chr, CHR_EVENT_CLOSED); ++} ++ + static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + { + TCPCharDriver *s = chr->opaque; +@@ -2299,15 +2314,7 @@ static void tcp_chr_read(void *opaque) + len = s->max_size; + size = tcp_chr_recv(chr, (void *)buf, len); + if (size == 0) { +- /* connection closed */ +- s->connected = 0; +- if (s->listen_fd >= 0) { +- qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); +- } +- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); +- closesocket(s->fd); +- s->fd = -1; +- qemu_chr_be_event(chr, CHR_EVENT_CLOSED); ++ tcp_closed(chr); + } else if (size > 0) { + if (s->do_telnetopt) + tcp_chr_process_IAC_bytes(chr, s, buf, &size); diff --git a/0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch b/0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch deleted file mode 100644 index cfc7cd2..0000000 --- a/0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 2ac23d2134611b4e5b0fb389911bd03baa685df3 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 20:32:58 +0100 -Subject: [PATCH] iohandlers: Add enable/disable_write_fd_handler() functions - -These will be used to provide a cleaner API for the nonblocking case. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - iohandler.c | 35 +++++++++++++++++++++++++++++++++++ - main-loop.h | 3 +++ - 2 files changed, 38 insertions(+) - -diff --git a/iohandler.c b/iohandler.c -index a2d871b..c00fecd 100644 ---- a/iohandler.c -+++ b/iohandler.c -@@ -45,6 +45,41 @@ typedef struct IOHandlerRecord { - static QLIST_HEAD(, IOHandlerRecord) io_handlers = - QLIST_HEAD_INITIALIZER(io_handlers); - -+static IOHandlerRecord *find_iohandler(int fd) -+{ -+ IOHandlerRecord *ioh; -+ -+ QLIST_FOREACH(ioh, &io_handlers, next) { -+ if (ioh->fd == fd) { -+ return ioh; -+ } -+ } -+ return NULL; -+} -+ -+void enable_write_fd_handler(int fd, IOHandler *fd_write) -+{ -+ IOHandlerRecord *ioh; -+ -+ ioh = find_iohandler(fd); -+ if (!ioh) { -+ return; -+ } -+ -+ ioh->fd_write = fd_write; -+} -+ -+void disable_write_fd_handler(int fd) -+{ -+ IOHandlerRecord *ioh; -+ -+ ioh = find_iohandler(fd); -+ if (!ioh) { -+ return; -+ } -+ -+ ioh->fd_write = NULL; -+} - - /* XXX: fd_read_poll should be suppressed, but an API change is - necessary in the character devices to suppress fd_can_read(). */ -diff --git a/main-loop.h b/main-loop.h -index dce1cd9..eb31273 100644 ---- a/main-loop.h -+++ b/main-loop.h -@@ -175,6 +175,9 @@ typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); - typedef int IOCanReadHandler(void *opaque); - typedef void IOHandler(void *opaque); - -+void enable_write_fd_handler(int fd, IOHandler *fd_write); -+void disable_write_fd_handler(int fd); -+ - /** - * qemu_set_fd_handler2: Register a file descriptor with the main loop - * --- -1.7.12.1 - diff --git a/0403-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch b/0403-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch new file mode 100644 index 0000000..1273bc9 --- /dev/null +++ b/0403-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch @@ -0,0 +1,959 @@ +From 064e087beb96eb5b9716c9058f1d1e461421233e Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 20:31:45 +0100 +Subject: [PATCH] char: Add a QemuChrHandlers struct to initialise chardev + handlers + +Instead of passing each handler in the qemu_add_handlers() function, +create a struct of handlers that can be passed to the function instead. + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + gdbstub.c | 9 +++++++-- + hw/cadence_uart.c | 9 +++++++-- + hw/ccid-card-passthru.c | 11 +++++++---- + hw/debugcon.c | 2 +- + hw/escc.c | 9 +++++++-- + hw/etraxfs_ser.c | 13 +++++++++---- + hw/exynos4210_uart.c | 9 +++++++-- + hw/grlib_apbuart.c | 12 +++++++----- + hw/imx_serial.c | 9 +++++++-- + hw/ivshmem.c | 28 ++++++++++++++++++++++------ + hw/lm32_juart.c | 8 +++++++- + hw/lm32_uart.c | 8 +++++++- + hw/mcf_uart.c | 9 +++++++-- + hw/milkymist-uart.c | 8 +++++++- + hw/pl011.c | 9 +++++++-- + hw/pxa2xx.c | 13 +++++++++---- + hw/qdev-properties.c | 2 +- + hw/serial.c | 9 +++++++-- + hw/sh_serial.c | 12 +++++++++--- + hw/spapr_vty.c | 8 ++++++-- + hw/strongarm.c | 12 +++++++----- + hw/usb/dev-serial.c | 9 +++++++-- + hw/usb/redirect.c | 9 +++++++-- + hw/virtio-console.c | 9 +++++++-- + hw/xen_console.c | 16 +++++++++++----- + hw/xilinx_uartlite.c | 11 +++++++++-- + monitor.c | 18 ++++++++++++++---- + net/slirp.c | 8 ++++++-- + qemu-char.c | 32 ++++++++++++++++++++++---------- + qemu-char.h | 13 +++++++++---- + qtest.c | 9 ++++++++- + 31 files changed, 255 insertions(+), 88 deletions(-) + +diff --git a/gdbstub.c b/gdbstub.c +index a91709f..b905c15 100644 +--- a/gdbstub.c ++++ b/gdbstub.c +@@ -2965,6 +2965,12 @@ static void gdb_sigterm_handler(int signal) + } + #endif + ++static const QemuChrHandlers gdb_handlers = { ++ .fd_can_read = gdb_chr_can_receive, ++ .fd_read = gdb_chr_receive, ++ .fd_event = gdb_chr_event, ++}; ++ + int gdbserver_start(const char *device) + { + GDBState *s; +@@ -2994,8 +3000,7 @@ int gdbserver_start(const char *device) + if (!chr) + return -1; + +- qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive, +- gdb_chr_event, NULL); ++ qemu_chr_add_handlers(chr, &gdb_handlers, NULL); + } + + s = gdbserver_state; +diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c +index f8afc4e..c9d3b21 100644 +--- a/hw/cadence_uart.c ++++ b/hw/cadence_uart.c +@@ -435,6 +435,12 @@ static void cadence_uart_reset(UartState *s) + s->rx_wpos = 0; + } + ++static const QemuChrHandlers cadence_uart_handlers = { ++ .fd_can_read = uart_can_receive, ++ .fd_read = uart_receive, ++ .fd_event = uart_event, ++}; ++ + static int cadence_uart_init(SysBusDevice *dev) + { + UartState *s = FROM_SYSBUS(UartState, dev); +@@ -456,8 +462,7 @@ static int cadence_uart_init(SysBusDevice *dev) + cadence_uart_reset(s); + + if (s->chr) { +- qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive, +- uart_event, s); ++ qemu_chr_add_handlers(s->chr, &cadence_uart_handlers, s); + } + + return 0; +diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c +index bd6c777..fb32107 100644 +--- a/hw/ccid-card-passthru.c ++++ b/hw/ccid-card-passthru.c +@@ -274,6 +274,12 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len) + return card->atr; + } + ++static const QemuChrHandlers passthru_handlers = { ++ .fd_can_read = ccid_card_vscard_can_read, ++ .fd_read = ccid_card_vscard_read, ++ .fd_event = ccid_card_vscard_event, ++}; ++ + static int passthru_initfn(CCIDCardState *base) + { + PassthruState *card = DO_UPCAST(PassthruState, base, base); +@@ -282,10 +288,7 @@ static int passthru_initfn(CCIDCardState *base) + card->vscard_in_hdr = 0; + if (card->cs) { + DPRINTF(card, D_INFO, "initing chardev\n"); +- qemu_chr_add_handlers(card->cs, +- ccid_card_vscard_can_read, +- ccid_card_vscard_read, +- ccid_card_vscard_event, card); ++ qemu_chr_add_handlers(card->cs, &passthru_handlers, card); + ccid_card_vscard_send_init(card); + } else { + error_report("missing chardev"); +diff --git a/hw/debugcon.c b/hw/debugcon.c +index 14ab326..7887fd2 100644 +--- a/hw/debugcon.c ++++ b/hw/debugcon.c +@@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s) + exit(1); + } + +- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s); ++ qemu_chr_add_handlers(s->chr, NULL, s); + } + + static int debugcon_isa_initfn(ISADevice *dev) +diff --git a/hw/escc.c b/hw/escc.c +index e1f5e73..ff9d8b1 100644 +--- a/hw/escc.c ++++ b/hw/escc.c +@@ -867,6 +867,12 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, + sysbus_mmio_map(s, 0, base); + } + ++static const QemuChrHandlers serial_handlers = { ++ .fd_can_read = serial_can_receive, ++ .fd_read = serial_receive1, ++ .fd_event = serial_event, ++}; ++ + static int escc_init1(SysBusDevice *dev) + { + SerialState *s = FROM_SYSBUS(SerialState, dev); +@@ -879,8 +885,7 @@ static int escc_init1(SysBusDevice *dev) + s->chn[i].chn = 1 - i; + s->chn[i].clock = s->frequency / 2; + if (s->chn[i].chr) { +- qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, +- serial_receive1, serial_event, &s->chn[i]); ++ qemu_chr_add_handlers(s->chn[i].chr, &serial_handlers, &s->chn[i]); + } + } + s->chn[0].otherchn = &s->chn[1]; +diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c +index 5f16b17..f2571c2 100644 +--- a/hw/etraxfs_ser.c ++++ b/hw/etraxfs_ser.c +@@ -208,6 +208,12 @@ static void etraxfs_ser_reset(DeviceState *d) + + } + ++static const QemuChrHandlers serial_handlers = { ++ .fd_can_read = serial_can_receive, ++ .fd_read = serial_receive, ++ .fd_event = serial_event, ++}; ++ + static int etraxfs_ser_init(SysBusDevice *dev) + { + struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev); +@@ -217,10 +223,9 @@ static int etraxfs_ser_init(SysBusDevice *dev) + sysbus_init_mmio(dev, &s->mmio); + + s->chr = qemu_char_get_next_serial(); +- if (s->chr) +- qemu_chr_add_handlers(s->chr, +- serial_can_receive, serial_receive, +- serial_event, s); ++ if (s->chr) { ++ qemu_chr_add_handlers(s->chr, &serial_handlers, s); ++ } + return 0; + } + +diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c +index ccc4780..fefe400 100644 +--- a/hw/exynos4210_uart.c ++++ b/hw/exynos4210_uart.c +@@ -625,6 +625,12 @@ DeviceState *exynos4210_uart_create(target_phys_addr_t addr, + return dev; + } + ++static const QemuChrHandlers exynos4210_handlers = { ++ .fd_can_read = exynos4210_uart_can_receive, ++ .fd_read = exynos4210_uart_receive, ++ .fd_event = exynos4210_uart_event, ++}; ++ + static int exynos4210_uart_init(SysBusDevice *dev) + { + Exynos4210UartState *s = FROM_SYSBUS(Exynos4210UartState, dev); +@@ -636,8 +642,7 @@ static int exynos4210_uart_init(SysBusDevice *dev) + + sysbus_init_irq(dev, &s->irq); + +- qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive, +- exynos4210_uart_receive, exynos4210_uart_event, s); ++ qemu_chr_add_handlers(s->chr, &exynos4210_handlers, s); + + return 0; + } +diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c +index 73fc989..fd77d52 100644 +--- a/hw/grlib_apbuart.c ++++ b/hw/grlib_apbuart.c +@@ -222,15 +222,17 @@ static const MemoryRegionOps grlib_apbuart_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + }; + ++static const QemuChrHandlers grlib_handlers = { ++ .fd_can_read = grlib_apbuart_can_receive, ++ .fd_read = grlib_apbuart_receive, ++ .fd_event = grlib_apbuart_event, ++}; ++ + static int grlib_apbuart_init(SysBusDevice *dev) + { + UART *uart = FROM_SYSBUS(typeof(*uart), dev); + +- qemu_chr_add_handlers(uart->chr, +- grlib_apbuart_can_receive, +- grlib_apbuart_receive, +- grlib_apbuart_event, +- uart); ++ qemu_chr_add_handlers(uart->chr, &grlib_handlers, uart); + + sysbus_init_irq(dev, &uart->irq); + +diff --git a/hw/imx_serial.c b/hw/imx_serial.c +index d4eae43..f2304d2 100644 +--- a/hw/imx_serial.c ++++ b/hw/imx_serial.c +@@ -381,6 +381,12 @@ static const struct MemoryRegionOps imx_serial_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + }; + ++static const QemuChrHandlers imx_handlers = { ++ .fd_can_read = imx_can_receive, ++ .fd_read = imx_receive, ++ .fd_event = imx_event, ++}; ++ + static int imx_serial_init(SysBusDevice *dev) + { + IMXSerialState *s = FROM_SYSBUS(IMXSerialState, dev); +@@ -391,8 +397,7 @@ static int imx_serial_init(SysBusDevice *dev) + sysbus_init_irq(dev, &s->irq); + + if (s->chr) { +- qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive, +- imx_event, s); ++ qemu_chr_add_handlers(s->chr, &imx_handlers, s); + } else { + DPRINTF("No char dev for uart at 0x%lx\n", + (unsigned long)s->iomem.ram_addr); +diff --git a/hw/ivshmem.c b/hw/ivshmem.c +index 62fe53a..e90f691 100644 +--- a/hw/ivshmem.c ++++ b/hw/ivshmem.c +@@ -273,6 +273,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) { + msix_notify(pdev, entry->vector); + } + ++static const QemuChrHandlers ivshmem_handlers = { ++ .fd_can_read = ivshmem_can_receive, ++ .fd_read = ivshmem_receive, ++ .fd_event = ivshmem_event, ++}; ++ ++static const QemuChrHandlers ivshmem_msi_handlers = { ++ .fd_can_read = ivshmem_can_receive, ++ .fd_read = fake_irqfd, ++ .fd_event = ivshmem_event, ++}; ++ + static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *n, + int vector) + { +@@ -293,11 +305,10 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier * + s->eventfd_table[vector].pdev = &s->dev; + s->eventfd_table[vector].vector = vector; + +- qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd, +- ivshmem_event, &s->eventfd_table[vector]); ++ qemu_chr_add_handlers(chr, &ivshmem_msi_handlers, ++ &s->eventfd_table[vector]); + } else { +- qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive, +- ivshmem_event, s); ++ qemu_chr_add_handlers(chr, &ivshmem_handlers, s); + } + + return chr; +@@ -634,6 +645,12 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address, + msix_write_config(pci_dev, address, val, len); + } + ++static const QemuChrHandlers ivshmem_server_handlers = { ++ .fd_can_read = ivshmem_can_receive, ++ .fd_read = ivshmem_read, ++ .fd_event = ivshmem_event, ++}; ++ + static int pci_ivshmem_init(PCIDevice *dev) + { + IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); +@@ -720,8 +737,7 @@ static int pci_ivshmem_init(PCIDevice *dev) + + s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *)); + +- qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read, +- ivshmem_event, s); ++ qemu_chr_add_handlers(s->server_chr, &ivshmem_server_handlers, s); + } else { + /* just map the file immediately, we're not using a server */ + int fd; +diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c +index f07ed39..d4daeb8 100644 +--- a/hw/lm32_juart.c ++++ b/hw/lm32_juart.c +@@ -110,13 +110,19 @@ static void juart_reset(DeviceState *d) + s->jrx = 0; + } + ++static const QemuChrHandlers juart_handlers = { ++ .fd_can_read = juart_can_rx, ++ .fd_read = juart_rx, ++ .fd_event = juart_event, ++}; ++ + static int lm32_juart_init(SysBusDevice *dev) + { + LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev); + + s->chr = qemu_char_get_next_serial(); + if (s->chr) { +- qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s); ++ qemu_chr_add_handlers(s->chr, &juart_handlers, s); + } + + return 0; +diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c +index 57066e2..4ea130b 100644 +--- a/hw/lm32_uart.c ++++ b/hw/lm32_uart.c +@@ -243,6 +243,12 @@ static void uart_reset(DeviceState *d) + s->regs[R_LSR] = LSR_THRE | LSR_TEMT; + } + ++static const QemuChrHandlers uart_handlers = { ++ .fd_can_read = uart_can_rx, ++ .fd_read = uart_rx, ++ .fd_event = uart_event, ++}; ++ + static int lm32_uart_init(SysBusDevice *dev) + { + LM32UartState *s = FROM_SYSBUS(typeof(*s), dev); +@@ -254,7 +260,7 @@ static int lm32_uart_init(SysBusDevice *dev) + + s->chr = qemu_char_get_next_serial(); + if (s->chr) { +- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); ++ qemu_chr_add_handlers(s->chr, &uart_handlers, s); + } + + return 0; +diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c +index ec6a87f..f52fb96 100644 +--- a/hw/mcf_uart.c ++++ b/hw/mcf_uart.c +@@ -272,6 +272,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size) + mcf_uart_push_byte(s, buf[0]); + } + ++static const QemuChrHandlers mcf_uart_handlers = { ++ .fd_can_read = mcf_uart_can_receive, ++ .fd_read = mcf_uart_receive, ++ .fd_event = mcf_uart_event, ++}; ++ + void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) + { + mcf_uart_state *s; +@@ -280,8 +286,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) + s->chr = chr; + s->irq = irq; + if (chr) { +- qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive, +- mcf_uart_event, s); ++ qemu_chr_add_handlers(chr, &mcf_uart_handlers, s); + } + mcf_uart_reset(s); + return s; +diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c +index 291fe3c..2dcb41c 100644 +--- a/hw/milkymist-uart.c ++++ b/hw/milkymist-uart.c +@@ -189,6 +189,12 @@ static void milkymist_uart_reset(DeviceState *d) + s->regs[R_STAT] = STAT_THRE; + } + ++static const QemuChrHandlers uart_handlers = { ++ .fd_can_read = uart_can_rx, ++ .fd_read = uart_rx, ++ .fd_event = uart_event, ++}; ++ + static int milkymist_uart_init(SysBusDevice *dev) + { + MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev); +@@ -201,7 +207,7 @@ static int milkymist_uart_init(SysBusDevice *dev) + + s->chr = qemu_char_get_next_serial(); + if (s->chr) { +- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); ++ qemu_chr_add_handlers(s->chr, &uart_handlers, s); + } + + return 0; +diff --git a/hw/pl011.c b/hw/pl011.c +index 3245702..0d620f8 100644 +--- a/hw/pl011.c ++++ b/hw/pl011.c +@@ -258,6 +258,12 @@ static const VMStateDescription vmstate_pl011 = { + } + }; + ++static const QemuChrHandlers pl011_handlers = { ++ .fd_can_read = pl011_can_receive, ++ .fd_read = pl011_receive, ++ .fd_event = pl011_event, ++}; ++ + static int pl011_init(SysBusDevice *dev, const unsigned char *id) + { + pl011_state *s = FROM_SYSBUS(pl011_state, dev); +@@ -273,8 +279,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id) + s->cr = 0x300; + s->flags = 0x90; + if (s->chr) { +- qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, +- pl011_event, s); ++ qemu_chr_add_handlers(s->chr, &pl011_handlers, s); + } + vmstate_register(&dev->qdev, -1, &vmstate_pl011, s); + return 0; +diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c +index d5f1420..0b308cf 100644 +--- a/hw/pxa2xx.c ++++ b/hw/pxa2xx.c +@@ -1962,6 +1962,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id) + return 0; + } + ++static const QemuChrHandlers pxa2xx_handlers = { ++ .fd_can_read = pxa2xx_fir_is_empty, ++ .fd_read = pxa2xx_fir_rx, ++ .fd_event = pxa2xx_fir_event, ++}; ++ + static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, + target_phys_addr_t base, + qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma, +@@ -1980,10 +1986,9 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, + memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000); + memory_region_add_subregion(sysmem, base, &s->iomem); + +- if (chr) +- qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty, +- pxa2xx_fir_rx, pxa2xx_fir_event, s); +- ++ if (chr) { ++ qemu_chr_add_handlers(chr, &pxa2xx_handlers, s); ++ } + register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save, + pxa2xx_fir_load, s); + +diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c +index 8aca0d4..677c665 100644 +--- a/hw/qdev-properties.c ++++ b/hw/qdev-properties.c +@@ -549,7 +549,7 @@ static void release_chr(Object *obj, const char *name, void *opaque) + CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); + + if (*ptr) { +- qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); ++ qemu_chr_add_handlers(*ptr, NULL, NULL); + } + } + +diff --git a/hw/serial.c b/hw/serial.c +index a421d1e..056d823 100644 +--- a/hw/serial.c ++++ b/hw/serial.c +@@ -736,6 +736,12 @@ static void serial_reset(void *opaque) + qemu_irq_lower(s->irq); + } + ++static const QemuChrHandlers serial_handlers = { ++ .fd_can_read = serial_can_receive1, ++ .fd_read = serial_receive1, ++ .fd_event = serial_event, ++}; ++ + static void serial_init_core(SerialState *s) + { + if (!s->chr) { +@@ -750,8 +756,7 @@ static void serial_init_core(SerialState *s) + + qemu_register_reset(serial_reset, s); + +- qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1, +- serial_event, s); ++ qemu_chr_add_handlers(s->chr, &serial_handlers, s); + } + + /* Change the main reference oscillator frequency. */ +diff --git a/hw/sh_serial.c b/hw/sh_serial.c +index 1d1883d..ce1c765 100644 +--- a/hw/sh_serial.c ++++ b/hw/sh_serial.c +@@ -352,6 +352,12 @@ static const MemoryRegionOps sh_serial_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + }; + ++static const QemuChrHandlers sh_serial_handlers = { ++ .fd_can_read = sh_serial_can_receive1, ++ .fd_read = sh_serial_receive1, ++ .fd_event = sh_serial_event, ++}; ++ + void sh_serial_init(MemoryRegion *sysmem, + target_phys_addr_t base, int feat, + uint32_t freq, CharDriverState *chr, +@@ -396,9 +402,9 @@ void sh_serial_init(MemoryRegion *sysmem, + + s->chr = chr; + +- if (chr) +- qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, +- sh_serial_event, s); ++ if (chr) { ++ qemu_chr_add_handlers(chr, &sh_serial_handlers, s); ++ } + + s->eri = eri_source; + s->rxi = rxi_source; +diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c +index 5da17a3..6c2ada1 100644 +--- a/hw/spapr_vty.c ++++ b/hw/spapr_vty.c +@@ -54,6 +54,11 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len) + qemu_chr_fe_write(dev->chardev, buf, len); + } + ++static const QemuChrHandlers vty_handlers = { ++ .fd_can_read = vty_can_receive, ++ .fd_read = vty_receive, ++}; ++ + static int spapr_vty_init(VIOsPAPRDevice *sdev) + { + VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev; +@@ -63,8 +68,7 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev) + exit(1); + } + +- qemu_chr_add_handlers(dev->chardev, vty_can_receive, +- vty_receive, NULL, dev); ++ qemu_chr_add_handlers(dev->chardev, &vty_handlers, dev); + + return 0; + } +diff --git a/hw/strongarm.c b/hw/strongarm.c +index 7150eeb..594cf31 100644 +--- a/hw/strongarm.c ++++ b/hw/strongarm.c +@@ -1199,6 +1199,12 @@ static const MemoryRegionOps strongarm_uart_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + }; + ++static const QemuChrHandlers strongarm_uart_handlers = { ++ .fd_can_read = strongarm_uart_can_receive, ++ .fd_read = strongarm_uart_receive, ++ .fd_event = strongarm_uart_event, ++}; ++ + static int strongarm_uart_init(SysBusDevice *dev) + { + StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev); +@@ -1211,11 +1217,7 @@ static int strongarm_uart_init(SysBusDevice *dev) + s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s); + + if (s->chr) { +- qemu_chr_add_handlers(s->chr, +- strongarm_uart_can_receive, +- strongarm_uart_receive, +- strongarm_uart_event, +- s); ++ qemu_chr_add_handlers(s->chr, &strongarm_uart_handlers, s); + } + + return 0; +diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c +index 69b6e48..0ddfab6 100644 +--- a/hw/usb/dev-serial.c ++++ b/hw/usb/dev-serial.c +@@ -475,6 +475,12 @@ static void usb_serial_event(void *opaque, int event) + } + } + ++static const QemuChrHandlers usb_serial_handlers = { ++ .fd_can_read = usb_serial_can_read, ++ .fd_read = usb_serial_read, ++ .fd_event = usb_serial_event, ++}; ++ + static int usb_serial_initfn(USBDevice *dev) + { + USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev); +@@ -487,8 +493,7 @@ static int usb_serial_initfn(USBDevice *dev) + return -1; + } + +- qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read, +- usb_serial_event, s); ++ qemu_chr_add_handlers(s->cs, &usb_serial_handlers, s); + usb_serial_handle_reset(dev); + return 0; + } +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index ab8d79a..8b22c80 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -867,6 +867,12 @@ static void usbredir_chardev_event(void *opaque, int event) + } + } + ++static const QemuChrHandlers usbredir_chr_handlers = { ++ .fd_can_read = usbredir_chardev_can_read, ++ .fd_read = usbredir_chardev_read, ++ .fd_event = usbredir_chardev_event, ++}; ++ + /* + * init + destroy + */ +@@ -905,8 +911,7 @@ static int usbredir_initfn(USBDevice *udev) + + /* Let the backend know we are ready */ + qemu_chr_fe_open(dev->cs); +- qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read, +- usbredir_chardev_read, usbredir_chardev_event, dev); ++ qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev); + + add_boot_device_path(dev->bootindex, &udev->qdev, NULL); + return 0; +diff --git a/hw/virtio-console.c b/hw/virtio-console.c +index cffee3d..066590c 100644 +--- a/hw/virtio-console.c ++++ b/hw/virtio-console.c +@@ -106,6 +106,12 @@ static void chr_event(void *opaque, int event) + } + } + ++static const QemuChrHandlers chr_handlers = { ++ .fd_can_read = chr_can_read, ++ .fd_read = chr_read, ++ .fd_event = chr_event, ++}; ++ + static int virtconsole_initfn(VirtIOSerialPort *port) + { + VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); +@@ -117,8 +123,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port) + } + + if (vcon->chr) { +- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, +- vcon); ++ qemu_chr_add_handlers(vcon->chr, &chr_handlers, vcon); + } + + return 0; +diff --git a/hw/xen_console.c b/hw/xen_console.c +index 9426d73..e9fcadc 100644 +--- a/hw/xen_console.c ++++ b/hw/xen_console.c +@@ -211,6 +211,11 @@ out: + return ret; + } + ++static const QemuChrHandlers xencons_handlers = { ++ .fd_can_read = xencons_can_receive, ++ .fd_read = xencons_receive, ++}; ++ + static int con_initialise(struct XenDevice *xendev) + { + struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); +@@ -231,9 +236,9 @@ static int con_initialise(struct XenDevice *xendev) + return -1; + + xen_be_bind_evtchn(&con->xendev); +- if (con->chr) +- qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive, +- NULL, con); ++ if (con->chr) { ++ qemu_chr_add_handlers(con->chr, &xencons_handlers, con); ++ } + + xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n", + con->ring_ref, +@@ -250,8 +255,9 @@ static void con_disconnect(struct XenDevice *xendev) + if (!xendev->dev) { + return; + } +- if (con->chr) +- qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL); ++ if (con->chr) { ++ qemu_chr_add_handlers(con->chr, NULL, NULL); ++ } + xen_be_unbind_evtchn(&con->xendev); + + if (con->sring) { +diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c +index d0f32db..33f0cd5 100644 +--- a/hw/xilinx_uartlite.c ++++ b/hw/xilinx_uartlite.c +@@ -195,6 +195,12 @@ static void uart_event(void *opaque, int event) + + } + ++static const QemuChrHandlers uart_handlers = { ++ .fd_can_read = uart_can_rx, ++ .fd_read = uart_rx, ++ .fd_event = uart_event, ++}; ++ + static int xilinx_uartlite_init(SysBusDevice *dev) + { + struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev); +@@ -207,8 +213,9 @@ static int xilinx_uartlite_init(SysBusDevice *dev) + sysbus_init_mmio(dev, &s->mmio); + + s->chr = qemu_char_get_next_serial(); +- if (s->chr) +- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); ++ if (s->chr) { ++ qemu_chr_add_handlers(s->chr, &uart_handlers, s); ++ } + return 0; + } + +diff --git a/monitor.c b/monitor.c +index f45cf92..99eee98 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -4942,6 +4942,18 @@ static void sortcmdlist(void) + * End: + */ + ++static const QemuChrHandlers monitor_handlers = { ++ .fd_can_read = monitor_can_read, ++ .fd_read = monitor_read, ++ .fd_event = monitor_event, ++}; ++ ++static const QemuChrHandlers monitor_control_handlers = { ++ .fd_can_read = monitor_can_read, ++ .fd_read = monitor_control_read, ++ .fd_event = monitor_control_event, ++}; ++ + void monitor_init(CharDriverState *chr, int flags) + { + static int is_first_init = 1; +@@ -4965,14 +4977,12 @@ void monitor_init(CharDriverState *chr, int flags) + if (monitor_ctrl_mode(mon)) { + mon->mc = g_malloc0(sizeof(MonitorControl)); + /* Control mode requires special handlers */ +- qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read, +- monitor_control_event, mon); ++ qemu_chr_add_handlers(chr, &monitor_control_handlers, mon); + qemu_chr_fe_set_echo(chr, true); + + json_message_parser_init(&mon->mc->parser, handle_qmp_command); + } else { +- qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, +- monitor_event, mon); ++ qemu_chr_add_handlers(chr, &monitor_handlers, mon); + } + + QLIST_INSERT_HEAD(&mon_list, mon, entry); +diff --git a/net/slirp.c b/net/slirp.c +index 8db66ea..63542cb 100644 +--- a/net/slirp.c ++++ b/net/slirp.c +@@ -593,6 +593,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size) + slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size); + } + ++static const QemuChrHandlers guestfwd_handlers = { ++ .fd_can_read = guestfwd_can_read, ++ .fd_read = guestfwd_read, ++}; ++ + static int slirp_guestfwd(SlirpState *s, const char *config_str, + int legacy_format) + { +@@ -658,8 +663,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, + fwd->port = port; + fwd->slirp = s->slirp; + +- qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read, +- NULL, fwd); ++ qemu_chr_add_handlers(fwd->hd, &guestfwd_handlers, fwd); + } + return 0; + +diff --git a/qemu-char.c b/qemu-char.c +index a1fdf88..bd443db 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -192,19 +192,26 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) + va_end(ap); + } + ++static const QemuChrHandlers null_handlers = { ++ /* All handlers are initialised to NULL */ ++}; ++ + void qemu_chr_add_handlers(CharDriverState *s, +- IOCanReadHandler *fd_can_read, +- IOReadHandler *fd_read, +- IOEventHandler *fd_event, +- void *opaque) ++ const QemuChrHandlers *handlers, void *opaque) + { +- if (!opaque && !fd_can_read && !fd_read && !fd_event) { ++ if (!s) { ++ return; ++ } ++ if (!opaque && !handlers) { + /* chr driver being released. */ + ++s->avail_connections; + } +- s->chr_can_read = fd_can_read; +- s->chr_read = fd_read; +- s->chr_event = fd_event; ++ if (!handlers) { ++ handlers = &null_handlers; ++ } ++ s->chr_can_read = handlers->fd_can_read; ++ s->chr_read = handlers->fd_read; ++ s->chr_event = handlers->fd_event; + s->handler_opaque = opaque; + if (s->chr_update_read_handler) + s->chr_update_read_handler(s); +@@ -442,6 +449,12 @@ static void mux_chr_event(void *opaque, int event) + mux_chr_send_event(d, i, event); + } + ++static const QemuChrHandlers mux_chr_handlers = { ++ .fd_can_read = mux_chr_can_read, ++ .fd_read = mux_chr_read, ++ .fd_event = mux_chr_event, ++}; ++ + static void mux_chr_update_read_handler(CharDriverState *chr) + { + MuxDriver *d = chr->opaque; +@@ -456,8 +469,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr) + d->chr_event[d->mux_cnt] = chr->chr_event; + /* Fix up the real driver with mux routines */ + if (d->mux_cnt == 0) { +- qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read, +- mux_chr_event, chr); ++ qemu_chr_add_handlers(d->drv, &mux_chr_handlers, chr); + } + if (d->focus != -1) { + mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); +diff --git a/qemu-char.h b/qemu-char.h +index 486644b..dfa8c2d 100644 +--- a/qemu-char.h ++++ b/qemu-char.h +@@ -222,10 +222,15 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); + */ + void qemu_chr_be_event(CharDriverState *s, int event); + +-void qemu_chr_add_handlers(CharDriverState *s, +- IOCanReadHandler *fd_can_read, +- IOReadHandler *fd_read, +- IOEventHandler *fd_event, ++ ++typedef struct QemuChrHandlers { ++ IOCanReadHandler *fd_can_read; ++ IOReadHandler *fd_read; ++ IOHandler *fd_write_unblocked; ++ IOEventHandler *fd_event; ++} QemuChrHandlers; ++ ++void qemu_chr_add_handlers(CharDriverState *s, const QemuChrHandlers *handlers, + void *opaque); + + void qemu_chr_generic_open(CharDriverState *s); +diff --git a/qtest.c b/qtest.c +index fbfab4e..4ab5b69 100644 +--- a/qtest.c ++++ b/qtest.c +@@ -416,6 +416,13 @@ static void qtest_event(void *opaque, int event) + } + } + ++static const QemuChrHandlers test_handlers = { ++ .fd_can_read = qtest_can_read, ++ .fd_read = qtest_read, ++ .fd_event = qtest_event, ++}; ++ ++ + int qtest_init(void) + { + CharDriverState *chr; +@@ -425,7 +432,7 @@ int qtest_init(void) + configure_icount("0"); + chr = qemu_chr_new("qtest", qtest_chrdev, NULL); + +- qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr); ++ qemu_chr_add_handlers(chr, &test_handlers, chr); + qemu_chr_fe_set_echo(chr, true); + + inbuf = g_string_new(""); diff --git a/0403-char-Add-framework-for-a-write-unblocked-callback.patch b/0403-char-Add-framework-for-a-write-unblocked-callback.patch deleted file mode 100644 index 67f83f6..0000000 --- a/0403-char-Add-framework-for-a-write-unblocked-callback.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 8ca97117074b5eb12bf9cb0b25548116174601a8 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 21:41:42 +0100 -Subject: [PATCH] char: Add framework for a 'write unblocked' callback - -The char layer can let users know that the driver will block on further -input. For users interested in not blocking, they can assign a function -pointer that will be called back when the driver becomes writable. This -patch just adds the function pointers to the CharDriverState structure, -future patches will enable the nonblocking and callback functionality. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 3 +++ - qemu-char.h | 4 ++++ - 2 files changed, 7 insertions(+) - -diff --git a/qemu-char.c b/qemu-char.c -index bd443db..b5266d1 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -211,11 +211,14 @@ void qemu_chr_add_handlers(CharDriverState *s, - } - s->chr_can_read = handlers->fd_can_read; - s->chr_read = handlers->fd_read; -+ s->chr_write_unblocked = handlers->fd_write_unblocked; - s->chr_event = handlers->fd_event; - s->handler_opaque = opaque; - if (s->chr_update_read_handler) - s->chr_update_read_handler(s); - -+ s->write_blocked = false; -+ - /* We're connecting to an already opened device, so let's make sure we - also get the open event */ - if (s->opened) { -diff --git a/qemu-char.h b/qemu-char.h -index dfa8c2d..b5e23a4 100644 ---- a/qemu-char.h -+++ b/qemu-char.h -@@ -62,6 +62,9 @@ struct CharDriverState { - IOEventHandler *chr_event; - IOCanReadHandler *chr_can_read; - IOReadHandler *chr_read; -+ IOHandler *chr_write_unblocked; -+ void (*chr_enable_write_fd_handler)(struct CharDriverState *chr); -+ void (*chr_disable_write_fd_handler)(struct CharDriverState *chr); - void *handler_opaque; - void (*chr_close)(struct CharDriverState *chr); - void (*chr_accept_input)(struct CharDriverState *chr); -@@ -74,6 +77,7 @@ struct CharDriverState { - char *filename; - int opened; - int avail_connections; -+ bool write_blocked; /* Are we in a blocked state? */ - QTAILQ_ENTRY(CharDriverState) next; - }; - --- -1.7.12.1 - diff --git a/0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch b/0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch deleted file mode 100644 index b53d594..0000000 --- a/0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch +++ /dev/null @@ -1,173 +0,0 @@ -From dd7b138971deb72c7e37c4b79665df6ff5c1130b Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 22:00:27 +0100 -Subject: [PATCH] char: Update send_all() to handle nonblocking chardev write - requests - -The send_all function is modified to return to the caller in case the -driver cannot handle any more data. It returns -EAGAIN or -WSAEWOULDBLOCK on non-Windows and Windows platforms respectively. This -is only done when the caller sets a callback function handler indicating -it's not interested in blocking till the driver has written out all the -data. - -Currently there's no driver or caller that supports this. Future -commits will add such capability. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ - qemu_socket.h | 2 +- - 2 files changed, 64 insertions(+), 7 deletions(-) - -diff --git a/qemu-char.c b/qemu-char.c -index b5266d1..b46cc97 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -508,7 +508,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) - - - #ifdef _WIN32 --int send_all(int fd, const void *buf, int len1) -+static int do_send(int fd, const void *buf, int len1, bool nonblock) - { - int ret, len; - -@@ -516,9 +516,14 @@ int send_all(int fd, const void *buf, int len1) - while (len > 0) { - ret = send(fd, buf, len, 0); - if (ret < 0) { -+ if (nonblock && len1 - len) { -+ return len1 - len; -+ } - errno = WSAGetLastError(); - if (errno != WSAEWOULDBLOCK) { - return -1; -+ } else if (errno == WSAEWOULDBLOCK && nonblock) { -+ return WSAEWOULDBLOCK; - } - } else if (ret == 0) { - break; -@@ -532,7 +537,7 @@ int send_all(int fd, const void *buf, int len1) - - #else - --int send_all(int fd, const void *_buf, int len1) -+static int do_send(int fd, const void *_buf, int len1, bool nonblock) - { - int ret, len; - const uint8_t *buf = _buf; -@@ -541,8 +546,15 @@ int send_all(int fd, const void *_buf, int len1) - while (len > 0) { - ret = write(fd, buf, len); - if (ret < 0) { -- if (errno != EINTR && errno != EAGAIN) -+ if (nonblock && len1 - len) { -+ return len1 - len; -+ } -+ if (errno == EAGAIN && nonblock) { -+ return -EAGAIN; -+ } -+ if (errno != EINTR && errno != EAGAIN) { - return -1; -+ } - } else if (ret == 0) { - break; - } else { -@@ -557,6 +569,44 @@ int send_all(int fd, const void *_buf, int len1) - #define STDIO_MAX_CLIENTS 1 - static int stdio_nb_clients; - -+int send_all(CharDriverState *chr, int fd, const void *_buf, int len1) -+{ -+ int ret, eagain_errno; -+ bool nonblock; -+ -+ if (chr && chr->write_blocked) { -+ /* -+ * The caller should not send us data while we're blocked, -+ * but this can happen when multiple writers are woken at once, -+ * so simply return -EAGAIN. -+ */ -+ return -EAGAIN; -+ } -+ -+ nonblock = false; -+ /* -+ * Ensure the char backend is able to receive and handle the -+ * 'write unblocked' event before we turn on nonblock support. -+ */ -+ if (chr && chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) { -+ nonblock = true; -+ } -+ ret = do_send(fd, _buf, len1, nonblock); -+ -+#ifdef _WIN32 -+ eagain_errno = WSAEWOULDBLOCK; -+#else -+ eagain_errno = -EAGAIN; -+#endif -+ -+ if (nonblock && (ret == eagain_errno || (ret >= 0 && ret < len1))) { -+ /* Update fd handler to wake up when chr becomes writable */ -+ chr->chr_enable_write_fd_handler(chr); -+ chr->write_blocked = true; -+ } -+ return ret; -+} -+ - #ifndef _WIN32 - - typedef struct { -@@ -568,7 +618,7 @@ typedef struct { - static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - FDCharDriver *s = chr->opaque; -- return send_all(s->fd_out, buf, len); -+ return send_all(chr, s->fd_out, buf, len); - } - - static int fd_chr_read_poll(void *opaque) -@@ -887,7 +937,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - pty_chr_update_read_handler(chr); - return 0; - } -- return send_all(s->fd, buf, len); -+ return send_all(chr, s->fd, buf, len); - } - - static int pty_chr_read_poll(void *opaque) -@@ -2174,8 +2224,15 @@ static void tcp_closed(void *opaque) - static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - TCPCharDriver *s = chr->opaque; -+ - if (s->connected) { -- return send_all(s->fd, buf, len); -+ int ret; -+ -+ ret = send_all(chr, s->fd, buf, len); -+ if (ret == -1 && errno == EPIPE) { -+ tcp_closed(chr); -+ } -+ return ret; - } else { - /* XXX: indicate an error ? */ - return len; -diff --git a/qemu_socket.h b/qemu_socket.h -index 3e8aee9..a537d86 100644 ---- a/qemu_socket.h -+++ b/qemu_socket.h -@@ -36,7 +36,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); - int socket_set_cork(int fd, int v); - void socket_set_block(int fd); - void socket_set_nonblock(int fd); --int send_all(int fd, const void *buf, int len1); -+int send_all(CharDriverState *chr, int fd, const void *buf, int len1); - - /* callback function for nonblocking connect - * valid fd on success, negative error code on failure --- -1.7.12.1 - diff --git a/0404-iohandlers-Add-enable-disable_write_fd_handler-funct.patch b/0404-iohandlers-Add-enable-disable_write_fd_handler-funct.patch new file mode 100644 index 0000000..6f593d6 --- /dev/null +++ b/0404-iohandlers-Add-enable-disable_write_fd_handler-funct.patch @@ -0,0 +1,74 @@ +From 9fade7c07dc84824b8e4130df7a3c499c322539a Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 20:32:58 +0100 +Subject: [PATCH] iohandlers: Add enable/disable_write_fd_handler() functions + +These will be used to provide a cleaner API for the nonblocking case. + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + iohandler.c | 35 +++++++++++++++++++++++++++++++++++ + main-loop.h | 3 +++ + 2 files changed, 38 insertions(+) + +diff --git a/iohandler.c b/iohandler.c +index a2d871b..c00fecd 100644 +--- a/iohandler.c ++++ b/iohandler.c +@@ -45,6 +45,41 @@ typedef struct IOHandlerRecord { + static QLIST_HEAD(, IOHandlerRecord) io_handlers = + QLIST_HEAD_INITIALIZER(io_handlers); + ++static IOHandlerRecord *find_iohandler(int fd) ++{ ++ IOHandlerRecord *ioh; ++ ++ QLIST_FOREACH(ioh, &io_handlers, next) { ++ if (ioh->fd == fd) { ++ return ioh; ++ } ++ } ++ return NULL; ++} ++ ++void enable_write_fd_handler(int fd, IOHandler *fd_write) ++{ ++ IOHandlerRecord *ioh; ++ ++ ioh = find_iohandler(fd); ++ if (!ioh) { ++ return; ++ } ++ ++ ioh->fd_write = fd_write; ++} ++ ++void disable_write_fd_handler(int fd) ++{ ++ IOHandlerRecord *ioh; ++ ++ ioh = find_iohandler(fd); ++ if (!ioh) { ++ return; ++ } ++ ++ ioh->fd_write = NULL; ++} + + /* XXX: fd_read_poll should be suppressed, but an API change is + necessary in the character devices to suppress fd_can_read(). */ +diff --git a/main-loop.h b/main-loop.h +index dce1cd9..eb31273 100644 +--- a/main-loop.h ++++ b/main-loop.h +@@ -175,6 +175,9 @@ typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); + typedef int IOCanReadHandler(void *opaque); + typedef void IOHandler(void *opaque); + ++void enable_write_fd_handler(int fd, IOHandler *fd_write); ++void disable_write_fd_handler(int fd); ++ + /** + * qemu_set_fd_handler2: Register a file descriptor with the main loop + * diff --git a/0405-char-Add-framework-for-a-write-unblocked-callback.patch b/0405-char-Add-framework-for-a-write-unblocked-callback.patch new file mode 100644 index 0000000..fc245e9 --- /dev/null +++ b/0405-char-Add-framework-for-a-write-unblocked-callback.patch @@ -0,0 +1,59 @@ +From a0dd0fc78abcc1039af4d39a9c0eb65d838621f4 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 21:41:42 +0100 +Subject: [PATCH] char: Add framework for a 'write unblocked' callback + +The char layer can let users know that the driver will block on further +input. For users interested in not blocking, they can assign a function +pointer that will be called back when the driver becomes writable. This +patch just adds the function pointers to the CharDriverState structure, +future patches will enable the nonblocking and callback functionality. + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + qemu-char.c | 3 +++ + qemu-char.h | 4 ++++ + 2 files changed, 7 insertions(+) + +diff --git a/qemu-char.c b/qemu-char.c +index bd443db..b5266d1 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -211,11 +211,14 @@ void qemu_chr_add_handlers(CharDriverState *s, + } + s->chr_can_read = handlers->fd_can_read; + s->chr_read = handlers->fd_read; ++ s->chr_write_unblocked = handlers->fd_write_unblocked; + s->chr_event = handlers->fd_event; + s->handler_opaque = opaque; + if (s->chr_update_read_handler) + s->chr_update_read_handler(s); + ++ s->write_blocked = false; ++ + /* We're connecting to an already opened device, so let's make sure we + also get the open event */ + if (s->opened) { +diff --git a/qemu-char.h b/qemu-char.h +index dfa8c2d..b5e23a4 100644 +--- a/qemu-char.h ++++ b/qemu-char.h +@@ -62,6 +62,9 @@ struct CharDriverState { + IOEventHandler *chr_event; + IOCanReadHandler *chr_can_read; + IOReadHandler *chr_read; ++ IOHandler *chr_write_unblocked; ++ void (*chr_enable_write_fd_handler)(struct CharDriverState *chr); ++ void (*chr_disable_write_fd_handler)(struct CharDriverState *chr); + void *handler_opaque; + void (*chr_close)(struct CharDriverState *chr); + void (*chr_accept_input)(struct CharDriverState *chr); +@@ -74,6 +77,7 @@ struct CharDriverState { + char *filename; + int opened; + int avail_connections; ++ bool write_blocked; /* Are we in a blocked state? */ + QTAILQ_ENTRY(CharDriverState) next; + }; + diff --git a/0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch b/0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch deleted file mode 100644 index 830ed84..0000000 --- a/0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 625915146f56f77c275be1aee160f40183008b8d Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 22:02:47 +0100 -Subject: [PATCH] char: Equip the unix/tcp backend to handle nonblocking - writes# - -Now that the infrastructure is in place to return -EAGAIN to callers, -individual char drivers can set their update_fd_handlers() function to -set or remove an fd's write handler. This handler checks if the driver -became writable. - -A generic callback routine is used for unblocking writes and letting -users of chardevs know that a driver became writable again. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - -diff --git a/qemu-char.c b/qemu-char.c -index b46cc97..9f8608a 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -106,6 +106,19 @@ - static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = - QTAILQ_HEAD_INITIALIZER(chardevs); - -+/* -+ * Generic routine that gets called when chardev becomes writable. -+ * Lets chardev user know it's OK to send more data. -+ */ -+static void char_write_unblocked(void *opaque) -+{ -+ CharDriverState *chr = opaque; -+ -+ chr->write_blocked = false; -+ chr->chr_disable_write_fd_handler(chr); -+ chr->chr_write_unblocked(chr->handler_opaque); -+} -+ - void qemu_chr_be_event(CharDriverState *s, int event) - { - /* Keep track if the char device is open */ -@@ -2503,6 +2516,25 @@ static void tcp_chr_close(CharDriverState *chr) - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); - } - -+static void tcp_enable_write_fd_handler(CharDriverState *chr) -+{ -+ TCPCharDriver *s = chr->opaque; -+ -+ /* -+ * This function is called only after tcp_chr_connect() is called -+ * (either in 'server' mode or client mode. So we're sure of -+ * s->fd being initialised. -+ */ -+ enable_write_fd_handler(s->fd, char_write_unblocked); -+} -+ -+static void tcp_disable_write_fd_handler(CharDriverState *chr) -+{ -+ TCPCharDriver *s = chr->opaque; -+ -+ disable_write_fd_handler(s->fd); -+} -+ - static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) - { - CharDriverState *chr = NULL; -@@ -2557,6 +2589,8 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) - chr->chr_close = tcp_chr_close; - chr->get_msgfd = tcp_get_msgfd; - chr->chr_add_client = tcp_chr_add_client; -+ chr->chr_enable_write_fd_handler = tcp_enable_write_fd_handler; -+ chr->chr_disable_write_fd_handler = tcp_disable_write_fd_handler; - - if (is_listen) { - s->listen_fd = fd; --- -1.7.12.1 - diff --git a/0406-char-Throttle-when-host-connection-is-down.patch b/0406-char-Throttle-when-host-connection-is-down.patch deleted file mode 100644 index 2190637..0000000 --- a/0406-char-Throttle-when-host-connection-is-down.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 542fa14530022044ab577c543fba83202d52b703 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 22:05:10 +0100 -Subject: [PATCH] char: Throttle when host connection is down# - -When the host-side connection goes down, throttle the virtio-serial bus -and later unthrottle when a connection gets established. This helps -prevent any lost IO (guest->host) while the host connection was down. - -Bugzilla: 621484 - -This commit actually helps the bug mentioned above as no writes will now -get lost because of the throttling done here. With just the patches -sent earlier for that bug, one write will end up getting lost in the -worst case (host d/c, guest write, host connect). - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/qemu-char.c b/qemu-char.c -index 9f8608a..bfc94a5 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -140,6 +140,9 @@ static void qemu_chr_generic_open_bh(void *opaque) - { - CharDriverState *s = opaque; - qemu_chr_be_event(s, CHR_EVENT_OPENED); -+ if (s->write_blocked) { -+ char_write_unblocked(s); -+ } - qemu_bh_delete(s->bh); - s->bh = NULL; - } -@@ -2244,6 +2247,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - ret = send_all(chr, s->fd, buf, len); - if (ret == -1 && errno == EPIPE) { - tcp_closed(chr); -+ -+ if (chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) { -+ /* -+ * Since we haven't written out anything, let's say -+ * we're throttled. This will prevent any output from -+ * the guest getting lost if host-side chardev goes -+ * down. Unthrottle when we re-connect. -+ */ -+ chr->write_blocked = true; -+ return 0; -+ } - } - return ret; - } else { --- -1.7.12.1 - diff --git a/0406-char-Update-send_all-to-handle-nonblocking-chardev-w.patch b/0406-char-Update-send_all-to-handle-nonblocking-chardev-w.patch new file mode 100644 index 0000000..823204e --- /dev/null +++ b/0406-char-Update-send_all-to-handle-nonblocking-chardev-w.patch @@ -0,0 +1,170 @@ +From 0bb331d124049a9157c08bb1d3572493e6691f05 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 22:00:27 +0100 +Subject: [PATCH] char: Update send_all() to handle nonblocking chardev write + requests + +The send_all function is modified to return to the caller in case the +driver cannot handle any more data. It returns -EAGAIN or +WSAEWOULDBLOCK on non-Windows and Windows platforms respectively. This +is only done when the caller sets a callback function handler indicating +it's not interested in blocking till the driver has written out all the +data. + +Currently there's no driver or caller that supports this. Future +commits will add such capability. + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + qemu-char.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ + qemu_socket.h | 2 +- + 2 files changed, 64 insertions(+), 7 deletions(-) + +diff --git a/qemu-char.c b/qemu-char.c +index b5266d1..b46cc97 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -508,7 +508,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) + + + #ifdef _WIN32 +-int send_all(int fd, const void *buf, int len1) ++static int do_send(int fd, const void *buf, int len1, bool nonblock) + { + int ret, len; + +@@ -516,9 +516,14 @@ int send_all(int fd, const void *buf, int len1) + while (len > 0) { + ret = send(fd, buf, len, 0); + if (ret < 0) { ++ if (nonblock && len1 - len) { ++ return len1 - len; ++ } + errno = WSAGetLastError(); + if (errno != WSAEWOULDBLOCK) { + return -1; ++ } else if (errno == WSAEWOULDBLOCK && nonblock) { ++ return WSAEWOULDBLOCK; + } + } else if (ret == 0) { + break; +@@ -532,7 +537,7 @@ int send_all(int fd, const void *buf, int len1) + + #else + +-int send_all(int fd, const void *_buf, int len1) ++static int do_send(int fd, const void *_buf, int len1, bool nonblock) + { + int ret, len; + const uint8_t *buf = _buf; +@@ -541,8 +546,15 @@ int send_all(int fd, const void *_buf, int len1) + while (len > 0) { + ret = write(fd, buf, len); + if (ret < 0) { +- if (errno != EINTR && errno != EAGAIN) ++ if (nonblock && len1 - len) { ++ return len1 - len; ++ } ++ if (errno == EAGAIN && nonblock) { ++ return -EAGAIN; ++ } ++ if (errno != EINTR && errno != EAGAIN) { + return -1; ++ } + } else if (ret == 0) { + break; + } else { +@@ -557,6 +569,44 @@ int send_all(int fd, const void *_buf, int len1) + #define STDIO_MAX_CLIENTS 1 + static int stdio_nb_clients; + ++int send_all(CharDriverState *chr, int fd, const void *_buf, int len1) ++{ ++ int ret, eagain_errno; ++ bool nonblock; ++ ++ if (chr && chr->write_blocked) { ++ /* ++ * The caller should not send us data while we're blocked, ++ * but this can happen when multiple writers are woken at once, ++ * so simply return -EAGAIN. ++ */ ++ return -EAGAIN; ++ } ++ ++ nonblock = false; ++ /* ++ * Ensure the char backend is able to receive and handle the ++ * 'write unblocked' event before we turn on nonblock support. ++ */ ++ if (chr && chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) { ++ nonblock = true; ++ } ++ ret = do_send(fd, _buf, len1, nonblock); ++ ++#ifdef _WIN32 ++ eagain_errno = WSAEWOULDBLOCK; ++#else ++ eagain_errno = -EAGAIN; ++#endif ++ ++ if (nonblock && (ret == eagain_errno || (ret >= 0 && ret < len1))) { ++ /* Update fd handler to wake up when chr becomes writable */ ++ chr->chr_enable_write_fd_handler(chr); ++ chr->write_blocked = true; ++ } ++ return ret; ++} ++ + #ifndef _WIN32 + + typedef struct { +@@ -568,7 +618,7 @@ typedef struct { + static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + { + FDCharDriver *s = chr->opaque; +- return send_all(s->fd_out, buf, len); ++ return send_all(chr, s->fd_out, buf, len); + } + + static int fd_chr_read_poll(void *opaque) +@@ -887,7 +937,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + pty_chr_update_read_handler(chr); + return 0; + } +- return send_all(s->fd, buf, len); ++ return send_all(chr, s->fd, buf, len); + } + + static int pty_chr_read_poll(void *opaque) +@@ -2174,8 +2224,15 @@ static void tcp_closed(void *opaque) + static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + { + TCPCharDriver *s = chr->opaque; ++ + if (s->connected) { +- return send_all(s->fd, buf, len); ++ int ret; ++ ++ ret = send_all(chr, s->fd, buf, len); ++ if (ret == -1 && errno == EPIPE) { ++ tcp_closed(chr); ++ } ++ return ret; + } else { + /* XXX: indicate an error ? */ + return len; +diff --git a/qemu_socket.h b/qemu_socket.h +index 3e8aee9..a537d86 100644 +--- a/qemu_socket.h ++++ b/qemu_socket.h +@@ -36,7 +36,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); + int socket_set_cork(int fd, int v); + void socket_set_block(int fd); + void socket_set_nonblock(int fd); +-int send_all(int fd, const void *buf, int len1); ++int send_all(CharDriverState *chr, int fd, const void *buf, int len1); + + /* callback function for nonblocking connect + * valid fd on success, negative error code on failure diff --git a/0407-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch b/0407-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch new file mode 100644 index 0000000..a4718cf --- /dev/null +++ b/0407-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch @@ -0,0 +1,79 @@ +From f249489e3f81a99bb60d1c008aabf9c8ad90b381 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 22:02:47 +0100 +Subject: [PATCH] char: Equip the unix/tcp backend to handle nonblocking + writes# + +Now that the infrastructure is in place to return -EAGAIN to callers, +individual char drivers can set their update_fd_handlers() function to +set or remove an fd's write handler. This handler checks if the driver +became writable. + +A generic callback routine is used for unblocking writes and letting +users of chardevs know that a driver became writable again. + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + qemu-char.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/qemu-char.c b/qemu-char.c +index b46cc97..9f8608a 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -106,6 +106,19 @@ + static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = + QTAILQ_HEAD_INITIALIZER(chardevs); + ++/* ++ * Generic routine that gets called when chardev becomes writable. ++ * Lets chardev user know it's OK to send more data. ++ */ ++static void char_write_unblocked(void *opaque) ++{ ++ CharDriverState *chr = opaque; ++ ++ chr->write_blocked = false; ++ chr->chr_disable_write_fd_handler(chr); ++ chr->chr_write_unblocked(chr->handler_opaque); ++} ++ + void qemu_chr_be_event(CharDriverState *s, int event) + { + /* Keep track if the char device is open */ +@@ -2503,6 +2516,25 @@ static void tcp_chr_close(CharDriverState *chr) + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); + } + ++static void tcp_enable_write_fd_handler(CharDriverState *chr) ++{ ++ TCPCharDriver *s = chr->opaque; ++ ++ /* ++ * This function is called only after tcp_chr_connect() is called ++ * (either in 'server' mode or client mode. So we're sure of ++ * s->fd being initialised. ++ */ ++ enable_write_fd_handler(s->fd, char_write_unblocked); ++} ++ ++static void tcp_disable_write_fd_handler(CharDriverState *chr) ++{ ++ TCPCharDriver *s = chr->opaque; ++ ++ disable_write_fd_handler(s->fd); ++} ++ + static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) + { + CharDriverState *chr = NULL; +@@ -2557,6 +2589,8 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) + chr->chr_close = tcp_chr_close; + chr->get_msgfd = tcp_get_msgfd; + chr->chr_add_client = tcp_chr_add_client; ++ chr->chr_enable_write_fd_handler = tcp_enable_write_fd_handler; ++ chr->chr_disable_write_fd_handler = tcp_disable_write_fd_handler; + + if (is_listen) { + s->listen_fd = fd; diff --git a/0407-virtio-console-Enable-port-throttling-when-chardev-i.patch b/0407-virtio-console-Enable-port-throttling-when-chardev-i.patch deleted file mode 100644 index 85630c0..0000000 --- a/0407-virtio-console-Enable-port-throttling-when-chardev-i.patch +++ /dev/null @@ -1,50 +0,0 @@ -From feeea13d5eac9c0dd5da1ee7639a57ca519f4c91 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 22:06:41 +0100 -Subject: [PATCH] virtio-console: Enable port throttling when chardev is slow - to consume data - -When a chardev indicates it can't accept more data, we tell the -virtio-serial code to stop sending us any more data till we tell -otherwise. This helps in guests continuing to run normally while the vq -keeps getting full and eventually the guest stops queueing more data. -As soon as the chardev indicates it can accept more data, start pushing! - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - hw/virtio-console.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/hw/virtio-console.c b/hw/virtio-console.c -index 066590c..2b5e515 100644 ---- a/hw/virtio-console.c -+++ b/hw/virtio-console.c -@@ -20,6 +20,16 @@ typedef struct VirtConsole { - CharDriverState *chr; - } VirtConsole; - -+/* -+ * Callback function that's called from chardevs when backend becomes -+ * writable. -+ */ -+static void chr_write_unblocked(void *opaque) -+{ -+ VirtConsole *vcon = opaque; -+ -+ virtio_serial_throttle_port(&vcon->port, false); -+} - - /* Callback function that's called when the guest sends us data */ - static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) -@@ -110,6 +120,7 @@ static const QemuChrHandlers chr_handlers = { - .fd_can_read = chr_can_read, - .fd_read = chr_read, - .fd_event = chr_event, -+ .fd_write_unblocked = chr_write_unblocked, - }; - - static int virtconsole_initfn(VirtIOSerialPort *port) --- -1.7.12.1 - diff --git a/0408-char-Throttle-when-host-connection-is-down.patch b/0408-char-Throttle-when-host-connection-is-down.patch new file mode 100644 index 0000000..6050547 --- /dev/null +++ b/0408-char-Throttle-when-host-connection-is-down.patch @@ -0,0 +1,54 @@ +From d06d51e96773ab8295e31f666466fb2edb093aa0 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 22:05:10 +0100 +Subject: [PATCH] char: Throttle when host connection is down# + +When the host-side connection goes down, throttle the virtio-serial bus +and later unthrottle when a connection gets established. This helps +prevent any lost IO (guest->host) while the host connection was down. + +Bugzilla: 621484 + +This commit actually helps the bug mentioned above as no writes will now +get lost because of the throttling done here. With just the patches +sent earlier for that bug, one write will end up getting lost in the +worst case (host d/c, guest write, host connect). + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + qemu-char.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/qemu-char.c b/qemu-char.c +index 9f8608a..bfc94a5 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -140,6 +140,9 @@ static void qemu_chr_generic_open_bh(void *opaque) + { + CharDriverState *s = opaque; + qemu_chr_be_event(s, CHR_EVENT_OPENED); ++ if (s->write_blocked) { ++ char_write_unblocked(s); ++ } + qemu_bh_delete(s->bh); + s->bh = NULL; + } +@@ -2244,6 +2247,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + ret = send_all(chr, s->fd, buf, len); + if (ret == -1 && errno == EPIPE) { + tcp_closed(chr); ++ ++ if (chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) { ++ /* ++ * Since we haven't written out anything, let's say ++ * we're throttled. This will prevent any output from ++ * the guest getting lost if host-side chardev goes ++ * down. Unthrottle when we re-connect. ++ */ ++ chr->write_blocked = true; ++ return 0; ++ } + } + return ret; + } else { diff --git a/0408-spice-qemu-char.c-add-throttling.patch b/0408-spice-qemu-char.c-add-throttling.patch deleted file mode 100644 index 23018ec..0000000 --- a/0408-spice-qemu-char.c-add-throttling.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 2d1cf5b1be8cbd9c5a8c5f96ca699676fc1b23a7 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 22 Mar 2011 12:27:59 +0200 -Subject: [PATCH] spice-qemu-char.c: add throttling - -BZ: 672191 - -upstream: not submitted (explained below) - -Adds throttling support to spicevmc chardev. Uses a timer to avoid recursing: -1. spice-server: reds.c: read_from_vdi_port -2. qemu: spice-qemu-char.c: vmc_read -3. chr_write_unblocked - (calls virtio_serial_throttle_port(port, false)) -4. qemu: virtio ... -5. qemu: spice-qemu-char.c: spice_chr_write -6. qemu: spice-qemu-char.c: wakeup (calls into spice-server) -7. spice-server: ... -8. qemu: spice-qemu-char.c: vmc_read - -Instead, in vmc_read if we were throttled and we are just about to return -all the bytes we will set a timer to be triggered immediately to call -chr_write_unblocked. Then we return after 2 above, and 3 is called from the -timer callback. This also means we can later remove some ugly recursion protection -from spice-server. - -The other tricky point in this patch is not returning the leftover chunk twice. -When we throttle, by definition we have data that spice server didn't consume. -It is being kept by virtio-serial, and by us. The next vmc_read callback needs -to not return it, but just do unthrottling. Then virtio will give us the remaining -chunk as usual in spice_chr_write, and we will pass it to spice server in the -next vmc_read. - -This patch relies on Amit's series to expose throttling to chardev's, which -was not accepted upstream, and will not be accepted upstream until the mainloop -is reworked to use glib. - -Signed-off-by: Cole Robinson ---- - spice-qemu-char.c | 39 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 35 insertions(+), 4 deletions(-) - -diff --git a/spice-qemu-char.c b/spice-qemu-char.c -index 09aa22d..fba2bfb 100644 ---- a/spice-qemu-char.c -+++ b/spice-qemu-char.c -@@ -1,4 +1,6 @@ - #include "config-host.h" -+#include "qemu-common.h" -+#include "qemu-timer.h" - #include "trace.h" - #include "ui/qemu-spice.h" - #include -@@ -25,6 +27,7 @@ typedef struct SpiceCharDriver { - uint8_t *datapos; - ssize_t bufsize, datalen; - uint32_t debug; -+ QEMUTimer *unblock_timer; - } SpiceCharDriver; - - static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) -@@ -50,6 +53,17 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) - return out; - } - -+static void spice_chr_unblock(void *opaque) -+{ -+ SpiceCharDriver *scd = opaque; -+ -+ if (scd->chr->chr_write_unblocked == NULL) { -+ dprintf(scd, 1, "%s: backend doesn't support unthrottling.\n", __func__); -+ return; -+ } -+ scd->chr->chr_write_unblocked(scd->chr->handler_opaque); -+} -+ - static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) - { - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); -@@ -61,9 +75,16 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) - scd->datapos += bytes; - scd->datalen -= bytes; - assert(scd->datalen >= 0); -- if (scd->datalen == 0) { -- scd->datapos = 0; -- } -+ } -+ if (scd->datalen == 0 && scd->chr->write_blocked) { -+ dprintf(scd, 1, "%s: unthrottling (%d)\n", __func__, bytes); -+ scd->chr->write_blocked = false; -+ /* -+ * set a timer instead of calling scd->chr->chr_write_unblocked directly, -+ * because that will call back into spice_chr_write (see -+ * virtio-console.c:chr_write_unblocked), which is unwanted. -+ */ -+ qemu_mod_timer(scd->unblock_timer, 0); - } - trace_spice_vmc_read(bytes, len); - return bytes; -@@ -135,6 +156,7 @@ static void vmc_unregister_interface(SpiceCharDriver *scd) - static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - SpiceCharDriver *s = chr->opaque; -+ int read_bytes; - - dprintf(s, 2, "%s: %d\n", __func__, len); - vmc_register_interface(s); -@@ -147,7 +169,15 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - s->datapos = s->buffer; - s->datalen = len; - spice_server_char_device_wakeup(&s->sin); -- return len; -+ read_bytes = len - s->datalen; -+ if (read_bytes != len) { -+ dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__, -+ read_bytes, len, s->bufsize); -+ s->chr->write_blocked = true; -+ /* We'll get passed in the unconsumed data with the next call */ -+ s->datalen = 0; -+ } -+ return read_bytes; - } - - static void spice_chr_close(struct CharDriverState *chr) -@@ -225,6 +255,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts) - chr->chr_close = spice_chr_close; - chr->chr_guest_open = spice_chr_guest_open; - chr->chr_guest_close = spice_chr_guest_close; -+ s->unblock_timer = qemu_new_timer_ms(vm_clock, spice_chr_unblock, s); - - #if SPICE_SERVER_VERSION < 0x000901 - /* See comment in vmc_state() */ --- -1.7.12.1 - diff --git a/0409-spice-qemu-char.c-remove-intermediate-buffer.patch b/0409-spice-qemu-char.c-remove-intermediate-buffer.patch deleted file mode 100644 index e1c6f0a..0000000 --- a/0409-spice-qemu-char.c-remove-intermediate-buffer.patch +++ /dev/null @@ -1,73 +0,0 @@ -From fb481324641fc36e6f58aca8d8e5ada0536332f2 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 22 Mar 2011 12:28:00 +0200 -Subject: [PATCH] spice-qemu-char.c: remove intermediate buffer - -BZ: 672191 -upstream: not submitted (explained below) - -virtio-serial's buffer is valid when it calls us, and we don't -access it otherwise: vmc_read is only called in response to wakeup, -or else we set datalen=0 and throttle. Then vmc_read is called back, -we return 0 (not accessing the buffer) and set the timer to unthrottle. - -Also make datalen int and not ssize_t (to fit spice_chr_write signature). - -This relied on the previous patch that introduces throttling, which -can't go upstream right now as explained in that patch. - -Signed-off-by: Cole Robinson ---- - spice-qemu-char.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - -diff --git a/spice-qemu-char.c b/spice-qemu-char.c -index fba2bfb..ef44bc0 100644 ---- a/spice-qemu-char.c -+++ b/spice-qemu-char.c -@@ -23,9 +23,8 @@ typedef struct SpiceCharDriver { - SpiceCharDeviceInstance sin; - char *subtype; - bool active; -- uint8_t *buffer; -- uint8_t *datapos; -- ssize_t bufsize, datalen; -+ const uint8_t *datapos; -+ int datalen; - uint32_t debug; - QEMUTimer *unblock_timer; - } SpiceCharDriver; -@@ -69,7 +68,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); - int bytes = MIN(len, scd->datalen); - -- dprintf(scd, 2, "%s: %p %d/%d/%zd\n", __func__, scd->datapos, len, bytes, scd->datalen); -+ dprintf(scd, 2, "%s: %p %d/%d/%d\n", __func__, scd->datapos, len, bytes, scd->datalen); - if (bytes > 0) { - memcpy(buf, scd->datapos, bytes); - scd->datapos += bytes; -@@ -161,18 +160,13 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - dprintf(s, 2, "%s: %d\n", __func__, len); - vmc_register_interface(s); - assert(s->datalen == 0); -- if (s->bufsize < len) { -- s->bufsize = len; -- s->buffer = g_realloc(s->buffer, s->bufsize); -- } -- memcpy(s->buffer, buf, len); -- s->datapos = s->buffer; -+ s->datapos = buf; - s->datalen = len; - spice_server_char_device_wakeup(&s->sin); - read_bytes = len - s->datalen; - if (read_bytes != len) { -- dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__, -- read_bytes, len, s->bufsize); -+ dprintf(s, 1, "%s: throttling: %d < %d\n", __func__, -+ read_bytes, len); - s->chr->write_blocked = true; - /* We'll get passed in the unconsumed data with the next call */ - s->datalen = 0; --- -1.7.12.1 - diff --git a/0409-virtio-console-Enable-port-throttling-when-chardev-i.patch b/0409-virtio-console-Enable-port-throttling-when-chardev-i.patch new file mode 100644 index 0000000..c897d42 --- /dev/null +++ b/0409-virtio-console-Enable-port-throttling-when-chardev-i.patch @@ -0,0 +1,47 @@ +From d79d2a6ea50bd4dd07afe05471c8074f2f668150 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Mon, 21 Mar 2011 22:06:41 +0100 +Subject: [PATCH] virtio-console: Enable port throttling when chardev is slow + to consume data + +When a chardev indicates it can't accept more data, we tell the +virtio-serial code to stop sending us any more data till we tell +otherwise. This helps in guests continuing to run normally while the vq +keeps getting full and eventually the guest stops queueing more data. +As soon as the chardev indicates it can accept more data, start pushing! + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + hw/virtio-console.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/hw/virtio-console.c b/hw/virtio-console.c +index 066590c..2b5e515 100644 +--- a/hw/virtio-console.c ++++ b/hw/virtio-console.c +@@ -20,6 +20,16 @@ typedef struct VirtConsole { + CharDriverState *chr; + } VirtConsole; + ++/* ++ * Callback function that's called from chardevs when backend becomes ++ * writable. ++ */ ++static void chr_write_unblocked(void *opaque) ++{ ++ VirtConsole *vcon = opaque; ++ ++ virtio_serial_throttle_port(&vcon->port, false); ++} + + /* Callback function that's called when the guest sends us data */ + static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) +@@ -110,6 +120,7 @@ static const QemuChrHandlers chr_handlers = { + .fd_can_read = chr_can_read, + .fd_read = chr_read, + .fd_event = chr_event, ++ .fd_write_unblocked = chr_write_unblocked, + }; + + static int virtconsole_initfn(VirtIOSerialPort *port) diff --git a/0410-spice-qemu-char.c-add-throttling.patch b/0410-spice-qemu-char.c-add-throttling.patch new file mode 100644 index 0000000..c11cb88 --- /dev/null +++ b/0410-spice-qemu-char.c-add-throttling.patch @@ -0,0 +1,132 @@ +From 89e95288a8f5b462230910d25fc97c8eeb33dd5f Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Tue, 22 Mar 2011 12:27:59 +0200 +Subject: [PATCH] spice-qemu-char.c: add throttling + +BZ: 672191 + +upstream: not submitted (explained below) + +Adds throttling support to spicevmc chardev. Uses a timer to avoid recursing: +1. spice-server: reds.c: read_from_vdi_port +2. qemu: spice-qemu-char.c: vmc_read +3. chr_write_unblocked + (calls virtio_serial_throttle_port(port, false)) +4. qemu: virtio ... +5. qemu: spice-qemu-char.c: spice_chr_write +6. qemu: spice-qemu-char.c: wakeup (calls into spice-server) +7. spice-server: ... +8. qemu: spice-qemu-char.c: vmc_read + +Instead, in vmc_read if we were throttled and we are just about to return +all the bytes we will set a timer to be triggered immediately to call +chr_write_unblocked. Then we return after 2 above, and 3 is called from the +timer callback. This also means we can later remove some ugly recursion protection +from spice-server. + +The other tricky point in this patch is not returning the leftover chunk twice. +When we throttle, by definition we have data that spice server didn't consume. +It is being kept by virtio-serial, and by us. The next vmc_read callback needs +to not return it, but just do unthrottling. Then virtio will give us the remaining +chunk as usual in spice_chr_write, and we will pass it to spice server in the +next vmc_read. + +This patch relies on Amit's series to expose throttling to chardev's, which +was not accepted upstream, and will not be accepted upstream until the mainloop +is reworked to use glib. + +Signed-off-by: Cole Robinson +--- + spice-qemu-char.c | 39 +++++++++++++++++++++++++++++++++++---- + 1 file changed, 35 insertions(+), 4 deletions(-) + +diff --git a/spice-qemu-char.c b/spice-qemu-char.c +index 09aa22d..fba2bfb 100644 +--- a/spice-qemu-char.c ++++ b/spice-qemu-char.c +@@ -1,4 +1,6 @@ + #include "config-host.h" ++#include "qemu-common.h" ++#include "qemu-timer.h" + #include "trace.h" + #include "ui/qemu-spice.h" + #include +@@ -25,6 +27,7 @@ typedef struct SpiceCharDriver { + uint8_t *datapos; + ssize_t bufsize, datalen; + uint32_t debug; ++ QEMUTimer *unblock_timer; + } SpiceCharDriver; + + static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) +@@ -50,6 +53,17 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) + return out; + } + ++static void spice_chr_unblock(void *opaque) ++{ ++ SpiceCharDriver *scd = opaque; ++ ++ if (scd->chr->chr_write_unblocked == NULL) { ++ dprintf(scd, 1, "%s: backend doesn't support unthrottling.\n", __func__); ++ return; ++ } ++ scd->chr->chr_write_unblocked(scd->chr->handler_opaque); ++} ++ + static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) + { + SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); +@@ -61,9 +75,16 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) + scd->datapos += bytes; + scd->datalen -= bytes; + assert(scd->datalen >= 0); +- if (scd->datalen == 0) { +- scd->datapos = 0; +- } ++ } ++ if (scd->datalen == 0 && scd->chr->write_blocked) { ++ dprintf(scd, 1, "%s: unthrottling (%d)\n", __func__, bytes); ++ scd->chr->write_blocked = false; ++ /* ++ * set a timer instead of calling scd->chr->chr_write_unblocked directly, ++ * because that will call back into spice_chr_write (see ++ * virtio-console.c:chr_write_unblocked), which is unwanted. ++ */ ++ qemu_mod_timer(scd->unblock_timer, 0); + } + trace_spice_vmc_read(bytes, len); + return bytes; +@@ -135,6 +156,7 @@ static void vmc_unregister_interface(SpiceCharDriver *scd) + static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + { + SpiceCharDriver *s = chr->opaque; ++ int read_bytes; + + dprintf(s, 2, "%s: %d\n", __func__, len); + vmc_register_interface(s); +@@ -147,7 +169,15 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + s->datapos = s->buffer; + s->datalen = len; + spice_server_char_device_wakeup(&s->sin); +- return len; ++ read_bytes = len - s->datalen; ++ if (read_bytes != len) { ++ dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__, ++ read_bytes, len, s->bufsize); ++ s->chr->write_blocked = true; ++ /* We'll get passed in the unconsumed data with the next call */ ++ s->datalen = 0; ++ } ++ return read_bytes; + } + + static void spice_chr_close(struct CharDriverState *chr) +@@ -225,6 +255,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts) + chr->chr_close = spice_chr_close; + chr->chr_guest_open = spice_chr_guest_open; + chr->chr_guest_close = spice_chr_guest_close; ++ s->unblock_timer = qemu_new_timer_ms(vm_clock, spice_chr_unblock, s); + + #if SPICE_SERVER_VERSION < 0x000901 + /* See comment in vmc_state() */ diff --git a/0410-usb-redir-Add-flow-control-support.patch b/0410-usb-redir-Add-flow-control-support.patch deleted file mode 100644 index 8506b22..0000000 --- a/0410-usb-redir-Add-flow-control-support.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 539b42dbeefbf2fc7dc40ab7c1b5d9592a87d9b8 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 19 Jul 2011 10:56:19 +0200 -Subject: [PATCH] usb-redir: Add flow control support - -Signed-off-by: Hans de Goede -Signed-off-by: Cole Robinson ---- - hw/usb/redirect.c | 22 ++++++++++++++++++++-- - 1 file changed, 20 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 8b22c80..b7c7f1e 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -229,12 +229,22 @@ static int usbredir_read(void *priv, uint8_t *data, int count) - static int usbredir_write(void *priv, uint8_t *data, int count) - { - USBRedirDevice *dev = priv; -+ int r; - -- if (!dev->cs->opened) { -+ if (!dev->cs->opened || dev->cs->write_blocked) { - return 0; - } - -- return qemu_chr_fe_write(dev->cs, data, count); -+ r = qemu_chr_fe_write(dev->cs, data, count); -+ -+ if (r < 0) { -+ if (dev->cs->write_blocked) { -+ return 0; -+ } -+ return -1; -+ } -+ -+ return r; - } - - /* -@@ -867,10 +877,18 @@ static void usbredir_chardev_event(void *opaque, int event) - } - } - -+static void usbredir_chardev_write_unblocked(void *opaque) -+{ -+ USBRedirDevice *dev = opaque; -+ -+ usbredirparser_do_write(dev->parser); -+} -+ - static const QemuChrHandlers usbredir_chr_handlers = { - .fd_can_read = usbredir_chardev_can_read, - .fd_read = usbredir_chardev_read, - .fd_event = usbredir_chardev_event, -+ .fd_write_unblocked = usbredir_chardev_write_unblocked, - }; - - /* --- -1.7.12.1 - diff --git a/0411-spice-qemu-char.c-remove-intermediate-buffer.patch b/0411-spice-qemu-char.c-remove-intermediate-buffer.patch new file mode 100644 index 0000000..8b0cb95 --- /dev/null +++ b/0411-spice-qemu-char.c-remove-intermediate-buffer.patch @@ -0,0 +1,70 @@ +From 7c96741eb22bbfc8c257334e28493adabbeee5ff Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Tue, 22 Mar 2011 12:28:00 +0200 +Subject: [PATCH] spice-qemu-char.c: remove intermediate buffer + +BZ: 672191 +upstream: not submitted (explained below) + +virtio-serial's buffer is valid when it calls us, and we don't +access it otherwise: vmc_read is only called in response to wakeup, +or else we set datalen=0 and throttle. Then vmc_read is called back, +we return 0 (not accessing the buffer) and set the timer to unthrottle. + +Also make datalen int and not ssize_t (to fit spice_chr_write signature). + +This relied on the previous patch that introduces throttling, which +can't go upstream right now as explained in that patch. + +Signed-off-by: Cole Robinson +--- + spice-qemu-char.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +diff --git a/spice-qemu-char.c b/spice-qemu-char.c +index fba2bfb..ef44bc0 100644 +--- a/spice-qemu-char.c ++++ b/spice-qemu-char.c +@@ -23,9 +23,8 @@ typedef struct SpiceCharDriver { + SpiceCharDeviceInstance sin; + char *subtype; + bool active; +- uint8_t *buffer; +- uint8_t *datapos; +- ssize_t bufsize, datalen; ++ const uint8_t *datapos; ++ int datalen; + uint32_t debug; + QEMUTimer *unblock_timer; + } SpiceCharDriver; +@@ -69,7 +68,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) + SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); + int bytes = MIN(len, scd->datalen); + +- dprintf(scd, 2, "%s: %p %d/%d/%zd\n", __func__, scd->datapos, len, bytes, scd->datalen); ++ dprintf(scd, 2, "%s: %p %d/%d/%d\n", __func__, scd->datapos, len, bytes, scd->datalen); + if (bytes > 0) { + memcpy(buf, scd->datapos, bytes); + scd->datapos += bytes; +@@ -161,18 +160,13 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) + dprintf(s, 2, "%s: %d\n", __func__, len); + vmc_register_interface(s); + assert(s->datalen == 0); +- if (s->bufsize < len) { +- s->bufsize = len; +- s->buffer = g_realloc(s->buffer, s->bufsize); +- } +- memcpy(s->buffer, buf, len); +- s->datapos = s->buffer; ++ s->datapos = buf; + s->datalen = len; + spice_server_char_device_wakeup(&s->sin); + read_bytes = len - s->datalen; + if (read_bytes != len) { +- dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__, +- read_bytes, len, s->bufsize); ++ dprintf(s, 1, "%s: throttling: %d < %d\n", __func__, ++ read_bytes, len); + s->chr->write_blocked = true; + /* We'll get passed in the unconsumed data with the next call */ + s->datalen = 0; diff --git a/0411-virtio-serial-bus-replay-guest_open-on-migration.patch b/0411-virtio-serial-bus-replay-guest_open-on-migration.patch deleted file mode 100644 index 7cdc9bb..0000000 --- a/0411-virtio-serial-bus-replay-guest_open-on-migration.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a9bc20afc1f0604ee81c23b7c67d627e51d2e8d4 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Thu, 28 Jul 2011 15:08:48 +0300 -Subject: [PATCH] virtio-serial-bus: replay guest_open on migration - -When migrating a host with with a spice agent running the mouse becomes -non operational after the migration. This is rhbz #725965. - -The problem is that after migration spice doesn't know the guest agent is open. -Spice is just a char dev here. And a chardev cannot query it's device, the -device has to let the chardev know when it is open. Right now after migration -the chardev which is recreated is in it's default state, which assumes the -guest is disconnected. - -Char devices carry no information across migration, but the virtio-serial does -already carry the guest_connected state. This patch passes that bit to the -chardev. - -Signed-off-by: Alon Levy -Signed-off-by: Cole Robinson ---- - hw/virtio-serial-bus.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index 82073f5..18c2ed3 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -682,6 +682,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - for (i = 0; i < nr_active_ports; i++) { - uint32_t id; - bool host_connected; -+ VirtIOSerialPortClass *vsc; - - id = qemu_get_be32(f); - port = find_port_by_id(s, id); -@@ -690,6 +691,11 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - } - - port->guest_connected = qemu_get_byte(f); -+ vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); -+ if (port->guest_connected && vsc->guest_open) { -+ /* replay guest open */ -+ vsc->guest_open(port); -+ } - host_connected = qemu_get_byte(f); - if (host_connected != port->host_connected) { - /* --- -1.7.12.1 - diff --git a/0412-char-Disable-write-callback-if-throttled-chardev-is-.patch b/0412-char-Disable-write-callback-if-throttled-chardev-is-.patch deleted file mode 100644 index ae0be6f..0000000 --- a/0412-char-Disable-write-callback-if-throttled-chardev-is-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From f3551d3640f3436b0e5505fd208cbd7bbfef411f Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Fri, 2 Dec 2011 15:42:55 +0530 -Subject: [PATCH] char: Disable write callback if throttled chardev is - detached - -If a throttled chardev is detached from the frontend device, all future -callbacks should be suppressed. Not doing this results in a segfault. - -Bugzilla: 745758 -Upstream: Not applicable, since throttling is a RHEL6-only feature. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/qemu-char.c b/qemu-char.c -index bfc94a5..67a6d73 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -223,6 +223,11 @@ void qemu_chr_add_handlers(CharDriverState *s, - ++s->avail_connections; - } - if (!handlers) { -+ if (s->write_blocked) { -+ /* Ensure we disable the callback if we were throttled */ -+ s->chr_disable_write_fd_handler(s); -+ /* s->write_blocked is cleared below */ -+ } - handlers = &null_handlers; - } - s->chr_can_read = handlers->fd_can_read; --- -1.7.12.1 - diff --git a/0412-usb-redir-Add-flow-control-support.patch b/0412-usb-redir-Add-flow-control-support.patch new file mode 100644 index 0000000..19f37cb --- /dev/null +++ b/0412-usb-redir-Add-flow-control-support.patch @@ -0,0 +1,59 @@ +From 5399dd7756a093453751dea34212ba19db328eb4 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 19 Jul 2011 10:56:19 +0200 +Subject: [PATCH] usb-redir: Add flow control support + +Signed-off-by: Hans de Goede +Signed-off-by: Cole Robinson +--- + hw/usb/redirect.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 8b22c80..b7c7f1e 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -229,12 +229,22 @@ static int usbredir_read(void *priv, uint8_t *data, int count) + static int usbredir_write(void *priv, uint8_t *data, int count) + { + USBRedirDevice *dev = priv; ++ int r; + +- if (!dev->cs->opened) { ++ if (!dev->cs->opened || dev->cs->write_blocked) { + return 0; + } + +- return qemu_chr_fe_write(dev->cs, data, count); ++ r = qemu_chr_fe_write(dev->cs, data, count); ++ ++ if (r < 0) { ++ if (dev->cs->write_blocked) { ++ return 0; ++ } ++ return -1; ++ } ++ ++ return r; + } + + /* +@@ -867,10 +877,18 @@ static void usbredir_chardev_event(void *opaque, int event) + } + } + ++static void usbredir_chardev_write_unblocked(void *opaque) ++{ ++ USBRedirDevice *dev = opaque; ++ ++ usbredirparser_do_write(dev->parser); ++} ++ + static const QemuChrHandlers usbredir_chr_handlers = { + .fd_can_read = usbredir_chardev_can_read, + .fd_read = usbredir_chardev_read, + .fd_event = usbredir_chardev_event, ++ .fd_write_unblocked = usbredir_chardev_write_unblocked, + }; + + /* diff --git a/0413-virtio-serial-bus-replay-guest_open-on-migration.patch b/0413-virtio-serial-bus-replay-guest_open-on-migration.patch new file mode 100644 index 0000000..9f4e8a0 --- /dev/null +++ b/0413-virtio-serial-bus-replay-guest_open-on-migration.patch @@ -0,0 +1,48 @@ +From 0811633a396481e1cf1614362afd57c179fcf3de Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Thu, 28 Jul 2011 15:08:48 +0300 +Subject: [PATCH] virtio-serial-bus: replay guest_open on migration + +When migrating a host with with a spice agent running the mouse becomes +non operational after the migration. This is rhbz #725965. + +The problem is that after migration spice doesn't know the guest agent is open. +Spice is just a char dev here. And a chardev cannot query it's device, the +device has to let the chardev know when it is open. Right now after migration +the chardev which is recreated is in it's default state, which assumes the +guest is disconnected. + +Char devices carry no information across migration, but the virtio-serial does +already carry the guest_connected state. This patch passes that bit to the +chardev. + +Signed-off-by: Alon Levy +Signed-off-by: Cole Robinson +--- + hw/virtio-serial-bus.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c +index 82073f5..18c2ed3 100644 +--- a/hw/virtio-serial-bus.c ++++ b/hw/virtio-serial-bus.c +@@ -682,6 +682,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) + for (i = 0; i < nr_active_ports; i++) { + uint32_t id; + bool host_connected; ++ VirtIOSerialPortClass *vsc; + + id = qemu_get_be32(f); + port = find_port_by_id(s, id); +@@ -690,6 +691,11 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) + } + + port->guest_connected = qemu_get_byte(f); ++ vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); ++ if (port->guest_connected && vsc->guest_open) { ++ /* replay guest open */ ++ vsc->guest_open(port); ++ } + host_connected = qemu_get_byte(f); + if (host_connected != port->host_connected) { + /* diff --git a/0414-char-Disable-write-callback-if-throttled-chardev-is-.patch b/0414-char-Disable-write-callback-if-throttled-chardev-is-.patch new file mode 100644 index 0000000..6a74b30 --- /dev/null +++ b/0414-char-Disable-write-callback-if-throttled-chardev-is-.patch @@ -0,0 +1,33 @@ +From 58c0c0de01663aab4e8fdd03c05e2762a35d77a8 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Fri, 2 Dec 2011 15:42:55 +0530 +Subject: [PATCH] char: Disable write callback if throttled chardev is detached + +If a throttled chardev is detached from the frontend device, all future +callbacks should be suppressed. Not doing this results in a segfault. + +Bugzilla: 745758 +Upstream: Not applicable, since throttling is a RHEL6-only feature. + +Signed-off-by: Amit Shah +Signed-off-by: Cole Robinson +--- + qemu-char.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/qemu-char.c b/qemu-char.c +index bfc94a5..67a6d73 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -223,6 +223,11 @@ void qemu_chr_add_handlers(CharDriverState *s, + ++s->avail_connections; + } + if (!handlers) { ++ if (s->write_blocked) { ++ /* Ensure we disable the callback if we were throttled */ ++ s->chr_disable_write_fd_handler(s); ++ /* s->write_blocked is cleared below */ ++ } + handlers = &null_handlers; + } + s->chr_can_read = handlers->fd_can_read; diff --git a/0500-qxl-disallow-unknown-revisions.patch b/0500-qxl-disallow-unknown-revisions.patch deleted file mode 100644 index 331ca45..0000000 --- a/0500-qxl-disallow-unknown-revisions.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4b9d4103e5ff91b022ee8e9522040829f009543a Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 21 Aug 2012 13:51:32 +0300 -Subject: [PATCH] qxl: disallow unknown revisions - -Signed-off-by: Alon Levy -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 59bf822..71879fe 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -1873,9 +1873,9 @@ static int qxl_init_common(PCIQXLDevice *qxl) - break; - #endif - default: -- pci_device_rev = QXL_DEFAULT_REVISION; -- io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); -- break; -+ error_report("Invalid revision %d for qxl device (max %d)", -+ qxl->revision, QXL_DEFAULT_REVISION); -+ return -1; - } - - pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev); --- -1.7.12.1 - diff --git a/0501-qxl-disallow-unknown-revisions.patch b/0501-qxl-disallow-unknown-revisions.patch new file mode 100644 index 0000000..06c01ab --- /dev/null +++ b/0501-qxl-disallow-unknown-revisions.patch @@ -0,0 +1,28 @@ +From 0826dcf575c1f88b5082458d3876c2bfe0a1d9a3 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Tue, 21 Aug 2012 13:51:32 +0300 +Subject: [PATCH] qxl: disallow unknown revisions + +Signed-off-by: Alon Levy +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index e7e9dd9..20e844f 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -1873,9 +1873,9 @@ static int qxl_init_common(PCIQXLDevice *qxl) + break; + #endif + default: +- pci_device_rev = QXL_DEFAULT_REVISION; +- io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); +- break; ++ error_report("Invalid revision %d for qxl device (max %d)", ++ qxl->revision, QXL_DEFAULT_REVISION); ++ return -1; + } + + pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev); diff --git a/0501-spice-make-number-of-surfaces-runtime-configurable.patch b/0501-spice-make-number-of-surfaces-runtime-configurable.patch deleted file mode 100644 index b55c3df..0000000 --- a/0501-spice-make-number-of-surfaces-runtime-configurable.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 1c74b60fa972c9489f9cf8fa59165dedd0c23de2 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 4 Sep 2012 11:39:41 +0200 -Subject: [PATCH] spice: make number of surfaces runtime-configurable. - -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 31 +++++++++++++++++-------------- - hw/qxl.h | 3 +-- - ui/spice-display.c | 5 ++++- - ui/spice-display.h | 3 +-- - 4 files changed, 23 insertions(+), 19 deletions(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 71879fe..83df499 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -238,7 +238,8 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl) - { - trace_qxl_spice_destroy_surfaces_complete(qxl->id); - qemu_mutex_lock(&qxl->track_lock); -- memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds)); -+ memset(qxl->guest_surfaces.cmds, 0, -+ sizeof(qxl->guest_surfaces.cmds) * qxl->ssd.num_surfaces); - qxl->guest_surfaces.count = 0; - qemu_mutex_unlock(&qxl->track_lock); - } -@@ -347,7 +348,7 @@ static void init_qxl_rom(PCIQXLDevice *d) - rom->slot_id_bits = MEMSLOT_SLOT_BITS; - rom->slots_start = 1; - rom->slots_end = NUM_MEMSLOTS - 1; -- rom->n_surfaces = cpu_to_le32(NUM_SURFACES); -+ rom->n_surfaces = cpu_to_le32(d->ssd.num_surfaces); - - for (i = 0, n = 0; i < ARRAY_SIZE(qxl_modes); i++) { - fb = qxl_modes[i].y_res * qxl_modes[i].stride; -@@ -451,9 +452,9 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) - } - uint32_t id = le32_to_cpu(cmd->surface_id); - -- if (id >= NUM_SURFACES) { -+ if (id >= qxl->ssd.num_surfaces) { - qxl_set_guest_bug(qxl, "QXL_CMD_SURFACE id %d >= %d", id, -- NUM_SURFACES); -+ qxl->ssd.num_surfaces); - return 1; - } - qemu_mutex_lock(&qxl->track_lock); -@@ -529,7 +530,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) - info->num_memslots_groups = NUM_MEMSLOTS_GROUPS; - info->internal_groupslot_id = 0; - info->qxl_ram_size = le32_to_cpu(qxl->shadow_rom.num_pages) << TARGET_PAGE_BITS; -- info->n_surfaces = NUM_SURFACES; -+ info->n_surfaces = qxl->ssd.num_surfaces; - } - - static const char *qxl_mode_to_string(int mode) -@@ -1438,7 +1439,7 @@ async_common: - QXLCookie *cookie = NULL; - QXLRect update = d->ram->update_area; - -- if (d->ram->update_surface > NUM_SURFACES) { -+ if (d->ram->update_surface > d->ssd.num_surfaces) { - qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n", - d->ram->update_surface); - return; -@@ -1538,7 +1539,7 @@ async_common: - } - break; - case QXL_IO_DESTROY_SURFACE_WAIT: -- if (val >= NUM_SURFACES) { -+ if (val >= d->ssd.num_surfaces) { - qxl_set_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):" - "%" PRIu64 " >= NUM_SURFACES", async, val); - goto cancel_async; -@@ -1717,7 +1718,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) - vram_start = (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); - - /* dirty the off-screen surfaces */ -- for (i = 0; i < NUM_SURFACES; i++) { -+ for (i = 0; i < qxl->ssd.num_surfaces; i++) { - QXLSurfaceCmd *cmd; - intptr_t surface_offset; - int surface_size; -@@ -1845,7 +1846,6 @@ static int qxl_init_common(PCIQXLDevice *qxl) - qxl->mode = QXL_MODE_UNDEFINED; - qxl->generation = 1; - qxl->num_memslots = NUM_MEMSLOTS; -- qxl->num_surfaces = NUM_SURFACES; - qemu_mutex_init(&qxl->track_lock); - qemu_mutex_init(&qxl->async_lock); - qxl->current_async = QXL_UNDEFINED_IO; -@@ -1887,6 +1887,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) - init_qxl_rom(qxl); - init_qxl_ram(qxl); - -+ qxl->guest_surfaces.cmds = g_new0(QXLPHYSICAL, qxl->ssd.num_surfaces); - memory_region_init_ram(&qxl->vram_bar, "qxl.vram", qxl->vram_size); - vmstate_register_ram(&qxl->vram_bar, &qxl->pci.qdev); - memory_region_init_alias(&qxl->vram32_bar, "qxl.vram32", &qxl->vram_bar, -@@ -2052,8 +2053,8 @@ static int qxl_post_load(void *opaque, int version) - qxl_create_guest_primary(d, 1, QXL_SYNC); - - /* replay surface-create and cursor-set commands */ -- cmds = g_malloc0(sizeof(QXLCommandExt) * (NUM_SURFACES + 1)); -- for (in = 0, out = 0; in < NUM_SURFACES; in++) { -+ cmds = g_malloc0(sizeof(QXLCommandExt) * (d->ssd.num_surfaces + 1)); -+ for (in = 0, out = 0; in < d->ssd.num_surfaces; in++) { - if (d->guest_surfaces.cmds[in] == 0) { - continue; - } -@@ -2153,9 +2154,10 @@ static VMStateDescription qxl_vmstate = { - qxl_memslot, struct guest_slots), - VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0, - qxl_surface, QXLSurfaceCreate), -- VMSTATE_INT32_EQUAL(num_surfaces, PCIQXLDevice), -- VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, 0, -- vmstate_info_uint64, uint64_t), -+ VMSTATE_INT32_EQUAL(ssd.num_surfaces, PCIQXLDevice), -+ VMSTATE_VARRAY_INT32(guest_surfaces.cmds, PCIQXLDevice, -+ ssd.num_surfaces, 0, -+ vmstate_info_uint64, uint64_t), - VMSTATE_UINT64(guest_cursor, PCIQXLDevice), - VMSTATE_END_OF_LIST() - }, -@@ -2183,6 +2185,7 @@ static Property qxl_properties[] = { - DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, -1), - DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1), - DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16), -+ DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/hw/qxl.h b/hw/qxl.h -index 9cfedb7..5553824 100644 ---- a/hw/qxl.h -+++ b/hw/qxl.h -@@ -40,7 +40,6 @@ typedef struct PCIQXLDevice { - uint32_t revision; - - int32_t num_memslots; -- int32_t num_surfaces; - - uint32_t current_async; - QemuMutex async_lock; -@@ -65,7 +64,7 @@ typedef struct PCIQXLDevice { - } guest_primary; - - struct surfaces { -- QXLPHYSICAL cmds[NUM_SURFACES]; -+ QXLPHYSICAL *cmds; - uint32_t count; - uint32_t max; - } guest_surfaces; -diff --git a/ui/spice-display.c b/ui/spice-display.c -index 1c31418..99bc665 100644 ---- a/ui/spice-display.c -+++ b/ui/spice-display.c -@@ -317,6 +317,9 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) - qemu_mutex_init(&ssd->lock); - ssd->mouse_x = -1; - ssd->mouse_y = -1; -+ if (ssd->num_surfaces == 0) { -+ ssd->num_surfaces = 1024; -+ } - ssd->bufsize = (16 * 1024 * 1024); - ssd->buf = g_malloc(ssd->bufsize); - } -@@ -427,7 +430,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) - info->num_memslots_groups = NUM_MEMSLOTS_GROUPS; - info->internal_groupslot_id = 0; - info->qxl_ram_size = ssd->bufsize; -- info->n_surfaces = NUM_SURFACES; -+ info->n_surfaces = ssd->num_surfaces; - } - - static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) -diff --git a/ui/spice-display.h b/ui/spice-display.h -index bcff114..512ab78 100644 ---- a/ui/spice-display.h -+++ b/ui/spice-display.h -@@ -32,8 +32,6 @@ - #define MEMSLOT_GROUP_GUEST 1 - #define NUM_MEMSLOTS_GROUPS 2 - --#define NUM_SURFACES 1024 -- - /* - * Internal enum to differenciate between options for - * io calls that have a sync (old) version and an _async (new) -@@ -80,6 +78,7 @@ struct SimpleSpiceDisplay { - QXLInstance qxl; - uint32_t unique; - QemuPfConv *conv; -+ int32_t num_surfaces; - - QXLRect dirty; - int notify; --- -1.7.12.1 - diff --git a/0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch b/0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch deleted file mode 100644 index 41c05f5..0000000 --- a/0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0fe78ffd13555bed86a41acf96cdc15ece961b0d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= -Date: Tue, 4 Sep 2012 10:14:48 -0400 -Subject: [PATCH] qxl: Add set_client_capabilities() interface to QXLInterface - -This new interface lets spice server inform the guest whether - -(a) a client is connected -(b) what capabilities the client has - -There is a fixed number (464) of bits reserved for capabilities, and -when the capabilities bits change, the QXL_INTERRUPT_CLIENT interrupt -is generated. - -Signed-off-by: Soren Sandmann -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 83df499..d8b67b2 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -946,6 +946,26 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token) - } - } - -+#if SPICE_SERVER_VERSION >= 0x000b04 -+ -+/* called from spice server thread context only */ -+static void interface_set_client_capabilities(QXLInstance *sin, -+ uint8_t client_present, -+ uint8_t caps[58]) -+{ -+ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); -+ -+ qxl->shadow_rom.client_present = client_present; -+ memcpy(qxl->shadow_rom.client_capabilities, caps, sizeof(caps)); -+ qxl->rom->client_present = client_present; -+ memcpy(qxl->rom->client_capabilities, caps, sizeof(caps)); -+ qxl_rom_set_dirty(qxl); -+ -+ qxl_send_events(qxl, QXL_INTERRUPT_CLIENT); -+} -+ -+#endif -+ - static const QXLInterface qxl_interface = { - .base.type = SPICE_INTERFACE_QXL, - .base.description = "qxl gpu", -@@ -967,6 +987,9 @@ static const QXLInterface qxl_interface = { - .flush_resources = interface_flush_resources, - .async_complete = interface_async_complete, - .update_area_complete = interface_update_area_complete, -+#if SPICE_SERVER_VERSION >= 0x000b04 -+ .set_client_capabilities = interface_set_client_capabilities, -+#endif - }; - - static void qxl_enter_vga_mode(PCIQXLDevice *d) --- -1.7.12.1 - diff --git a/0502-spice-make-number-of-surfaces-runtime-configurable.patch b/0502-spice-make-number-of-surfaces-runtime-configurable.patch new file mode 100644 index 0000000..850e627 --- /dev/null +++ b/0502-spice-make-number-of-surfaces-runtime-configurable.patch @@ -0,0 +1,198 @@ +From 0d67ff8e7dee8babc61c939946836cc8c74b05b1 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 4 Sep 2012 11:39:41 +0200 +Subject: [PATCH] spice: make number of surfaces runtime-configurable. + +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 31 +++++++++++++++++-------------- + hw/qxl.h | 3 +-- + ui/spice-display.c | 5 ++++- + ui/spice-display.h | 3 +-- + 4 files changed, 23 insertions(+), 19 deletions(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 20e844f..c7b4e9a 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -238,7 +238,8 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl) + { + trace_qxl_spice_destroy_surfaces_complete(qxl->id); + qemu_mutex_lock(&qxl->track_lock); +- memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds)); ++ memset(qxl->guest_surfaces.cmds, 0, ++ sizeof(qxl->guest_surfaces.cmds) * qxl->ssd.num_surfaces); + qxl->guest_surfaces.count = 0; + qemu_mutex_unlock(&qxl->track_lock); + } +@@ -347,7 +348,7 @@ static void init_qxl_rom(PCIQXLDevice *d) + rom->slot_id_bits = MEMSLOT_SLOT_BITS; + rom->slots_start = 1; + rom->slots_end = NUM_MEMSLOTS - 1; +- rom->n_surfaces = cpu_to_le32(NUM_SURFACES); ++ rom->n_surfaces = cpu_to_le32(d->ssd.num_surfaces); + + for (i = 0, n = 0; i < ARRAY_SIZE(qxl_modes); i++) { + fb = qxl_modes[i].y_res * qxl_modes[i].stride; +@@ -451,9 +452,9 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) + } + uint32_t id = le32_to_cpu(cmd->surface_id); + +- if (id >= NUM_SURFACES) { ++ if (id >= qxl->ssd.num_surfaces) { + qxl_set_guest_bug(qxl, "QXL_CMD_SURFACE id %d >= %d", id, +- NUM_SURFACES); ++ qxl->ssd.num_surfaces); + return 1; + } + qemu_mutex_lock(&qxl->track_lock); +@@ -529,7 +530,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) + info->num_memslots_groups = NUM_MEMSLOTS_GROUPS; + info->internal_groupslot_id = 0; + info->qxl_ram_size = le32_to_cpu(qxl->shadow_rom.num_pages) << TARGET_PAGE_BITS; +- info->n_surfaces = NUM_SURFACES; ++ info->n_surfaces = qxl->ssd.num_surfaces; + } + + static const char *qxl_mode_to_string(int mode) +@@ -1438,7 +1439,7 @@ async_common: + QXLCookie *cookie = NULL; + QXLRect update = d->ram->update_area; + +- if (d->ram->update_surface > NUM_SURFACES) { ++ if (d->ram->update_surface > d->ssd.num_surfaces) { + qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n", + d->ram->update_surface); + return; +@@ -1538,7 +1539,7 @@ async_common: + } + break; + case QXL_IO_DESTROY_SURFACE_WAIT: +- if (val >= NUM_SURFACES) { ++ if (val >= d->ssd.num_surfaces) { + qxl_set_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):" + "%" PRIu64 " >= NUM_SURFACES", async, val); + goto cancel_async; +@@ -1717,7 +1718,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) + vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); + + /* dirty the off-screen surfaces */ +- for (i = 0; i < NUM_SURFACES; i++) { ++ for (i = 0; i < qxl->ssd.num_surfaces; i++) { + QXLSurfaceCmd *cmd; + intptr_t surface_offset; + int surface_size; +@@ -1845,7 +1846,6 @@ static int qxl_init_common(PCIQXLDevice *qxl) + qxl->mode = QXL_MODE_UNDEFINED; + qxl->generation = 1; + qxl->num_memslots = NUM_MEMSLOTS; +- qxl->num_surfaces = NUM_SURFACES; + qemu_mutex_init(&qxl->track_lock); + qemu_mutex_init(&qxl->async_lock); + qxl->current_async = QXL_UNDEFINED_IO; +@@ -1887,6 +1887,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) + init_qxl_rom(qxl); + init_qxl_ram(qxl); + ++ qxl->guest_surfaces.cmds = g_new0(QXLPHYSICAL, qxl->ssd.num_surfaces); + memory_region_init_ram(&qxl->vram_bar, "qxl.vram", qxl->vram_size); + vmstate_register_ram(&qxl->vram_bar, &qxl->pci.qdev); + memory_region_init_alias(&qxl->vram32_bar, "qxl.vram32", &qxl->vram_bar, +@@ -2053,8 +2054,8 @@ static int qxl_post_load(void *opaque, int version) + qxl_create_guest_primary(d, 1, QXL_SYNC); + + /* replay surface-create and cursor-set commands */ +- cmds = g_malloc0(sizeof(QXLCommandExt) * (NUM_SURFACES + 1)); +- for (in = 0, out = 0; in < NUM_SURFACES; in++) { ++ cmds = g_malloc0(sizeof(QXLCommandExt) * (d->ssd.num_surfaces + 1)); ++ for (in = 0, out = 0; in < d->ssd.num_surfaces; in++) { + if (d->guest_surfaces.cmds[in] == 0) { + continue; + } +@@ -2154,9 +2155,10 @@ static VMStateDescription qxl_vmstate = { + qxl_memslot, struct guest_slots), + VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0, + qxl_surface, QXLSurfaceCreate), +- VMSTATE_INT32_EQUAL(num_surfaces, PCIQXLDevice), +- VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, 0, +- vmstate_info_uint64, uint64_t), ++ VMSTATE_INT32_EQUAL(ssd.num_surfaces, PCIQXLDevice), ++ VMSTATE_VARRAY_INT32(guest_surfaces.cmds, PCIQXLDevice, ++ ssd.num_surfaces, 0, ++ vmstate_info_uint64, uint64_t), + VMSTATE_UINT64(guest_cursor, PCIQXLDevice), + VMSTATE_END_OF_LIST() + }, +@@ -2184,6 +2186,7 @@ static Property qxl_properties[] = { + DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, -1), + DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1), + DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16), ++ DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/qxl.h b/hw/qxl.h +index 9cfedb7..5553824 100644 +--- a/hw/qxl.h ++++ b/hw/qxl.h +@@ -40,7 +40,6 @@ typedef struct PCIQXLDevice { + uint32_t revision; + + int32_t num_memslots; +- int32_t num_surfaces; + + uint32_t current_async; + QemuMutex async_lock; +@@ -65,7 +64,7 @@ typedef struct PCIQXLDevice { + } guest_primary; + + struct surfaces { +- QXLPHYSICAL cmds[NUM_SURFACES]; ++ QXLPHYSICAL *cmds; + uint32_t count; + uint32_t max; + } guest_surfaces; +diff --git a/ui/spice-display.c b/ui/spice-display.c +index 1c31418..99bc665 100644 +--- a/ui/spice-display.c ++++ b/ui/spice-display.c +@@ -317,6 +317,9 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) + qemu_mutex_init(&ssd->lock); + ssd->mouse_x = -1; + ssd->mouse_y = -1; ++ if (ssd->num_surfaces == 0) { ++ ssd->num_surfaces = 1024; ++ } + ssd->bufsize = (16 * 1024 * 1024); + ssd->buf = g_malloc(ssd->bufsize); + } +@@ -427,7 +430,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) + info->num_memslots_groups = NUM_MEMSLOTS_GROUPS; + info->internal_groupslot_id = 0; + info->qxl_ram_size = ssd->bufsize; +- info->n_surfaces = NUM_SURFACES; ++ info->n_surfaces = ssd->num_surfaces; + } + + static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) +diff --git a/ui/spice-display.h b/ui/spice-display.h +index bcff114..512ab78 100644 +--- a/ui/spice-display.h ++++ b/ui/spice-display.h +@@ -32,8 +32,6 @@ + #define MEMSLOT_GROUP_GUEST 1 + #define NUM_MEMSLOTS_GROUPS 2 + +-#define NUM_SURFACES 1024 +- + /* + * Internal enum to differenciate between options for + * io calls that have a sync (old) version and an _async (new) +@@ -80,6 +78,7 @@ struct SimpleSpiceDisplay { + QXLInstance qxl; + uint32_t unique; + QemuPfConv *conv; ++ int32_t num_surfaces; + + QXLRect dirty; + int notify; diff --git a/0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch b/0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch deleted file mode 100644 index 899e280..0000000 --- a/0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0dcef831a875505fdaffb824de9e4450273ea53d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= -Date: Tue, 4 Sep 2012 10:14:49 -0400 -Subject: [PATCH] Remove #ifdef QXL_COMMAND_FLAG_COMPAT_16BPP - -We require spice >= 0.8 now, so this flag is always present. - -Signed-off-by: Soren Sandmann -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index d8b67b2..a6e6cf1 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -1361,11 +1361,9 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) - - d->mode = QXL_MODE_COMPAT; - d->cmdflags = QXL_COMMAND_FLAG_COMPAT; --#ifdef QXL_COMMAND_FLAG_COMPAT_16BPP /* new in spice 0.6.1 */ - if (mode->bits == 16) { - d->cmdflags |= QXL_COMMAND_FLAG_COMPAT_16BPP; - } --#endif - d->shadow_rom.mode = cpu_to_le32(modenr); - d->rom->mode = cpu_to_le32(modenr); - qxl_rom_set_dirty(d); --- -1.7.12.1 - diff --git a/0503-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch b/0503-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch new file mode 100644 index 0000000..40b3fa1 --- /dev/null +++ b/0503-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch @@ -0,0 +1,61 @@ +From 6e338ef1256bd8672e9a03f6a57a76191d8538e7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= +Date: Tue, 4 Sep 2012 10:14:48 -0400 +Subject: [PATCH] qxl: Add set_client_capabilities() interface to QXLInterface + +This new interface lets spice server inform the guest whether + +(a) a client is connected +(b) what capabilities the client has + +There is a fixed number (464) of bits reserved for capabilities, and +when the capabilities bits change, the QXL_INTERRUPT_CLIENT interrupt +is generated. + +Signed-off-by: Soren Sandmann +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/hw/qxl.c b/hw/qxl.c +index c7b4e9a..552d208 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -946,6 +946,26 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token) + } + } + ++#if SPICE_SERVER_VERSION >= 0x000b04 ++ ++/* called from spice server thread context only */ ++static void interface_set_client_capabilities(QXLInstance *sin, ++ uint8_t client_present, ++ uint8_t caps[58]) ++{ ++ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); ++ ++ qxl->shadow_rom.client_present = client_present; ++ memcpy(qxl->shadow_rom.client_capabilities, caps, sizeof(caps)); ++ qxl->rom->client_present = client_present; ++ memcpy(qxl->rom->client_capabilities, caps, sizeof(caps)); ++ qxl_rom_set_dirty(qxl); ++ ++ qxl_send_events(qxl, QXL_INTERRUPT_CLIENT); ++} ++ ++#endif ++ + static const QXLInterface qxl_interface = { + .base.type = SPICE_INTERFACE_QXL, + .base.description = "qxl gpu", +@@ -967,6 +987,9 @@ static const QXLInterface qxl_interface = { + .flush_resources = interface_flush_resources, + .async_complete = interface_async_complete, + .update_area_complete = interface_update_area_complete, ++#if SPICE_SERVER_VERSION >= 0x000b04 ++ .set_client_capabilities = interface_set_client_capabilities, ++#endif + }; + + static void qxl_enter_vga_mode(PCIQXLDevice *d) diff --git a/0504-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch b/0504-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch new file mode 100644 index 0000000..842f0d5 --- /dev/null +++ b/0504-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch @@ -0,0 +1,29 @@ +From 2c3ddbb6b2b53fd06dfd3d5c1fd4c95bc4d8fa28 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= +Date: Tue, 4 Sep 2012 10:14:49 -0400 +Subject: [PATCH] Remove #ifdef QXL_COMMAND_FLAG_COMPAT_16BPP + +We require spice >= 0.8 now, so this flag is always present. + +Signed-off-by: Soren Sandmann +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 552d208..d1d995c 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -1361,11 +1361,9 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) + + d->mode = QXL_MODE_COMPAT; + d->cmdflags = QXL_COMMAND_FLAG_COMPAT; +-#ifdef QXL_COMMAND_FLAG_COMPAT_16BPP /* new in spice 0.6.1 */ + if (mode->bits == 16) { + d->cmdflags |= QXL_COMMAND_FLAG_COMPAT_16BPP; + } +-#endif + d->shadow_rom.mode = cpu_to_le32(modenr); + d->rom->mode = cpu_to_le32(modenr); + qxl_rom_set_dirty(d); diff --git a/0504-spice-switch-to-queue-for-vga-mode-updates.patch b/0504-spice-switch-to-queue-for-vga-mode-updates.patch deleted file mode 100644 index b9726e8..0000000 --- a/0504-spice-switch-to-queue-for-vga-mode-updates.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 244ff52221b4c4181422861a930d8f755a1a5c08 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 5 Sep 2012 08:25:08 +0200 -Subject: [PATCH] spice: switch to queue for vga mode updates - -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 6 +++--- - ui/spice-display.c | 25 ++++++++++++++----------- - ui/spice-display.h | 3 ++- - 3 files changed, 19 insertions(+), 15 deletions(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index a6e6cf1..2ec4341 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -599,9 +599,9 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) - case QXL_MODE_VGA: - ret = false; - qemu_mutex_lock(&qxl->ssd.lock); -- if (qxl->ssd.update != NULL) { -- update = qxl->ssd.update; -- qxl->ssd.update = NULL; -+ update = QTAILQ_FIRST(&qxl->ssd.updates); -+ if (update != NULL) { -+ QTAILQ_REMOVE(&qxl->ssd.updates, update, next); - *ext = update->ext; - ret = true; - } -diff --git a/ui/spice-display.c b/ui/spice-display.c -index 99bc665..59c5fd7 100644 ---- a/ui/spice-display.c -+++ b/ui/spice-display.c -@@ -164,7 +164,7 @@ int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd) - #endif - } - --static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) -+static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) - { - SimpleSpiceUpdate *update; - QXLDrawable *drawable; -@@ -175,7 +175,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) - struct timespec time_space; - - if (qemu_spice_rect_is_empty(&ssd->dirty)) { -- return NULL; -+ return; - }; - - trace_qemu_spice_create_update( -@@ -239,7 +239,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) - cmd->data = (uintptr_t)drawable; - - memset(&ssd->dirty, 0, sizeof(ssd->dirty)); -- return update; -+ QTAILQ_INSERT_TAIL(&ssd->updates, update, next); - } - - /* -@@ -315,6 +315,7 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) - { - ssd->ds = ds; - qemu_mutex_init(&ssd->lock); -+ QTAILQ_INIT(&ssd->updates); - ssd->mouse_x = -1; - ssd->mouse_y = -1; - if (ssd->num_surfaces == 0) { -@@ -345,6 +346,8 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd, - - void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) - { -+ SimpleSpiceUpdate *update; -+ - dprint(1, "%s:\n", __FUNCTION__); - - memset(&ssd->dirty, 0, sizeof(ssd->dirty)); -@@ -352,9 +355,9 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) - ssd->conv = NULL; - - qemu_mutex_lock(&ssd->lock); -- if (ssd->update != NULL) { -- qemu_spice_destroy_update(ssd, ssd->update); -- ssd->update = NULL; -+ while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) { -+ QTAILQ_REMOVE(&ssd->updates, update, next); -+ qemu_spice_destroy_update(ssd, update); - } - qemu_mutex_unlock(&ssd->lock); - qemu_spice_destroy_host_primary(ssd); -@@ -384,8 +387,8 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd) - vga_hw_update(); - - qemu_mutex_lock(&ssd->lock); -- if (ssd->update == NULL) { -- ssd->update = qemu_spice_create_update(ssd); -+ if (QTAILQ_EMPTY(&ssd->updates)) { -+ qemu_spice_create_update(ssd); - ssd->notify++; - } - qemu_spice_cursor_refresh_unlocked(ssd); -@@ -442,9 +445,9 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) - dprint(3, "%s:\n", __FUNCTION__); - - qemu_mutex_lock(&ssd->lock); -- if (ssd->update != NULL) { -- update = ssd->update; -- ssd->update = NULL; -+ update = QTAILQ_FIRST(&ssd->updates); -+ if (update != NULL) { -+ QTAILQ_REMOVE(&ssd->updates, update, next); - *ext = update->ext; - ret = true; - } -diff --git a/ui/spice-display.h b/ui/spice-display.h -index 512ab78..3fcb6fe 100644 ---- a/ui/spice-display.h -+++ b/ui/spice-display.h -@@ -92,7 +92,7 @@ struct SimpleSpiceDisplay { - * to them must be protected by the lock. - */ - QemuMutex lock; -- SimpleSpiceUpdate *update; -+ QTAILQ_HEAD(, SimpleSpiceUpdate) updates; - QEMUCursor *cursor; - int mouse_x, mouse_y; - }; -@@ -102,6 +102,7 @@ struct SimpleSpiceUpdate { - QXLImage image; - QXLCommandExt ext; - uint8_t *bitmap; -+ QTAILQ_ENTRY(SimpleSpiceUpdate) next; - }; - - int qemu_spice_rect_is_empty(const QXLRect* r); --- -1.7.12.1 - diff --git a/0505-spice-split-qemu_spice_create_update.patch b/0505-spice-split-qemu_spice_create_update.patch deleted file mode 100644 index d761fcf..0000000 --- a/0505-spice-split-qemu_spice_create_update.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 6d196973a9adba583cf9bbc5a4196a58f2cb0eb3 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 5 Sep 2012 08:52:23 +0200 -Subject: [PATCH] spice: split qemu_spice_create_update - -Creating one function which creates a single update for a given -rectangle. And one (for now) pretty simple wrapper around it to -queue up screen updates for the dirty region. - -[ v2: also update bounding box ] - -Signed-off-by: Gerd Hoffmann ---- - ui/spice-display.c | 31 ++++++++++++++++++------------- - 1 file changed, 18 insertions(+), 13 deletions(-) - -diff --git a/ui/spice-display.c b/ui/spice-display.c -index 59c5fd7..6f68f28 100644 ---- a/ui/spice-display.c -+++ b/ui/spice-display.c -@@ -164,7 +164,8 @@ int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd) - #endif - } - --static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) -+static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, -+ QXLRect *rect) - { - SimpleSpiceUpdate *update; - QXLDrawable *drawable; -@@ -174,24 +175,20 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) - int by, bw, bh; - struct timespec time_space; - -- if (qemu_spice_rect_is_empty(&ssd->dirty)) { -- return; -- }; -- - trace_qemu_spice_create_update( -- ssd->dirty.left, ssd->dirty.right, -- ssd->dirty.top, ssd->dirty.bottom); -+ rect->left, rect->right, -+ rect->top, rect->bottom); - - update = g_malloc0(sizeof(*update)); - drawable = &update->drawable; - image = &update->image; - cmd = &update->ext.cmd; - -- bw = ssd->dirty.right - ssd->dirty.left; -- bh = ssd->dirty.bottom - ssd->dirty.top; -+ bw = rect->right - rect->left; -+ bh = rect->bottom - rect->top; - update->bitmap = g_malloc(bw * bh * 4); - -- drawable->bbox = ssd->dirty; -+ drawable->bbox = *rect; - drawable->clip.type = SPICE_CLIP_TYPE_NONE; - drawable->effect = QXL_EFFECT_OPAQUE; - drawable->release_info.id = (uintptr_t)update; -@@ -226,8 +223,8 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) - } - - src = ds_get_data(ssd->ds) + -- ssd->dirty.top * ds_get_linesize(ssd->ds) + -- ssd->dirty.left * ds_get_bytes_per_pixel(ssd->ds); -+ rect->top * ds_get_linesize(ssd->ds) + -+ rect->left * ds_get_bytes_per_pixel(ssd->ds); - dst = update->bitmap; - for (by = 0; by < bh; by++) { - qemu_pf_conv_run(ssd->conv, dst, src, bw); -@@ -238,10 +235,18 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) - cmd->type = QXL_CMD_DRAW; - cmd->data = (uintptr_t)drawable; - -- memset(&ssd->dirty, 0, sizeof(ssd->dirty)); - QTAILQ_INSERT_TAIL(&ssd->updates, update, next); - } - -+static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) -+{ -+ if (qemu_spice_rect_is_empty(&ssd->dirty)) { -+ return; -+ }; -+ qemu_spice_create_one_update(ssd, &ssd->dirty); -+ memset(&ssd->dirty, 0, sizeof(ssd->dirty)); -+} -+ - /* - * Called from spice server thread context (via interface_release_ressource) - * We do *not* hold the global qemu mutex here, so extra care is needed --- -1.7.12.1 - diff --git a/0505-spice-switch-to-queue-for-vga-mode-updates.patch b/0505-spice-switch-to-queue-for-vga-mode-updates.patch new file mode 100644 index 0000000..f27d73c --- /dev/null +++ b/0505-spice-switch-to-queue-for-vga-mode-updates.patch @@ -0,0 +1,135 @@ +From 5d125d9e030ea1ab3c1568d7a88e2b2b1a265363 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 5 Sep 2012 08:25:08 +0200 +Subject: [PATCH] spice: switch to queue for vga mode updates + +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 6 +++--- + ui/spice-display.c | 25 ++++++++++++++----------- + ui/spice-display.h | 3 ++- + 3 files changed, 19 insertions(+), 15 deletions(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index d1d995c..743082d 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -599,9 +599,9 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) + case QXL_MODE_VGA: + ret = false; + qemu_mutex_lock(&qxl->ssd.lock); +- if (qxl->ssd.update != NULL) { +- update = qxl->ssd.update; +- qxl->ssd.update = NULL; ++ update = QTAILQ_FIRST(&qxl->ssd.updates); ++ if (update != NULL) { ++ QTAILQ_REMOVE(&qxl->ssd.updates, update, next); + *ext = update->ext; + ret = true; + } +diff --git a/ui/spice-display.c b/ui/spice-display.c +index 99bc665..59c5fd7 100644 +--- a/ui/spice-display.c ++++ b/ui/spice-display.c +@@ -164,7 +164,7 @@ int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd) + #endif + } + +-static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) ++static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) + { + SimpleSpiceUpdate *update; + QXLDrawable *drawable; +@@ -175,7 +175,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) + struct timespec time_space; + + if (qemu_spice_rect_is_empty(&ssd->dirty)) { +- return NULL; ++ return; + }; + + trace_qemu_spice_create_update( +@@ -239,7 +239,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) + cmd->data = (uintptr_t)drawable; + + memset(&ssd->dirty, 0, sizeof(ssd->dirty)); +- return update; ++ QTAILQ_INSERT_TAIL(&ssd->updates, update, next); + } + + /* +@@ -315,6 +315,7 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) + { + ssd->ds = ds; + qemu_mutex_init(&ssd->lock); ++ QTAILQ_INIT(&ssd->updates); + ssd->mouse_x = -1; + ssd->mouse_y = -1; + if (ssd->num_surfaces == 0) { +@@ -345,6 +346,8 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd, + + void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) + { ++ SimpleSpiceUpdate *update; ++ + dprint(1, "%s:\n", __FUNCTION__); + + memset(&ssd->dirty, 0, sizeof(ssd->dirty)); +@@ -352,9 +355,9 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) + ssd->conv = NULL; + + qemu_mutex_lock(&ssd->lock); +- if (ssd->update != NULL) { +- qemu_spice_destroy_update(ssd, ssd->update); +- ssd->update = NULL; ++ while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) { ++ QTAILQ_REMOVE(&ssd->updates, update, next); ++ qemu_spice_destroy_update(ssd, update); + } + qemu_mutex_unlock(&ssd->lock); + qemu_spice_destroy_host_primary(ssd); +@@ -384,8 +387,8 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd) + vga_hw_update(); + + qemu_mutex_lock(&ssd->lock); +- if (ssd->update == NULL) { +- ssd->update = qemu_spice_create_update(ssd); ++ if (QTAILQ_EMPTY(&ssd->updates)) { ++ qemu_spice_create_update(ssd); + ssd->notify++; + } + qemu_spice_cursor_refresh_unlocked(ssd); +@@ -442,9 +445,9 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) + dprint(3, "%s:\n", __FUNCTION__); + + qemu_mutex_lock(&ssd->lock); +- if (ssd->update != NULL) { +- update = ssd->update; +- ssd->update = NULL; ++ update = QTAILQ_FIRST(&ssd->updates); ++ if (update != NULL) { ++ QTAILQ_REMOVE(&ssd->updates, update, next); + *ext = update->ext; + ret = true; + } +diff --git a/ui/spice-display.h b/ui/spice-display.h +index 512ab78..3fcb6fe 100644 +--- a/ui/spice-display.h ++++ b/ui/spice-display.h +@@ -92,7 +92,7 @@ struct SimpleSpiceDisplay { + * to them must be protected by the lock. + */ + QemuMutex lock; +- SimpleSpiceUpdate *update; ++ QTAILQ_HEAD(, SimpleSpiceUpdate) updates; + QEMUCursor *cursor; + int mouse_x, mouse_y; + }; +@@ -102,6 +102,7 @@ struct SimpleSpiceUpdate { + QXLImage image; + QXLCommandExt ext; + uint8_t *bitmap; ++ QTAILQ_ENTRY(SimpleSpiceUpdate) next; + }; + + int qemu_spice_rect_is_empty(const QXLRect* r); diff --git a/0506-spice-add-screen-mirror.patch b/0506-spice-add-screen-mirror.patch deleted file mode 100644 index 6ee91d1..0000000 --- a/0506-spice-add-screen-mirror.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 9f4c601032d7a27e8856517a1a020c9988667ed3 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 5 Sep 2012 09:35:57 +0200 -Subject: [PATCH] spice: add screen mirror - -Create a screen mirror, keep there a copy of the most recent update -passed on to spice-server. - -Signed-off-by: Gerd Hoffmann ---- - ui/spice-display.c | 32 ++++++++++++++++++++++---------- - ui/spice-display.h | 1 + - 2 files changed, 23 insertions(+), 10 deletions(-) - -diff --git a/ui/spice-display.c b/ui/spice-display.c -index 6f68f28..973cd53 100644 ---- a/ui/spice-display.c -+++ b/ui/spice-display.c -@@ -171,8 +171,8 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, - QXLDrawable *drawable; - QXLImage *image; - QXLCommand *cmd; -- uint8_t *src, *dst; -- int by, bw, bh; -+ uint8_t *src, *mirror, *dst; -+ int by, bw, bh, offset, bytes; - struct timespec time_space; - - trace_qemu_spice_create_update( -@@ -216,19 +216,18 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, - image->bitmap.palette = 0; - image->bitmap.format = SPICE_BITMAP_FMT_32BIT; - -- if (ssd->conv == NULL) { -- PixelFormat dst = qemu_default_pixelformat(32); -- ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf); -- assert(ssd->conv); -- } -- -- src = ds_get_data(ssd->ds) + -+ offset = - rect->top * ds_get_linesize(ssd->ds) + - rect->left * ds_get_bytes_per_pixel(ssd->ds); -+ bytes = ds_get_bytes_per_pixel(ssd->ds) * bw; -+ src = ds_get_data(ssd->ds) + offset; -+ mirror = ssd->ds_mirror + offset; - dst = update->bitmap; - for (by = 0; by < bh; by++) { -- qemu_pf_conv_run(ssd->conv, dst, src, bw); -+ memcpy(mirror, src, bytes); -+ qemu_pf_conv_run(ssd->conv, dst, mirror, bw); - src += ds_get_linesize(ssd->ds); -+ mirror += ds_get_linesize(ssd->ds); - dst += image->bitmap.stride; - } - -@@ -243,6 +242,17 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) - if (qemu_spice_rect_is_empty(&ssd->dirty)) { - return; - }; -+ -+ if (ssd->conv == NULL) { -+ PixelFormat dst = qemu_default_pixelformat(32); -+ ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf); -+ assert(ssd->conv); -+ } -+ if (ssd->ds_mirror == NULL) { -+ int size = ds_get_height(ssd->ds) * ds_get_linesize(ssd->ds); -+ ssd->ds_mirror = g_malloc0(size); -+ } -+ - qemu_spice_create_one_update(ssd, &ssd->dirty); - memset(&ssd->dirty, 0, sizeof(ssd->dirty)); - } -@@ -358,6 +368,8 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) - memset(&ssd->dirty, 0, sizeof(ssd->dirty)); - qemu_pf_conv_put(ssd->conv); - ssd->conv = NULL; -+ g_free(ssd->ds_mirror); -+ ssd->ds_mirror = NULL; - - qemu_mutex_lock(&ssd->lock); - while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) { -diff --git a/ui/spice-display.h b/ui/spice-display.h -index 3fcb6fe..dea41c1 100644 ---- a/ui/spice-display.h -+++ b/ui/spice-display.h -@@ -72,6 +72,7 @@ typedef struct SimpleSpiceUpdate SimpleSpiceUpdate; - - struct SimpleSpiceDisplay { - DisplayState *ds; -+ uint8_t *ds_mirror; - void *buf; - int bufsize; - QXLWorker *worker; --- -1.7.12.1 - diff --git a/0506-spice-split-qemu_spice_create_update.patch b/0506-spice-split-qemu_spice_create_update.patch new file mode 100644 index 0000000..c773e90 --- /dev/null +++ b/0506-spice-split-qemu_spice_create_update.patch @@ -0,0 +1,91 @@ +From fc15ba066a059c49cf1022345d7ac8fa24a1dd92 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 5 Sep 2012 08:52:23 +0200 +Subject: [PATCH] spice: split qemu_spice_create_update + +Creating one function which creates a single update for a given +rectangle. And one (for now) pretty simple wrapper around it to +queue up screen updates for the dirty region. + +[ v2: also update bounding box ] + +Signed-off-by: Gerd Hoffmann +--- + ui/spice-display.c | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/ui/spice-display.c b/ui/spice-display.c +index 59c5fd7..6f68f28 100644 +--- a/ui/spice-display.c ++++ b/ui/spice-display.c +@@ -164,7 +164,8 @@ int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd) + #endif + } + +-static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) ++static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, ++ QXLRect *rect) + { + SimpleSpiceUpdate *update; + QXLDrawable *drawable; +@@ -174,24 +175,20 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) + int by, bw, bh; + struct timespec time_space; + +- if (qemu_spice_rect_is_empty(&ssd->dirty)) { +- return; +- }; +- + trace_qemu_spice_create_update( +- ssd->dirty.left, ssd->dirty.right, +- ssd->dirty.top, ssd->dirty.bottom); ++ rect->left, rect->right, ++ rect->top, rect->bottom); + + update = g_malloc0(sizeof(*update)); + drawable = &update->drawable; + image = &update->image; + cmd = &update->ext.cmd; + +- bw = ssd->dirty.right - ssd->dirty.left; +- bh = ssd->dirty.bottom - ssd->dirty.top; ++ bw = rect->right - rect->left; ++ bh = rect->bottom - rect->top; + update->bitmap = g_malloc(bw * bh * 4); + +- drawable->bbox = ssd->dirty; ++ drawable->bbox = *rect; + drawable->clip.type = SPICE_CLIP_TYPE_NONE; + drawable->effect = QXL_EFFECT_OPAQUE; + drawable->release_info.id = (uintptr_t)update; +@@ -226,8 +223,8 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) + } + + src = ds_get_data(ssd->ds) + +- ssd->dirty.top * ds_get_linesize(ssd->ds) + +- ssd->dirty.left * ds_get_bytes_per_pixel(ssd->ds); ++ rect->top * ds_get_linesize(ssd->ds) + ++ rect->left * ds_get_bytes_per_pixel(ssd->ds); + dst = update->bitmap; + for (by = 0; by < bh; by++) { + qemu_pf_conv_run(ssd->conv, dst, src, bw); +@@ -238,10 +235,18 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) + cmd->type = QXL_CMD_DRAW; + cmd->data = (uintptr_t)drawable; + +- memset(&ssd->dirty, 0, sizeof(ssd->dirty)); + QTAILQ_INSERT_TAIL(&ssd->updates, update, next); + } + ++static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) ++{ ++ if (qemu_spice_rect_is_empty(&ssd->dirty)) { ++ return; ++ }; ++ qemu_spice_create_one_update(ssd, &ssd->dirty); ++ memset(&ssd->dirty, 0, sizeof(ssd->dirty)); ++} ++ + /* + * Called from spice server thread context (via interface_release_ressource) + * We do *not* hold the global qemu mutex here, so extra care is needed diff --git a/0507-spice-add-screen-mirror.patch b/0507-spice-add-screen-mirror.patch new file mode 100644 index 0000000..ef3f45c --- /dev/null +++ b/0507-spice-add-screen-mirror.patch @@ -0,0 +1,95 @@ +From d02ed657b7ad55f2111a049c3e175ed78c63e5b1 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 5 Sep 2012 09:35:57 +0200 +Subject: [PATCH] spice: add screen mirror + +Create a screen mirror, keep there a copy of the most recent update +passed on to spice-server. + +Signed-off-by: Gerd Hoffmann +--- + ui/spice-display.c | 32 ++++++++++++++++++++++---------- + ui/spice-display.h | 1 + + 2 files changed, 23 insertions(+), 10 deletions(-) + +diff --git a/ui/spice-display.c b/ui/spice-display.c +index 6f68f28..973cd53 100644 +--- a/ui/spice-display.c ++++ b/ui/spice-display.c +@@ -171,8 +171,8 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, + QXLDrawable *drawable; + QXLImage *image; + QXLCommand *cmd; +- uint8_t *src, *dst; +- int by, bw, bh; ++ uint8_t *src, *mirror, *dst; ++ int by, bw, bh, offset, bytes; + struct timespec time_space; + + trace_qemu_spice_create_update( +@@ -216,19 +216,18 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, + image->bitmap.palette = 0; + image->bitmap.format = SPICE_BITMAP_FMT_32BIT; + +- if (ssd->conv == NULL) { +- PixelFormat dst = qemu_default_pixelformat(32); +- ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf); +- assert(ssd->conv); +- } +- +- src = ds_get_data(ssd->ds) + ++ offset = + rect->top * ds_get_linesize(ssd->ds) + + rect->left * ds_get_bytes_per_pixel(ssd->ds); ++ bytes = ds_get_bytes_per_pixel(ssd->ds) * bw; ++ src = ds_get_data(ssd->ds) + offset; ++ mirror = ssd->ds_mirror + offset; + dst = update->bitmap; + for (by = 0; by < bh; by++) { +- qemu_pf_conv_run(ssd->conv, dst, src, bw); ++ memcpy(mirror, src, bytes); ++ qemu_pf_conv_run(ssd->conv, dst, mirror, bw); + src += ds_get_linesize(ssd->ds); ++ mirror += ds_get_linesize(ssd->ds); + dst += image->bitmap.stride; + } + +@@ -243,6 +242,17 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) + if (qemu_spice_rect_is_empty(&ssd->dirty)) { + return; + }; ++ ++ if (ssd->conv == NULL) { ++ PixelFormat dst = qemu_default_pixelformat(32); ++ ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf); ++ assert(ssd->conv); ++ } ++ if (ssd->ds_mirror == NULL) { ++ int size = ds_get_height(ssd->ds) * ds_get_linesize(ssd->ds); ++ ssd->ds_mirror = g_malloc0(size); ++ } ++ + qemu_spice_create_one_update(ssd, &ssd->dirty); + memset(&ssd->dirty, 0, sizeof(ssd->dirty)); + } +@@ -358,6 +368,8 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) + memset(&ssd->dirty, 0, sizeof(ssd->dirty)); + qemu_pf_conv_put(ssd->conv); + ssd->conv = NULL; ++ g_free(ssd->ds_mirror); ++ ssd->ds_mirror = NULL; + + qemu_mutex_lock(&ssd->lock); + while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) { +diff --git a/ui/spice-display.h b/ui/spice-display.h +index 3fcb6fe..dea41c1 100644 +--- a/ui/spice-display.h ++++ b/ui/spice-display.h +@@ -72,6 +72,7 @@ typedef struct SimpleSpiceUpdate SimpleSpiceUpdate; + + struct SimpleSpiceDisplay { + DisplayState *ds; ++ uint8_t *ds_mirror; + void *buf; + int bufsize; + QXLWorker *worker; diff --git a/0507-spice-send-updates-only-for-changed-screen-content.patch b/0507-spice-send-updates-only-for-changed-screen-content.patch deleted file mode 100644 index b575091..0000000 --- a/0507-spice-send-updates-only-for-changed-screen-content.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e2da4b3f683ae63a55b8e50903a164f704be9e1d Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 5 Sep 2012 10:41:42 +0200 -Subject: [PATCH] spice: send updates only for changed screen content - -when creating screen updates go compare the current guest screen -against the mirror (which holds the most recent update sent), then -only create updates for the screen areas which did actually change. - -[ v2: drop redundant qemu_spice_create_one_update call ] - -Signed-off-by: Gerd Hoffmann ---- - ui/spice-display.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 55 insertions(+), 1 deletion(-) - -diff --git a/ui/spice-display.c b/ui/spice-display.c -index 973cd53..d062765 100644 ---- a/ui/spice-display.c -+++ b/ui/spice-display.c -@@ -239,6 +239,13 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, - - static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) - { -+ static const int blksize = 32; -+ int blocks = (ds_get_width(ssd->ds) + blksize - 1) / blksize; -+ int dirty_top[blocks]; -+ int y, yoff, x, xoff, blk, bw; -+ int bpp = ds_get_bytes_per_pixel(ssd->ds); -+ uint8_t *guest, *mirror; -+ - if (qemu_spice_rect_is_empty(&ssd->dirty)) { - return; - }; -@@ -253,7 +260,54 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) - ssd->ds_mirror = g_malloc0(size); - } - -- qemu_spice_create_one_update(ssd, &ssd->dirty); -+ for (blk = 0; blk < blocks; blk++) { -+ dirty_top[blk] = -1; -+ } -+ -+ guest = ds_get_data(ssd->ds); -+ mirror = ssd->ds_mirror; -+ for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) { -+ yoff = y * ds_get_linesize(ssd->ds); -+ for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { -+ xoff = x * bpp; -+ blk = x / blksize; -+ bw = MIN(blksize, ssd->dirty.right - x); -+ if (memcmp(guest + yoff + xoff, -+ mirror + yoff + xoff, -+ bw * bpp) == 0) { -+ if (dirty_top[blk] != -1) { -+ QXLRect update = { -+ .top = dirty_top[blk], -+ .bottom = y, -+ .left = x, -+ .right = x + bw, -+ }; -+ qemu_spice_create_one_update(ssd, &update); -+ dirty_top[blk] = -1; -+ } -+ } else { -+ if (dirty_top[blk] == -1) { -+ dirty_top[blk] = y; -+ } -+ } -+ } -+ } -+ -+ for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { -+ blk = x / blksize; -+ bw = MIN(blksize, ssd->dirty.right - x); -+ if (dirty_top[blk] != -1) { -+ QXLRect update = { -+ .top = dirty_top[blk], -+ .bottom = ssd->dirty.bottom, -+ .left = x, -+ .right = x + bw, -+ }; -+ qemu_spice_create_one_update(ssd, &update); -+ dirty_top[blk] = -1; -+ } -+ } -+ - memset(&ssd->dirty, 0, sizeof(ssd->dirty)); - } - --- -1.7.12.1 - diff --git a/0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch b/0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch deleted file mode 100644 index 78845b8..0000000 --- a/0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 984e5c7aee378a8de44ff54891695115b92fe585 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 7 Sep 2012 21:29:22 +0200 -Subject: [PATCH] qxl: Ignore set_client_capabilities pre/post migrate - -The recent introduction of set_client_capabilities has broken -(seamless) migration by trying to call qxl_send_events pre (seamless -incoming) and post (*) migration, triggering the following assert: -qxl_send_events: Assertion `qemu_spice_display_is_running(&d->ssd)' failed. - -The solution is easy, pre migration the guest will have already received -the client caps on the migration source side, and post migration there no -longer is a guest, so we can simply ignore the set_client_capabilities call -in both those scenarios. - -*) Post migration, so not fatal for to the migration itself, but still a crash - -Signed-off-by: Hans de Goede ---- - hw/qxl.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 2ec4341..360f4f6 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -955,6 +955,11 @@ static void interface_set_client_capabilities(QXLInstance *sin, - { - PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); - -+ if (runstate_check(RUN_STATE_INMIGRATE) || -+ runstate_check(RUN_STATE_POSTMIGRATE)) { -+ return; -+ } -+ - qxl->shadow_rom.client_present = client_present; - memcpy(qxl->shadow_rom.client_capabilities, caps, sizeof(caps)); - qxl->rom->client_present = client_present; --- -1.7.12.1 - diff --git a/0508-spice-send-updates-only-for-changed-screen-content.patch b/0508-spice-send-updates-only-for-changed-screen-content.patch new file mode 100644 index 0000000..5d5036c --- /dev/null +++ b/0508-spice-send-updates-only-for-changed-screen-content.patch @@ -0,0 +1,90 @@ +From d112b2fbcc278746037badfb96619b6a87c7b7a3 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 5 Sep 2012 10:41:42 +0200 +Subject: [PATCH] spice: send updates only for changed screen content + +when creating screen updates go compare the current guest screen +against the mirror (which holds the most recent update sent), then +only create updates for the screen areas which did actually change. + +[ v2: drop redundant qemu_spice_create_one_update call ] + +Signed-off-by: Gerd Hoffmann +--- + ui/spice-display.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 55 insertions(+), 1 deletion(-) + +diff --git a/ui/spice-display.c b/ui/spice-display.c +index 973cd53..d062765 100644 +--- a/ui/spice-display.c ++++ b/ui/spice-display.c +@@ -239,6 +239,13 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, + + static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) + { ++ static const int blksize = 32; ++ int blocks = (ds_get_width(ssd->ds) + blksize - 1) / blksize; ++ int dirty_top[blocks]; ++ int y, yoff, x, xoff, blk, bw; ++ int bpp = ds_get_bytes_per_pixel(ssd->ds); ++ uint8_t *guest, *mirror; ++ + if (qemu_spice_rect_is_empty(&ssd->dirty)) { + return; + }; +@@ -253,7 +260,54 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) + ssd->ds_mirror = g_malloc0(size); + } + +- qemu_spice_create_one_update(ssd, &ssd->dirty); ++ for (blk = 0; blk < blocks; blk++) { ++ dirty_top[blk] = -1; ++ } ++ ++ guest = ds_get_data(ssd->ds); ++ mirror = ssd->ds_mirror; ++ for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) { ++ yoff = y * ds_get_linesize(ssd->ds); ++ for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { ++ xoff = x * bpp; ++ blk = x / blksize; ++ bw = MIN(blksize, ssd->dirty.right - x); ++ if (memcmp(guest + yoff + xoff, ++ mirror + yoff + xoff, ++ bw * bpp) == 0) { ++ if (dirty_top[blk] != -1) { ++ QXLRect update = { ++ .top = dirty_top[blk], ++ .bottom = y, ++ .left = x, ++ .right = x + bw, ++ }; ++ qemu_spice_create_one_update(ssd, &update); ++ dirty_top[blk] = -1; ++ } ++ } else { ++ if (dirty_top[blk] == -1) { ++ dirty_top[blk] = y; ++ } ++ } ++ } ++ } ++ ++ for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { ++ blk = x / blksize; ++ bw = MIN(blksize, ssd->dirty.right - x); ++ if (dirty_top[blk] != -1) { ++ QXLRect update = { ++ .top = dirty_top[blk], ++ .bottom = ssd->dirty.bottom, ++ .left = x, ++ .right = x + bw, ++ }; ++ qemu_spice_create_one_update(ssd, &update); ++ dirty_top[blk] = -1; ++ } ++ } ++ + memset(&ssd->dirty, 0, sizeof(ssd->dirty)); + } + diff --git a/0509-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch b/0509-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch new file mode 100644 index 0000000..6cadb3b --- /dev/null +++ b/0509-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch @@ -0,0 +1,38 @@ +From a075bce1994a52556beada7d81195e1bfeafe609 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 7 Sep 2012 21:29:22 +0200 +Subject: [PATCH] qxl: Ignore set_client_capabilities pre/post migrate + +The recent introduction of set_client_capabilities has broken +(seamless) migration by trying to call qxl_send_events pre (seamless +incoming) and post (*) migration, triggering the following assert: +qxl_send_events: Assertion `qemu_spice_display_is_running(&d->ssd)' failed. + +The solution is easy, pre migration the guest will have already received +the client caps on the migration source side, and post migration there no +longer is a guest, so we can simply ignore the set_client_capabilities call +in both those scenarios. + +*) Post migration, so not fatal for to the migration itself, but still a crash + +Signed-off-by: Hans de Goede +--- + hw/qxl.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 743082d..8a86ffc 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -955,6 +955,11 @@ static void interface_set_client_capabilities(QXLInstance *sin, + { + PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); + ++ if (runstate_check(RUN_STATE_INMIGRATE) || ++ runstate_check(RUN_STATE_POSTMIGRATE)) { ++ return; ++ } ++ + qxl->shadow_rom.client_present = client_present; + memcpy(qxl->shadow_rom.client_capabilities, caps, sizeof(caps)); + qxl->rom->client_present = client_present; diff --git a/0509-qxl-add-trace-event-for-QXL_IO_LOG.patch b/0509-qxl-add-trace-event-for-QXL_IO_LOG.patch deleted file mode 100644 index d5093de..0000000 --- a/0509-qxl-add-trace-event-for-QXL_IO_LOG.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 720192d056402f47a8f71d9ac9bc4b0cf37902ed Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Wed, 12 Sep 2012 16:13:27 +0300 -Subject: [PATCH] qxl: add trace-event for QXL_IO_LOG - -Signed-off-by: Alon Levy -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 1 + - trace-events | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 360f4f6..1ef117a 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -1515,6 +1515,7 @@ async_common: - qxl_set_mode(d, val, 0); - break; - case QXL_IO_LOG: -+ trace_qxl_io_log(d->id, d->ram->log_buf); - if (d->guestdebug) { - fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id, - qemu_get_clock_ns(vm_clock), d->ram->log_buf); -diff --git a/trace-events b/trace-events -index aa79836..80a52d9 100644 ---- a/trace-events -+++ b/trace-events -@@ -930,6 +930,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d - qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d" - qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d" - qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s" -+qxl_io_log(int qid, const uint8_t *str) "%d %s" - qxl_io_read_unexpected(int qid) "%d" - qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)" - qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d" --- -1.7.12.1 - diff --git a/0510-hw-qxl-support-client-monitor-configuration-via-devi.patch b/0510-hw-qxl-support-client-monitor-configuration-via-devi.patch deleted file mode 100644 index 4a00940..0000000 --- a/0510-hw-qxl-support-client-monitor-configuration-via-devi.patch +++ /dev/null @@ -1,181 +0,0 @@ -From f5c2bd00890dc32e940e8b2fae09f62f758317eb Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Wed, 12 Sep 2012 16:13:28 +0300 -Subject: [PATCH] hw/qxl: support client monitor configuration via device - -Until now we used only the agent to change the monitor count and each -monitor resolution. This patch introduces the qemu part of using the -device as the mediator instead of the agent via virtio-serial. - -Spice (>=0.11.5) calls the new QXLInterface::client_monitors_config, -which returns wether the interrupt is enabled, and if so and given a non -NULL monitors config will -generate an interrupt QXL_INTERRUPT_CLIENT_MONITORS_CONFIG with crc -checksum for the guest to verify a second call hasn't interfered. - -The maximal number of monitors is limited on the QXLRom to 64. - -Signed-off-by: Alon Levy -Signed-off-by: Gerd Hoffmann ---- - configure | 7 ++++++ - hw/qxl.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - trace-events | 6 ++++- - 3 files changed, 91 insertions(+), 1 deletion(-) - -diff --git a/configure b/configure -index f528146..83c478c 100755 ---- a/configure -+++ b/configure -@@ -2706,6 +2706,9 @@ EOF - if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then - spice_qxl_io_monitors_config_async="yes" - fi -+ if $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1; then -+ spice_qxl_client_monitors_config="yes" -+ fi - else - if test "$spice" = "yes" ; then - feature_not_found "spice" -@@ -3453,6 +3456,10 @@ if test "$spice_qxl_io_monitors_config_async" = "yes" ; then - echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak - fi - -+if test "$spice_qxl_client_monitors_config" = "yes" ; then -+ echo "CONFIG_QXL_CLIENT_MONITORS_CONFIG=y" >> $config_host_mak -+fi -+ - if test "$smartcard" = "yes" ; then - echo "CONFIG_SMARTCARD=y" >> $config_host_mak - fi -diff --git a/hw/qxl.c b/hw/qxl.c -index 1ef117a..0695872 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -18,6 +18,8 @@ - * along with this program; if not, see . - */ - -+#include -+ - #include "qemu-common.h" - #include "qemu-timer.h" - #include "qemu-queue.h" -@@ -971,6 +973,79 @@ static void interface_set_client_capabilities(QXLInstance *sin, - - #endif - -+#if defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) \ -+ && SPICE_SERVER_VERSION >= 0x000b05 -+ -+static uint32_t qxl_crc32(const uint8_t *p, unsigned len) -+{ -+ /* -+ * zlib xors the seed with 0xffffffff, and xors the result -+ * again with 0xffffffff; Both are not done with linux's crc32, -+ * which we want to be compatible with, so undo that. -+ */ -+ return crc32(0xffffffff, p, len) ^ 0xffffffff; -+} -+ -+/* called from main context only */ -+static int interface_client_monitors_config(QXLInstance *sin, -+ VDAgentMonitorsConfig *monitors_config) -+{ -+ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); -+ QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar); -+ int i; -+ -+ /* -+ * Older windows drivers set int_mask to 0 when their ISR is called, -+ * then later set it to ~0. So it doesn't relate to the actual interrupts -+ * handled. However, they are old, so clearly they don't support this -+ * interrupt -+ */ -+ if (qxl->ram->int_mask == 0 || qxl->ram->int_mask == ~0 || -+ !(qxl->ram->int_mask & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG)) { -+ trace_qxl_client_monitors_config_unsupported_by_guest(qxl->id, -+ qxl->ram->int_mask, -+ monitors_config); -+ return 0; -+ } -+ if (!monitors_config) { -+ return 1; -+ } -+ memset(&rom->client_monitors_config, 0, -+ sizeof(rom->client_monitors_config)); -+ rom->client_monitors_config.count = monitors_config->num_of_monitors; -+ /* monitors_config->flags ignored */ -+ if (rom->client_monitors_config.count >= -+ ARRAY_SIZE(rom->client_monitors_config.heads)) { -+ trace_qxl_client_monitors_config_capped(qxl->id, -+ monitors_config->num_of_monitors, -+ ARRAY_SIZE(rom->client_monitors_config.heads)); -+ rom->client_monitors_config.count = -+ ARRAY_SIZE(rom->client_monitors_config.heads); -+ } -+ for (i = 0 ; i < rom->client_monitors_config.count ; ++i) { -+ VDAgentMonConfig *monitor = &monitors_config->monitors[i]; -+ QXLURect *rect = &rom->client_monitors_config.heads[i]; -+ /* monitor->depth ignored */ -+ rect->left = monitor->x; -+ rect->top = monitor->y; -+ rect->right = monitor->x + monitor->width; -+ rect->bottom = monitor->y + monitor->height; -+ } -+ rom->client_monitors_config_crc = qxl_crc32( -+ (const uint8_t *)&rom->client_monitors_config, -+ sizeof(rom->client_monitors_config)); -+ trace_qxl_client_monitors_config_crc(qxl->id, -+ sizeof(rom->client_monitors_config), -+ rom->client_monitors_config_crc); -+ -+ trace_qxl_interrupt_client_monitors_config(qxl->id, -+ rom->client_monitors_config.count, -+ rom->client_monitors_config.heads); -+ qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG); -+ return 1; -+} -+#endif -+ - static const QXLInterface qxl_interface = { - .base.type = SPICE_INTERFACE_QXL, - .base.description = "qxl gpu", -@@ -995,6 +1070,10 @@ static const QXLInterface qxl_interface = { - #if SPICE_SERVER_VERSION >= 0x000b04 - .set_client_capabilities = interface_set_client_capabilities, - #endif -+#if SPICE_SERVER_VERSION >= 0x000b05 && \ -+ defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) -+ .client_monitors_config = interface_client_monitors_config, -+#endif - }; - - static void qxl_enter_vga_mode(PCIQXLDevice *d) -diff --git a/trace-events b/trace-events -index 80a52d9..07b63f1 100644 ---- a/trace-events -+++ b/trace-events -@@ -930,7 +930,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d - qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d" - qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d" - qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s" --qxl_io_log(int qid, const uint8_t *str) "%d %s" -+qxl_io_log(int qid, const uint8_t *log_buf) "%d %s" - qxl_io_read_unexpected(int qid) "%d" - qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)" - qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d" -@@ -974,6 +974,10 @@ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dir - qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d" - qxl_send_events(int qid, uint32_t events) "%d %d" - qxl_set_guest_bug(int qid) "%d" -+qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p" -+qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p" -+qxl_client_monitors_config_capped(int qid, int requested, int limit) "%d %d %d" -+qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32) "%d %u %u" - - # hw/qxl-render.c - qxl_render_blit_guest_primary_initialized(void) "" --- -1.7.12.1 - diff --git a/0510-qxl-add-trace-event-for-QXL_IO_LOG.patch b/0510-qxl-add-trace-event-for-QXL_IO_LOG.patch new file mode 100644 index 0000000..2b4d451 --- /dev/null +++ b/0510-qxl-add-trace-event-for-QXL_IO_LOG.patch @@ -0,0 +1,36 @@ +From 82eab431ed1b9b198f2cab46a6a59fa2e5a31dc1 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Wed, 12 Sep 2012 16:13:27 +0300 +Subject: [PATCH] qxl: add trace-event for QXL_IO_LOG + +Signed-off-by: Alon Levy +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 1 + + trace-events | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 8a86ffc..006a9b7 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -1515,6 +1515,7 @@ async_common: + qxl_set_mode(d, val, 0); + break; + case QXL_IO_LOG: ++ trace_qxl_io_log(d->id, d->ram->log_buf); + if (d->guestdebug) { + fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id, + qemu_get_clock_ns(vm_clock), d->ram->log_buf); +diff --git a/trace-events b/trace-events +index aa79836..80a52d9 100644 +--- a/trace-events ++++ b/trace-events +@@ -930,6 +930,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d + qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d" + qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d" + qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s" ++qxl_io_log(int qid, const uint8_t *str) "%d %s" + qxl_io_read_unexpected(int qid) "%d" + qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)" + qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d" diff --git a/0511-hw-qxl-support-client-monitor-configuration-via-devi.patch b/0511-hw-qxl-support-client-monitor-configuration-via-devi.patch new file mode 100644 index 0000000..8d032ef --- /dev/null +++ b/0511-hw-qxl-support-client-monitor-configuration-via-devi.patch @@ -0,0 +1,178 @@ +From 6477aff05e661c5fb7d73d7c10e1a8a0af175e92 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Wed, 12 Sep 2012 16:13:28 +0300 +Subject: [PATCH] hw/qxl: support client monitor configuration via device + +Until now we used only the agent to change the monitor count and each +monitor resolution. This patch introduces the qemu part of using the +device as the mediator instead of the agent via virtio-serial. + +Spice (>=0.11.5) calls the new QXLInterface::client_monitors_config, +which returns wether the interrupt is enabled, and if so and given a non +NULL monitors config will +generate an interrupt QXL_INTERRUPT_CLIENT_MONITORS_CONFIG with crc +checksum for the guest to verify a second call hasn't interfered. + +The maximal number of monitors is limited on the QXLRom to 64. + +Signed-off-by: Alon Levy +Signed-off-by: Gerd Hoffmann +--- + configure | 7 ++++++ + hw/qxl.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + trace-events | 6 ++++- + 3 files changed, 91 insertions(+), 1 deletion(-) + +diff --git a/configure b/configure +index 9129433..5eb4369 100755 +--- a/configure ++++ b/configure +@@ -2705,6 +2705,9 @@ EOF + if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then + spice_qxl_io_monitors_config_async="yes" + fi ++ if $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1; then ++ spice_qxl_client_monitors_config="yes" ++ fi + else + if test "$spice" = "yes" ; then + feature_not_found "spice" +@@ -3452,6 +3455,10 @@ if test "$spice_qxl_io_monitors_config_async" = "yes" ; then + echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak + fi + ++if test "$spice_qxl_client_monitors_config" = "yes" ; then ++ echo "CONFIG_QXL_CLIENT_MONITORS_CONFIG=y" >> $config_host_mak ++fi ++ + if test "$smartcard" = "yes" ; then + echo "CONFIG_SMARTCARD=y" >> $config_host_mak + fi +diff --git a/hw/qxl.c b/hw/qxl.c +index 006a9b7..1aac04b 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -18,6 +18,8 @@ + * along with this program; if not, see . + */ + ++#include ++ + #include "qemu-common.h" + #include "qemu-timer.h" + #include "qemu-queue.h" +@@ -971,6 +973,79 @@ static void interface_set_client_capabilities(QXLInstance *sin, + + #endif + ++#if defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) \ ++ && SPICE_SERVER_VERSION >= 0x000b05 ++ ++static uint32_t qxl_crc32(const uint8_t *p, unsigned len) ++{ ++ /* ++ * zlib xors the seed with 0xffffffff, and xors the result ++ * again with 0xffffffff; Both are not done with linux's crc32, ++ * which we want to be compatible with, so undo that. ++ */ ++ return crc32(0xffffffff, p, len) ^ 0xffffffff; ++} ++ ++/* called from main context only */ ++static int interface_client_monitors_config(QXLInstance *sin, ++ VDAgentMonitorsConfig *monitors_config) ++{ ++ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); ++ QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar); ++ int i; ++ ++ /* ++ * Older windows drivers set int_mask to 0 when their ISR is called, ++ * then later set it to ~0. So it doesn't relate to the actual interrupts ++ * handled. However, they are old, so clearly they don't support this ++ * interrupt ++ */ ++ if (qxl->ram->int_mask == 0 || qxl->ram->int_mask == ~0 || ++ !(qxl->ram->int_mask & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG)) { ++ trace_qxl_client_monitors_config_unsupported_by_guest(qxl->id, ++ qxl->ram->int_mask, ++ monitors_config); ++ return 0; ++ } ++ if (!monitors_config) { ++ return 1; ++ } ++ memset(&rom->client_monitors_config, 0, ++ sizeof(rom->client_monitors_config)); ++ rom->client_monitors_config.count = monitors_config->num_of_monitors; ++ /* monitors_config->flags ignored */ ++ if (rom->client_monitors_config.count >= ++ ARRAY_SIZE(rom->client_monitors_config.heads)) { ++ trace_qxl_client_monitors_config_capped(qxl->id, ++ monitors_config->num_of_monitors, ++ ARRAY_SIZE(rom->client_monitors_config.heads)); ++ rom->client_monitors_config.count = ++ ARRAY_SIZE(rom->client_monitors_config.heads); ++ } ++ for (i = 0 ; i < rom->client_monitors_config.count ; ++i) { ++ VDAgentMonConfig *monitor = &monitors_config->monitors[i]; ++ QXLURect *rect = &rom->client_monitors_config.heads[i]; ++ /* monitor->depth ignored */ ++ rect->left = monitor->x; ++ rect->top = monitor->y; ++ rect->right = monitor->x + monitor->width; ++ rect->bottom = monitor->y + monitor->height; ++ } ++ rom->client_monitors_config_crc = qxl_crc32( ++ (const uint8_t *)&rom->client_monitors_config, ++ sizeof(rom->client_monitors_config)); ++ trace_qxl_client_monitors_config_crc(qxl->id, ++ sizeof(rom->client_monitors_config), ++ rom->client_monitors_config_crc); ++ ++ trace_qxl_interrupt_client_monitors_config(qxl->id, ++ rom->client_monitors_config.count, ++ rom->client_monitors_config.heads); ++ qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG); ++ return 1; ++} ++#endif ++ + static const QXLInterface qxl_interface = { + .base.type = SPICE_INTERFACE_QXL, + .base.description = "qxl gpu", +@@ -995,6 +1070,10 @@ static const QXLInterface qxl_interface = { + #if SPICE_SERVER_VERSION >= 0x000b04 + .set_client_capabilities = interface_set_client_capabilities, + #endif ++#if SPICE_SERVER_VERSION >= 0x000b05 && \ ++ defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) ++ .client_monitors_config = interface_client_monitors_config, ++#endif + }; + + static void qxl_enter_vga_mode(PCIQXLDevice *d) +diff --git a/trace-events b/trace-events +index 80a52d9..07b63f1 100644 +--- a/trace-events ++++ b/trace-events +@@ -930,7 +930,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d + qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d" + qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d" + qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s" +-qxl_io_log(int qid, const uint8_t *str) "%d %s" ++qxl_io_log(int qid, const uint8_t *log_buf) "%d %s" + qxl_io_read_unexpected(int qid) "%d" + qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)" + qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d" +@@ -974,6 +974,10 @@ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dir + qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d" + qxl_send_events(int qid, uint32_t events) "%d %d" + qxl_set_guest_bug(int qid) "%d" ++qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p" ++qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p" ++qxl_client_monitors_config_capped(int qid, int requested, int limit) "%d %d %d" ++qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32) "%d %u %u" + + # hw/qxl-render.c + qxl_render_blit_guest_primary_initialized(void) "" diff --git a/0511-qxl-always-update-displaysurface-on-resize.patch b/0511-qxl-always-update-displaysurface-on-resize.patch deleted file mode 100644 index 4b556c7..0000000 --- a/0511-qxl-always-update-displaysurface-on-resize.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d0b5c82d532ef14bbbc770b06a6ae68f6ec3c1a8 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 14 Sep 2012 22:09:23 +0200 -Subject: [PATCH] qxl: always update displaysurface on resize - -Don't try to be clever and skip displaysurface reinitialization in case -the size hasn't changed. Other parameters might have changed -nevertheless, for example depth or stride, resulting in rendering being -broken then. - -Trigger: boot linux guest with vesafb, start X11, make sure both vesafb -and X11 use the display same resolution. Then watch X11 screen being -upside down. - -Signed-off-by: Gerd Hoffmann ---- - hw/qxl-render.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/hw/qxl-render.c b/hw/qxl-render.c -index e2e3fe2..b66c168 100644 ---- a/hw/qxl-render.c -+++ b/hw/qxl-render.c -@@ -99,7 +99,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) - { - VGACommonState *vga = &qxl->vga; - int i; -- DisplaySurface *surface = vga->ds->surface; - - if (qxl->guest_primary.resized) { - qxl->guest_primary.resized = 0; -@@ -112,9 +111,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) - qxl->guest_primary.qxl_stride, - qxl->guest_primary.bytes_pp, - qxl->guest_primary.bits_pp); -- } -- if (surface->width != qxl->guest_primary.surface.width || -- surface->height != qxl->guest_primary.surface.height) { - if (qxl->guest_primary.qxl_stride > 0) { - qemu_free_displaysurface(vga->ds); - qemu_create_displaysurface_from(qxl->guest_primary.surface.width, --- -1.7.12.1 - diff --git a/0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch b/0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch index e742f65..059e13e 100644 --- a/0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch +++ b/0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch @@ -1,4 +1,4 @@ -From 2bbe4bb8c12976312c9421489f7568a70e5ffae3 Mon Sep 17 00:00:00 2001 +From eaea06c56ee6569bbd6864a6f767160a74c9c65d Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Wed, 19 Sep 2012 17:41:26 +0400 Subject: [PATCH] qxl/update_area_io: cleanup invalid parameters handling @@ -16,7 +16,7 @@ Signed-off-by: Gerd Hoffmann 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c -index 0695872..720363f 100644 +index 1aac04b..6b9d5d0 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1547,20 +1547,13 @@ async_common: @@ -43,6 +43,3 @@ index 0695872..720363f 100644 break; } if (async == QXL_ASYNC) { --- -1.7.12.1 - diff --git a/0513-qxl-fix-range-check-for-rev3-io-commands.patch b/0513-qxl-fix-range-check-for-rev3-io-commands.patch index 65f8763..19caaf0 100644 --- a/0513-qxl-fix-range-check-for-rev3-io-commands.patch +++ b/0513-qxl-fix-range-check-for-rev3-io-commands.patch @@ -1,4 +1,4 @@ -From 0e0d8cfb93813c0d693b14e3d433d36ee9bc6bab Mon Sep 17 00:00:00 2001 +From 7d349451b0b2561922927e45d7febeed514d7a86 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 25 Sep 2012 13:56:40 +0200 Subject: [PATCH] qxl: fix range check for rev3 io commands. @@ -12,7 +12,7 @@ Signed-off-by: Gerd Hoffmann 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/qxl.c b/hw/qxl.c -index 720363f..9389752 100644 +index 6b9d5d0..8d33745 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1466,7 +1466,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr, @@ -24,6 +24,3 @@ index 720363f..9389752 100644 qxl_set_guest_bug(d, "unsupported io %d for revision %d\n", io_port, d->revision); return; --- -1.7.12.1 - diff --git a/0514-hw-qxl-exit-on-failure-to-register-qxl-interface.patch b/0514-hw-qxl-exit-on-failure-to-register-qxl-interface.patch deleted file mode 100644 index a89db68..0000000 --- a/0514-hw-qxl-exit-on-failure-to-register-qxl-interface.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a0f199b76debf55933c2b3b917c13c86784e3be0 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Wed, 3 Oct 2012 20:13:58 +0200 -Subject: [PATCH 514/647] hw/qxl: exit on failure to register qxl interface - -This prevents a segfault later on when the device reset handler -tries to access a NULL ssd.worker since interface_attach_worker has -not been called. - -Signed-off-by: Alon Levy -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 9389752..a2dd020 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -2035,7 +2035,11 @@ static int qxl_init_common(PCIQXLDevice *qxl) - - qxl->ssd.qxl.base.sif = &qxl_interface.base; - qxl->ssd.qxl.id = qxl->id; -- qemu_spice_add_interface(&qxl->ssd.qxl.base); -+ if (qemu_spice_add_interface(&qxl->ssd.qxl.base) != 0) { -+ error_report("qxl interface %d.%d not supported by spice-server\n", -+ SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR); -+ return -1; -+ } - qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl); - - init_pipe_signaling(qxl); --- -1.7.12.1 - diff --git a/0514-qxl-vnc-register-a-vm-state-change-handler-for-dummy.patch b/0514-qxl-vnc-register-a-vm-state-change-handler-for-dummy.patch new file mode 100644 index 0000000..d2bb1f1 --- /dev/null +++ b/0514-qxl-vnc-register-a-vm-state-change-handler-for-dummy.patch @@ -0,0 +1,33 @@ +From 2c410bf8bafee23b4a4d1041b833645c6320851e Mon Sep 17 00:00:00 2001 +From: Uri Lublin +Date: Wed, 12 Dec 2012 16:30:47 +0000 +Subject: [PATCH] qxl+vnc: register a vm state change handler for dummy + spice_server + +When qxl + vnc are used, a dummy spice_server is initialized. +The spice_server has to be told when the VM runstate changes, +which is what this patch does. + +Without it, from qxl_send_events(), the following error message is shown: + qxl_send_events: spice-server bug: guest stopped, ignoring + +Cc: qemu-stable@nongnu.org +Signed-off-by: Uri Lublin +Signed-off-by: Gerd Hoffmann +--- + ui/spice-core.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ui/spice-core.c b/ui/spice-core.c +index ba0d0bd..cb4b8b9 100644 +--- a/ui/spice-core.c ++++ b/ui/spice-core.c +@@ -775,6 +775,8 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin) + */ + spice_server = spice_server_new(); + spice_server_init(spice_server, &core_interface); ++ qemu_add_vm_change_state_handler(vm_change_state_handler, ++ &spice_server); + } + + return spice_server_add_interface(spice_server, sin); diff --git a/0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch b/0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch new file mode 100644 index 0000000..f013c14 --- /dev/null +++ b/0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch @@ -0,0 +1,32 @@ +From 8502c47123cbbb2f81b751780bdc8bc2fd3024ca Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Wed, 3 Oct 2012 20:13:58 +0200 +Subject: [PATCH] hw/qxl: exit on failure to register qxl interface + +This prevents a segfault later on when the device reset handler +tries to access a NULL ssd.worker since interface_attach_worker has +not been called. + +Signed-off-by: Alon Levy +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 8d33745..db6440e 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -2035,7 +2035,11 @@ static int qxl_init_common(PCIQXLDevice *qxl) + + qxl->ssd.qxl.base.sif = &qxl_interface.base; + qxl->ssd.qxl.id = qxl->id; +- qemu_spice_add_interface(&qxl->ssd.qxl.base); ++ if (qemu_spice_add_interface(&qxl->ssd.qxl.base) != 0) { ++ error_report("qxl interface %d.%d not supported by spice-server\n", ++ SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR); ++ return -1; ++ } + qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl); + + init_pipe_signaling(qxl); diff --git a/0515-hw-qxl-fix-condition-for-exiting-guest_bug.patch b/0515-hw-qxl-fix-condition-for-exiting-guest_bug.patch deleted file mode 100644 index 945b5df..0000000 --- a/0515-hw-qxl-fix-condition-for-exiting-guest_bug.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 73a691f6799e05afda0be01c1cd5e2f6914e8773 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 2 Oct 2012 11:39:14 +0200 -Subject: [PATCH 515/647] hw/qxl: fix condition for exiting guest_bug - -Reported and suggested by Paolo Bonzini, thanks. - -Signed-off-by: Alon Levy -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index a2dd020..e3a164a 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -1461,7 +1461,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr, - qxl_async_io async = QXL_SYNC; - uint32_t orig_io_port = io_port; - -- if (d->guest_bug && !io_port == QXL_IO_RESET) { -+ if (d->guest_bug && io_port != QXL_IO_RESET) { - return; - } - --- -1.7.12.1 - diff --git a/0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch b/0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch new file mode 100644 index 0000000..ef6e3a2 --- /dev/null +++ b/0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch @@ -0,0 +1,26 @@ +From 35bc51bb66018c3b387c735070612cd81200a2f9 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Tue, 2 Oct 2012 11:39:14 +0200 +Subject: [PATCH] hw/qxl: fix condition for exiting guest_bug + +Reported and suggested by Paolo Bonzini, thanks. + +Signed-off-by: Alon Levy +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index db6440e..445705e 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -1461,7 +1461,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr, + qxl_async_io async = QXL_SYNC; + uint32_t orig_io_port = io_port; + +- if (d->guest_bug && !io_port == QXL_IO_RESET) { ++ if (d->guest_bug && io_port != QXL_IO_RESET) { + return; + } + diff --git a/0516-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch b/0516-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch deleted file mode 100644 index e285559..0000000 --- a/0516-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch +++ /dev/null @@ -1,38 +0,0 @@ -From d59685f5667e25d0805bde93c068052afb30efda Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Sun, 7 Oct 2012 17:03:35 +0200 -Subject: [PATCH 516/647] hw/qxl: qxl_dirty_surfaces: use uintptr_t - -As suggested by Paolo Bonzini, to avoid possible integer overflow issues. - -Signed-off-by: Alon Levy -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index e3a164a..5a9bf1c 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -1803,7 +1803,7 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata) - - static void qxl_dirty_surfaces(PCIQXLDevice *qxl) - { -- intptr_t vram_start; -+ uintptr_t vram_start; - int i; - - if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) { -@@ -1814,7 +1814,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) - qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset, - qxl->shadow_rom.surface0_area_size); - -- vram_start = (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); -+ vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); - - /* dirty the off-screen surfaces */ - for (i = 0; i < qxl->ssd.num_surfaces; i++) { --- -1.7.12.1 - diff --git a/0517-hw-qxl-qxl_send_events-nop-if-stopped.patch b/0517-hw-qxl-qxl_send_events-nop-if-stopped.patch new file mode 100644 index 0000000..e787f66 --- /dev/null +++ b/0517-hw-qxl-qxl_send_events-nop-if-stopped.patch @@ -0,0 +1,47 @@ +From 46afee90f84ed7f03a6c1e086cb7a3894451682d Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Thu, 1 Nov 2012 14:56:00 +0200 +Subject: [PATCH] hw/qxl: qxl_send_events: nop if stopped + +Added a trace point for easy logging. + +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=870972 + +Signed-off-by: Alon Levy +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 8 +++++++- + trace-events | 1 + + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 445705e..8111bb9 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -1714,7 +1714,13 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events) + uint32_t le_events = cpu_to_le32(events); + + trace_qxl_send_events(d->id, events); +- assert(qemu_spice_display_is_running(&d->ssd)); ++ if (!qemu_spice_display_is_running(&d->ssd)) { ++ /* spice-server tracks guest running state and should not do this */ ++ fprintf(stderr, "%s: spice-server bug: guest stopped, ignoring\n", ++ __func__); ++ trace_qxl_send_events_vm_stopped(d->id, events); ++ return; ++ } + old_pending = __sync_fetch_and_or(&d->ram->int_pending, le_events); + if ((old_pending & le_events) == le_events) { + return; +diff --git a/trace-events b/trace-events +index 07b63f1..992aef1 100644 +--- a/trace-events ++++ b/trace-events +@@ -973,6 +973,7 @@ qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t righ + qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d" + qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d" + qxl_send_events(int qid, uint32_t events) "%d %d" ++qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d" + qxl_set_guest_bug(int qid) "%d" + qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p" + qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p" diff --git a/0517-spice-raise-requirement-to-0.12.patch b/0517-spice-raise-requirement-to-0.12.patch deleted file mode 100644 index 4ffb529..0000000 --- a/0517-spice-raise-requirement-to-0.12.patch +++ /dev/null @@ -1,465 +0,0 @@ -From be955ad2a04cb7be9b5f34cd0e43d29f34113c6e Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 24 Sep 2012 10:23:40 +0200 -Subject: [PATCH 517/647] spice: raise requirement to 0.12 - -With the next qemu version (1.3) we are going to bump the qxl device -revision to 4. The new features available require a recent spice-server -version, so raise up the bar. Otherwise we would end up with different -qxl revisions depending on the spice-server version installed, which -would be a major PITA when it comes to compat properties. - -Clear out a big bunch of #ifdefs which are not needed any more. - -Signed-off-by: Gerd Hoffmann ---- - configure | 18 ++---------------- - hw/qxl.c | 30 ------------------------------ - ui/spice-core.c | 51 ++------------------------------------------------- - ui/spice-display.c | 38 -------------------------------------- - ui/spice-display.h | 5 ----- - 5 files changed, 4 insertions(+), 138 deletions(-) - -diff --git a/configure b/configure -index ebe8b1c..b843d20 100755 ---- a/configure -+++ b/configure -@@ -2705,20 +2705,14 @@ int main(void) { spice_server_new(); return 0; } - EOF - spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null) - spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null) -- if $pkg_config --atleast-version=0.8.2 spice-server >/dev/null 2>&1 && \ -- $pkg_config --atleast-version=0.8.1 spice-protocol > /dev/null 2>&1 && \ -+ if $pkg_config --atleast-version=0.12.0 spice-server >/dev/null 2>&1 && \ -+ $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1 && \ - compile_prog "$spice_cflags" "$spice_libs" ; then - spice="yes" - libs_softmmu="$libs_softmmu $spice_libs" - QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags" - spice_protocol_version=$($pkg_config --modversion spice-protocol) - spice_server_version=$($pkg_config --modversion spice-server) -- if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then -- spice_qxl_io_monitors_config_async="yes" -- fi -- if $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1; then -- spice_qxl_client_monitors_config="yes" -- fi - else - if test "$spice" = "yes" ; then - feature_not_found "spice" -@@ -3456,14 +3450,6 @@ if test "$spice" = "yes" ; then - echo "CONFIG_SPICE=y" >> $config_host_mak - fi - --if test "$spice_qxl_io_monitors_config_async" = "yes" ; then -- echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak --fi -- --if test "$spice_qxl_client_monitors_config" = "yes" ; then -- echo "CONFIG_QXL_CLIENT_MONITORS_CONFIG=y" >> $config_host_mak --fi -- - if test "$smartcard" = "yes" ; then - echo "CONFIG_SMARTCARD=y" >> $config_host_mak - fi -diff --git a/hw/qxl.c b/hw/qxl.c -index 5a9bf1c..255fdf4 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -29,11 +29,6 @@ - - #include "qxl.h" - --#ifndef CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC --/* spice-protocol is too old, add missing definitions */ --#define QXL_IO_MONITORS_CONFIG_ASYNC (QXL_IO_FLUSH_RELEASE + 1) --#endif -- - /* - * NOTE: SPICE_RING_PROD_ITEM accesses memory on the pci bar and as - * such can be changed by the guest, so to avoid a guest trigerrable -@@ -262,9 +257,6 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async) - static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay) - { - trace_qxl_spice_monitors_config(qxl->id); --/* 0x000b01 == 0.11.1 */ --#if SPICE_SERVER_VERSION >= 0x000b01 && \ -- defined(CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC) - if (replay) { - /* - * don't use QXL_COOKIE_TYPE_IO: -@@ -286,10 +278,6 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay) - (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO, - QXL_IO_MONITORS_CONFIG_ASYNC)); - } --#else -- fprintf(stderr, "qxl: too old spice-protocol/spice-server for " -- "QXL_IO_MONITORS_CONFIG_ASYNC\n"); --#endif - } - - void qxl_spice_reset_image_cache(PCIQXLDevice *qxl) -@@ -948,8 +936,6 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token) - } - } - --#if SPICE_SERVER_VERSION >= 0x000b04 -- - /* called from spice server thread context only */ - static void interface_set_client_capabilities(QXLInstance *sin, - uint8_t client_present, -@@ -971,11 +957,6 @@ static void interface_set_client_capabilities(QXLInstance *sin, - qxl_send_events(qxl, QXL_INTERRUPT_CLIENT); - } - --#endif -- --#if defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) \ -- && SPICE_SERVER_VERSION >= 0x000b05 -- - static uint32_t qxl_crc32(const uint8_t *p, unsigned len) - { - /* -@@ -1044,7 +1025,6 @@ static int interface_client_monitors_config(QXLInstance *sin, - qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG); - return 1; - } --#endif - - static const QXLInterface qxl_interface = { - .base.type = SPICE_INTERFACE_QXL, -@@ -1067,13 +1047,8 @@ static const QXLInterface qxl_interface = { - .flush_resources = interface_flush_resources, - .async_complete = interface_async_complete, - .update_area_complete = interface_update_area_complete, --#if SPICE_SERVER_VERSION >= 0x000b04 - .set_client_capabilities = interface_set_client_capabilities, --#endif --#if SPICE_SERVER_VERSION >= 0x000b05 && \ -- defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) - .client_monitors_config = interface_client_monitors_config, --#endif - }; - - static void qxl_enter_vga_mode(PCIQXLDevice *d) -@@ -1846,7 +1821,6 @@ static void qxl_vm_change_state_handler(void *opaque, int running, - RunState state) - { - PCIQXLDevice *qxl = opaque; -- qemu_spice_vm_change_state_handler(&qxl->ssd, running, state); - - if (running) { - /* -@@ -1963,14 +1937,10 @@ static int qxl_init_common(PCIQXLDevice *qxl) - pci_device_rev = QXL_REVISION_STABLE_V10; - io_size = 32; /* PCI region size must be pow2 */ - break; --/* 0x000b01 == 0.11.1 */ --#if SPICE_SERVER_VERSION >= 0x000b01 && \ -- defined(CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC) - case 4: /* qxl-4 */ - pci_device_rev = QXL_REVISION_STABLE_V12; - io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); - break; --#endif - default: - error_report("Invalid revision %d for qxl device (max %d)", - qxl->revision, QXL_DEFAULT_REVISION); -diff --git a/ui/spice-core.c b/ui/spice-core.c -index ba0d0bd..5147365 100644 ---- a/ui/spice-core.c -+++ b/ui/spice-core.c -@@ -223,7 +223,6 @@ static void channel_event(int event, SpiceChannelEventInfo *info) - client = qdict_new(); - server = qdict_new(); - --#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT - if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) { - add_addr_info(client, (struct sockaddr *)&info->paddr_ext, - info->plen_ext); -@@ -232,12 +231,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info) - } else { - error_report("spice: %s, extended address is expected", - __func__); --#endif -- add_addr_info(client, &info->paddr, info->plen); -- add_addr_info(server, &info->laddr, info->llen); --#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT - } --#endif - - if (event == SPICE_CHANNEL_EVENT_INITIALIZED) { - qdict_put(server, "auth", qstring_from_str(auth)); -@@ -276,7 +270,6 @@ static SpiceCoreInterface core_interface = { - .channel_event = channel_event, - }; - --#ifdef SPICE_INTERFACE_MIGRATION - typedef struct SpiceMigration { - SpiceMigrateInstance sin; - struct { -@@ -313,7 +306,6 @@ static void migrate_end_complete_cb(SpiceMigrateInstance *sin) - monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL); - spice_migration_completed = true; - } --#endif - - /* config string parsing */ - -@@ -393,17 +385,13 @@ static SpiceChannelList *qmp_query_spice_channels(void) - chan = g_malloc0(sizeof(*chan)); - chan->value = g_malloc0(sizeof(*chan->value)); - --#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT - if (item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) { - paddr = (struct sockaddr *)&item->info->paddr_ext; - plen = item->info->plen_ext; - } else { --#endif - paddr = &item->info->paddr; - plen = item->info->plen; --#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT - } --#endif - - getnameinfo(paddr, plen, - host, sizeof(host), port, sizeof(port), -@@ -473,13 +461,10 @@ SpiceInfo *qmp_query_spice(Error **errp) - info->tls_port = tls_port; - } - --#if SPICE_SERVER_VERSION >= 0x000a03 /* 0.10.3 */ - info->mouse_mode = spice_server_is_server_mouse(spice_server) ? - SPICE_QUERY_MOUSE_MODE_SERVER : - SPICE_QUERY_MOUSE_MODE_CLIENT; --#else -- info->mouse_mode = SPICE_QUERY_MOUSE_MODE_UNKNOWN; --#endif -+ - /* for compatibility with the original command */ - info->has_channels = true; - info->channels = qmp_query_spice_channels(); -@@ -492,19 +477,11 @@ static void migration_state_notifier(Notifier *notifier, void *data) - MigrationState *s = data; - - if (migration_is_active(s)) { --#ifdef SPICE_INTERFACE_MIGRATION - spice_server_migrate_start(spice_server); --#endif - } else if (migration_has_finished(s)) { --#ifndef SPICE_INTERFACE_MIGRATION -- spice_server_migrate_switch(spice_server); -- monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL); -- spice_migration_completed = true; --#else - spice_server_migrate_end(spice_server, true); - } else if (migration_has_failed(s)) { - spice_server_migrate_end(spice_server, false); --#endif - } - } - -@@ -513,16 +490,11 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, - MonitorCompletion *cb, void *opaque) - { - int ret; --#ifdef SPICE_INTERFACE_MIGRATION -+ - spice_migrate.connect_complete.cb = cb; - spice_migrate.connect_complete.opaque = opaque; - ret = spice_server_migrate_connect(spice_server, hostname, - port, tls_port, subject); --#else -- ret = spice_server_migrate_info(spice_server, hostname, -- port, tls_port, subject); -- cb(opaque, NULL); --#endif - return ret; - } - -@@ -561,7 +533,6 @@ static int add_channel(const char *name, const char *value, void *opaque) - static void vm_change_state_handler(void *opaque, int running, - RunState state) - { --#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */ - if (running) { - qemu_spice_display_start(); - spice_server_vm_start(spice_server); -@@ -569,7 +540,6 @@ static void vm_change_state_handler(void *opaque, int running, - spice_server_vm_stop(spice_server); - qemu_spice_display_stop(); - } --#endif - } - - void qemu_spice_init(void) -@@ -585,9 +555,7 @@ void qemu_spice_init(void) - int port, tls_port, len, addr_flags; - spice_image_compression_t compression; - spice_wan_compression_t wan_compr; --#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */ - bool seamless_migration; --#endif - - qemu_thread_get_self(&me); - -@@ -672,16 +640,11 @@ void qemu_spice_init(void) - spice_server_set_ticket(spice_server, password, 0, 0, 0); - } - if (qemu_opt_get_bool(opts, "sasl", 0)) { --#if SPICE_SERVER_VERSION >= 0x000900 /* 0.9.0 */ - if (spice_server_set_sasl_appname(spice_server, "qemu") == -1 || - spice_server_set_sasl(spice_server, 1) == -1) { - error_report("spice: failed to enable sasl"); - exit(1); - } --#else -- error_report("spice: sasl is not available (spice >= 0.9 required)"); -- exit(1); --#endif - } - if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) { - auth = "none"; -@@ -726,15 +689,11 @@ void qemu_spice_init(void) - - qemu_opt_foreach(opts, add_channel, &tls_port, 0); - --#if SPICE_SERVER_VERSION >= 0x000a02 /* 0.10.2 */ - spice_server_set_name(spice_server, qemu_name); - spice_server_set_uuid(spice_server, qemu_uuid); --#endif - --#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */ - seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0); - spice_server_set_seamless_migration(spice_server, seamless_migration); --#endif - if (0 != spice_server_init(spice_server, &core_interface)) { - error_report("failed to initialize spice server"); - exit(1); -@@ -743,11 +702,9 @@ void qemu_spice_init(void) - - migration_state.notify = migration_state_notifier; - add_migration_state_change_notifier(&migration_state); --#ifdef SPICE_INTERFACE_MIGRATION - spice_migrate.sin.base.sif = &migrate_interface.base; - spice_migrate.connect_complete.cb = NULL; - qemu_spice_add_interface(&spice_migrate.sin.base); --#endif - - qemu_spice_input_init(); - qemu_spice_audio_init(); -@@ -815,15 +772,11 @@ int qemu_spice_set_pw_expire(time_t expires) - - int qemu_spice_display_add_client(int csock, int skipauth, int tls) - { --#if SPICE_SERVER_VERSION >= 0x000a01 - if (tls) { - return spice_server_add_ssl_client(spice_server, csock, skipauth); - } else { - return spice_server_add_client(spice_server, csock, skipauth); - } --#else -- return -1; --#endif - } - - static void spice_register_config(void) -diff --git a/ui/spice-display.c b/ui/spice-display.c -index d062765..422e7c4 100644 ---- a/ui/spice-display.c -+++ b/ui/spice-display.c -@@ -126,21 +126,6 @@ void qemu_spice_wakeup(SimpleSpiceDisplay *ssd) - ssd->worker->wakeup(ssd->worker); - } - --#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ --static void qemu_spice_start(SimpleSpiceDisplay *ssd) --{ -- trace_qemu_spice_start(ssd->qxl.id); -- ssd->worker->start(ssd->worker); --} -- --static void qemu_spice_stop(SimpleSpiceDisplay *ssd) --{ -- trace_qemu_spice_stop(ssd->qxl.id); -- ssd->worker->stop(ssd->worker); --} -- --#else -- - static int spice_display_is_running; - - void qemu_spice_display_start(void) -@@ -153,15 +138,9 @@ void qemu_spice_display_stop(void) - spice_display_is_running = false; - } - --#endif -- - int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd) - { --#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ -- return ssd->running; --#else - return spice_display_is_running; --#endif - } - - static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, -@@ -364,22 +343,6 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd) - qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC); - } - --void qemu_spice_vm_change_state_handler(void *opaque, int running, -- RunState state) --{ --#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ -- SimpleSpiceDisplay *ssd = opaque; -- -- if (running) { -- ssd->running = true; -- qemu_spice_start(ssd); -- } else { -- qemu_spice_stop(ssd); -- ssd->running = false; -- } --#endif --} -- - void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) - { - ssd->ds = ds; -@@ -623,7 +586,6 @@ void qemu_spice_display_init(DisplayState *ds) - qemu_spice_add_interface(&sdpy.qxl.base); - assert(sdpy.worker); - -- qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy); - qemu_spice_create_host_memslot(&sdpy); - qemu_spice_create_host_primary(&sdpy); - } -diff --git a/ui/spice-display.h b/ui/spice-display.h -index dea41c1..d766927 100644 ---- a/ui/spice-display.h -+++ b/ui/spice-display.h -@@ -83,9 +83,6 @@ struct SimpleSpiceDisplay { - - QXLRect dirty; - int notify; --#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ -- int running; --#endif - - /* - * All struct members below this comment can be accessed from -@@ -133,8 +130,6 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id, - void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, - uint32_t id, qxl_async_io async); - void qemu_spice_wakeup(SimpleSpiceDisplay *ssd); --#if SPICE_SERVER_VERSION >= 0x000b02 /* before 0.11.2 */ - void qemu_spice_display_start(void); - void qemu_spice_display_stop(void); --#endif - int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd); --- -1.7.12.1 - diff --git a/0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch b/0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch new file mode 100644 index 0000000..d5a81a0 --- /dev/null +++ b/0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch @@ -0,0 +1,34 @@ +From 97ccbacab3e9cc19ebb54f1aacbe84118cbb3a29 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 30 Oct 2012 14:55:12 +0100 +Subject: [PATCH] qxl: call dpy_gfx_resize when entering vga mode + +When entering vga mode the display size likely changes, +notify all displaychangelisteners about this. + +Probably went unnoticed for a while as one if the first +things the guest does after leaving qxl native mode and +entering qxl vga mode is to set the vga video mode. But +there is still a small window where qemu can operate on +stale data, leading to crashes now and then. + +https://bugzilla.redhat.com/show_bug.cgi?id=865767 + +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index 8111bb9..f88829c 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -1084,7 +1084,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d) + trace_qxl_enter_vga_mode(d->id); + qemu_spice_create_host_primary(&d->ssd); + d->mode = QXL_MODE_VGA; +- memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty)); ++ dpy_resize(d->ssd.ds); + vga_dirty_log_start(&d->vga); + } + diff --git a/0518-qxl-set-default-revision-to-4.patch b/0518-qxl-set-default-revision-to-4.patch deleted file mode 100644 index c2eab7b..0000000 --- a/0518-qxl-set-default-revision-to-4.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7b1c2ac1342371bf43035b2ee1b02d9f554da49d Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 1 Nov 2012 11:06:54 +0100 -Subject: [PATCH 518/647] qxl: set default revision to 4 - -Set qxl pci revision to 4 so guests know spice-server 0.12 features -are available. - -Signed-off-by: Gerd Hoffmann ---- - hw/qxl.h | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/hw/qxl.h b/hw/qxl.h -index 5553824..e583cfb 100644 ---- a/hw/qxl.h -+++ b/hw/qxl.h -@@ -129,12 +129,7 @@ typedef struct PCIQXLDevice { - } \ - } while (0) - --#if 0 --/* spice-server 0.12 is still in development */ - #define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12 --#else --#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10 --#endif - - /* qxl.c */ - void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); --- -1.7.12.1 - diff --git a/0519-spice-fix-initialization-order.patch b/0519-spice-fix-initialization-order.patch new file mode 100644 index 0000000..681efdd --- /dev/null +++ b/0519-spice-fix-initialization-order.patch @@ -0,0 +1,64 @@ +From 13cc38946d570a43c1a913b8fb014c189e660ceb Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 2 Nov 2012 09:37:27 +0100 +Subject: [PATCH] spice: fix initialization order + +Register displaychangelistener last, after spice is fully initialized, +otherwise we may hit NULL pointer dereferences when qemu starts calling +our callbacks. + +Commit e250d949feb1334828f27f0d145c35f29c4b7639 triggers this bug. + +Signed-off-by: Gerd Hoffmann +--- + hw/qxl.c | 10 ++++++++-- + ui/spice-display.c | 2 +- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/hw/qxl.c b/hw/qxl.c +index f88829c..9418ecb 100644 +--- a/hw/qxl.c ++++ b/hw/qxl.c +@@ -2061,6 +2061,7 @@ static int qxl_init_primary(PCIDevice *dev) + PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev); + VGACommonState *vga = &qxl->vga; + PortioList *qxl_vga_port_list = g_new(PortioList, 1); ++ int rc; + + qxl->id = 0; + qxl_init_ramsize(qxl); +@@ -2075,9 +2076,14 @@ static int qxl_init_primary(PCIDevice *dev) + qemu_spice_display_init_common(&qxl->ssd, vga->ds); + + qxl0 = qxl; +- register_displaychangelistener(vga->ds, &display_listener); + +- return qxl_init_common(qxl); ++ rc = qxl_init_common(qxl); ++ if (rc != 0) { ++ return rc; ++ } ++ ++ register_displaychangelistener(vga->ds, &display_listener); ++ return rc; + } + + static int qxl_init_secondary(PCIDevice *dev) +diff --git a/ui/spice-display.c b/ui/spice-display.c +index d062765..4c24c32 100644 +--- a/ui/spice-display.c ++++ b/ui/spice-display.c +@@ -617,7 +617,6 @@ void qemu_spice_display_init(DisplayState *ds) + { + assert(sdpy.ds == NULL); + qemu_spice_display_init_common(&sdpy, ds); +- register_displaychangelistener(ds, &display_listener); + + sdpy.qxl.base.sif = &dpy_interface.base; + qemu_spice_add_interface(&sdpy.qxl.base); +@@ -626,4 +625,5 @@ void qemu_spice_display_init(DisplayState *ds) + qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy); + qemu_spice_create_host_memslot(&sdpy); + qemu_spice_create_host_primary(&sdpy); ++ register_displaychangelistener(ds, &display_listener); + } diff --git a/0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch b/0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch new file mode 100644 index 0000000..b28cb59 --- /dev/null +++ b/0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch @@ -0,0 +1,65 @@ +From 12bf3d6ef0b57952276361b274dcb5704480b08e Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 21 Nov 2012 14:41:48 +0100 +Subject: [PATCH] spice: add new spice-server callbacks to ui/spice-display.c + +Otherwise qemu crashes with non-qxl graphics cards. + +Signed-off-by: Gerd Hoffmann +--- + ui/spice-display.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/ui/spice-display.c b/ui/spice-display.c +index 4c24c32..85c055e 100644 +--- a/ui/spice-display.c ++++ b/ui/spice-display.c +@@ -569,6 +569,37 @@ static int interface_flush_resources(QXLInstance *sin) + return 0; + } + ++static void interface_update_area_complete(QXLInstance *sin, ++ uint32_t surface_id, ++ QXLRect *dirty, uint32_t num_updated_rects) ++{ ++ /* should never be called, used in qxl native mode only */ ++ fprintf(stderr, "%s: abort()\n", __func__); ++ abort(); ++} ++ ++/* called from spice server thread context only */ ++static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token) ++{ ++ /* should never be called, used in qxl native mode only */ ++ fprintf(stderr, "%s: abort()\n", __func__); ++ abort(); ++} ++ ++static void interface_set_client_capabilities(QXLInstance *sin, ++ uint8_t client_present, ++ uint8_t caps[58]) ++{ ++ dprint(3, "%s:\n", __func__); ++} ++ ++static int interface_client_monitors_config(QXLInstance *sin, ++ VDAgentMonitorsConfig *monitors_config) ++{ ++ dprint(3, "%s:\n", __func__); ++ return 0; /* == not supported by guest */ ++} ++ + static const QXLInterface dpy_interface = { + .base.type = SPICE_INTERFACE_QXL, + .base.description = "qemu simple display", +@@ -588,6 +619,10 @@ static const QXLInterface dpy_interface = { + .req_cursor_notification = interface_req_cursor_notification, + .notify_update = interface_notify_update, + .flush_resources = interface_flush_resources, ++ .async_complete = interface_async_complete, ++ .update_area_complete = interface_update_area_complete, ++ .set_client_capabilities = interface_set_client_capabilities, ++ .client_monitors_config = interface_client_monitors_config, + }; + + static SimpleSpiceDisplay sdpy; diff --git a/0521-qxl-save-qemu_create_displaysurface_from-result.patch b/0521-qxl-save-qemu_create_displaysurface_from-result.patch new file mode 100644 index 0000000..4e4b7ea --- /dev/null +++ b/0521-qxl-save-qemu_create_displaysurface_from-result.patch @@ -0,0 +1,38 @@ +From 67a3c5e0e9b7e2ae4444f374c698fc3fbf16a1ac Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 10 Dec 2012 07:41:07 +0100 +Subject: [PATCH] qxl: save qemu_create_displaysurface_from result + +Spotted by Coverity. + +https://bugzilla.redhat.com/show_bug.cgi?id=885644 + +Cc: qemu-stable@nongnu.org +Reported-by: Markus Armbruster +Signed-off-by: Gerd Hoffmann +--- + hw/qxl-render.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/hw/qxl-render.c b/hw/qxl-render.c +index b66c168..e7d41ec 100644 +--- a/hw/qxl-render.c ++++ b/hw/qxl-render.c +@@ -113,11 +113,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) + qxl->guest_primary.bits_pp); + if (qxl->guest_primary.qxl_stride > 0) { + qemu_free_displaysurface(vga->ds); +- qemu_create_displaysurface_from(qxl->guest_primary.surface.width, +- qxl->guest_primary.surface.height, +- qxl->guest_primary.bits_pp, +- qxl->guest_primary.abs_stride, +- qxl->guest_primary.data); ++ vga->ds->surface = qemu_create_displaysurface_from ++ (qxl->guest_primary.surface.width, ++ qxl->guest_primary.surface.height, ++ qxl->guest_primary.bits_pp, ++ qxl->guest_primary.abs_stride, ++ qxl->guest_primary.data); + } else { + qemu_resize_displaysurface(vga->ds, + qxl->guest_primary.surface.width, diff --git a/0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch b/0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch deleted file mode 100644 index 3651fda..0000000 --- a/0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch +++ /dev/null @@ -1,232 +0,0 @@ -From a6400ff20f4e32eecce44931e33939cdf04e2a3e Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 31 Aug 2012 13:41:38 +0200 -Subject: [PATCH] usb-redir: Convert to new libusbredirparser 0.5 API - -This gives us support for 64 bit ids which is needed for using XHCI with -the new hcd generated ids. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - configure | 2 +- - hw/usb/redirect.c | 62 +++++++++++++++++++++++++++---------------------------- - 2 files changed, 32 insertions(+), 32 deletions(-) - -diff --git a/configure b/configure -index 83c478c..2c4469f 100755 ---- a/configure -+++ b/configure -@@ -2758,7 +2758,7 @@ fi - - # check for usbredirparser for usb network redirection support - if test "$usb_redir" != "no" ; then -- if $pkg_config --atleast-version=0.3.4 libusbredirparser >/dev/null 2>&1 ; then -+ if $pkg_config --atleast-version=0.5 libusbredirparser >/dev/null 2>&1 ; then - usb_redir="yes" - usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null) - usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null) -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index b7c7f1e..321f5be 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -107,27 +107,27 @@ static void usbredir_interface_info(void *priv, - struct usb_redir_interface_info_header *interface_info); - static void usbredir_ep_info(void *priv, - struct usb_redir_ep_info_header *ep_info); --static void usbredir_configuration_status(void *priv, uint32_t id, -+static void usbredir_configuration_status(void *priv, uint64_t id, - struct usb_redir_configuration_status_header *configuration_status); --static void usbredir_alt_setting_status(void *priv, uint32_t id, -+static void usbredir_alt_setting_status(void *priv, uint64_t id, - struct usb_redir_alt_setting_status_header *alt_setting_status); --static void usbredir_iso_stream_status(void *priv, uint32_t id, -+static void usbredir_iso_stream_status(void *priv, uint64_t id, - struct usb_redir_iso_stream_status_header *iso_stream_status); --static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, -+static void usbredir_interrupt_receiving_status(void *priv, uint64_t id, - struct usb_redir_interrupt_receiving_status_header - *interrupt_receiving_status); --static void usbredir_bulk_streams_status(void *priv, uint32_t id, -+static void usbredir_bulk_streams_status(void *priv, uint64_t id, - struct usb_redir_bulk_streams_status_header *bulk_streams_status); --static void usbredir_control_packet(void *priv, uint32_t id, -+static void usbredir_control_packet(void *priv, uint64_t id, - struct usb_redir_control_packet_header *control_packet, - uint8_t *data, int data_len); --static void usbredir_bulk_packet(void *priv, uint32_t id, -+static void usbredir_bulk_packet(void *priv, uint64_t id, - struct usb_redir_bulk_packet_header *bulk_packet, - uint8_t *data, int data_len); --static void usbredir_iso_packet(void *priv, uint32_t id, -+static void usbredir_iso_packet(void *priv, uint64_t id, - struct usb_redir_iso_packet_header *iso_packet, - uint8_t *data, int data_len); --static void usbredir_interrupt_packet(void *priv, uint32_t id, -+static void usbredir_interrupt_packet(void *priv, uint64_t id, - struct usb_redir_interrupt_packet_header *interrupt_header, - uint8_t *data, int data_len); - -@@ -814,6 +814,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev) - - usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version); - usbredirparser_caps_set_cap(caps, usb_redir_cap_filter); -+ usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids); - usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0); - usbredirparser_do_write(dev->parser); - } -@@ -1204,15 +1205,15 @@ static void usbredir_ep_info(void *priv, - } - } - --static void usbredir_configuration_status(void *priv, uint32_t id, -+static void usbredir_configuration_status(void *priv, uint64_t id, - struct usb_redir_configuration_status_header *config_status) - { - USBRedirDevice *dev = priv; - USBPacket *p; - int len = 0; - -- DPRINTF("set config status %d config %d id %u\n", config_status->status, -- config_status->configuration, id); -+ DPRINTF("set config status %d config %d id %"PRIu64"\n", -+ config_status->status, config_status->configuration, id); - - p = usbredir_find_packet_by_id(dev, 0, id); - if (p) { -@@ -1225,16 +1226,15 @@ static void usbredir_configuration_status(void *priv, uint32_t id, - } - } - --static void usbredir_alt_setting_status(void *priv, uint32_t id, -+static void usbredir_alt_setting_status(void *priv, uint64_t id, - struct usb_redir_alt_setting_status_header *alt_setting_status) - { - USBRedirDevice *dev = priv; - USBPacket *p; - int len = 0; - -- DPRINTF("alt status %d intf %d alt %d id: %u\n", -- alt_setting_status->status, -- alt_setting_status->interface, -+ DPRINTF("alt status %d intf %d alt %d id: %"PRIu64"\n", -+ alt_setting_status->status, alt_setting_status->interface, - alt_setting_status->alt, id); - - p = usbredir_find_packet_by_id(dev, 0, id); -@@ -1249,13 +1249,13 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id, - } - } - --static void usbredir_iso_stream_status(void *priv, uint32_t id, -+static void usbredir_iso_stream_status(void *priv, uint64_t id, - struct usb_redir_iso_stream_status_header *iso_stream_status) - { - USBRedirDevice *dev = priv; - uint8_t ep = iso_stream_status->endpoint; - -- DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status, -+ DPRINTF("iso status %d ep %02X id %"PRIu64"\n", iso_stream_status->status, - ep, id); - - if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) { -@@ -1269,14 +1269,14 @@ static void usbredir_iso_stream_status(void *priv, uint32_t id, - } - } - --static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, -+static void usbredir_interrupt_receiving_status(void *priv, uint64_t id, - struct usb_redir_interrupt_receiving_status_header - *interrupt_receiving_status) - { - USBRedirDevice *dev = priv; - uint8_t ep = interrupt_receiving_status->endpoint; - -- DPRINTF("interrupt recv status %d ep %02X id %u\n", -+ DPRINTF("interrupt recv status %d ep %02X id %"PRIu64"\n", - interrupt_receiving_status->status, ep, id); - - if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) { -@@ -1291,12 +1291,12 @@ static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, - } - } - --static void usbredir_bulk_streams_status(void *priv, uint32_t id, -+static void usbredir_bulk_streams_status(void *priv, uint64_t id, - struct usb_redir_bulk_streams_status_header *bulk_streams_status) - { - } - --static void usbredir_control_packet(void *priv, uint32_t id, -+static void usbredir_control_packet(void *priv, uint64_t id, - struct usb_redir_control_packet_header *control_packet, - uint8_t *data, int data_len) - { -@@ -1304,7 +1304,7 @@ static void usbredir_control_packet(void *priv, uint32_t id, - USBPacket *p; - int len = control_packet->length; - -- DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status, -+ DPRINTF("ctrl-in status %d len %d id %"PRIu64"\n", control_packet->status, - len, id); - - p = usbredir_find_packet_by_id(dev, 0, id); -@@ -1326,7 +1326,7 @@ static void usbredir_control_packet(void *priv, uint32_t id, - free(data); - } - --static void usbredir_bulk_packet(void *priv, uint32_t id, -+static void usbredir_bulk_packet(void *priv, uint64_t id, - struct usb_redir_bulk_packet_header *bulk_packet, - uint8_t *data, int data_len) - { -@@ -1335,8 +1335,8 @@ static void usbredir_bulk_packet(void *priv, uint32_t id, - int len = bulk_packet->length; - USBPacket *p; - -- DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status, -- ep, len, id); -+ DPRINTF("bulk-in status %d ep %02X len %d id %"PRIu64"\n", -+ bulk_packet->status, ep, len, id); - - p = usbredir_find_packet_by_id(dev, ep, id); - if (p) { -@@ -1357,15 +1357,15 @@ static void usbredir_bulk_packet(void *priv, uint32_t id, - free(data); - } - --static void usbredir_iso_packet(void *priv, uint32_t id, -+static void usbredir_iso_packet(void *priv, uint64_t id, - struct usb_redir_iso_packet_header *iso_packet, - uint8_t *data, int data_len) - { - USBRedirDevice *dev = priv; - uint8_t ep = iso_packet->endpoint; - -- DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep, -- data_len, id); -+ DPRINTF2("iso-in status %d ep %02X len %d id %"PRIu64"\n", -+ iso_packet->status, ep, data_len, id); - - if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) { - ERROR("received iso packet for non iso endpoint %02X\n", ep); -@@ -1383,14 +1383,14 @@ static void usbredir_iso_packet(void *priv, uint32_t id, - bufp_alloc(dev, data, data_len, iso_packet->status, ep); - } - --static void usbredir_interrupt_packet(void *priv, uint32_t id, -+static void usbredir_interrupt_packet(void *priv, uint64_t id, - struct usb_redir_interrupt_packet_header *interrupt_packet, - uint8_t *data, int data_len) - { - USBRedirDevice *dev = priv; - uint8_t ep = interrupt_packet->endpoint; - -- DPRINTF("interrupt-in status %d ep %02X len %d id %u\n", -+ DPRINTF("interrupt-in status %d ep %02X len %d id %"PRIu64"\n", - interrupt_packet->status, ep, data_len, id); - - if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) { --- -1.7.12.1 - diff --git a/0601-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch b/0601-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch new file mode 100644 index 0000000..03520e4 --- /dev/null +++ b/0601-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch @@ -0,0 +1,229 @@ +From 3fe6c1a36c08f282402f4487013d7e15a1c79095 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 31 Aug 2012 13:41:38 +0200 +Subject: [PATCH] usb-redir: Convert to new libusbredirparser 0.5 API + +This gives us support for 64 bit ids which is needed for using XHCI with +the new hcd generated ids. + +Signed-off-by: Hans de Goede +Signed-off-by: Gerd Hoffmann +--- + configure | 2 +- + hw/usb/redirect.c | 62 +++++++++++++++++++++++++++---------------------------- + 2 files changed, 32 insertions(+), 32 deletions(-) + +diff --git a/configure b/configure +index 5eb4369..d43d61a 100755 +--- a/configure ++++ b/configure +@@ -2757,7 +2757,7 @@ fi + + # check for usbredirparser for usb network redirection support + if test "$usb_redir" != "no" ; then +- if $pkg_config --atleast-version=0.3.4 libusbredirparser >/dev/null 2>&1 ; then ++ if $pkg_config --atleast-version=0.5 libusbredirparser >/dev/null 2>&1 ; then + usb_redir="yes" + usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null) + usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null) +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index b7c7f1e..321f5be 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -107,27 +107,27 @@ static void usbredir_interface_info(void *priv, + struct usb_redir_interface_info_header *interface_info); + static void usbredir_ep_info(void *priv, + struct usb_redir_ep_info_header *ep_info); +-static void usbredir_configuration_status(void *priv, uint32_t id, ++static void usbredir_configuration_status(void *priv, uint64_t id, + struct usb_redir_configuration_status_header *configuration_status); +-static void usbredir_alt_setting_status(void *priv, uint32_t id, ++static void usbredir_alt_setting_status(void *priv, uint64_t id, + struct usb_redir_alt_setting_status_header *alt_setting_status); +-static void usbredir_iso_stream_status(void *priv, uint32_t id, ++static void usbredir_iso_stream_status(void *priv, uint64_t id, + struct usb_redir_iso_stream_status_header *iso_stream_status); +-static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, ++static void usbredir_interrupt_receiving_status(void *priv, uint64_t id, + struct usb_redir_interrupt_receiving_status_header + *interrupt_receiving_status); +-static void usbredir_bulk_streams_status(void *priv, uint32_t id, ++static void usbredir_bulk_streams_status(void *priv, uint64_t id, + struct usb_redir_bulk_streams_status_header *bulk_streams_status); +-static void usbredir_control_packet(void *priv, uint32_t id, ++static void usbredir_control_packet(void *priv, uint64_t id, + struct usb_redir_control_packet_header *control_packet, + uint8_t *data, int data_len); +-static void usbredir_bulk_packet(void *priv, uint32_t id, ++static void usbredir_bulk_packet(void *priv, uint64_t id, + struct usb_redir_bulk_packet_header *bulk_packet, + uint8_t *data, int data_len); +-static void usbredir_iso_packet(void *priv, uint32_t id, ++static void usbredir_iso_packet(void *priv, uint64_t id, + struct usb_redir_iso_packet_header *iso_packet, + uint8_t *data, int data_len); +-static void usbredir_interrupt_packet(void *priv, uint32_t id, ++static void usbredir_interrupt_packet(void *priv, uint64_t id, + struct usb_redir_interrupt_packet_header *interrupt_header, + uint8_t *data, int data_len); + +@@ -814,6 +814,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev) + + usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version); + usbredirparser_caps_set_cap(caps, usb_redir_cap_filter); ++ usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids); + usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0); + usbredirparser_do_write(dev->parser); + } +@@ -1204,15 +1205,15 @@ static void usbredir_ep_info(void *priv, + } + } + +-static void usbredir_configuration_status(void *priv, uint32_t id, ++static void usbredir_configuration_status(void *priv, uint64_t id, + struct usb_redir_configuration_status_header *config_status) + { + USBRedirDevice *dev = priv; + USBPacket *p; + int len = 0; + +- DPRINTF("set config status %d config %d id %u\n", config_status->status, +- config_status->configuration, id); ++ DPRINTF("set config status %d config %d id %"PRIu64"\n", ++ config_status->status, config_status->configuration, id); + + p = usbredir_find_packet_by_id(dev, 0, id); + if (p) { +@@ -1225,16 +1226,15 @@ static void usbredir_configuration_status(void *priv, uint32_t id, + } + } + +-static void usbredir_alt_setting_status(void *priv, uint32_t id, ++static void usbredir_alt_setting_status(void *priv, uint64_t id, + struct usb_redir_alt_setting_status_header *alt_setting_status) + { + USBRedirDevice *dev = priv; + USBPacket *p; + int len = 0; + +- DPRINTF("alt status %d intf %d alt %d id: %u\n", +- alt_setting_status->status, +- alt_setting_status->interface, ++ DPRINTF("alt status %d intf %d alt %d id: %"PRIu64"\n", ++ alt_setting_status->status, alt_setting_status->interface, + alt_setting_status->alt, id); + + p = usbredir_find_packet_by_id(dev, 0, id); +@@ -1249,13 +1249,13 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id, + } + } + +-static void usbredir_iso_stream_status(void *priv, uint32_t id, ++static void usbredir_iso_stream_status(void *priv, uint64_t id, + struct usb_redir_iso_stream_status_header *iso_stream_status) + { + USBRedirDevice *dev = priv; + uint8_t ep = iso_stream_status->endpoint; + +- DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status, ++ DPRINTF("iso status %d ep %02X id %"PRIu64"\n", iso_stream_status->status, + ep, id); + + if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) { +@@ -1269,14 +1269,14 @@ static void usbredir_iso_stream_status(void *priv, uint32_t id, + } + } + +-static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, ++static void usbredir_interrupt_receiving_status(void *priv, uint64_t id, + struct usb_redir_interrupt_receiving_status_header + *interrupt_receiving_status) + { + USBRedirDevice *dev = priv; + uint8_t ep = interrupt_receiving_status->endpoint; + +- DPRINTF("interrupt recv status %d ep %02X id %u\n", ++ DPRINTF("interrupt recv status %d ep %02X id %"PRIu64"\n", + interrupt_receiving_status->status, ep, id); + + if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) { +@@ -1291,12 +1291,12 @@ static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, + } + } + +-static void usbredir_bulk_streams_status(void *priv, uint32_t id, ++static void usbredir_bulk_streams_status(void *priv, uint64_t id, + struct usb_redir_bulk_streams_status_header *bulk_streams_status) + { + } + +-static void usbredir_control_packet(void *priv, uint32_t id, ++static void usbredir_control_packet(void *priv, uint64_t id, + struct usb_redir_control_packet_header *control_packet, + uint8_t *data, int data_len) + { +@@ -1304,7 +1304,7 @@ static void usbredir_control_packet(void *priv, uint32_t id, + USBPacket *p; + int len = control_packet->length; + +- DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status, ++ DPRINTF("ctrl-in status %d len %d id %"PRIu64"\n", control_packet->status, + len, id); + + p = usbredir_find_packet_by_id(dev, 0, id); +@@ -1326,7 +1326,7 @@ static void usbredir_control_packet(void *priv, uint32_t id, + free(data); + } + +-static void usbredir_bulk_packet(void *priv, uint32_t id, ++static void usbredir_bulk_packet(void *priv, uint64_t id, + struct usb_redir_bulk_packet_header *bulk_packet, + uint8_t *data, int data_len) + { +@@ -1335,8 +1335,8 @@ static void usbredir_bulk_packet(void *priv, uint32_t id, + int len = bulk_packet->length; + USBPacket *p; + +- DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status, +- ep, len, id); ++ DPRINTF("bulk-in status %d ep %02X len %d id %"PRIu64"\n", ++ bulk_packet->status, ep, len, id); + + p = usbredir_find_packet_by_id(dev, ep, id); + if (p) { +@@ -1357,15 +1357,15 @@ static void usbredir_bulk_packet(void *priv, uint32_t id, + free(data); + } + +-static void usbredir_iso_packet(void *priv, uint32_t id, ++static void usbredir_iso_packet(void *priv, uint64_t id, + struct usb_redir_iso_packet_header *iso_packet, + uint8_t *data, int data_len) + { + USBRedirDevice *dev = priv; + uint8_t ep = iso_packet->endpoint; + +- DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep, +- data_len, id); ++ DPRINTF2("iso-in status %d ep %02X len %d id %"PRIu64"\n", ++ iso_packet->status, ep, data_len, id); + + if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) { + ERROR("received iso packet for non iso endpoint %02X\n", ep); +@@ -1383,14 +1383,14 @@ static void usbredir_iso_packet(void *priv, uint32_t id, + bufp_alloc(dev, data, data_len, iso_packet->status, ep); + } + +-static void usbredir_interrupt_packet(void *priv, uint32_t id, ++static void usbredir_interrupt_packet(void *priv, uint64_t id, + struct usb_redir_interrupt_packet_header *interrupt_packet, + uint8_t *data, int data_len) + { + USBRedirDevice *dev = priv; + uint8_t ep = interrupt_packet->endpoint; + +- DPRINTF("interrupt-in status %d ep %02X len %d id %u\n", ++ DPRINTF("interrupt-in status %d ep %02X len %d id %"PRIu64"\n", + interrupt_packet->status, ep, data_len, id); + + if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) { diff --git a/0601-usb-redir-Set-ep-max_packet_size-if-available.patch b/0601-usb-redir-Set-ep-max_packet_size-if-available.patch deleted file mode 100644 index 8dacdb4..0000000 --- a/0601-usb-redir-Set-ep-max_packet_size-if-available.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0995eaeb06c4810cd133e710170a7b181caf04cd Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 3 Sep 2012 11:49:07 +0200 -Subject: [PATCH] usb-redir: Set ep max_packet_size if available - -This is needed for usb-redir to work properly with the xhci emulation. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb/redirect.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 321f5be..b9a3633 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -814,6 +814,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev) - - usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version); - usbredirparser_caps_set_cap(caps, usb_redir_cap_filter); -+ usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size); - usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids); - usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0); - usbredirparser_do_write(dev->parser); -@@ -1202,6 +1203,10 @@ static void usbredir_ep_info(void *priv, - i & 0x0f); - usb_ep->type = dev->endpoint[i].type; - usb_ep->ifnum = dev->endpoint[i].interface; -+ if (usbredirparser_peer_has_cap(dev->parser, -+ usb_redir_cap_ep_info_max_packet_size)) { -+ usb_ep->max_packet_size = ep_info->max_packet_size[i]; -+ } - } - } - --- -1.7.12.1 - diff --git a/0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch b/0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch deleted file mode 100644 index cfe0fa1..0000000 --- a/0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 596013354fd1d5b102cdb54449b10e11346f9fda Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 3 Sep 2012 11:53:28 +0200 -Subject: [PATCH] usb-redir: Add a usbredir_reject_device helper function - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb/redirect.c | 21 +++++++++++---------- - 1 file changed, 11 insertions(+), 10 deletions(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index b9a3633..a590cb2 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -820,16 +820,21 @@ static void usbredir_chardev_open(USBRedirDevice *dev) - usbredirparser_do_write(dev->parser); - } - -+static void usbredir_reject_device(USBRedirDevice *dev) -+{ -+ usbredir_device_disconnect(dev); -+ if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) { -+ usbredirparser_send_filter_reject(dev->parser); -+ usbredirparser_do_write(dev->parser); -+ } -+} -+ - static void usbredir_do_attach(void *opaque) - { - USBRedirDevice *dev = opaque; - - if (usb_device_attach(&dev->dev) != 0) { -- usbredir_device_disconnect(dev); -- if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) { -- usbredirparser_send_filter_reject(dev->parser); -- usbredirparser_do_write(dev->parser); -- } -+ usbredir_reject_device(dev); - } - } - -@@ -1008,11 +1013,7 @@ static int usbredir_check_filter(USBRedirDevice *dev) - return 0; - - error: -- usbredir_device_disconnect(dev); -- if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) { -- usbredirparser_send_filter_reject(dev->parser); -- usbredirparser_do_write(dev->parser); -- } -+ usbredir_reject_device(dev); - return -1; - } - --- -1.7.12.1 - diff --git a/0602-usb-redir-Set-ep-max_packet_size-if-available.patch b/0602-usb-redir-Set-ep-max_packet_size-if-available.patch new file mode 100644 index 0000000..49af939 --- /dev/null +++ b/0602-usb-redir-Set-ep-max_packet_size-if-available.patch @@ -0,0 +1,36 @@ +From bbc0ef6979ccab369335839da645e68d15845fde Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 3 Sep 2012 11:49:07 +0200 +Subject: [PATCH] usb-redir: Set ep max_packet_size if available + +This is needed for usb-redir to work properly with the xhci emulation. + +Signed-off-by: Hans de Goede +Signed-off-by: Gerd Hoffmann +--- + hw/usb/redirect.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 321f5be..b9a3633 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -814,6 +814,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev) + + usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version); + usbredirparser_caps_set_cap(caps, usb_redir_cap_filter); ++ usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size); + usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids); + usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0); + usbredirparser_do_write(dev->parser); +@@ -1202,6 +1203,10 @@ static void usbredir_ep_info(void *priv, + i & 0x0f); + usb_ep->type = dev->endpoint[i].type; + usb_ep->ifnum = dev->endpoint[i].interface; ++ if (usbredirparser_peer_has_cap(dev->parser, ++ usb_redir_cap_ep_info_max_packet_size)) { ++ usb_ep->max_packet_size = ep_info->max_packet_size[i]; ++ } + } + } + diff --git a/0603-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch b/0603-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch new file mode 100644 index 0000000..1874c40 --- /dev/null +++ b/0603-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch @@ -0,0 +1,55 @@ +From f1747cd3b2231a4d9d53ad5576f4e0a0cba50998 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 3 Sep 2012 11:53:28 +0200 +Subject: [PATCH] usb-redir: Add a usbredir_reject_device helper function + +Signed-off-by: Hans de Goede +Signed-off-by: Gerd Hoffmann +--- + hw/usb/redirect.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index b9a3633..a590cb2 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -820,16 +820,21 @@ static void usbredir_chardev_open(USBRedirDevice *dev) + usbredirparser_do_write(dev->parser); + } + ++static void usbredir_reject_device(USBRedirDevice *dev) ++{ ++ usbredir_device_disconnect(dev); ++ if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) { ++ usbredirparser_send_filter_reject(dev->parser); ++ usbredirparser_do_write(dev->parser); ++ } ++} ++ + static void usbredir_do_attach(void *opaque) + { + USBRedirDevice *dev = opaque; + + if (usb_device_attach(&dev->dev) != 0) { +- usbredir_device_disconnect(dev); +- if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) { +- usbredirparser_send_filter_reject(dev->parser); +- usbredirparser_do_write(dev->parser); +- } ++ usbredir_reject_device(dev); + } + } + +@@ -1008,11 +1013,7 @@ static int usbredir_check_filter(USBRedirDevice *dev) + return 0; + + error: +- usbredir_device_disconnect(dev); +- if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) { +- usbredirparser_send_filter_reject(dev->parser); +- usbredirparser_do_write(dev->parser); +- } ++ usbredir_reject_device(dev); + return -1; + } + diff --git a/0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch b/0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch deleted file mode 100644 index ef6b4a2..0000000 --- a/0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 87317670541ed043a21964c29e0e613aab375224 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 3 Sep 2012 12:04:49 +0200 -Subject: [PATCH] usb-redir: Ensure our peer has the necessary caps when - redirecting to XHCI - -In order for redirection to work properly when redirecting to an emulated -XHCI controller, the usb-redir-host must support both -usb_redir_cap_ep_info_max_packet_size and usb_redir_cap_64bits_ids, -reject any devices redirected to an XHCI controller when these are not -supported. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb/redirect.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index a590cb2..f1bb692 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -833,6 +833,17 @@ static void usbredir_do_attach(void *opaque) - { - USBRedirDevice *dev = opaque; - -+ /* In order to work properly with XHCI controllers we need these caps */ -+ if ((dev->dev.port->speedmask & USB_SPEED_MASK_SUPER) && !( -+ usbredirparser_peer_has_cap(dev->parser, -+ usb_redir_cap_ep_info_max_packet_size) && -+ usbredirparser_peer_has_cap(dev->parser, -+ usb_redir_cap_64bits_ids))) { -+ ERROR("usb-redir-host lacks capabilities needed for use with XHCI\n"); -+ usbredir_reject_device(dev); -+ return; -+ } -+ - if (usb_device_attach(&dev->dev) != 0) { - usbredir_reject_device(dev); - } --- -1.7.12.1 - diff --git a/0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch b/0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch deleted file mode 100644 index cfb988e..0000000 --- a/0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c12ef3d896e426505ea3ca4fb2f1d9017f9cf828 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 3 Sep 2012 13:44:04 +0200 -Subject: [PATCH] usb-redir: Enable pipelining for bulk endpoints - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb/redirect.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index f1bb692..f183263 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -1219,6 +1219,9 @@ static void usbredir_ep_info(void *priv, - usb_redir_cap_ep_info_max_packet_size)) { - usb_ep->max_packet_size = ep_info->max_packet_size[i]; - } -+ if (ep_info->type[i] == usb_redir_type_bulk) { -+ usb_ep->pipeline = true; -+ } - } - } - --- -1.7.12.1 - diff --git a/0604-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch b/0604-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch new file mode 100644 index 0000000..68fb2c6 --- /dev/null +++ b/0604-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch @@ -0,0 +1,40 @@ +From ef07a05e357649d52058bcd980924b107a85fb56 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 3 Sep 2012 12:04:49 +0200 +Subject: [PATCH] usb-redir: Ensure our peer has the necessary caps when + redirecting to XHCI + +In order for redirection to work properly when redirecting to an emulated +XHCI controller, the usb-redir-host must support both +usb_redir_cap_ep_info_max_packet_size and usb_redir_cap_64bits_ids, +reject any devices redirected to an XHCI controller when these are not +supported. + +Signed-off-by: Hans de Goede +Signed-off-by: Gerd Hoffmann +--- + hw/usb/redirect.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index a590cb2..f1bb692 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -833,6 +833,17 @@ static void usbredir_do_attach(void *opaque) + { + USBRedirDevice *dev = opaque; + ++ /* In order to work properly with XHCI controllers we need these caps */ ++ if ((dev->dev.port->speedmask & USB_SPEED_MASK_SUPER) && !( ++ usbredirparser_peer_has_cap(dev->parser, ++ usb_redir_cap_ep_info_max_packet_size) && ++ usbredirparser_peer_has_cap(dev->parser, ++ usb_redir_cap_64bits_ids))) { ++ ERROR("usb-redir-host lacks capabilities needed for use with XHCI\n"); ++ usbredir_reject_device(dev); ++ return; ++ } ++ + if (usb_device_attach(&dev->dev) != 0) { + usbredir_reject_device(dev); + } diff --git a/0605-usb-redir-Enable-pipelining-for-bulk-endpoints.patch b/0605-usb-redir-Enable-pipelining-for-bulk-endpoints.patch new file mode 100644 index 0000000..e5dc1e5 --- /dev/null +++ b/0605-usb-redir-Enable-pipelining-for-bulk-endpoints.patch @@ -0,0 +1,25 @@ +From 71b8edadc72990f1f987a8b39ab2fc10582b454d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 3 Sep 2012 13:44:04 +0200 +Subject: [PATCH] usb-redir: Enable pipelining for bulk endpoints + +Signed-off-by: Hans de Goede +Signed-off-by: Gerd Hoffmann +--- + hw/usb/redirect.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index f1bb692..f183263 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -1219,6 +1219,9 @@ static void usbredir_ep_info(void *priv, + usb_redir_cap_ep_info_max_packet_size)) { + usb_ep->max_packet_size = ep_info->max_packet_size[i]; + } ++ if (ep_info->type[i] == usb_redir_type_bulk) { ++ usb_ep->pipeline = true; ++ } + } + } + diff --git a/0605-xhci-move-device-lookup-into-xhci_setup_packet.patch b/0605-xhci-move-device-lookup-into-xhci_setup_packet.patch deleted file mode 100644 index 3a2ad62..0000000 --- a/0605-xhci-move-device-lookup-into-xhci_setup_packet.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 2255facbc338e73aa2442e2a1dc13b3474b35f98 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 24 Aug 2012 14:21:39 +0200 -Subject: [PATCH] xhci: move device lookup into xhci_setup_packet - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 74 ++++++++++++++++++++++++++++--------------------------- - 1 file changed, 38 insertions(+), 36 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 333df59..316a303 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -1196,13 +1196,38 @@ static void xhci_stall_ep(XHCITransfer *xfer) - static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, - XHCIEPContext *epctx); - --static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev) -+static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) - { -+ if (!(port->portsc & PORTSC_PED)) { -+ return NULL; -+ } -+ return usb_find_device(&port->port, addr); -+} -+ -+static int xhci_setup_packet(XHCITransfer *xfer) -+{ -+ XHCIState *xhci = xfer->xhci; -+ XHCIPort *port; -+ USBDevice *dev; - USBEndpoint *ep; - int dir; - - dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT; -- ep = usb_ep_get(dev, dir, xfer->epid >> 1); -+ -+ if (xfer->packet.ep) { -+ ep = xfer->packet.ep; -+ dev = ep->dev; -+ } else { -+ port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; -+ dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); -+ if (!dev) { -+ fprintf(stderr, "xhci: slot %d port %d has no device\n", -+ xfer->slotid, xhci->slots[xfer->slotid-1].port); -+ return -1; -+ } -+ ep = usb_ep_get(dev, dir, xfer->epid >> 1); -+ } -+ - usb_packet_setup(&xfer->packet, dir, ep, xfer->trbs[0].addr); - xhci_xfer_map(xfer); - DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n", -@@ -1260,20 +1285,10 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret) - return 0; - } - --static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) --{ -- if (!(port->portsc & PORTSC_PED)) { -- return NULL; -- } -- return usb_find_device(&port->port, addr); --} -- - static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) - { - XHCITRB *trb_setup, *trb_status; - uint8_t bmRequestType; -- XHCIPort *port; -- USBDevice *dev; - int ret; - - trb_setup = &xfer->trbs[0]; -@@ -1309,21 +1324,15 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) - - bmRequestType = trb_setup->parameter; - -- port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; -- dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); -- if (!dev) { -- fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, -- xhci->slots[xfer->slotid-1].port); -- return -1; -- } -- - xfer->in_xfer = bmRequestType & USB_DIR_IN; - xfer->iso_xfer = false; - -- xhci_setup_packet(xfer, dev); -+ if (xhci_setup_packet(xfer) < 0) { -+ return -1; -+ } - xfer->packet.parameter = trb_setup->parameter; - -- ret = usb_handle_packet(dev, &xfer->packet); -+ ret = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); - - xhci_complete_packet(xfer, ret); - if (!xfer->running_async && !xfer->running_retry) { -@@ -1334,8 +1343,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) - - static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx) - { -- XHCIPort *port; -- USBDevice *dev; - int ret; - - DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); -@@ -1348,16 +1355,6 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx - xfer->pkts = 0; - } - -- port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; -- dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); -- if (!dev) { -- fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, -- xhci->slots[xfer->slotid-1].port); -- return -1; -- } -- -- xhci_setup_packet(xfer, dev); -- - switch(epctx->type) { - case ET_INTR_OUT: - case ET_INTR_IN: -@@ -1375,7 +1372,10 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx - return -1; - } - -- ret = usb_handle_packet(dev, &xfer->packet); -+ if (xhci_setup_packet(xfer) < 0) { -+ return -1; -+ } -+ ret = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); - - xhci_complete_packet(xfer, ret); - if (!xfer->running_async && !xfer->running_retry) { -@@ -1418,7 +1418,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid - - trace_usb_xhci_xfer_retry(xfer); - assert(xfer->running_retry); -- xhci_setup_packet(xfer, xfer->packet.ep->dev); -+ if (xhci_setup_packet(xfer) < 0) { -+ return; -+ } - result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); - if (result == USB_RET_NAK) { - return; --- -1.7.12.1 - diff --git a/0606-xhci-implement-mfindex.patch b/0606-xhci-implement-mfindex.patch deleted file mode 100644 index 4e4d268..0000000 --- a/0606-xhci-implement-mfindex.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 1f98b775c9f02caece1df5813edbb9c0a509bd58 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 21 Aug 2012 12:32:58 +0200 -Subject: [PATCH] xhci: implement mfindex - -Implement mfindex register and mfindex wrap event. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 46 insertions(+), 7 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 316a303..f5ba6a4 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -380,8 +380,6 @@ struct XHCIState { - XHCISlot slots[MAXSLOTS]; - - /* Runtime Registers */ -- uint32_t mfindex; -- /* note: we only support one interrupter */ - uint32_t iman; - uint32_t imod; - uint32_t erstsz; -@@ -390,6 +388,9 @@ struct XHCIState { - uint32_t erdp_low; - uint32_t erdp_high; - -+ int64_t mfindex_start; -+ QEMUTimer *mfwrap_timer; -+ - dma_addr_t er_start; - uint32_t er_size; - bool er_pcs; -@@ -410,6 +411,11 @@ typedef struct XHCIEvRingSeg { - uint32_t rsvd; - } XHCIEvRingSeg; - -+static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, -+ unsigned int epid); -+static void xhci_event(XHCIState *xhci, XHCIEvent *event); -+static void xhci_write_event(XHCIState *xhci, XHCIEvent *event); -+ - static const char *TRBType_names[] = { - [TRB_RESERVED] = "TRB_RESERVED", - [TR_NORMAL] = "TR_NORMAL", -@@ -462,8 +468,36 @@ static const char *trb_name(XHCITRB *trb) - ARRAY_SIZE(TRBType_names)); - } - --static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, -- unsigned int epid); -+static uint64_t xhci_mfindex_get(XHCIState *xhci) -+{ -+ int64_t now = qemu_get_clock_ns(vm_clock); -+ return (now - xhci->mfindex_start) / 125000; -+} -+ -+static void xhci_mfwrap_update(XHCIState *xhci) -+{ -+ const uint32_t bits = USBCMD_RS | USBCMD_EWE; -+ uint32_t mfindex, left; -+ int64_t now; -+ -+ if ((xhci->usbcmd & bits) == bits) { -+ now = qemu_get_clock_ns(vm_clock); -+ mfindex = ((now - xhci->mfindex_start) / 125000) & 0x3fff; -+ left = 0x4000 - mfindex; -+ qemu_mod_timer(xhci->mfwrap_timer, now + left * 125000); -+ } else { -+ qemu_del_timer(xhci->mfwrap_timer); -+ } -+} -+ -+static void xhci_mfwrap_timer(void *opaque) -+{ -+ XHCIState *xhci = opaque; -+ XHCIEvent wrap = { ER_MFINDEX_WRAP, CC_SUCCESS }; -+ -+ xhci_event(xhci, &wrap); -+ xhci_mfwrap_update(xhci); -+} - - static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high) - { -@@ -793,6 +827,7 @@ static void xhci_run(XHCIState *xhci) - { - trace_usb_xhci_run(); - xhci->usbsts &= ~USBSTS_HCH; -+ xhci->mfindex_start = qemu_get_clock_ns(vm_clock); - } - - static void xhci_stop(XHCIState *xhci) -@@ -2048,7 +2083,6 @@ static void xhci_reset(DeviceState *dev) - xhci_update_port(xhci, xhci->ports + i, 0); - } - -- xhci->mfindex = 0; - xhci->iman = 0; - xhci->imod = 0; - xhci->erstsz = 0; -@@ -2062,6 +2096,9 @@ static void xhci_reset(DeviceState *dev) - xhci->er_full = 0; - xhci->ev_buffer_put = 0; - xhci->ev_buffer_get = 0; -+ -+ xhci->mfindex_start = qemu_get_clock_ns(vm_clock); -+ xhci_mfwrap_update(xhci); - } - - static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) -@@ -2264,6 +2301,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) - xhci_stop(xhci); - } - xhci->usbcmd = val & 0xc0f; -+ xhci_mfwrap_update(xhci); - if (val & USBCMD_HCRST) { - xhci_reset(&xhci->pci_dev.qdev); - } -@@ -2315,8 +2353,7 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - - switch (reg) { - case 0x00: /* MFINDEX */ -- fprintf(stderr, "xhci_runtime_read: MFINDEX not yet implemented\n"); -- ret = xhci->mfindex; -+ ret = xhci_mfindex_get(xhci) & 0x3fff; - break; - case 0x20: /* IMAN */ - ret = xhci->iman; -@@ -2618,6 +2655,8 @@ static int usb_xhci_initfn(struct PCIDevice *dev) - - usb_xhci_init(xhci, &dev->qdev); - -+ xhci->mfwrap_timer = qemu_new_timer_ns(vm_clock, xhci_mfwrap_timer, xhci); -+ - xhci->irq = xhci->pci_dev.irq[0]; - - memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci, --- -1.7.12.1 - diff --git a/0606-xhci-move-device-lookup-into-xhci_setup_packet.patch b/0606-xhci-move-device-lookup-into-xhci_setup_packet.patch new file mode 100644 index 0000000..f78bbac --- /dev/null +++ b/0606-xhci-move-device-lookup-into-xhci_setup_packet.patch @@ -0,0 +1,151 @@ +From d2b51c117c29bd6c643b38dee8e1f49572711c13 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 24 Aug 2012 14:21:39 +0200 +Subject: [PATCH] xhci: move device lookup into xhci_setup_packet + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 74 ++++++++++++++++++++++++++++--------------------------- + 1 file changed, 38 insertions(+), 36 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 30cb0d5..1a65063 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -1196,13 +1196,38 @@ static void xhci_stall_ep(XHCITransfer *xfer) + static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, + XHCIEPContext *epctx); + +-static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev) ++static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) + { ++ if (!(port->portsc & PORTSC_PED)) { ++ return NULL; ++ } ++ return usb_find_device(&port->port, addr); ++} ++ ++static int xhci_setup_packet(XHCITransfer *xfer) ++{ ++ XHCIState *xhci = xfer->xhci; ++ XHCIPort *port; ++ USBDevice *dev; + USBEndpoint *ep; + int dir; + + dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT; +- ep = usb_ep_get(dev, dir, xfer->epid >> 1); ++ ++ if (xfer->packet.ep) { ++ ep = xfer->packet.ep; ++ dev = ep->dev; ++ } else { ++ port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; ++ dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); ++ if (!dev) { ++ fprintf(stderr, "xhci: slot %d port %d has no device\n", ++ xfer->slotid, xhci->slots[xfer->slotid-1].port); ++ return -1; ++ } ++ ep = usb_ep_get(dev, dir, xfer->epid >> 1); ++ } ++ + usb_packet_setup(&xfer->packet, dir, ep, xfer->trbs[0].addr); + xhci_xfer_map(xfer); + DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n", +@@ -1260,20 +1285,10 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret) + return 0; + } + +-static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) +-{ +- if (!(port->portsc & PORTSC_PED)) { +- return NULL; +- } +- return usb_find_device(&port->port, addr); +-} +- + static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) + { + XHCITRB *trb_setup, *trb_status; + uint8_t bmRequestType; +- XHCIPort *port; +- USBDevice *dev; + int ret; + + trb_setup = &xfer->trbs[0]; +@@ -1309,21 +1324,15 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) + + bmRequestType = trb_setup->parameter; + +- port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; +- dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); +- if (!dev) { +- fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, +- xhci->slots[xfer->slotid-1].port); +- return -1; +- } +- + xfer->in_xfer = bmRequestType & USB_DIR_IN; + xfer->iso_xfer = false; + +- xhci_setup_packet(xfer, dev); ++ if (xhci_setup_packet(xfer) < 0) { ++ return -1; ++ } + xfer->packet.parameter = trb_setup->parameter; + +- ret = usb_handle_packet(dev, &xfer->packet); ++ ret = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); + + xhci_complete_packet(xfer, ret); + if (!xfer->running_async && !xfer->running_retry) { +@@ -1334,8 +1343,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) + + static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx) + { +- XHCIPort *port; +- USBDevice *dev; + int ret; + + DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); +@@ -1348,16 +1355,6 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx + xfer->pkts = 0; + } + +- port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; +- dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); +- if (!dev) { +- fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, +- xhci->slots[xfer->slotid-1].port); +- return -1; +- } +- +- xhci_setup_packet(xfer, dev); +- + switch(epctx->type) { + case ET_INTR_OUT: + case ET_INTR_IN: +@@ -1375,7 +1372,10 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx + return -1; + } + +- ret = usb_handle_packet(dev, &xfer->packet); ++ if (xhci_setup_packet(xfer) < 0) { ++ return -1; ++ } ++ ret = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); + + xhci_complete_packet(xfer, ret); + if (!xfer->running_async && !xfer->running_retry) { +@@ -1418,7 +1418,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid + + trace_usb_xhci_xfer_retry(xfer); + assert(xfer->running_retry); +- xhci_setup_packet(xfer, xfer->packet.ep->dev); ++ if (xhci_setup_packet(xfer) < 0) { ++ return; ++ } + result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); + if (result == USB_RET_NAK) { + return; diff --git a/0607-xhci-implement-mfindex.patch b/0607-xhci-implement-mfindex.patch new file mode 100644 index 0000000..68f1382 --- /dev/null +++ b/0607-xhci-implement-mfindex.patch @@ -0,0 +1,139 @@ +From 3529c46a54fcd3e1bc0bef97be254005177e5054 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 21 Aug 2012 12:32:58 +0200 +Subject: [PATCH] xhci: implement mfindex + +Implement mfindex register and mfindex wrap event. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 46 insertions(+), 7 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 1a65063..88f71fc 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -380,8 +380,6 @@ struct XHCIState { + XHCISlot slots[MAXSLOTS]; + + /* Runtime Registers */ +- uint32_t mfindex; +- /* note: we only support one interrupter */ + uint32_t iman; + uint32_t imod; + uint32_t erstsz; +@@ -390,6 +388,9 @@ struct XHCIState { + uint32_t erdp_low; + uint32_t erdp_high; + ++ int64_t mfindex_start; ++ QEMUTimer *mfwrap_timer; ++ + dma_addr_t er_start; + uint32_t er_size; + bool er_pcs; +@@ -410,6 +411,11 @@ typedef struct XHCIEvRingSeg { + uint32_t rsvd; + } XHCIEvRingSeg; + ++static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, ++ unsigned int epid); ++static void xhci_event(XHCIState *xhci, XHCIEvent *event); ++static void xhci_write_event(XHCIState *xhci, XHCIEvent *event); ++ + static const char *TRBType_names[] = { + [TRB_RESERVED] = "TRB_RESERVED", + [TR_NORMAL] = "TR_NORMAL", +@@ -462,8 +468,36 @@ static const char *trb_name(XHCITRB *trb) + ARRAY_SIZE(TRBType_names)); + } + +-static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, +- unsigned int epid); ++static uint64_t xhci_mfindex_get(XHCIState *xhci) ++{ ++ int64_t now = qemu_get_clock_ns(vm_clock); ++ return (now - xhci->mfindex_start) / 125000; ++} ++ ++static void xhci_mfwrap_update(XHCIState *xhci) ++{ ++ const uint32_t bits = USBCMD_RS | USBCMD_EWE; ++ uint32_t mfindex, left; ++ int64_t now; ++ ++ if ((xhci->usbcmd & bits) == bits) { ++ now = qemu_get_clock_ns(vm_clock); ++ mfindex = ((now - xhci->mfindex_start) / 125000) & 0x3fff; ++ left = 0x4000 - mfindex; ++ qemu_mod_timer(xhci->mfwrap_timer, now + left * 125000); ++ } else { ++ qemu_del_timer(xhci->mfwrap_timer); ++ } ++} ++ ++static void xhci_mfwrap_timer(void *opaque) ++{ ++ XHCIState *xhci = opaque; ++ XHCIEvent wrap = { ER_MFINDEX_WRAP, CC_SUCCESS }; ++ ++ xhci_event(xhci, &wrap); ++ xhci_mfwrap_update(xhci); ++} + + static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high) + { +@@ -793,6 +827,7 @@ static void xhci_run(XHCIState *xhci) + { + trace_usb_xhci_run(); + xhci->usbsts &= ~USBSTS_HCH; ++ xhci->mfindex_start = qemu_get_clock_ns(vm_clock); + } + + static void xhci_stop(XHCIState *xhci) +@@ -2048,7 +2083,6 @@ static void xhci_reset(DeviceState *dev) + xhci_update_port(xhci, xhci->ports + i, 0); + } + +- xhci->mfindex = 0; + xhci->iman = 0; + xhci->imod = 0; + xhci->erstsz = 0; +@@ -2062,6 +2096,9 @@ static void xhci_reset(DeviceState *dev) + xhci->er_full = 0; + xhci->ev_buffer_put = 0; + xhci->ev_buffer_get = 0; ++ ++ xhci->mfindex_start = qemu_get_clock_ns(vm_clock); ++ xhci_mfwrap_update(xhci); + } + + static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) +@@ -2264,6 +2301,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) + xhci_stop(xhci); + } + xhci->usbcmd = val & 0xc0f; ++ xhci_mfwrap_update(xhci); + if (val & USBCMD_HCRST) { + xhci_reset(&xhci->pci_dev.qdev); + } +@@ -2315,8 +2353,7 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + + switch (reg) { + case 0x00: /* MFINDEX */ +- fprintf(stderr, "xhci_runtime_read: MFINDEX not yet implemented\n"); +- ret = xhci->mfindex; ++ ret = xhci_mfindex_get(xhci) & 0x3fff; + break; + case 0x20: /* IMAN */ + ret = xhci->iman; +@@ -2618,6 +2655,8 @@ static int usb_xhci_initfn(struct PCIDevice *dev) + + usb_xhci_init(xhci, &dev->qdev); + ++ xhci->mfwrap_timer = qemu_new_timer_ns(vm_clock, xhci_mfwrap_timer, xhci); ++ + xhci->irq = xhci->pci_dev.irq[0]; + + memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci, diff --git a/0607-xhci-iso-xfer-support.patch b/0607-xhci-iso-xfer-support.patch deleted file mode 100644 index acaee96..0000000 --- a/0607-xhci-iso-xfer-support.patch +++ /dev/null @@ -1,238 +0,0 @@ -From 82508212e19333e527b64fb76cd1bc016afacc8a Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 24 Aug 2012 14:13:08 +0200 -Subject: [PATCH] xhci: iso xfer support - -Add support for iso transfers. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 101 insertions(+), 16 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index f5ba6a4..b313330 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -325,9 +325,15 @@ typedef struct XHCITransfer { - unsigned int pkts; - unsigned int pktsize; - unsigned int cur_pkt; -+ -+ uint64_t mfindex_kick; - } XHCITransfer; - - typedef struct XHCIEPContext { -+ XHCIState *xhci; -+ unsigned int slotid; -+ unsigned int epid; -+ - XHCIRing ring; - unsigned int next_xfer; - unsigned int comp_xfer; -@@ -337,6 +343,11 @@ typedef struct XHCIEPContext { - dma_addr_t pctx; - unsigned int max_psize; - uint32_t state; -+ -+ /* iso xfer scheduling */ -+ unsigned int interval; -+ int64_t mfindex_last; -+ QEMUTimer *kick_timer; - } XHCIEPContext; - - typedef struct XHCISlot { -@@ -856,6 +867,12 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx, - epctx->state = state; - } - -+static void xhci_ep_kick_timer(void *opaque) -+{ -+ XHCIEPContext *epctx = opaque; -+ xhci_kick_ep(epctx->xhci, epctx->slotid, epctx->epid); -+} -+ - static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, - unsigned int epid, dma_addr_t pctx, - uint32_t *ctx) -@@ -877,6 +894,9 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, - - epctx = g_malloc(sizeof(XHCIEPContext)); - memset(epctx, 0, sizeof(XHCIEPContext)); -+ epctx->xhci = xhci; -+ epctx->slotid = slotid; -+ epctx->epid = epid; - - slot->eps[epid-1] = epctx; - -@@ -895,6 +915,10 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, - usb_packet_init(&epctx->transfers[i].packet); - } - -+ epctx->interval = 1 << (ctx[0] >> 16) & 0xff; -+ epctx->mfindex_last = 0; -+ epctx->kick_timer = qemu_new_timer_ns(vm_clock, xhci_ep_kick_timer, epctx); -+ - epctx->state = EP_RUNNING; - ctx[0] &= ~EP_STATE_MASK; - ctx[0] |= EP_RUNNING; -@@ -934,6 +958,7 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid, - if (t->running_retry) { - t->running_retry = 0; - epctx->retry = NULL; -+ qemu_del_timer(epctx->kick_timer); - } - if (t->trbs) { - g_free(t->trbs); -@@ -969,6 +994,7 @@ static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid, - - xhci_set_ep_state(xhci, epctx, EP_DISABLED); - -+ qemu_free_timer(epctx->kick_timer); - g_free(epctx); - slot->eps[epid-1] = NULL; - -@@ -1376,29 +1402,70 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) - return 0; - } - -+static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer, -+ XHCIEPContext *epctx, uint64_t mfindex) -+{ -+ if (xfer->trbs[0].control & TRB_TR_SIA) { -+ uint64_t asap = ((mfindex + epctx->interval - 1) & -+ ~(epctx->interval-1)); -+ if (asap >= epctx->mfindex_last && -+ asap <= epctx->mfindex_last + epctx->interval * 4) { -+ xfer->mfindex_kick = epctx->mfindex_last + epctx->interval; -+ } else { -+ xfer->mfindex_kick = asap; -+ } -+ } else { -+ xfer->mfindex_kick = (xfer->trbs[0].control >> TRB_TR_FRAMEID_SHIFT) -+ & TRB_TR_FRAMEID_MASK; -+ xfer->mfindex_kick |= mfindex & ~0x3fff; -+ if (xfer->mfindex_kick < mfindex) { -+ xfer->mfindex_kick += 0x4000; -+ } -+ } -+} -+ -+static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer, -+ XHCIEPContext *epctx, uint64_t mfindex) -+{ -+ if (xfer->mfindex_kick > mfindex) { -+ qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock) + -+ (xfer->mfindex_kick - mfindex) * 125000); -+ xfer->running_retry = 1; -+ } else { -+ epctx->mfindex_last = xfer->mfindex_kick; -+ qemu_del_timer(epctx->kick_timer); -+ xfer->running_retry = 0; -+ } -+} -+ -+ - static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx) - { -+ uint64_t mfindex; - int ret; - - DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); - - xfer->in_xfer = epctx->type>>2; - -- if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) { -- xfer->pkts = 1; -- } else { -- xfer->pkts = 0; -- } -- - switch(epctx->type) { - case ET_INTR_OUT: - case ET_INTR_IN: - case ET_BULK_OUT: - case ET_BULK_IN: -+ xfer->pkts = 0; -+ xfer->iso_xfer = false; - break; - case ET_ISO_OUT: - case ET_ISO_IN: -- FIXME(); -+ xfer->pkts = 1; -+ xfer->iso_xfer = true; -+ mfindex = xhci_mfindex_get(xhci); -+ xhci_calc_iso_kick(xhci, xfer, epctx, mfindex); -+ xhci_check_iso_kick(xhci, xfer, epctx, mfindex); -+ if (xfer->running_retry) { -+ return -1; -+ } - break; - default: - fprintf(stderr, "xhci: unknown or unhandled EP " -@@ -1428,6 +1495,7 @@ static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext - static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid) - { - XHCIEPContext *epctx; -+ uint64_t mfindex; - int length; - int i; - -@@ -1447,20 +1515,35 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid - } - - if (epctx->retry) { -- /* retry nak'ed transfer */ - XHCITransfer *xfer = epctx->retry; - int result; - - trace_usb_xhci_xfer_retry(xfer); - assert(xfer->running_retry); -- if (xhci_setup_packet(xfer) < 0) { -- return; -- } -- result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); -- if (result == USB_RET_NAK) { -- return; -+ if (xfer->iso_xfer) { -+ /* retry delayed iso transfer */ -+ mfindex = xhci_mfindex_get(xhci); -+ xhci_check_iso_kick(xhci, xfer, epctx, mfindex); -+ if (xfer->running_retry) { -+ return; -+ } -+ if (xhci_setup_packet(xfer) < 0) { -+ return; -+ } -+ result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); -+ assert(result != USB_RET_NAK); -+ xhci_complete_packet(xfer, result); -+ } else { -+ /* retry nak'ed transfer */ -+ if (xhci_setup_packet(xfer) < 0) { -+ return; -+ } -+ result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); -+ if (result == USB_RET_NAK) { -+ return; -+ } -+ xhci_complete_packet(xfer, result); - } -- xhci_complete_packet(xfer, result); - assert(!xfer->running_retry); - epctx->retry = NULL; - } -@@ -1512,7 +1595,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid - if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) { - epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE; - } else { -- fprintf(stderr, "xhci: error firing data transfer\n"); -+ if (!xfer->iso_xfer) { -+ fprintf(stderr, "xhci: error firing data transfer\n"); -+ } - } - } - --- -1.7.12.1 - diff --git a/0608-xhci-iso-xfer-support.patch b/0608-xhci-iso-xfer-support.patch new file mode 100644 index 0000000..b2f77e7 --- /dev/null +++ b/0608-xhci-iso-xfer-support.patch @@ -0,0 +1,235 @@ +From c578154e75f7dc2433bcde4180320b0bfd884e62 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 24 Aug 2012 14:13:08 +0200 +Subject: [PATCH] xhci: iso xfer support + +Add support for iso transfers. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 101 insertions(+), 16 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 88f71fc..f3f1d61 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -325,9 +325,15 @@ typedef struct XHCITransfer { + unsigned int pkts; + unsigned int pktsize; + unsigned int cur_pkt; ++ ++ uint64_t mfindex_kick; + } XHCITransfer; + + typedef struct XHCIEPContext { ++ XHCIState *xhci; ++ unsigned int slotid; ++ unsigned int epid; ++ + XHCIRing ring; + unsigned int next_xfer; + unsigned int comp_xfer; +@@ -337,6 +343,11 @@ typedef struct XHCIEPContext { + dma_addr_t pctx; + unsigned int max_psize; + uint32_t state; ++ ++ /* iso xfer scheduling */ ++ unsigned int interval; ++ int64_t mfindex_last; ++ QEMUTimer *kick_timer; + } XHCIEPContext; + + typedef struct XHCISlot { +@@ -856,6 +867,12 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx, + epctx->state = state; + } + ++static void xhci_ep_kick_timer(void *opaque) ++{ ++ XHCIEPContext *epctx = opaque; ++ xhci_kick_ep(epctx->xhci, epctx->slotid, epctx->epid); ++} ++ + static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, + unsigned int epid, dma_addr_t pctx, + uint32_t *ctx) +@@ -877,6 +894,9 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, + + epctx = g_malloc(sizeof(XHCIEPContext)); + memset(epctx, 0, sizeof(XHCIEPContext)); ++ epctx->xhci = xhci; ++ epctx->slotid = slotid; ++ epctx->epid = epid; + + slot->eps[epid-1] = epctx; + +@@ -895,6 +915,10 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, + usb_packet_init(&epctx->transfers[i].packet); + } + ++ epctx->interval = 1 << (ctx[0] >> 16) & 0xff; ++ epctx->mfindex_last = 0; ++ epctx->kick_timer = qemu_new_timer_ns(vm_clock, xhci_ep_kick_timer, epctx); ++ + epctx->state = EP_RUNNING; + ctx[0] &= ~EP_STATE_MASK; + ctx[0] |= EP_RUNNING; +@@ -934,6 +958,7 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid, + if (t->running_retry) { + t->running_retry = 0; + epctx->retry = NULL; ++ qemu_del_timer(epctx->kick_timer); + } + if (t->trbs) { + g_free(t->trbs); +@@ -969,6 +994,7 @@ static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid, + + xhci_set_ep_state(xhci, epctx, EP_DISABLED); + ++ qemu_free_timer(epctx->kick_timer); + g_free(epctx); + slot->eps[epid-1] = NULL; + +@@ -1376,29 +1402,70 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) + return 0; + } + ++static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer, ++ XHCIEPContext *epctx, uint64_t mfindex) ++{ ++ if (xfer->trbs[0].control & TRB_TR_SIA) { ++ uint64_t asap = ((mfindex + epctx->interval - 1) & ++ ~(epctx->interval-1)); ++ if (asap >= epctx->mfindex_last && ++ asap <= epctx->mfindex_last + epctx->interval * 4) { ++ xfer->mfindex_kick = epctx->mfindex_last + epctx->interval; ++ } else { ++ xfer->mfindex_kick = asap; ++ } ++ } else { ++ xfer->mfindex_kick = (xfer->trbs[0].control >> TRB_TR_FRAMEID_SHIFT) ++ & TRB_TR_FRAMEID_MASK; ++ xfer->mfindex_kick |= mfindex & ~0x3fff; ++ if (xfer->mfindex_kick < mfindex) { ++ xfer->mfindex_kick += 0x4000; ++ } ++ } ++} ++ ++static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer, ++ XHCIEPContext *epctx, uint64_t mfindex) ++{ ++ if (xfer->mfindex_kick > mfindex) { ++ qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock) + ++ (xfer->mfindex_kick - mfindex) * 125000); ++ xfer->running_retry = 1; ++ } else { ++ epctx->mfindex_last = xfer->mfindex_kick; ++ qemu_del_timer(epctx->kick_timer); ++ xfer->running_retry = 0; ++ } ++} ++ ++ + static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx) + { ++ uint64_t mfindex; + int ret; + + DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); + + xfer->in_xfer = epctx->type>>2; + +- if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) { +- xfer->pkts = 1; +- } else { +- xfer->pkts = 0; +- } +- + switch(epctx->type) { + case ET_INTR_OUT: + case ET_INTR_IN: + case ET_BULK_OUT: + case ET_BULK_IN: ++ xfer->pkts = 0; ++ xfer->iso_xfer = false; + break; + case ET_ISO_OUT: + case ET_ISO_IN: +- FIXME(); ++ xfer->pkts = 1; ++ xfer->iso_xfer = true; ++ mfindex = xhci_mfindex_get(xhci); ++ xhci_calc_iso_kick(xhci, xfer, epctx, mfindex); ++ xhci_check_iso_kick(xhci, xfer, epctx, mfindex); ++ if (xfer->running_retry) { ++ return -1; ++ } + break; + default: + fprintf(stderr, "xhci: unknown or unhandled EP " +@@ -1428,6 +1495,7 @@ static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext + static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid) + { + XHCIEPContext *epctx; ++ uint64_t mfindex; + int length; + int i; + +@@ -1447,20 +1515,35 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid + } + + if (epctx->retry) { +- /* retry nak'ed transfer */ + XHCITransfer *xfer = epctx->retry; + int result; + + trace_usb_xhci_xfer_retry(xfer); + assert(xfer->running_retry); +- if (xhci_setup_packet(xfer) < 0) { +- return; +- } +- result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); +- if (result == USB_RET_NAK) { +- return; ++ if (xfer->iso_xfer) { ++ /* retry delayed iso transfer */ ++ mfindex = xhci_mfindex_get(xhci); ++ xhci_check_iso_kick(xhci, xfer, epctx, mfindex); ++ if (xfer->running_retry) { ++ return; ++ } ++ if (xhci_setup_packet(xfer) < 0) { ++ return; ++ } ++ result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); ++ assert(result != USB_RET_NAK); ++ xhci_complete_packet(xfer, result); ++ } else { ++ /* retry nak'ed transfer */ ++ if (xhci_setup_packet(xfer) < 0) { ++ return; ++ } ++ result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); ++ if (result == USB_RET_NAK) { ++ return; ++ } ++ xhci_complete_packet(xfer, result); + } +- xhci_complete_packet(xfer, result); + assert(!xfer->running_retry); + epctx->retry = NULL; + } +@@ -1512,7 +1595,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid + if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) { + epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE; + } else { +- fprintf(stderr, "xhci: error firing data transfer\n"); ++ if (!xfer->iso_xfer) { ++ fprintf(stderr, "xhci: error firing data transfer\n"); ++ } + } + } + diff --git a/0608-xhci-trace-cc-codes-in-cleartext.patch b/0608-xhci-trace-cc-codes-in-cleartext.patch deleted file mode 100644 index b2b70f6..0000000 --- a/0608-xhci-trace-cc-codes-in-cleartext.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 188fbd363df2e7f23ea37fb1b179e984bbce39e5 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 27 Aug 2012 16:09:20 +0200 -Subject: [PATCH] xhci: trace cc codes in cleartext - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- - trace-events | 2 +- - 2 files changed, 48 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index b313330..ab352c0 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -465,6 +465,45 @@ static const char *TRBType_names[] = { - [CR_VENDOR_NEC_CHALLENGE_RESPONSE] = "CR_VENDOR_NEC_CHALLENGE_RESPONSE", - }; - -+static const char *TRBCCode_names[] = { -+ [CC_INVALID] = "CC_INVALID", -+ [CC_SUCCESS] = "CC_SUCCESS", -+ [CC_DATA_BUFFER_ERROR] = "CC_DATA_BUFFER_ERROR", -+ [CC_BABBLE_DETECTED] = "CC_BABBLE_DETECTED", -+ [CC_USB_TRANSACTION_ERROR] = "CC_USB_TRANSACTION_ERROR", -+ [CC_TRB_ERROR] = "CC_TRB_ERROR", -+ [CC_STALL_ERROR] = "CC_STALL_ERROR", -+ [CC_RESOURCE_ERROR] = "CC_RESOURCE_ERROR", -+ [CC_BANDWIDTH_ERROR] = "CC_BANDWIDTH_ERROR", -+ [CC_NO_SLOTS_ERROR] = "CC_NO_SLOTS_ERROR", -+ [CC_INVALID_STREAM_TYPE_ERROR] = "CC_INVALID_STREAM_TYPE_ERROR", -+ [CC_SLOT_NOT_ENABLED_ERROR] = "CC_SLOT_NOT_ENABLED_ERROR", -+ [CC_EP_NOT_ENABLED_ERROR] = "CC_EP_NOT_ENABLED_ERROR", -+ [CC_SHORT_PACKET] = "CC_SHORT_PACKET", -+ [CC_RING_UNDERRUN] = "CC_RING_UNDERRUN", -+ [CC_RING_OVERRUN] = "CC_RING_OVERRUN", -+ [CC_VF_ER_FULL] = "CC_VF_ER_FULL", -+ [CC_PARAMETER_ERROR] = "CC_PARAMETER_ERROR", -+ [CC_BANDWIDTH_OVERRUN] = "CC_BANDWIDTH_OVERRUN", -+ [CC_CONTEXT_STATE_ERROR] = "CC_CONTEXT_STATE_ERROR", -+ [CC_NO_PING_RESPONSE_ERROR] = "CC_NO_PING_RESPONSE_ERROR", -+ [CC_EVENT_RING_FULL_ERROR] = "CC_EVENT_RING_FULL_ERROR", -+ [CC_INCOMPATIBLE_DEVICE_ERROR] = "CC_INCOMPATIBLE_DEVICE_ERROR", -+ [CC_MISSED_SERVICE_ERROR] = "CC_MISSED_SERVICE_ERROR", -+ [CC_COMMAND_RING_STOPPED] = "CC_COMMAND_RING_STOPPED", -+ [CC_COMMAND_ABORTED] = "CC_COMMAND_ABORTED", -+ [CC_STOPPED] = "CC_STOPPED", -+ [CC_STOPPED_LENGTH_INVALID] = "CC_STOPPED_LENGTH_INVALID", -+ [CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR] -+ = "CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR", -+ [CC_ISOCH_BUFFER_OVERRUN] = "CC_ISOCH_BUFFER_OVERRUN", -+ [CC_EVENT_LOST_ERROR] = "CC_EVENT_LOST_ERROR", -+ [CC_UNDEFINED_ERROR] = "CC_UNDEFINED_ERROR", -+ [CC_INVALID_STREAM_ID_ERROR] = "CC_INVALID_STREAM_ID_ERROR", -+ [CC_SECONDARY_BANDWIDTH_ERROR] = "CC_SECONDARY_BANDWIDTH_ERROR", -+ [CC_SPLIT_TRANSACTION_ERROR] = "CC_SPLIT_TRANSACTION_ERROR", -+}; -+ - static const char *lookup_name(uint32_t index, const char **list, uint32_t llen) - { - if (index >= llen || list[index] == NULL) { -@@ -479,6 +518,12 @@ static const char *trb_name(XHCITRB *trb) - ARRAY_SIZE(TRBType_names)); - } - -+static const char *event_name(XHCIEvent *event) -+{ -+ return lookup_name(event->ccode, TRBCCode_names, -+ ARRAY_SIZE(TRBCCode_names)); -+} -+ - static uint64_t xhci_mfindex_get(XHCIState *xhci) - { - int64_t now = qemu_get_clock_ns(vm_clock); -@@ -574,7 +619,8 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) - ev_trb.control = cpu_to_le32(ev_trb.control); - - trace_usb_xhci_queue_event(xhci->er_ep_idx, trb_name(&ev_trb), -- ev_trb.parameter, ev_trb.status, ev_trb.control); -+ event_name(event), ev_trb.parameter, -+ ev_trb.status, ev_trb.control); - - addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; - pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE); -diff --git a/trace-events b/trace-events -index 07b63f1..b38e32a 100644 ---- a/trace-events -+++ b/trace-events -@@ -316,7 +316,7 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" - usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" - usb_xhci_irq_intx(uint32_t level) "level %d" - usb_xhci_irq_msi(uint32_t nr) "nr %d" --usb_xhci_queue_event(uint32_t idx, const char *name, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, p %016" PRIx64 ", s %08x, c 0x%08x" -+usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" - usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" - usb_xhci_slot_enable(uint32_t slotid) "slotid %d" - usb_xhci_slot_disable(uint32_t slotid) "slotid %d" --- -1.7.12.1 - diff --git a/0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch b/0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch deleted file mode 100644 index 7a07da9..0000000 --- a/0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 10a1380a50e33f98d5030d75d9d356f7ce024556 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 29 Aug 2012 12:54:59 +0200 -Subject: [PATCH] xhci: add trace_usb_xhci_ep_set_dequeue - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 2 +- - trace-events | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index ab352c0..c6ab4a1 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -1145,7 +1145,7 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid, - return CC_TRB_ERROR; - } - -- DPRINTF("xhci_set_ep_dequeue(%d, %d, %016"PRIx64")\n", slotid, epid, pdequeue); -+ trace_usb_xhci_ep_set_dequeue(slotid, epid, pdequeue); - dequeue = xhci_mask64(pdequeue); - - slot = &xhci->slots[slotid-1]; -diff --git a/trace-events b/trace-events -index b38e32a..2db1deb 100644 ---- a/trace-events -+++ b/trace-events -@@ -326,6 +326,7 @@ usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d" - usb_xhci_slot_reset(uint32_t slotid) "slotid %d" - usb_xhci_ep_enable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" - usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" -+usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint64_t param) "slotid %d, epid %d, ptr %016" PRIx64 - usb_xhci_ep_kick(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" - usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" - usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" --- -1.7.12.1 - diff --git a/0609-xhci-trace-cc-codes-in-cleartext.patch b/0609-xhci-trace-cc-codes-in-cleartext.patch new file mode 100644 index 0000000..8dd6dbd --- /dev/null +++ b/0609-xhci-trace-cc-codes-in-cleartext.patch @@ -0,0 +1,97 @@ +From f98ec7477ad72305a10d392a0b043df9192620ab Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 27 Aug 2012 16:09:20 +0200 +Subject: [PATCH] xhci: trace cc codes in cleartext + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- + trace-events | 2 +- + 2 files changed, 48 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index f3f1d61..ad2226f 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -465,6 +465,45 @@ static const char *TRBType_names[] = { + [CR_VENDOR_NEC_CHALLENGE_RESPONSE] = "CR_VENDOR_NEC_CHALLENGE_RESPONSE", + }; + ++static const char *TRBCCode_names[] = { ++ [CC_INVALID] = "CC_INVALID", ++ [CC_SUCCESS] = "CC_SUCCESS", ++ [CC_DATA_BUFFER_ERROR] = "CC_DATA_BUFFER_ERROR", ++ [CC_BABBLE_DETECTED] = "CC_BABBLE_DETECTED", ++ [CC_USB_TRANSACTION_ERROR] = "CC_USB_TRANSACTION_ERROR", ++ [CC_TRB_ERROR] = "CC_TRB_ERROR", ++ [CC_STALL_ERROR] = "CC_STALL_ERROR", ++ [CC_RESOURCE_ERROR] = "CC_RESOURCE_ERROR", ++ [CC_BANDWIDTH_ERROR] = "CC_BANDWIDTH_ERROR", ++ [CC_NO_SLOTS_ERROR] = "CC_NO_SLOTS_ERROR", ++ [CC_INVALID_STREAM_TYPE_ERROR] = "CC_INVALID_STREAM_TYPE_ERROR", ++ [CC_SLOT_NOT_ENABLED_ERROR] = "CC_SLOT_NOT_ENABLED_ERROR", ++ [CC_EP_NOT_ENABLED_ERROR] = "CC_EP_NOT_ENABLED_ERROR", ++ [CC_SHORT_PACKET] = "CC_SHORT_PACKET", ++ [CC_RING_UNDERRUN] = "CC_RING_UNDERRUN", ++ [CC_RING_OVERRUN] = "CC_RING_OVERRUN", ++ [CC_VF_ER_FULL] = "CC_VF_ER_FULL", ++ [CC_PARAMETER_ERROR] = "CC_PARAMETER_ERROR", ++ [CC_BANDWIDTH_OVERRUN] = "CC_BANDWIDTH_OVERRUN", ++ [CC_CONTEXT_STATE_ERROR] = "CC_CONTEXT_STATE_ERROR", ++ [CC_NO_PING_RESPONSE_ERROR] = "CC_NO_PING_RESPONSE_ERROR", ++ [CC_EVENT_RING_FULL_ERROR] = "CC_EVENT_RING_FULL_ERROR", ++ [CC_INCOMPATIBLE_DEVICE_ERROR] = "CC_INCOMPATIBLE_DEVICE_ERROR", ++ [CC_MISSED_SERVICE_ERROR] = "CC_MISSED_SERVICE_ERROR", ++ [CC_COMMAND_RING_STOPPED] = "CC_COMMAND_RING_STOPPED", ++ [CC_COMMAND_ABORTED] = "CC_COMMAND_ABORTED", ++ [CC_STOPPED] = "CC_STOPPED", ++ [CC_STOPPED_LENGTH_INVALID] = "CC_STOPPED_LENGTH_INVALID", ++ [CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR] ++ = "CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR", ++ [CC_ISOCH_BUFFER_OVERRUN] = "CC_ISOCH_BUFFER_OVERRUN", ++ [CC_EVENT_LOST_ERROR] = "CC_EVENT_LOST_ERROR", ++ [CC_UNDEFINED_ERROR] = "CC_UNDEFINED_ERROR", ++ [CC_INVALID_STREAM_ID_ERROR] = "CC_INVALID_STREAM_ID_ERROR", ++ [CC_SECONDARY_BANDWIDTH_ERROR] = "CC_SECONDARY_BANDWIDTH_ERROR", ++ [CC_SPLIT_TRANSACTION_ERROR] = "CC_SPLIT_TRANSACTION_ERROR", ++}; ++ + static const char *lookup_name(uint32_t index, const char **list, uint32_t llen) + { + if (index >= llen || list[index] == NULL) { +@@ -479,6 +518,12 @@ static const char *trb_name(XHCITRB *trb) + ARRAY_SIZE(TRBType_names)); + } + ++static const char *event_name(XHCIEvent *event) ++{ ++ return lookup_name(event->ccode, TRBCCode_names, ++ ARRAY_SIZE(TRBCCode_names)); ++} ++ + static uint64_t xhci_mfindex_get(XHCIState *xhci) + { + int64_t now = qemu_get_clock_ns(vm_clock); +@@ -574,7 +619,8 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) + ev_trb.control = cpu_to_le32(ev_trb.control); + + trace_usb_xhci_queue_event(xhci->er_ep_idx, trb_name(&ev_trb), +- ev_trb.parameter, ev_trb.status, ev_trb.control); ++ event_name(event), ev_trb.parameter, ++ ev_trb.status, ev_trb.control); + + addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; + pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE); +diff --git a/trace-events b/trace-events +index 992aef1..9fa7673 100644 +--- a/trace-events ++++ b/trace-events +@@ -316,7 +316,7 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" + usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" + usb_xhci_irq_intx(uint32_t level) "level %d" + usb_xhci_irq_msi(uint32_t nr) "nr %d" +-usb_xhci_queue_event(uint32_t idx, const char *name, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, p %016" PRIx64 ", s %08x, c 0x%08x" ++usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" + usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" + usb_xhci_slot_enable(uint32_t slotid) "slotid %d" + usb_xhci_slot_disable(uint32_t slotid) "slotid %d" diff --git a/0610-xhci-add-trace_usb_xhci_ep_set_dequeue.patch b/0610-xhci-add-trace_usb_xhci_ep_set_dequeue.patch new file mode 100644 index 0000000..0209424 --- /dev/null +++ b/0610-xhci-add-trace_usb_xhci_ep_set_dequeue.patch @@ -0,0 +1,36 @@ +From ef91b4721df38d041867d43300583321119c92e0 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 29 Aug 2012 12:54:59 +0200 +Subject: [PATCH] xhci: add trace_usb_xhci_ep_set_dequeue + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 2 +- + trace-events | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index ad2226f..a938ad3 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -1145,7 +1145,7 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid, + return CC_TRB_ERROR; + } + +- DPRINTF("xhci_set_ep_dequeue(%d, %d, %016"PRIx64")\n", slotid, epid, pdequeue); ++ trace_usb_xhci_ep_set_dequeue(slotid, epid, pdequeue); + dequeue = xhci_mask64(pdequeue); + + slot = &xhci->slots[slotid-1]; +diff --git a/trace-events b/trace-events +index 9fa7673..7b9cc9e 100644 +--- a/trace-events ++++ b/trace-events +@@ -326,6 +326,7 @@ usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d" + usb_xhci_slot_reset(uint32_t slotid) "slotid %d" + usb_xhci_ep_enable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" + usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" ++usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint64_t param) "slotid %d, epid %d, ptr %016" PRIx64 + usb_xhci_ep_kick(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" + usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" + usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d" diff --git a/0610-xhci-update-register-layout.patch b/0610-xhci-update-register-layout.patch deleted file mode 100644 index 6052e50..0000000 --- a/0610-xhci-update-register-layout.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 79e9a5ca778bfcb67073bfecd3f7cea7d93781ce Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 23 Aug 2012 13:26:25 +0200 -Subject: [PATCH] xhci: update register layout - -Change the register layout to be a bit more sparse and also not depend -on the number of ports. Useful when for making the number of ports -runtime-configurable. ---- - hw/usb/hcd-xhci.c | 21 +++++++++++++-------- - 1 file changed, 13 insertions(+), 8 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index c6ab4a1..d47539d 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -36,13 +36,12 @@ - #define FIXME() do { fprintf(stderr, "FIXME %s:%d\n", \ - __func__, __LINE__); abort(); } while (0) - --#define MAXSLOTS 8 --#define MAXINTRS 1 -- - #define USB2_PORTS 4 - #define USB3_PORTS 4 - - #define MAXPORTS (USB2_PORTS+USB3_PORTS) -+#define MAXSLOTS MAXPORTS -+#define MAXINTRS 1 /* MAXPORTS */ - - #define TD_QUEUE 24 - -@@ -53,16 +52,22 @@ - #define ER_FULL_HACK - - #define LEN_CAP 0x40 --#define OFF_OPER LEN_CAP - #define LEN_OPER (0x400 + 0x10 * MAXPORTS) --#define OFF_RUNTIME ((OFF_OPER + LEN_OPER + 0x20) & ~0x1f) --#define LEN_RUNTIME (0x20 + MAXINTRS * 0x20) --#define OFF_DOORBELL (OFF_RUNTIME + LEN_RUNTIME) -+#define LEN_RUNTIME ((MAXINTRS + 1) * 0x20) - #define LEN_DOORBELL ((MAXSLOTS + 1) * 0x20) - -+#define OFF_OPER LEN_CAP -+#define OFF_RUNTIME 0x1000 -+#define OFF_DOORBELL 0x2000 - /* must be power of 2 */ --#define LEN_REGS 0x2000 -+#define LEN_REGS 0x4000 - -+#if (OFF_OPER + LEN_OPER) > OFF_RUNTIME -+#error Increase OFF_RUNTIME -+#endif -+#if (OFF_RUNTIME + LEN_RUNTIME) > OFF_DOORBELL -+#error Increase OFF_DOORBELL -+#endif - #if (OFF_DOORBELL + LEN_DOORBELL) > LEN_REGS - # error Increase LEN_REGS - #endif --- -1.7.12.1 - diff --git a/0611-xhci-update-port-handling.patch b/0611-xhci-update-port-handling.patch deleted file mode 100644 index d47740a..0000000 --- a/0611-xhci-update-port-handling.patch +++ /dev/null @@ -1,352 +0,0 @@ -From 0b1ccd39faa8d1ea71f2d02dbab5dfd13f54ac98 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 28 Aug 2012 13:38:01 +0200 -Subject: [PATCH] xhci: update port handling - -This patch changes the way xhci ports are linked to USBPorts. The fixed -1:1 relationship between xhci ports and USBPorts is gone. Now each -USBPort represents a physical plug which has usually two xhci ports -assigned: one usb2 and ond usb3 port. usb devices show up at one or the -other, depending on whenever they support superspeed or not. - -This patch also makes the number of usb2 and usb3 ports runtime -configurable by adding 'p2' and 'p3' properties. It is allowed to -have different numbers of usb2 and usb3 ports. Specifying p2=4,p3=2 -will give you an xhci adapter which supports all speeds on physical -ports 1+2 and usb2 only on ports 3+4. ---- - hw/usb/hcd-xhci.c | 137 ++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 97 insertions(+), 40 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index d47539d..5813b4a 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -36,10 +36,10 @@ - #define FIXME() do { fprintf(stderr, "FIXME %s:%d\n", \ - __func__, __LINE__); abort(); } while (0) - --#define USB2_PORTS 4 --#define USB3_PORTS 4 -+#define MAXPORTS_2 8 -+#define MAXPORTS_3 8 - --#define MAXPORTS (USB2_PORTS+USB3_PORTS) -+#define MAXPORTS (MAXPORTS_2+MAXPORTS_3) - #define MAXSLOTS MAXPORTS - #define MAXINTRS 1 /* MAXPORTS */ - -@@ -300,8 +300,10 @@ typedef struct XHCIRing { - } XHCIRing; - - typedef struct XHCIPort { -- USBPort port; - uint32_t portsc; -+ uint32_t portnr; -+ USBPort *uport; -+ uint32_t speedmask; - } XHCIPort; - - struct XHCIState; -@@ -379,9 +381,13 @@ struct XHCIState { - qemu_irq irq; - MemoryRegion mem; - const char *name; -- uint32_t msi; - unsigned int devaddr; - -+ /* properties */ -+ uint32_t numports_2; -+ uint32_t numports_3; -+ uint32_t msi; -+ - /* Operational Registers */ - uint32_t usbcmd; - uint32_t usbsts; -@@ -392,8 +398,10 @@ struct XHCIState { - uint32_t dcbaap_high; - uint32_t config; - -+ USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)]; - XHCIPort ports[MAXPORTS]; - XHCISlot slots[MAXSLOTS]; -+ uint32_t numports; - - /* Runtime Registers */ - uint32_t iman; -@@ -578,6 +586,28 @@ static inline dma_addr_t xhci_mask64(uint64_t addr) - } - } - -+static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport) -+{ -+ int index; -+ -+ if (!uport->dev) { -+ return NULL; -+ } -+ switch (uport->dev->speed) { -+ case USB_SPEED_LOW: -+ case USB_SPEED_FULL: -+ case USB_SPEED_HIGH: -+ index = uport->index; -+ break; -+ case USB_SPEED_SUPER: -+ index = uport->index + xhci->numports_2; -+ break; -+ default: -+ return NULL; -+ } -+ return &xhci->ports[index]; -+} -+ - static void xhci_irq_update(XHCIState *xhci) - { - int level = 0; -@@ -1126,7 +1156,7 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid, - ep |= 0x80; - } - -- dev = xhci->ports[xhci->slots[slotid-1].port-1].port.dev; -+ dev = xhci->ports[xhci->slots[slotid-1].port-1].uport->dev; - if (!dev) { - return CC_USB_TRANSACTION_ERROR; - } -@@ -1313,7 +1343,7 @@ static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) - if (!(port->portsc & PORTSC_PED)) { - return NULL; - } -- return usb_find_device(&port->port, addr); -+ return usb_find_device(port->uport, addr); - } - - static int xhci_setup_packet(XHCITransfer *xfer) -@@ -1734,9 +1764,9 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, - ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]); - - port = (slot_ctx[1]>>16) & 0xFF; -- dev = xhci->ports[port-1].port.dev; -+ dev = xhci->ports[port-1].uport->dev; - -- if (port < 1 || port > MAXPORTS) { -+ if (port < 1 || port > xhci->numports) { - fprintf(stderr, "xhci: bad port %d\n", port); - return CC_TRB_ERROR; - } else if (!dev) { -@@ -1985,7 +2015,7 @@ static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *tr - static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) - { - dma_addr_t ctx; -- uint8_t bw_ctx[MAXPORTS+1]; -+ uint8_t bw_ctx[xhci->numports+1]; - - DPRINTF("xhci_get_port_bandwidth()\n"); - -@@ -1995,7 +2025,7 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) - - /* TODO: actually implement real values here */ - bw_ctx[0] = 0; -- memset(&bw_ctx[1], 80, MAXPORTS); /* 80% */ -+ memset(&bw_ctx[1], 80, xhci->numports); /* 80% */ - pci_dma_write(&xhci->pci_dev, ctx, bw_ctx, sizeof(bw_ctx)); - - return CC_SUCCESS; -@@ -2165,12 +2195,11 @@ static void xhci_process_commands(XHCIState *xhci) - - static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) - { -- int nr = port->port.index + 1; -- - port->portsc = PORTSC_PP; -- if (port->port.dev && port->port.dev->attached && !is_detach) { -+ if (port->uport->dev && port->uport->dev->attached && !is_detach && -+ (1 << port->uport->dev->speed) & port->speedmask) { - port->portsc |= PORTSC_CCS; -- switch (port->port.dev->speed) { -+ switch (port->uport->dev->speed) { - case USB_SPEED_LOW: - port->portsc |= PORTSC_SPEED_LOW; - break; -@@ -2180,14 +2209,18 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) - case USB_SPEED_HIGH: - port->portsc |= PORTSC_SPEED_HIGH; - break; -+ case USB_SPEED_SUPER: -+ port->portsc |= PORTSC_SPEED_SUPER; -+ break; - } - } - - if (xhci_running(xhci)) { - port->portsc |= PORTSC_CSC; -- XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; -+ XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, -+ port->portnr << 24}; - xhci_event(xhci, &ev); -- DPRINTF("xhci: port change event for port %d\n", nr); -+ DPRINTF("xhci: port change event for port %d\n", port->portnr); - } - } - -@@ -2215,7 +2248,7 @@ static void xhci_reset(DeviceState *dev) - xhci_disable_slot(xhci, i+1); - } - -- for (i = 0; i < MAXPORTS; i++) { -+ for (i = 0; i < xhci->numports; i++) { - xhci_update_port(xhci, xhci->ports + i, 0); - } - -@@ -2246,7 +2279,8 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) - ret = 0x01000000 | LEN_CAP; - break; - case 0x04: /* HCSPARAMS 1 */ -- ret = (MAXPORTS<<24) | (MAXINTRS<<8) | MAXSLOTS; -+ ret = ((xhci->numports_2+xhci->numports_3)<<24) -+ | (MAXINTRS<<8) | MAXSLOTS; - break; - case 0x08: /* HCSPARAMS 2 */ - ret = 0x0000000f; -@@ -2276,7 +2310,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) - ret = 0x20425455; /* "USB " */ - break; - case 0x28: /* Supported Protocol:08 */ -- ret = 0x00000001 | (USB2_PORTS<<8); -+ ret = 0x00000001 | (xhci->numports_2<<8); - break; - case 0x2c: /* Supported Protocol:0c */ - ret = 0x00000000; /* reserved */ -@@ -2288,7 +2322,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) - ret = 0x20425455; /* "USB " */ - break; - case 0x38: /* Supported Protocol:08 */ -- ret = 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8); -+ ret = 0x00000000 | (xhci->numports_2+1) | (xhci->numports_3<<8); - break; - case 0x3c: /* Supported Protocol:0c */ - ret = 0x00000000; /* reserved */ -@@ -2307,7 +2341,7 @@ static uint32_t xhci_port_read(XHCIState *xhci, uint32_t reg) - uint32_t port = reg >> 4; - uint32_t ret; - -- if (port >= MAXPORTS) { -+ if (port >= xhci->numports) { - fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); - ret = 0; - goto out; -@@ -2340,7 +2374,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) - - trace_usb_xhci_port_write(port, reg & 0x0f, val); - -- if (port >= MAXPORTS) { -+ if (port >= xhci->numports) { - fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); - return; - } -@@ -2362,7 +2396,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) - /* write-1-to-start bits */ - if (val & PORTSC_PR) { - DPRINTF("xhci: port %d reset\n", port); -- usb_device_reset(xhci->ports[port].port.dev); -+ usb_device_reset(xhci->ports[port].uport->dev); - portsc |= PORTSC_PRC | PORTSC_PED; - } - xhci->ports[port].portsc = portsc; -@@ -2659,7 +2693,7 @@ static const MemoryRegionOps xhci_mem_ops = { - static void xhci_attach(USBPort *usbport) - { - XHCIState *xhci = usbport->opaque; -- XHCIPort *port = &xhci->ports[usbport->index]; -+ XHCIPort *port = xhci_lookup_port(xhci, usbport); - - xhci_update_port(xhci, port, 0); - } -@@ -2667,7 +2701,7 @@ static void xhci_attach(USBPort *usbport) - static void xhci_detach(USBPort *usbport) - { - XHCIState *xhci = usbport->opaque; -- XHCIPort *port = &xhci->ports[usbport->index]; -+ XHCIPort *port = xhci_lookup_port(xhci, usbport); - - xhci_update_port(xhci, port, 1); - } -@@ -2675,9 +2709,9 @@ static void xhci_detach(USBPort *usbport) - static void xhci_wakeup(USBPort *usbport) - { - XHCIState *xhci = usbport->opaque; -- XHCIPort *port = &xhci->ports[usbport->index]; -- int nr = port->port.index + 1; -- XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; -+ XHCIPort *port = xhci_lookup_port(xhci, usbport); -+ XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, -+ port->portnr << 24}; - uint32_t pls; - - pls = (port->portsc >> PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK; -@@ -2759,22 +2793,43 @@ static USBBusOps xhci_bus_ops = { - - static void usb_xhci_init(XHCIState *xhci, DeviceState *dev) - { -- int i; -+ XHCIPort *port; -+ int i, usbports, speedmask; - - xhci->usbsts = USBSTS_HCH; - -+ if (xhci->numports_2 > MAXPORTS_2) { -+ xhci->numports_2 = MAXPORTS_2; -+ } -+ if (xhci->numports_3 > MAXPORTS_3) { -+ xhci->numports_3 = MAXPORTS_3; -+ } -+ usbports = MAX(xhci->numports_2, xhci->numports_3); -+ xhci->numports = xhci->numports_2 + xhci->numports_3; -+ - usb_bus_new(&xhci->bus, &xhci_bus_ops, &xhci->pci_dev.qdev); - -- for (i = 0; i < MAXPORTS; i++) { -- memset(&xhci->ports[i], 0, sizeof(xhci->ports[i])); -- usb_register_port(&xhci->bus, &xhci->ports[i].port, xhci, i, -- &xhci_port_ops, -- USB_SPEED_MASK_LOW | -- USB_SPEED_MASK_FULL | -- USB_SPEED_MASK_HIGH); -- } -- for (i = 0; i < MAXSLOTS; i++) { -- xhci->slots[i].enabled = 0; -+ for (i = 0; i < usbports; i++) { -+ speedmask = 0; -+ if (i < xhci->numports_2) { -+ port = &xhci->ports[i]; -+ port->portnr = i + 1; -+ port->uport = &xhci->uports[i]; -+ port->speedmask = -+ USB_SPEED_MASK_LOW | -+ USB_SPEED_MASK_FULL | -+ USB_SPEED_MASK_HIGH; -+ speedmask |= port->speedmask; -+ } -+ if (i < xhci->numports_3) { -+ port = &xhci->ports[i + xhci->numports_2]; -+ port->portnr = i + 1 + xhci->numports_2; -+ port->uport = &xhci->uports[i]; -+ port->speedmask = USB_SPEED_MASK_SUPER; -+ speedmask |= port->speedmask; -+ } -+ usb_register_port(&xhci->bus, &xhci->uports[i], xhci, i, -+ &xhci_port_ops, speedmask); - } - } - -@@ -2830,6 +2885,8 @@ static const VMStateDescription vmstate_xhci = { - - static Property xhci_properties[] = { - DEFINE_PROP_UINT32("msi", XHCIState, msi, 0), -+ DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), -+ DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), - DEFINE_PROP_END_OF_LIST(), - }; - --- -1.7.12.1 - diff --git a/0611-xhci-update-register-layout.patch b/0611-xhci-update-register-layout.patch new file mode 100644 index 0000000..81f071f --- /dev/null +++ b/0611-xhci-update-register-layout.patch @@ -0,0 +1,60 @@ +From 297556441abec3823fcf362395f2af650e53a631 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 23 Aug 2012 13:26:25 +0200 +Subject: [PATCH] xhci: update register layout + +Change the register layout to be a bit more sparse and also not depend +on the number of ports. Useful when for making the number of ports +runtime-configurable. +--- + hw/usb/hcd-xhci.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index a938ad3..11cb3bc 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -36,13 +36,12 @@ + #define FIXME() do { fprintf(stderr, "FIXME %s:%d\n", \ + __func__, __LINE__); abort(); } while (0) + +-#define MAXSLOTS 8 +-#define MAXINTRS 1 +- + #define USB2_PORTS 4 + #define USB3_PORTS 4 + + #define MAXPORTS (USB2_PORTS+USB3_PORTS) ++#define MAXSLOTS MAXPORTS ++#define MAXINTRS 1 /* MAXPORTS */ + + #define TD_QUEUE 24 + +@@ -53,16 +52,22 @@ + #define ER_FULL_HACK + + #define LEN_CAP 0x40 +-#define OFF_OPER LEN_CAP + #define LEN_OPER (0x400 + 0x10 * MAXPORTS) +-#define OFF_RUNTIME ((OFF_OPER + LEN_OPER + 0x20) & ~0x1f) +-#define LEN_RUNTIME (0x20 + MAXINTRS * 0x20) +-#define OFF_DOORBELL (OFF_RUNTIME + LEN_RUNTIME) ++#define LEN_RUNTIME ((MAXINTRS + 1) * 0x20) + #define LEN_DOORBELL ((MAXSLOTS + 1) * 0x20) + ++#define OFF_OPER LEN_CAP ++#define OFF_RUNTIME 0x1000 ++#define OFF_DOORBELL 0x2000 + /* must be power of 2 */ +-#define LEN_REGS 0x2000 ++#define LEN_REGS 0x4000 + ++#if (OFF_OPER + LEN_OPER) > OFF_RUNTIME ++#error Increase OFF_RUNTIME ++#endif ++#if (OFF_RUNTIME + LEN_RUNTIME) > OFF_DOORBELL ++#error Increase OFF_DOORBELL ++#endif + #if (OFF_DOORBELL + LEN_DOORBELL) > LEN_REGS + # error Increase LEN_REGS + #endif diff --git a/0612-usb3-superspeed-descriptors.patch b/0612-usb3-superspeed-descriptors.patch deleted file mode 100644 index 4c60573..0000000 --- a/0612-usb3-superspeed-descriptors.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 81e37421158a28277c9857ba733da4371cb06129 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 28 Aug 2012 17:28:50 +0200 -Subject: [PATCH] usb3: superspeed descriptors - -Add superspeed descriptor entry to USBDesc, -advertise superspeed support when present. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/desc.c | 10 +++++++++- - hw/usb/desc.h | 1 + - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/hw/usb/desc.c b/hw/usb/desc.c -index 0a9d3c9..3e8c6cb 100644 ---- a/hw/usb/desc.c -+++ b/hw/usb/desc.c -@@ -359,6 +359,9 @@ static void usb_desc_setdefaults(USBDevice *dev) - case USB_SPEED_HIGH: - dev->device = desc->high; - break; -+ case USB_SPEED_SUPER: -+ dev->device = desc->super; -+ break; - } - usb_desc_set_config(dev, 0); - } -@@ -376,6 +379,9 @@ void usb_desc_init(USBDevice *dev) - if (desc->high) { - dev->speedmask |= USB_SPEED_MASK_HIGH; - } -+ if (desc->super) { -+ dev->speedmask |= USB_SPEED_MASK_SUPER; -+ } - usb_desc_setdefaults(dev); - } - -@@ -384,7 +390,9 @@ void usb_desc_attach(USBDevice *dev) - const USBDesc *desc = usb_device_get_usb_desc(dev); - - assert(desc != NULL); -- if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) { -+ if (desc->super && (dev->port->speedmask & USB_SPEED_MASK_SUPER)) { -+ dev->speed = USB_SPEED_SUPER; -+ } else if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) { - dev->speed = USB_SPEED_HIGH; - } else if (desc->full && (dev->port->speedmask & USB_SPEED_MASK_FULL)) { - dev->speed = USB_SPEED_FULL; -diff --git a/hw/usb/desc.h b/hw/usb/desc.h -index 7cf5442..d89fa41 100644 ---- a/hw/usb/desc.h -+++ b/hw/usb/desc.h -@@ -152,6 +152,7 @@ struct USBDesc { - USBDescID id; - const USBDescDevice *full; - const USBDescDevice *high; -+ const USBDescDevice *super; - const char* const *str; - }; - --- -1.7.12.1 - diff --git a/0612-xhci-update-port-handling.patch b/0612-xhci-update-port-handling.patch new file mode 100644 index 0000000..c195f1f --- /dev/null +++ b/0612-xhci-update-port-handling.patch @@ -0,0 +1,349 @@ +From 2ed404cacc625272fb7017476634b77002ee880b Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 28 Aug 2012 13:38:01 +0200 +Subject: [PATCH] xhci: update port handling + +This patch changes the way xhci ports are linked to USBPorts. The fixed +1:1 relationship between xhci ports and USBPorts is gone. Now each +USBPort represents a physical plug which has usually two xhci ports +assigned: one usb2 and ond usb3 port. usb devices show up at one or the +other, depending on whenever they support superspeed or not. + +This patch also makes the number of usb2 and usb3 ports runtime +configurable by adding 'p2' and 'p3' properties. It is allowed to +have different numbers of usb2 and usb3 ports. Specifying p2=4,p3=2 +will give you an xhci adapter which supports all speeds on physical +ports 1+2 and usb2 only on ports 3+4. +--- + hw/usb/hcd-xhci.c | 137 ++++++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 97 insertions(+), 40 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 11cb3bc..642e8e5 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -36,10 +36,10 @@ + #define FIXME() do { fprintf(stderr, "FIXME %s:%d\n", \ + __func__, __LINE__); abort(); } while (0) + +-#define USB2_PORTS 4 +-#define USB3_PORTS 4 ++#define MAXPORTS_2 8 ++#define MAXPORTS_3 8 + +-#define MAXPORTS (USB2_PORTS+USB3_PORTS) ++#define MAXPORTS (MAXPORTS_2+MAXPORTS_3) + #define MAXSLOTS MAXPORTS + #define MAXINTRS 1 /* MAXPORTS */ + +@@ -300,8 +300,10 @@ typedef struct XHCIRing { + } XHCIRing; + + typedef struct XHCIPort { +- USBPort port; + uint32_t portsc; ++ uint32_t portnr; ++ USBPort *uport; ++ uint32_t speedmask; + } XHCIPort; + + struct XHCIState; +@@ -379,9 +381,13 @@ struct XHCIState { + qemu_irq irq; + MemoryRegion mem; + const char *name; +- uint32_t msi; + unsigned int devaddr; + ++ /* properties */ ++ uint32_t numports_2; ++ uint32_t numports_3; ++ uint32_t msi; ++ + /* Operational Registers */ + uint32_t usbcmd; + uint32_t usbsts; +@@ -392,8 +398,10 @@ struct XHCIState { + uint32_t dcbaap_high; + uint32_t config; + ++ USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)]; + XHCIPort ports[MAXPORTS]; + XHCISlot slots[MAXSLOTS]; ++ uint32_t numports; + + /* Runtime Registers */ + uint32_t iman; +@@ -578,6 +586,28 @@ static inline dma_addr_t xhci_mask64(uint64_t addr) + } + } + ++static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport) ++{ ++ int index; ++ ++ if (!uport->dev) { ++ return NULL; ++ } ++ switch (uport->dev->speed) { ++ case USB_SPEED_LOW: ++ case USB_SPEED_FULL: ++ case USB_SPEED_HIGH: ++ index = uport->index; ++ break; ++ case USB_SPEED_SUPER: ++ index = uport->index + xhci->numports_2; ++ break; ++ default: ++ return NULL; ++ } ++ return &xhci->ports[index]; ++} ++ + static void xhci_irq_update(XHCIState *xhci) + { + int level = 0; +@@ -1126,7 +1156,7 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid, + ep |= 0x80; + } + +- dev = xhci->ports[xhci->slots[slotid-1].port-1].port.dev; ++ dev = xhci->ports[xhci->slots[slotid-1].port-1].uport->dev; + if (!dev) { + return CC_USB_TRANSACTION_ERROR; + } +@@ -1313,7 +1343,7 @@ static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) + if (!(port->portsc & PORTSC_PED)) { + return NULL; + } +- return usb_find_device(&port->port, addr); ++ return usb_find_device(port->uport, addr); + } + + static int xhci_setup_packet(XHCITransfer *xfer) +@@ -1734,9 +1764,9 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, + ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]); + + port = (slot_ctx[1]>>16) & 0xFF; +- dev = xhci->ports[port-1].port.dev; ++ dev = xhci->ports[port-1].uport->dev; + +- if (port < 1 || port > MAXPORTS) { ++ if (port < 1 || port > xhci->numports) { + fprintf(stderr, "xhci: bad port %d\n", port); + return CC_TRB_ERROR; + } else if (!dev) { +@@ -1985,7 +2015,7 @@ static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *tr + static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) + { + dma_addr_t ctx; +- uint8_t bw_ctx[MAXPORTS+1]; ++ uint8_t bw_ctx[xhci->numports+1]; + + DPRINTF("xhci_get_port_bandwidth()\n"); + +@@ -1995,7 +2025,7 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) + + /* TODO: actually implement real values here */ + bw_ctx[0] = 0; +- memset(&bw_ctx[1], 80, MAXPORTS); /* 80% */ ++ memset(&bw_ctx[1], 80, xhci->numports); /* 80% */ + pci_dma_write(&xhci->pci_dev, ctx, bw_ctx, sizeof(bw_ctx)); + + return CC_SUCCESS; +@@ -2165,12 +2195,11 @@ static void xhci_process_commands(XHCIState *xhci) + + static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) + { +- int nr = port->port.index + 1; +- + port->portsc = PORTSC_PP; +- if (port->port.dev && port->port.dev->attached && !is_detach) { ++ if (port->uport->dev && port->uport->dev->attached && !is_detach && ++ (1 << port->uport->dev->speed) & port->speedmask) { + port->portsc |= PORTSC_CCS; +- switch (port->port.dev->speed) { ++ switch (port->uport->dev->speed) { + case USB_SPEED_LOW: + port->portsc |= PORTSC_SPEED_LOW; + break; +@@ -2180,14 +2209,18 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) + case USB_SPEED_HIGH: + port->portsc |= PORTSC_SPEED_HIGH; + break; ++ case USB_SPEED_SUPER: ++ port->portsc |= PORTSC_SPEED_SUPER; ++ break; + } + } + + if (xhci_running(xhci)) { + port->portsc |= PORTSC_CSC; +- XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; ++ XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, ++ port->portnr << 24}; + xhci_event(xhci, &ev); +- DPRINTF("xhci: port change event for port %d\n", nr); ++ DPRINTF("xhci: port change event for port %d\n", port->portnr); + } + } + +@@ -2215,7 +2248,7 @@ static void xhci_reset(DeviceState *dev) + xhci_disable_slot(xhci, i+1); + } + +- for (i = 0; i < MAXPORTS; i++) { ++ for (i = 0; i < xhci->numports; i++) { + xhci_update_port(xhci, xhci->ports + i, 0); + } + +@@ -2246,7 +2279,8 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) + ret = 0x01000000 | LEN_CAP; + break; + case 0x04: /* HCSPARAMS 1 */ +- ret = (MAXPORTS<<24) | (MAXINTRS<<8) | MAXSLOTS; ++ ret = ((xhci->numports_2+xhci->numports_3)<<24) ++ | (MAXINTRS<<8) | MAXSLOTS; + break; + case 0x08: /* HCSPARAMS 2 */ + ret = 0x0000000f; +@@ -2276,7 +2310,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) + ret = 0x20425355; /* "USB " */ + break; + case 0x28: /* Supported Protocol:08 */ +- ret = 0x00000001 | (USB2_PORTS<<8); ++ ret = 0x00000001 | (xhci->numports_2<<8); + break; + case 0x2c: /* Supported Protocol:0c */ + ret = 0x00000000; /* reserved */ +@@ -2288,7 +2322,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) + ret = 0x20425355; /* "USB " */ + break; + case 0x38: /* Supported Protocol:08 */ +- ret = 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8); ++ ret = 0x00000000 | (xhci->numports_2+1) | (xhci->numports_3<<8); + break; + case 0x3c: /* Supported Protocol:0c */ + ret = 0x00000000; /* reserved */ +@@ -2307,7 +2341,7 @@ static uint32_t xhci_port_read(XHCIState *xhci, uint32_t reg) + uint32_t port = reg >> 4; + uint32_t ret; + +- if (port >= MAXPORTS) { ++ if (port >= xhci->numports) { + fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); + ret = 0; + goto out; +@@ -2340,7 +2374,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) + + trace_usb_xhci_port_write(port, reg & 0x0f, val); + +- if (port >= MAXPORTS) { ++ if (port >= xhci->numports) { + fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); + return; + } +@@ -2362,7 +2396,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) + /* write-1-to-start bits */ + if (val & PORTSC_PR) { + DPRINTF("xhci: port %d reset\n", port); +- usb_device_reset(xhci->ports[port].port.dev); ++ usb_device_reset(xhci->ports[port].uport->dev); + portsc |= PORTSC_PRC | PORTSC_PED; + } + xhci->ports[port].portsc = portsc; +@@ -2659,7 +2693,7 @@ static const MemoryRegionOps xhci_mem_ops = { + static void xhci_attach(USBPort *usbport) + { + XHCIState *xhci = usbport->opaque; +- XHCIPort *port = &xhci->ports[usbport->index]; ++ XHCIPort *port = xhci_lookup_port(xhci, usbport); + + xhci_update_port(xhci, port, 0); + } +@@ -2667,7 +2701,7 @@ static void xhci_attach(USBPort *usbport) + static void xhci_detach(USBPort *usbport) + { + XHCIState *xhci = usbport->opaque; +- XHCIPort *port = &xhci->ports[usbport->index]; ++ XHCIPort *port = xhci_lookup_port(xhci, usbport); + + xhci_update_port(xhci, port, 1); + } +@@ -2675,9 +2709,9 @@ static void xhci_detach(USBPort *usbport) + static void xhci_wakeup(USBPort *usbport) + { + XHCIState *xhci = usbport->opaque; +- XHCIPort *port = &xhci->ports[usbport->index]; +- int nr = port->port.index + 1; +- XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; ++ XHCIPort *port = xhci_lookup_port(xhci, usbport); ++ XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, ++ port->portnr << 24}; + uint32_t pls; + + pls = (port->portsc >> PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK; +@@ -2759,22 +2793,43 @@ static USBBusOps xhci_bus_ops = { + + static void usb_xhci_init(XHCIState *xhci, DeviceState *dev) + { +- int i; ++ XHCIPort *port; ++ int i, usbports, speedmask; + + xhci->usbsts = USBSTS_HCH; + ++ if (xhci->numports_2 > MAXPORTS_2) { ++ xhci->numports_2 = MAXPORTS_2; ++ } ++ if (xhci->numports_3 > MAXPORTS_3) { ++ xhci->numports_3 = MAXPORTS_3; ++ } ++ usbports = MAX(xhci->numports_2, xhci->numports_3); ++ xhci->numports = xhci->numports_2 + xhci->numports_3; ++ + usb_bus_new(&xhci->bus, &xhci_bus_ops, &xhci->pci_dev.qdev); + +- for (i = 0; i < MAXPORTS; i++) { +- memset(&xhci->ports[i], 0, sizeof(xhci->ports[i])); +- usb_register_port(&xhci->bus, &xhci->ports[i].port, xhci, i, +- &xhci_port_ops, +- USB_SPEED_MASK_LOW | +- USB_SPEED_MASK_FULL | +- USB_SPEED_MASK_HIGH); +- } +- for (i = 0; i < MAXSLOTS; i++) { +- xhci->slots[i].enabled = 0; ++ for (i = 0; i < usbports; i++) { ++ speedmask = 0; ++ if (i < xhci->numports_2) { ++ port = &xhci->ports[i]; ++ port->portnr = i + 1; ++ port->uport = &xhci->uports[i]; ++ port->speedmask = ++ USB_SPEED_MASK_LOW | ++ USB_SPEED_MASK_FULL | ++ USB_SPEED_MASK_HIGH; ++ speedmask |= port->speedmask; ++ } ++ if (i < xhci->numports_3) { ++ port = &xhci->ports[i + xhci->numports_2]; ++ port->portnr = i + 1 + xhci->numports_2; ++ port->uport = &xhci->uports[i]; ++ port->speedmask = USB_SPEED_MASK_SUPER; ++ speedmask |= port->speedmask; ++ } ++ usb_register_port(&xhci->bus, &xhci->uports[i], xhci, i, ++ &xhci_port_ops, speedmask); + } + } + +@@ -2830,6 +2885,8 @@ static const VMStateDescription vmstate_xhci = { + + static Property xhci_properties[] = { + DEFINE_PROP_UINT32("msi", XHCIState, msi, 0), ++ DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), ++ DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), + DEFINE_PROP_END_OF_LIST(), + }; + diff --git a/0613-usb3-superspeed-descriptors.patch b/0613-usb3-superspeed-descriptors.patch new file mode 100644 index 0000000..a130320 --- /dev/null +++ b/0613-usb3-superspeed-descriptors.patch @@ -0,0 +1,61 @@ +From 626f97d5fb771fadedccc9d05f6fea47b689c3bc Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 28 Aug 2012 17:28:50 +0200 +Subject: [PATCH] usb3: superspeed descriptors + +Add superspeed descriptor entry to USBDesc, +advertise superspeed support when present. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/desc.c | 10 +++++++++- + hw/usb/desc.h | 1 + + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/desc.c b/hw/usb/desc.c +index 0a9d3c9..3e8c6cb 100644 +--- a/hw/usb/desc.c ++++ b/hw/usb/desc.c +@@ -359,6 +359,9 @@ static void usb_desc_setdefaults(USBDevice *dev) + case USB_SPEED_HIGH: + dev->device = desc->high; + break; ++ case USB_SPEED_SUPER: ++ dev->device = desc->super; ++ break; + } + usb_desc_set_config(dev, 0); + } +@@ -376,6 +379,9 @@ void usb_desc_init(USBDevice *dev) + if (desc->high) { + dev->speedmask |= USB_SPEED_MASK_HIGH; + } ++ if (desc->super) { ++ dev->speedmask |= USB_SPEED_MASK_SUPER; ++ } + usb_desc_setdefaults(dev); + } + +@@ -384,7 +390,9 @@ void usb_desc_attach(USBDevice *dev) + const USBDesc *desc = usb_device_get_usb_desc(dev); + + assert(desc != NULL); +- if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) { ++ if (desc->super && (dev->port->speedmask & USB_SPEED_MASK_SUPER)) { ++ dev->speed = USB_SPEED_SUPER; ++ } else if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) { + dev->speed = USB_SPEED_HIGH; + } else if (desc->full && (dev->port->speedmask & USB_SPEED_MASK_FULL)) { + dev->speed = USB_SPEED_FULL; +diff --git a/hw/usb/desc.h b/hw/usb/desc.h +index 7cf5442..d89fa41 100644 +--- a/hw/usb/desc.h ++++ b/hw/usb/desc.h +@@ -152,6 +152,7 @@ struct USBDesc { + USBDescID id; + const USBDescDevice *full; + const USBDescDevice *high; ++ const USBDescDevice *super; + const char* const *str; + }; + diff --git a/0613-usb3-superspeed-endpoint-companion.patch b/0613-usb3-superspeed-endpoint-companion.patch deleted file mode 100644 index 40983e4..0000000 --- a/0613-usb3-superspeed-endpoint-companion.patch +++ /dev/null @@ -1,248 +0,0 @@ -From e0354b4f91dd198b5bfe1ddf649588d6af84ea9c Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 28 Aug 2012 17:28:03 +0200 -Subject: [PATCH] usb3: superspeed endpoint companion - -Add support for building superspeed endpoint companion descriptors, -create them for superspeed usb devices. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb.h | 1 + - hw/usb/desc.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- - hw/usb/desc.h | 26 +++++++++++++++++++++----- - 3 files changed, 62 insertions(+), 20 deletions(-) - -diff --git a/hw/usb.h b/hw/usb.h -index 684e3f4..78ffdf4 100644 ---- a/hw/usb.h -+++ b/hw/usb.h -@@ -137,6 +137,7 @@ - #define USB_DT_INTERFACE_ASSOC 0x0B - #define USB_DT_CS_INTERFACE 0x24 - #define USB_DT_CS_ENDPOINT 0x25 -+#define USB_DT_ENDPOINT_COMPANION 0x30 - - #define USB_ENDPOINT_XFER_CONTROL 0 - #define USB_ENDPOINT_XFER_ISOC 1 -diff --git a/hw/usb/desc.c b/hw/usb/desc.c -index 3e8c6cb..8f5a8e5 100644 ---- a/hw/usb/desc.c -+++ b/hw/usb/desc.c -@@ -76,7 +76,8 @@ int usb_desc_device_qualifier(const USBDescDevice *dev, - return bLength; - } - --int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) -+int usb_desc_config(const USBDescConfig *conf, int flags, -+ uint8_t *dest, size_t len) - { - uint8_t bLength = 0x09; - uint16_t wTotalLength = 0; -@@ -99,7 +100,7 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) - - /* handle grouped interfaces if any */ - for (i = 0; i < conf->nif_groups; i++) { -- rc = usb_desc_iface_group(&(conf->if_groups[i]), -+ rc = usb_desc_iface_group(&(conf->if_groups[i]), flags, - dest + wTotalLength, - len - wTotalLength); - if (rc < 0) { -@@ -110,7 +111,8 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) - - /* handle normal (ungrouped / no IAD) interfaces if any */ - for (i = 0; i < conf->nif; i++) { -- rc = usb_desc_iface(conf->ifs + i, dest + wTotalLength, len - wTotalLength); -+ rc = usb_desc_iface(conf->ifs + i, flags, -+ dest + wTotalLength, len - wTotalLength); - if (rc < 0) { - return rc; - } -@@ -122,8 +124,8 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) - return wTotalLength; - } - --int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, -- size_t len) -+int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags, -+ uint8_t *dest, size_t len) - { - int pos = 0; - int i = 0; -@@ -147,7 +149,7 @@ int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, - - /* handle associated interfaces in this group */ - for (i = 0; i < iad->nif; i++) { -- int rc = usb_desc_iface(&(iad->ifs[i]), dest + pos, len - pos); -+ int rc = usb_desc_iface(&(iad->ifs[i]), flags, dest + pos, len - pos); - if (rc < 0) { - return rc; - } -@@ -157,7 +159,8 @@ int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, - return pos; - } - --int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) -+int usb_desc_iface(const USBDescIface *iface, int flags, -+ uint8_t *dest, size_t len) - { - uint8_t bLength = 0x09; - int i, rc, pos = 0; -@@ -188,7 +191,7 @@ int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) - } - - for (i = 0; i < iface->bNumEndpoints; i++) { -- rc = usb_desc_endpoint(iface->eps + i, dest + pos, len - pos); -+ rc = usb_desc_endpoint(iface->eps + i, flags, dest + pos, len - pos); - if (rc < 0) { - return rc; - } -@@ -198,13 +201,15 @@ int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) - return pos; - } - --int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len) -+int usb_desc_endpoint(const USBDescEndpoint *ep, int flags, -+ uint8_t *dest, size_t len) - { - uint8_t bLength = ep->is_audio ? 0x09 : 0x07; - uint8_t extralen = ep->extra ? ep->extra[0] : 0; -+ uint8_t superlen = (flags & USB_DESC_FLAG_SUPER) ? 0x06 : 0; - USBDescriptor *d = (void *)dest; - -- if (len < bLength + extralen) { -+ if (len < bLength + extralen + superlen) { - return -1; - } - -@@ -224,7 +229,21 @@ int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len) - memcpy(dest + bLength, ep->extra, extralen); - } - -- return bLength + extralen; -+ if (superlen) { -+ USBDescriptor *d = (void *)(dest + bLength + extralen); -+ -+ d->bLength = 0x06; -+ d->bDescriptorType = USB_DT_ENDPOINT_COMPANION; -+ -+ d->u.super_endpoint.bMaxBurst = ep->bMaxBurst; -+ d->u.super_endpoint.bmAttributes = ep->bmAttributes_super; -+ d->u.super_endpoint.wBytesPerInterval_lo = -+ usb_lo(ep->wBytesPerInterval); -+ d->u.super_endpoint.wBytesPerInterval_hi = -+ usb_hi(ep->wBytesPerInterval); -+ } -+ -+ return bLength + extralen + superlen; - } - - int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len) -@@ -509,7 +528,7 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len - uint8_t buf[256]; - uint8_t type = value >> 8; - uint8_t index = value & 0xff; -- int ret = -1; -+ int flags, ret = -1; - - if (dev->speed == USB_SPEED_HIGH) { - other_dev = usb_device_get_usb_desc(dev)->full; -@@ -517,6 +536,11 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len - other_dev = usb_device_get_usb_desc(dev)->high; - } - -+ flags = 0; -+ if (dev->device->bcdUSB >= 0x0300) { -+ flags |= USB_DESC_FLAG_SUPER; -+ } -+ - switch(type) { - case USB_DT_DEVICE: - ret = usb_desc_device(&desc->id, dev->device, buf, sizeof(buf)); -@@ -524,7 +548,8 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len - break; - case USB_DT_CONFIG: - if (index < dev->device->bNumConfigurations) { -- ret = usb_desc_config(dev->device->confs + index, buf, sizeof(buf)); -+ ret = usb_desc_config(dev->device->confs + index, flags, -+ buf, sizeof(buf)); - } - trace_usb_desc_config(dev->addr, index, len, ret); - break; -@@ -532,7 +557,6 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len - ret = usb_desc_string(dev, index, buf, sizeof(buf)); - trace_usb_desc_string(dev->addr, index, len, ret); - break; -- - case USB_DT_DEVICE_QUALIFIER: - if (other_dev != NULL) { - ret = usb_desc_device_qualifier(other_dev, buf, sizeof(buf)); -@@ -541,7 +565,8 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len - break; - case USB_DT_OTHER_SPEED_CONFIG: - if (other_dev != NULL && index < other_dev->bNumConfigurations) { -- ret = usb_desc_config(other_dev->confs + index, buf, sizeof(buf)); -+ ret = usb_desc_config(other_dev->confs + index, flags, -+ buf, sizeof(buf)); - buf[0x01] = USB_DT_OTHER_SPEED_CONFIG; - } - trace_usb_desc_other_speed_config(dev->addr, index, len, ret); -diff --git a/hw/usb/desc.h b/hw/usb/desc.h -index d89fa41..4b5e88d 100644 ---- a/hw/usb/desc.h -+++ b/hw/usb/desc.h -@@ -63,6 +63,12 @@ typedef struct USBDescriptor { - uint8_t bRefresh; /* only audio ep */ - uint8_t bSynchAddress; /* only audio ep */ - } endpoint; -+ struct { -+ uint8_t bMaxBurst; -+ uint8_t bmAttributes; -+ uint8_t wBytesPerInterval_lo; -+ uint8_t wBytesPerInterval_hi; -+ } super_endpoint; - } u; - } QEMU_PACKED USBDescriptor; - -@@ -139,6 +145,11 @@ struct USBDescEndpoint { - - uint8_t is_audio; /* has bRefresh + bSynchAddress */ - uint8_t *extra; -+ -+ /* superspeed endpoint companion */ -+ uint8_t bMaxBurst; -+ uint8_t bmAttributes_super; -+ uint16_t wBytesPerInterval; - }; - - struct USBDescOther { -@@ -156,16 +167,21 @@ struct USBDesc { - const char* const *str; - }; - -+#define USB_DESC_FLAG_SUPER (1 << 1) -+ - /* generate usb packages from structs */ - int usb_desc_device(const USBDescID *id, const USBDescDevice *dev, - uint8_t *dest, size_t len); - int usb_desc_device_qualifier(const USBDescDevice *dev, - uint8_t *dest, size_t len); --int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len); --int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, -- size_t len); --int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len); --int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len); -+int usb_desc_config(const USBDescConfig *conf, int flags, -+ uint8_t *dest, size_t len); -+int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags, -+ uint8_t *dest, size_t len); -+int usb_desc_iface(const USBDescIface *iface, int flags, -+ uint8_t *dest, size_t len); -+int usb_desc_endpoint(const USBDescEndpoint *ep, int flags, -+ uint8_t *dest, size_t len); - int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len); - - /* control message emulation helpers */ --- -1.7.12.1 - diff --git a/0614-usb3-bos-decriptor.patch b/0614-usb3-bos-decriptor.patch deleted file mode 100644 index 99d4f81..0000000 --- a/0614-usb3-bos-decriptor.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 2014680cdc2834fef9b4cee5e1239f22d8dbdba3 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 28 Aug 2012 17:46:29 +0200 -Subject: [PATCH] usb3: bos decriptor - -Add support for creating BOS descriptor and -device cappability descriptors. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb.h | 6 ++++ - hw/usb/desc.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - hw/usb/desc.h | 25 ++++++++++++++ - trace-events | 1 + - 4 files changed, 141 insertions(+) - -diff --git a/hw/usb.h b/hw/usb.h -index 78ffdf4..48c8926 100644 ---- a/hw/usb.h -+++ b/hw/usb.h -@@ -135,10 +135,16 @@ - #define USB_DT_OTHER_SPEED_CONFIG 0x07 - #define USB_DT_DEBUG 0x0A - #define USB_DT_INTERFACE_ASSOC 0x0B -+#define USB_DT_BOS 0x0F -+#define USB_DT_DEVICE_CAPABILITY 0x10 - #define USB_DT_CS_INTERFACE 0x24 - #define USB_DT_CS_ENDPOINT 0x25 - #define USB_DT_ENDPOINT_COMPANION 0x30 - -+#define USB_DEV_CAP_WIRELESS 0x01 -+#define USB_DEV_CAP_USB2_EXT 0x02 -+#define USB_DEV_CAP_SUPERSPEED 0x03 -+ - #define USB_ENDPOINT_XFER_CONTROL 0 - #define USB_ENDPOINT_XFER_ISOC 1 - #define USB_ENDPOINT_XFER_BULK 2 -diff --git a/hw/usb/desc.c b/hw/usb/desc.c -index 8f5a8e5..1f12eae 100644 ---- a/hw/usb/desc.c -+++ b/hw/usb/desc.c -@@ -258,6 +258,111 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len) - return bLength; - } - -+static int usb_desc_cap_usb2_ext(const USBDesc *desc, uint8_t *dest, size_t len) -+{ -+ uint8_t bLength = 0x07; -+ USBDescriptor *d = (void *)dest; -+ -+ if (len < bLength) { -+ return -1; -+ } -+ -+ d->bLength = bLength; -+ d->bDescriptorType = USB_DT_DEVICE_CAPABILITY; -+ d->u.cap.bDevCapabilityType = USB_DEV_CAP_USB2_EXT; -+ -+ d->u.cap.u.usb2_ext.bmAttributes_1 = (1 << 1); /* LPM */ -+ d->u.cap.u.usb2_ext.bmAttributes_2 = 0; -+ d->u.cap.u.usb2_ext.bmAttributes_3 = 0; -+ d->u.cap.u.usb2_ext.bmAttributes_4 = 0; -+ -+ return bLength; -+} -+ -+static int usb_desc_cap_super(const USBDesc *desc, uint8_t *dest, size_t len) -+{ -+ uint8_t bLength = 0x0a; -+ USBDescriptor *d = (void *)dest; -+ -+ if (len < bLength) { -+ return -1; -+ } -+ -+ d->bLength = bLength; -+ d->bDescriptorType = USB_DT_DEVICE_CAPABILITY; -+ d->u.cap.bDevCapabilityType = USB_DEV_CAP_SUPERSPEED; -+ -+ d->u.cap.u.super.bmAttributes = 0; -+ d->u.cap.u.super.wSpeedsSupported_lo = 0; -+ d->u.cap.u.super.wSpeedsSupported_hi = 0; -+ d->u.cap.u.super.bFunctionalitySupport = 0; -+ d->u.cap.u.super.bU1DevExitLat = 0x0a; -+ d->u.cap.u.super.wU2DevExitLat_lo = 0x20; -+ d->u.cap.u.super.wU2DevExitLat_hi = 0; -+ -+ if (desc->full) { -+ d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 1); -+ d->u.cap.u.super.bFunctionalitySupport = 1; -+ } -+ if (desc->high) { -+ d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 2); -+ if (!d->u.cap.u.super.bFunctionalitySupport) { -+ d->u.cap.u.super.bFunctionalitySupport = 2; -+ } -+ } -+ if (desc->super) { -+ d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 3); -+ if (!d->u.cap.u.super.bFunctionalitySupport) { -+ d->u.cap.u.super.bFunctionalitySupport = 3; -+ } -+ } -+ -+ return bLength; -+} -+ -+static int usb_desc_bos(const USBDesc *desc, uint8_t *dest, size_t len) -+{ -+ uint8_t bLength = 0x05; -+ uint16_t wTotalLength = 0; -+ uint8_t bNumDeviceCaps = 0; -+ USBDescriptor *d = (void *)dest; -+ int rc; -+ -+ if (len < bLength) { -+ return -1; -+ } -+ -+ d->bLength = bLength; -+ d->bDescriptorType = USB_DT_BOS; -+ -+ wTotalLength += bLength; -+ -+ if (desc->high != NULL) { -+ rc = usb_desc_cap_usb2_ext(desc, dest + wTotalLength, -+ len - wTotalLength); -+ if (rc < 0) { -+ return rc; -+ } -+ wTotalLength += rc; -+ bNumDeviceCaps++; -+ } -+ -+ if (desc->super != NULL) { -+ rc = usb_desc_cap_super(desc, dest + wTotalLength, -+ len - wTotalLength); -+ if (rc < 0) { -+ return rc; -+ } -+ wTotalLength += rc; -+ bNumDeviceCaps++; -+ } -+ -+ d->u.bos.wTotalLength_lo = usb_lo(wTotalLength); -+ d->u.bos.wTotalLength_hi = usb_hi(wTotalLength); -+ d->u.bos.bNumDeviceCaps = bNumDeviceCaps; -+ return wTotalLength; -+} -+ - /* ------------------------------------------------------------------ */ - - static void usb_desc_ep_init(USBDevice *dev) -@@ -571,6 +676,10 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len - } - trace_usb_desc_other_speed_config(dev->addr, index, len, ret); - break; -+ case USB_DT_BOS: -+ ret = usb_desc_bos(desc, buf, sizeof(buf)); -+ trace_usb_desc_bos(dev->addr, len, ret); -+ break; - - case USB_DT_DEBUG: - /* ignore silently */ -diff --git a/hw/usb/desc.h b/hw/usb/desc.h -index 4b5e88d..68bb570 100644 ---- a/hw/usb/desc.h -+++ b/hw/usb/desc.h -@@ -69,6 +69,31 @@ typedef struct USBDescriptor { - uint8_t wBytesPerInterval_lo; - uint8_t wBytesPerInterval_hi; - } super_endpoint; -+ struct { -+ uint8_t wTotalLength_lo; -+ uint8_t wTotalLength_hi; -+ uint8_t bNumDeviceCaps; -+ } bos; -+ struct { -+ uint8_t bDevCapabilityType; -+ union { -+ struct { -+ uint8_t bmAttributes_1; -+ uint8_t bmAttributes_2; -+ uint8_t bmAttributes_3; -+ uint8_t bmAttributes_4; -+ } usb2_ext; -+ struct { -+ uint8_t bmAttributes; -+ uint8_t wSpeedsSupported_lo; -+ uint8_t wSpeedsSupported_hi; -+ uint8_t bFunctionalitySupport; -+ uint8_t bU1DevExitLat; -+ uint8_t wU2DevExitLat_lo; -+ uint8_t wU2DevExitLat_hi; -+ } super; -+ } u; -+ } cap; - } u; - } QEMU_PACKED USBDescriptor; - -diff --git a/trace-events b/trace-events -index 2db1deb..d941e78 100644 ---- a/trace-events -+++ b/trace-events -@@ -343,6 +343,7 @@ usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device quali - usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d" - usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d" - usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d" -+usb_desc_bos(int addr, int len, int ret) "dev %d bos, len %d, ret %d" - usb_set_addr(int addr) "dev %d" - usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d" - usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d" --- -1.7.12.1 - diff --git a/0614-usb3-superspeed-endpoint-companion.patch b/0614-usb3-superspeed-endpoint-companion.patch new file mode 100644 index 0000000..fa7f9a9 --- /dev/null +++ b/0614-usb3-superspeed-endpoint-companion.patch @@ -0,0 +1,245 @@ +From 28606fe9b5e3554fa65d7fd7aef449da74ec1363 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 28 Aug 2012 17:28:03 +0200 +Subject: [PATCH] usb3: superspeed endpoint companion + +Add support for building superspeed endpoint companion descriptors, +create them for superspeed usb devices. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb.h | 1 + + hw/usb/desc.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- + hw/usb/desc.h | 26 +++++++++++++++++++++----- + 3 files changed, 62 insertions(+), 20 deletions(-) + +diff --git a/hw/usb.h b/hw/usb.h +index 684e3f4..78ffdf4 100644 +--- a/hw/usb.h ++++ b/hw/usb.h +@@ -137,6 +137,7 @@ + #define USB_DT_INTERFACE_ASSOC 0x0B + #define USB_DT_CS_INTERFACE 0x24 + #define USB_DT_CS_ENDPOINT 0x25 ++#define USB_DT_ENDPOINT_COMPANION 0x30 + + #define USB_ENDPOINT_XFER_CONTROL 0 + #define USB_ENDPOINT_XFER_ISOC 1 +diff --git a/hw/usb/desc.c b/hw/usb/desc.c +index 3e8c6cb..8f5a8e5 100644 +--- a/hw/usb/desc.c ++++ b/hw/usb/desc.c +@@ -76,7 +76,8 @@ int usb_desc_device_qualifier(const USBDescDevice *dev, + return bLength; + } + +-int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) ++int usb_desc_config(const USBDescConfig *conf, int flags, ++ uint8_t *dest, size_t len) + { + uint8_t bLength = 0x09; + uint16_t wTotalLength = 0; +@@ -99,7 +100,7 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) + + /* handle grouped interfaces if any */ + for (i = 0; i < conf->nif_groups; i++) { +- rc = usb_desc_iface_group(&(conf->if_groups[i]), ++ rc = usb_desc_iface_group(&(conf->if_groups[i]), flags, + dest + wTotalLength, + len - wTotalLength); + if (rc < 0) { +@@ -110,7 +111,8 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) + + /* handle normal (ungrouped / no IAD) interfaces if any */ + for (i = 0; i < conf->nif; i++) { +- rc = usb_desc_iface(conf->ifs + i, dest + wTotalLength, len - wTotalLength); ++ rc = usb_desc_iface(conf->ifs + i, flags, ++ dest + wTotalLength, len - wTotalLength); + if (rc < 0) { + return rc; + } +@@ -122,8 +124,8 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) + return wTotalLength; + } + +-int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, +- size_t len) ++int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags, ++ uint8_t *dest, size_t len) + { + int pos = 0; + int i = 0; +@@ -147,7 +149,7 @@ int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, + + /* handle associated interfaces in this group */ + for (i = 0; i < iad->nif; i++) { +- int rc = usb_desc_iface(&(iad->ifs[i]), dest + pos, len - pos); ++ int rc = usb_desc_iface(&(iad->ifs[i]), flags, dest + pos, len - pos); + if (rc < 0) { + return rc; + } +@@ -157,7 +159,8 @@ int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, + return pos; + } + +-int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) ++int usb_desc_iface(const USBDescIface *iface, int flags, ++ uint8_t *dest, size_t len) + { + uint8_t bLength = 0x09; + int i, rc, pos = 0; +@@ -188,7 +191,7 @@ int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) + } + + for (i = 0; i < iface->bNumEndpoints; i++) { +- rc = usb_desc_endpoint(iface->eps + i, dest + pos, len - pos); ++ rc = usb_desc_endpoint(iface->eps + i, flags, dest + pos, len - pos); + if (rc < 0) { + return rc; + } +@@ -198,13 +201,15 @@ int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) + return pos; + } + +-int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len) ++int usb_desc_endpoint(const USBDescEndpoint *ep, int flags, ++ uint8_t *dest, size_t len) + { + uint8_t bLength = ep->is_audio ? 0x09 : 0x07; + uint8_t extralen = ep->extra ? ep->extra[0] : 0; ++ uint8_t superlen = (flags & USB_DESC_FLAG_SUPER) ? 0x06 : 0; + USBDescriptor *d = (void *)dest; + +- if (len < bLength + extralen) { ++ if (len < bLength + extralen + superlen) { + return -1; + } + +@@ -224,7 +229,21 @@ int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len) + memcpy(dest + bLength, ep->extra, extralen); + } + +- return bLength + extralen; ++ if (superlen) { ++ USBDescriptor *d = (void *)(dest + bLength + extralen); ++ ++ d->bLength = 0x06; ++ d->bDescriptorType = USB_DT_ENDPOINT_COMPANION; ++ ++ d->u.super_endpoint.bMaxBurst = ep->bMaxBurst; ++ d->u.super_endpoint.bmAttributes = ep->bmAttributes_super; ++ d->u.super_endpoint.wBytesPerInterval_lo = ++ usb_lo(ep->wBytesPerInterval); ++ d->u.super_endpoint.wBytesPerInterval_hi = ++ usb_hi(ep->wBytesPerInterval); ++ } ++ ++ return bLength + extralen + superlen; + } + + int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len) +@@ -509,7 +528,7 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len + uint8_t buf[256]; + uint8_t type = value >> 8; + uint8_t index = value & 0xff; +- int ret = -1; ++ int flags, ret = -1; + + if (dev->speed == USB_SPEED_HIGH) { + other_dev = usb_device_get_usb_desc(dev)->full; +@@ -517,6 +536,11 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len + other_dev = usb_device_get_usb_desc(dev)->high; + } + ++ flags = 0; ++ if (dev->device->bcdUSB >= 0x0300) { ++ flags |= USB_DESC_FLAG_SUPER; ++ } ++ + switch(type) { + case USB_DT_DEVICE: + ret = usb_desc_device(&desc->id, dev->device, buf, sizeof(buf)); +@@ -524,7 +548,8 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len + break; + case USB_DT_CONFIG: + if (index < dev->device->bNumConfigurations) { +- ret = usb_desc_config(dev->device->confs + index, buf, sizeof(buf)); ++ ret = usb_desc_config(dev->device->confs + index, flags, ++ buf, sizeof(buf)); + } + trace_usb_desc_config(dev->addr, index, len, ret); + break; +@@ -532,7 +557,6 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len + ret = usb_desc_string(dev, index, buf, sizeof(buf)); + trace_usb_desc_string(dev->addr, index, len, ret); + break; +- + case USB_DT_DEVICE_QUALIFIER: + if (other_dev != NULL) { + ret = usb_desc_device_qualifier(other_dev, buf, sizeof(buf)); +@@ -541,7 +565,8 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len + break; + case USB_DT_OTHER_SPEED_CONFIG: + if (other_dev != NULL && index < other_dev->bNumConfigurations) { +- ret = usb_desc_config(other_dev->confs + index, buf, sizeof(buf)); ++ ret = usb_desc_config(other_dev->confs + index, flags, ++ buf, sizeof(buf)); + buf[0x01] = USB_DT_OTHER_SPEED_CONFIG; + } + trace_usb_desc_other_speed_config(dev->addr, index, len, ret); +diff --git a/hw/usb/desc.h b/hw/usb/desc.h +index d89fa41..4b5e88d 100644 +--- a/hw/usb/desc.h ++++ b/hw/usb/desc.h +@@ -63,6 +63,12 @@ typedef struct USBDescriptor { + uint8_t bRefresh; /* only audio ep */ + uint8_t bSynchAddress; /* only audio ep */ + } endpoint; ++ struct { ++ uint8_t bMaxBurst; ++ uint8_t bmAttributes; ++ uint8_t wBytesPerInterval_lo; ++ uint8_t wBytesPerInterval_hi; ++ } super_endpoint; + } u; + } QEMU_PACKED USBDescriptor; + +@@ -139,6 +145,11 @@ struct USBDescEndpoint { + + uint8_t is_audio; /* has bRefresh + bSynchAddress */ + uint8_t *extra; ++ ++ /* superspeed endpoint companion */ ++ uint8_t bMaxBurst; ++ uint8_t bmAttributes_super; ++ uint16_t wBytesPerInterval; + }; + + struct USBDescOther { +@@ -156,16 +167,21 @@ struct USBDesc { + const char* const *str; + }; + ++#define USB_DESC_FLAG_SUPER (1 << 1) ++ + /* generate usb packages from structs */ + int usb_desc_device(const USBDescID *id, const USBDescDevice *dev, + uint8_t *dest, size_t len); + int usb_desc_device_qualifier(const USBDescDevice *dev, + uint8_t *dest, size_t len); +-int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len); +-int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, +- size_t len); +-int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len); +-int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len); ++int usb_desc_config(const USBDescConfig *conf, int flags, ++ uint8_t *dest, size_t len); ++int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags, ++ uint8_t *dest, size_t len); ++int usb_desc_iface(const USBDescIface *iface, int flags, ++ uint8_t *dest, size_t len); ++int usb_desc_endpoint(const USBDescEndpoint *ep, int flags, ++ uint8_t *dest, size_t len); + int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len); + + /* control message emulation helpers */ diff --git a/0615-usb-storage-usb3-support.patch b/0615-usb-storage-usb3-support.patch deleted file mode 100644 index 7caeb42..0000000 --- a/0615-usb-storage-usb3-support.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 9a6fd10bf6a85c4df63a7ba1cf7d6203220d722e Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 28 Aug 2012 17:29:15 +0200 -Subject: [PATCH] usb-storage: usb3 support - -Add usb3 descriptors to usb-storage, so it shows up as superspeed -device when connected to xhci. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/dev-storage.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 43 insertions(+), 3 deletions(-) - -diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c -index ff48d91..e732191 100644 ---- a/hw/usb/dev-storage.c -+++ b/hw/usb/dev-storage.c -@@ -78,6 +78,7 @@ enum { - STR_SERIALNUMBER, - STR_CONFIG_FULL, - STR_CONFIG_HIGH, -+ STR_CONFIG_SUPER, - }; - - static const USBDescStrings desc_strings = { -@@ -86,6 +87,7 @@ static const USBDescStrings desc_strings = { - [STR_SERIALNUMBER] = "1", - [STR_CONFIG_FULL] = "Full speed config (usb 1.1)", - [STR_CONFIG_HIGH] = "High speed config (usb 2.0)", -+ [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)", - }; - - static const USBDescIface desc_iface_full = { -@@ -158,6 +160,43 @@ static const USBDescDevice desc_device_high = { - }, - }; - -+static const USBDescIface desc_iface_super = { -+ .bInterfaceNumber = 0, -+ .bNumEndpoints = 2, -+ .bInterfaceClass = USB_CLASS_MASS_STORAGE, -+ .bInterfaceSubClass = 0x06, /* SCSI */ -+ .bInterfaceProtocol = 0x50, /* Bulk */ -+ .eps = (USBDescEndpoint[]) { -+ { -+ .bEndpointAddress = USB_DIR_IN | 0x01, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+ .wMaxPacketSize = 1024, -+ .bMaxBurst = 15, -+ },{ -+ .bEndpointAddress = USB_DIR_OUT | 0x02, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+ .wMaxPacketSize = 1024, -+ .bMaxBurst = 15, -+ }, -+ } -+}; -+ -+static const USBDescDevice desc_device_super = { -+ .bcdUSB = 0x0300, -+ .bMaxPacketSize0 = 9, -+ .bNumConfigurations = 1, -+ .confs = (USBDescConfig[]) { -+ { -+ .bNumInterfaces = 1, -+ .bConfigurationValue = 1, -+ .iConfiguration = STR_CONFIG_SUPER, -+ .bmAttributes = 0xc0, -+ .nif = 1, -+ .ifs = &desc_iface_super, -+ }, -+ }, -+}; -+ - static const USBDesc desc = { - .id = { - .idVendor = 0x46f4, /* CRC16() of "QEMU" */ -@@ -167,9 +206,10 @@ static const USBDesc desc = { - .iProduct = STR_PRODUCT, - .iSerialNumber = STR_SERIALNUMBER, - }, -- .full = &desc_device_full, -- .high = &desc_device_high, -- .str = desc_strings, -+ .full = &desc_device_full, -+ .high = &desc_device_high, -+ .super = &desc_device_super, -+ .str = desc_strings, - }; - - static void usb_msd_copy_data(MSDState *s, USBPacket *p) --- -1.7.12.1 - diff --git a/0615-usb3-bos-decriptor.patch b/0615-usb3-bos-decriptor.patch new file mode 100644 index 0000000..2ec11bc --- /dev/null +++ b/0615-usb3-bos-decriptor.patch @@ -0,0 +1,212 @@ +From 56e4093206b136735942b1fa94fc9826b489fac1 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 28 Aug 2012 17:46:29 +0200 +Subject: [PATCH] usb3: bos decriptor + +Add support for creating BOS descriptor and +device cappability descriptors. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb.h | 6 ++++ + hw/usb/desc.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + hw/usb/desc.h | 25 ++++++++++++++ + trace-events | 1 + + 4 files changed, 141 insertions(+) + +diff --git a/hw/usb.h b/hw/usb.h +index 78ffdf4..48c8926 100644 +--- a/hw/usb.h ++++ b/hw/usb.h +@@ -135,10 +135,16 @@ + #define USB_DT_OTHER_SPEED_CONFIG 0x07 + #define USB_DT_DEBUG 0x0A + #define USB_DT_INTERFACE_ASSOC 0x0B ++#define USB_DT_BOS 0x0F ++#define USB_DT_DEVICE_CAPABILITY 0x10 + #define USB_DT_CS_INTERFACE 0x24 + #define USB_DT_CS_ENDPOINT 0x25 + #define USB_DT_ENDPOINT_COMPANION 0x30 + ++#define USB_DEV_CAP_WIRELESS 0x01 ++#define USB_DEV_CAP_USB2_EXT 0x02 ++#define USB_DEV_CAP_SUPERSPEED 0x03 ++ + #define USB_ENDPOINT_XFER_CONTROL 0 + #define USB_ENDPOINT_XFER_ISOC 1 + #define USB_ENDPOINT_XFER_BULK 2 +diff --git a/hw/usb/desc.c b/hw/usb/desc.c +index 8f5a8e5..1f12eae 100644 +--- a/hw/usb/desc.c ++++ b/hw/usb/desc.c +@@ -258,6 +258,111 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len) + return bLength; + } + ++static int usb_desc_cap_usb2_ext(const USBDesc *desc, uint8_t *dest, size_t len) ++{ ++ uint8_t bLength = 0x07; ++ USBDescriptor *d = (void *)dest; ++ ++ if (len < bLength) { ++ return -1; ++ } ++ ++ d->bLength = bLength; ++ d->bDescriptorType = USB_DT_DEVICE_CAPABILITY; ++ d->u.cap.bDevCapabilityType = USB_DEV_CAP_USB2_EXT; ++ ++ d->u.cap.u.usb2_ext.bmAttributes_1 = (1 << 1); /* LPM */ ++ d->u.cap.u.usb2_ext.bmAttributes_2 = 0; ++ d->u.cap.u.usb2_ext.bmAttributes_3 = 0; ++ d->u.cap.u.usb2_ext.bmAttributes_4 = 0; ++ ++ return bLength; ++} ++ ++static int usb_desc_cap_super(const USBDesc *desc, uint8_t *dest, size_t len) ++{ ++ uint8_t bLength = 0x0a; ++ USBDescriptor *d = (void *)dest; ++ ++ if (len < bLength) { ++ return -1; ++ } ++ ++ d->bLength = bLength; ++ d->bDescriptorType = USB_DT_DEVICE_CAPABILITY; ++ d->u.cap.bDevCapabilityType = USB_DEV_CAP_SUPERSPEED; ++ ++ d->u.cap.u.super.bmAttributes = 0; ++ d->u.cap.u.super.wSpeedsSupported_lo = 0; ++ d->u.cap.u.super.wSpeedsSupported_hi = 0; ++ d->u.cap.u.super.bFunctionalitySupport = 0; ++ d->u.cap.u.super.bU1DevExitLat = 0x0a; ++ d->u.cap.u.super.wU2DevExitLat_lo = 0x20; ++ d->u.cap.u.super.wU2DevExitLat_hi = 0; ++ ++ if (desc->full) { ++ d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 1); ++ d->u.cap.u.super.bFunctionalitySupport = 1; ++ } ++ if (desc->high) { ++ d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 2); ++ if (!d->u.cap.u.super.bFunctionalitySupport) { ++ d->u.cap.u.super.bFunctionalitySupport = 2; ++ } ++ } ++ if (desc->super) { ++ d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 3); ++ if (!d->u.cap.u.super.bFunctionalitySupport) { ++ d->u.cap.u.super.bFunctionalitySupport = 3; ++ } ++ } ++ ++ return bLength; ++} ++ ++static int usb_desc_bos(const USBDesc *desc, uint8_t *dest, size_t len) ++{ ++ uint8_t bLength = 0x05; ++ uint16_t wTotalLength = 0; ++ uint8_t bNumDeviceCaps = 0; ++ USBDescriptor *d = (void *)dest; ++ int rc; ++ ++ if (len < bLength) { ++ return -1; ++ } ++ ++ d->bLength = bLength; ++ d->bDescriptorType = USB_DT_BOS; ++ ++ wTotalLength += bLength; ++ ++ if (desc->high != NULL) { ++ rc = usb_desc_cap_usb2_ext(desc, dest + wTotalLength, ++ len - wTotalLength); ++ if (rc < 0) { ++ return rc; ++ } ++ wTotalLength += rc; ++ bNumDeviceCaps++; ++ } ++ ++ if (desc->super != NULL) { ++ rc = usb_desc_cap_super(desc, dest + wTotalLength, ++ len - wTotalLength); ++ if (rc < 0) { ++ return rc; ++ } ++ wTotalLength += rc; ++ bNumDeviceCaps++; ++ } ++ ++ d->u.bos.wTotalLength_lo = usb_lo(wTotalLength); ++ d->u.bos.wTotalLength_hi = usb_hi(wTotalLength); ++ d->u.bos.bNumDeviceCaps = bNumDeviceCaps; ++ return wTotalLength; ++} ++ + /* ------------------------------------------------------------------ */ + + static void usb_desc_ep_init(USBDevice *dev) +@@ -571,6 +676,10 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len + } + trace_usb_desc_other_speed_config(dev->addr, index, len, ret); + break; ++ case USB_DT_BOS: ++ ret = usb_desc_bos(desc, buf, sizeof(buf)); ++ trace_usb_desc_bos(dev->addr, len, ret); ++ break; + + case USB_DT_DEBUG: + /* ignore silently */ +diff --git a/hw/usb/desc.h b/hw/usb/desc.h +index 4b5e88d..68bb570 100644 +--- a/hw/usb/desc.h ++++ b/hw/usb/desc.h +@@ -69,6 +69,31 @@ typedef struct USBDescriptor { + uint8_t wBytesPerInterval_lo; + uint8_t wBytesPerInterval_hi; + } super_endpoint; ++ struct { ++ uint8_t wTotalLength_lo; ++ uint8_t wTotalLength_hi; ++ uint8_t bNumDeviceCaps; ++ } bos; ++ struct { ++ uint8_t bDevCapabilityType; ++ union { ++ struct { ++ uint8_t bmAttributes_1; ++ uint8_t bmAttributes_2; ++ uint8_t bmAttributes_3; ++ uint8_t bmAttributes_4; ++ } usb2_ext; ++ struct { ++ uint8_t bmAttributes; ++ uint8_t wSpeedsSupported_lo; ++ uint8_t wSpeedsSupported_hi; ++ uint8_t bFunctionalitySupport; ++ uint8_t bU1DevExitLat; ++ uint8_t wU2DevExitLat_lo; ++ uint8_t wU2DevExitLat_hi; ++ } super; ++ } u; ++ } cap; + } u; + } QEMU_PACKED USBDescriptor; + +diff --git a/trace-events b/trace-events +index 7b9cc9e..d978d42 100644 +--- a/trace-events ++++ b/trace-events +@@ -343,6 +343,7 @@ usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device quali + usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d" + usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d" + usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d" ++usb_desc_bos(int addr, int len, int ret) "dev %d bos, len %d, ret %d" + usb_set_addr(int addr) "dev %d" + usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d" + usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d" diff --git a/0616-usb-storage-usb3-support.patch b/0616-usb-storage-usb3-support.patch new file mode 100644 index 0000000..75857f6 --- /dev/null +++ b/0616-usb-storage-usb3-support.patch @@ -0,0 +1,91 @@ +From 3c762eeef7dc242a00552bb9b3f05e0208765f84 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 28 Aug 2012 17:29:15 +0200 +Subject: [PATCH] usb-storage: usb3 support + +Add usb3 descriptors to usb-storage, so it shows up as superspeed +device when connected to xhci. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/dev-storage.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 43 insertions(+), 3 deletions(-) + +diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c +index ff48d91..e732191 100644 +--- a/hw/usb/dev-storage.c ++++ b/hw/usb/dev-storage.c +@@ -78,6 +78,7 @@ enum { + STR_SERIALNUMBER, + STR_CONFIG_FULL, + STR_CONFIG_HIGH, ++ STR_CONFIG_SUPER, + }; + + static const USBDescStrings desc_strings = { +@@ -86,6 +87,7 @@ static const USBDescStrings desc_strings = { + [STR_SERIALNUMBER] = "1", + [STR_CONFIG_FULL] = "Full speed config (usb 1.1)", + [STR_CONFIG_HIGH] = "High speed config (usb 2.0)", ++ [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)", + }; + + static const USBDescIface desc_iface_full = { +@@ -158,6 +160,43 @@ static const USBDescDevice desc_device_high = { + }, + }; + ++static const USBDescIface desc_iface_super = { ++ .bInterfaceNumber = 0, ++ .bNumEndpoints = 2, ++ .bInterfaceClass = USB_CLASS_MASS_STORAGE, ++ .bInterfaceSubClass = 0x06, /* SCSI */ ++ .bInterfaceProtocol = 0x50, /* Bulk */ ++ .eps = (USBDescEndpoint[]) { ++ { ++ .bEndpointAddress = USB_DIR_IN | 0x01, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++ .wMaxPacketSize = 1024, ++ .bMaxBurst = 15, ++ },{ ++ .bEndpointAddress = USB_DIR_OUT | 0x02, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++ .wMaxPacketSize = 1024, ++ .bMaxBurst = 15, ++ }, ++ } ++}; ++ ++static const USBDescDevice desc_device_super = { ++ .bcdUSB = 0x0300, ++ .bMaxPacketSize0 = 9, ++ .bNumConfigurations = 1, ++ .confs = (USBDescConfig[]) { ++ { ++ .bNumInterfaces = 1, ++ .bConfigurationValue = 1, ++ .iConfiguration = STR_CONFIG_SUPER, ++ .bmAttributes = 0xc0, ++ .nif = 1, ++ .ifs = &desc_iface_super, ++ }, ++ }, ++}; ++ + static const USBDesc desc = { + .id = { + .idVendor = 0x46f4, /* CRC16() of "QEMU" */ +@@ -167,9 +206,10 @@ static const USBDesc desc = { + .iProduct = STR_PRODUCT, + .iSerialNumber = STR_SERIALNUMBER, + }, +- .full = &desc_device_full, +- .high = &desc_device_high, +- .str = desc_strings, ++ .full = &desc_device_full, ++ .high = &desc_device_high, ++ .super = &desc_device_super, ++ .str = desc_strings, + }; + + static void usb_msd_copy_data(MSDState *s, USBPacket *p) diff --git a/0616-xhci-fix-cleanup-msi.patch b/0616-xhci-fix-cleanup-msi.patch deleted file mode 100644 index 33fca14..0000000 --- a/0616-xhci-fix-cleanup-msi.patch +++ /dev/null @@ -1,96 +0,0 @@ -From e97e63460859a74cf53c85e97a6d60633a92cc64 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 30 Aug 2012 10:57:12 +0200 -Subject: [PATCH] xhci: fix & cleanup msi. - -Drop custom write_config function which isn't needed any more. -Make the msi property a bit property so it accepts 'on' & 'off'. -Enable MSI by default. - -TODO: add compat property to disable on old machine types. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 27 +++++++++------------------ - 1 file changed, 9 insertions(+), 18 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 5813b4a..d2e6ee6 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -386,7 +386,7 @@ struct XHCIState { - /* properties */ - uint32_t numports_2; - uint32_t numports_3; -- uint32_t msi; -+ uint32_t flags; - - /* Operational Registers */ - uint32_t usbcmd; -@@ -435,6 +435,10 @@ typedef struct XHCIEvRingSeg { - uint32_t rsvd; - } XHCIEvRingSeg; - -+enum xhci_flags { -+ XHCI_FLAG_USE_MSI = 1, -+}; -+ - static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, - unsigned int epid); - static void xhci_event(XHCIState *xhci, XHCIEvent *event); -@@ -617,7 +621,7 @@ static void xhci_irq_update(XHCIState *xhci) - level = 1; - } - -- if (xhci->msi && msi_enabled(&xhci->pci_dev)) { -+ if (msi_enabled(&xhci->pci_dev)) { - if (level) { - trace_usb_xhci_irq_msi(0); - msi_notify(&xhci->pci_dev, 0); -@@ -2859,32 +2863,20 @@ static int usb_xhci_initfn(struct PCIDevice *dev) - ret = pcie_cap_init(&xhci->pci_dev, 0xa0, PCI_EXP_TYPE_ENDPOINT, 0); - assert(ret >= 0); - -- if (xhci->msi) { -- ret = msi_init(&xhci->pci_dev, 0x70, 1, true, false); -- assert(ret >= 0); -+ if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) { -+ msi_init(&xhci->pci_dev, 0x70, MAXINTRS, true, false); - } - - return 0; - } - --static void xhci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, -- int len) --{ -- XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev, dev); -- -- pci_default_write_config(dev, addr, val, len); -- if (xhci->msi) { -- msi_write_config(dev, addr, val, len); -- } --} -- - static const VMStateDescription vmstate_xhci = { - .name = "xhci", - .unmigratable = 1, - }; - - static Property xhci_properties[] = { -- DEFINE_PROP_UINT32("msi", XHCIState, msi, 0), -+ DEFINE_PROP_BIT("msi", XHCIState, flags, XHCI_FLAG_USE_MSI, true), - DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), - DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), - DEFINE_PROP_END_OF_LIST(), -@@ -2904,7 +2896,6 @@ static void xhci_class_init(ObjectClass *klass, void *data) - k->class_id = PCI_CLASS_SERIAL_USB; - k->revision = 0x03; - k->is_express = 1; -- k->config_write = xhci_write_config; - } - - static TypeInfo xhci_info = { --- -1.7.12.1 - diff --git a/0617-xhci-fix-cleanup-msi.patch b/0617-xhci-fix-cleanup-msi.patch new file mode 100644 index 0000000..d7c87a7 --- /dev/null +++ b/0617-xhci-fix-cleanup-msi.patch @@ -0,0 +1,93 @@ +From b296bb59f2c9e56bc2ba5fadc53ab53c54ccbc4b Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 30 Aug 2012 10:57:12 +0200 +Subject: [PATCH] xhci: fix & cleanup msi. + +Drop custom write_config function which isn't needed any more. +Make the msi property a bit property so it accepts 'on' & 'off'. +Enable MSI by default. + +TODO: add compat property to disable on old machine types. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 27 +++++++++------------------ + 1 file changed, 9 insertions(+), 18 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 642e8e5..ff74ed9 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -386,7 +386,7 @@ struct XHCIState { + /* properties */ + uint32_t numports_2; + uint32_t numports_3; +- uint32_t msi; ++ uint32_t flags; + + /* Operational Registers */ + uint32_t usbcmd; +@@ -435,6 +435,10 @@ typedef struct XHCIEvRingSeg { + uint32_t rsvd; + } XHCIEvRingSeg; + ++enum xhci_flags { ++ XHCI_FLAG_USE_MSI = 1, ++}; ++ + static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, + unsigned int epid); + static void xhci_event(XHCIState *xhci, XHCIEvent *event); +@@ -617,7 +621,7 @@ static void xhci_irq_update(XHCIState *xhci) + level = 1; + } + +- if (xhci->msi && msi_enabled(&xhci->pci_dev)) { ++ if (msi_enabled(&xhci->pci_dev)) { + if (level) { + trace_usb_xhci_irq_msi(0); + msi_notify(&xhci->pci_dev, 0); +@@ -2859,32 +2863,20 @@ static int usb_xhci_initfn(struct PCIDevice *dev) + ret = pcie_cap_init(&xhci->pci_dev, 0xa0, PCI_EXP_TYPE_ENDPOINT, 0); + assert(ret >= 0); + +- if (xhci->msi) { +- ret = msi_init(&xhci->pci_dev, 0x70, 1, true, false); +- assert(ret >= 0); ++ if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) { ++ msi_init(&xhci->pci_dev, 0x70, MAXINTRS, true, false); + } + + return 0; + } + +-static void xhci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, +- int len) +-{ +- XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev, dev); +- +- pci_default_write_config(dev, addr, val, len); +- if (xhci->msi) { +- msi_write_config(dev, addr, val, len); +- } +-} +- + static const VMStateDescription vmstate_xhci = { + .name = "xhci", + .unmigratable = 1, + }; + + static Property xhci_properties[] = { +- DEFINE_PROP_UINT32("msi", XHCIState, msi, 0), ++ DEFINE_PROP_BIT("msi", XHCIState, flags, XHCI_FLAG_USE_MSI, true), + DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), + DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), + DEFINE_PROP_END_OF_LIST(), +@@ -2904,7 +2896,6 @@ static void xhci_class_init(ObjectClass *klass, void *data) + k->class_id = PCI_CLASS_SERIAL_USB; + k->revision = 0x03; + k->is_express = 1; +- k->config_write = xhci_write_config; + } + + static TypeInfo xhci_info = { diff --git a/0617-xhci-rework-interrupt-handling.patch b/0617-xhci-rework-interrupt-handling.patch deleted file mode 100644 index 3ac4ccc..0000000 --- a/0617-xhci-rework-interrupt-handling.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 3bf435b656390f75ce8b8990f7484efb162472c9 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 30 Aug 2012 13:05:10 +0200 -Subject: [PATCH] xhci: rework interrupt handling - -Split xhci_irq_update into a function which handles intx updates -(including lowering the irq line once the guests acks the interrupt) -and one which is used for raising an irq only. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 47 +++++++++++++++++++++++++++++++++-------------- - 1 file changed, 33 insertions(+), 14 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index d2e6ee6..1857f42 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -612,24 +612,43 @@ static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport) - return &xhci->ports[index]; - } - --static void xhci_irq_update(XHCIState *xhci) -+static void xhci_intx_update(XHCIState *xhci) - { - int level = 0; - -- if (xhci->iman & IMAN_IP && xhci->iman & IMAN_IE && -+ if (msi_enabled(&xhci->pci_dev)) { -+ return; -+ } -+ -+ if (xhci->iman & IMAN_IP && -+ xhci->iman & IMAN_IE && - xhci->usbcmd & USBCMD_INTE) { - level = 1; - } - -+ trace_usb_xhci_irq_intx(level); -+ qemu_set_irq(xhci->irq, level); -+} -+ -+static void xhci_intr_raise(XHCIState *xhci) -+{ -+ if (!(xhci->iman & IMAN_IP) || -+ !(xhci->iman & IMAN_IE)) { -+ return; -+ } -+ -+ if (!(xhci->usbcmd & USBCMD_INTE)) { -+ return; -+ } -+ - if (msi_enabled(&xhci->pci_dev)) { -- if (level) { -- trace_usb_xhci_irq_msi(0); -- msi_notify(&xhci->pci_dev, 0); -- } -- } else { -- trace_usb_xhci_irq_intx(level); -- qemu_set_irq(xhci->irq, level); -+ trace_usb_xhci_irq_msi(0); -+ msi_notify(&xhci->pci_dev, 0); -+ return; - } -+ -+ trace_usb_xhci_irq_intx(1); -+ qemu_set_irq(xhci->irq, 1); - } - - static inline int xhci_running(XHCIState *xhci) -@@ -732,7 +751,7 @@ static void xhci_events_update(XHCIState *xhci) - xhci->erdp_low |= ERDP_EHB; - xhci->iman |= IMAN_IP; - xhci->usbsts |= USBSTS_EINT; -- xhci_irq_update(xhci); -+ xhci_intr_raise(xhci); - } - - if (xhci->er_full && xhci->ev_buffer_put == xhci->ev_buffer_get) { -@@ -796,7 +815,7 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event) - xhci->iman |= IMAN_IP; - xhci->usbsts |= USBSTS_EINT; - -- xhci_irq_update(xhci); -+ xhci_intr_raise(xhci); - } - - static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring, -@@ -2479,13 +2498,13 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) - if (val & USBCMD_HCRST) { - xhci_reset(&xhci->pci_dev.qdev); - } -- xhci_irq_update(xhci); -+ xhci_intx_update(xhci); - break; - - case 0x04: /* USBSTS */ - /* these bits are write-1-to-clear */ - xhci->usbsts &= ~(val & (USBSTS_HSE|USBSTS_EINT|USBSTS_PCD|USBSTS_SRE)); -- xhci_irq_update(xhci); -+ xhci_intx_update(xhci); - break; - - case 0x14: /* DNCTRL */ -@@ -2570,7 +2589,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) - } - xhci->iman &= ~IMAN_IE; - xhci->iman |= val & IMAN_IE; -- xhci_irq_update(xhci); -+ xhci_intx_update(xhci); - break; - case 0x24: /* IMOD */ - xhci->imod = val; --- -1.7.12.1 - diff --git a/0618-xhci-add-msix-support.patch b/0618-xhci-add-msix-support.patch deleted file mode 100644 index ab0abab..0000000 --- a/0618-xhci-add-msix-support.patch +++ /dev/null @@ -1,156 +0,0 @@ -From b04ba21e22b2df805af8236bc462c5c403fc6ee4 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 30 Aug 2012 12:06:59 +0200 -Subject: [PATCH] xhci: add msix support - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- - trace-events | 3 +++ - 2 files changed, 49 insertions(+), 1 deletion(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 1857f42..777f903 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -23,6 +23,7 @@ - #include "hw/usb.h" - #include "hw/pci.h" - #include "hw/msi.h" -+#include "hw/msix.h" - #include "trace.h" - - //#define DEBUG_XHCI -@@ -59,6 +60,8 @@ - #define OFF_OPER LEN_CAP - #define OFF_RUNTIME 0x1000 - #define OFF_DOORBELL 0x2000 -+#define OFF_MSIX_TABLE 0x3000 -+#define OFF_MSIX_PBA 0x3800 - /* must be power of 2 */ - #define LEN_REGS 0x4000 - -@@ -411,6 +414,7 @@ struct XHCIState { - uint32_t erstba_high; - uint32_t erdp_low; - uint32_t erdp_high; -+ bool msix_used; - - int64_t mfindex_start; - QEMUTimer *mfwrap_timer; -@@ -437,6 +441,7 @@ typedef struct XHCIEvRingSeg { - - enum xhci_flags { - XHCI_FLAG_USE_MSI = 1, -+ XHCI_FLAG_USE_MSI_X, - }; - - static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, -@@ -616,7 +621,8 @@ static void xhci_intx_update(XHCIState *xhci) - { - int level = 0; - -- if (msi_enabled(&xhci->pci_dev)) { -+ if (msix_enabled(&xhci->pci_dev) || -+ msi_enabled(&xhci->pci_dev)) { - return; - } - -@@ -630,6 +636,30 @@ static void xhci_intx_update(XHCIState *xhci) - qemu_set_irq(xhci->irq, level); - } - -+static void xhci_msix_update(XHCIState *xhci) -+{ -+ bool enabled; -+ -+ if (!msix_enabled(&xhci->pci_dev)) { -+ return; -+ } -+ -+ enabled = xhci->iman & IMAN_IE; -+ if (enabled == xhci->msix_used) { -+ return; -+ } -+ -+ if (enabled) { -+ trace_usb_xhci_irq_msix_use(0); -+ msix_vector_use(&xhci->pci_dev, 0); -+ xhci->msix_used = true; -+ } else { -+ trace_usb_xhci_irq_msix_unuse(0); -+ msix_vector_unuse(&xhci->pci_dev, 0); -+ xhci->msix_used = false; -+ } -+} -+ - static void xhci_intr_raise(XHCIState *xhci) - { - if (!(xhci->iman & IMAN_IP) || -@@ -641,6 +671,12 @@ static void xhci_intr_raise(XHCIState *xhci) - return; - } - -+ if (msix_enabled(&xhci->pci_dev)) { -+ trace_usb_xhci_irq_msix(0); -+ msix_notify(&xhci->pci_dev, 0); -+ return; -+ } -+ - if (msi_enabled(&xhci->pci_dev)) { - trace_usb_xhci_irq_msi(0); - msi_notify(&xhci->pci_dev, 0); -@@ -2282,6 +2318,7 @@ static void xhci_reset(DeviceState *dev) - xhci->erstba_high = 0; - xhci->erdp_low = 0; - xhci->erdp_high = 0; -+ xhci->msix_used = 0; - - xhci->er_ep_idx = 0; - xhci->er_pcs = 1; -@@ -2590,6 +2627,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) - xhci->iman &= ~IMAN_IE; - xhci->iman |= val & IMAN_IE; - xhci_intx_update(xhci); -+ xhci_msix_update(xhci); - break; - case 0x24: /* IMOD */ - xhci->imod = val; -@@ -2885,6 +2923,12 @@ static int usb_xhci_initfn(struct PCIDevice *dev) - if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) { - msi_init(&xhci->pci_dev, 0x70, MAXINTRS, true, false); - } -+ if (xhci->flags & (1 << XHCI_FLAG_USE_MSI_X)) { -+ msix_init(&xhci->pci_dev, MAXINTRS, -+ &xhci->mem, 0, OFF_MSIX_TABLE, -+ &xhci->mem, 0, OFF_MSIX_PBA, -+ 0x90); -+ } - - return 0; - } -@@ -2896,6 +2940,7 @@ static const VMStateDescription vmstate_xhci = { - - static Property xhci_properties[] = { - DEFINE_PROP_BIT("msi", XHCIState, flags, XHCI_FLAG_USE_MSI, true), -+ DEFINE_PROP_BIT("msix", XHCIState, flags, XHCI_FLAG_USE_MSI_X, true), - DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), - DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), - DEFINE_PROP_END_OF_LIST(), -diff --git a/trace-events b/trace-events -index d941e78..f86bbda 100644 ---- a/trace-events -+++ b/trace-events -@@ -316,6 +316,9 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" - usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" - usb_xhci_irq_intx(uint32_t level) "level %d" - usb_xhci_irq_msi(uint32_t nr) "nr %d" -+usb_xhci_irq_msix(uint32_t nr) "nr %d" -+usb_xhci_irq_msix_use(uint32_t nr) "nr %d" -+usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d" - usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" - usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" - usb_xhci_slot_enable(uint32_t slotid) "slotid %d" --- -1.7.12.1 - diff --git a/0618-xhci-rework-interrupt-handling.patch b/0618-xhci-rework-interrupt-handling.patch new file mode 100644 index 0000000..19ae99c --- /dev/null +++ b/0618-xhci-rework-interrupt-handling.patch @@ -0,0 +1,114 @@ +From 5901a1ee90fbbddce3f0a17bc6dbb6a215b718a4 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 30 Aug 2012 13:05:10 +0200 +Subject: [PATCH] xhci: rework interrupt handling + +Split xhci_irq_update into a function which handles intx updates +(including lowering the irq line once the guests acks the interrupt) +and one which is used for raising an irq only. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 47 +++++++++++++++++++++++++++++++++-------------- + 1 file changed, 33 insertions(+), 14 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index ff74ed9..74a57fe 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -612,24 +612,43 @@ static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport) + return &xhci->ports[index]; + } + +-static void xhci_irq_update(XHCIState *xhci) ++static void xhci_intx_update(XHCIState *xhci) + { + int level = 0; + +- if (xhci->iman & IMAN_IP && xhci->iman & IMAN_IE && ++ if (msi_enabled(&xhci->pci_dev)) { ++ return; ++ } ++ ++ if (xhci->iman & IMAN_IP && ++ xhci->iman & IMAN_IE && + xhci->usbcmd & USBCMD_INTE) { + level = 1; + } + ++ trace_usb_xhci_irq_intx(level); ++ qemu_set_irq(xhci->irq, level); ++} ++ ++static void xhci_intr_raise(XHCIState *xhci) ++{ ++ if (!(xhci->iman & IMAN_IP) || ++ !(xhci->iman & IMAN_IE)) { ++ return; ++ } ++ ++ if (!(xhci->usbcmd & USBCMD_INTE)) { ++ return; ++ } ++ + if (msi_enabled(&xhci->pci_dev)) { +- if (level) { +- trace_usb_xhci_irq_msi(0); +- msi_notify(&xhci->pci_dev, 0); +- } +- } else { +- trace_usb_xhci_irq_intx(level); +- qemu_set_irq(xhci->irq, level); ++ trace_usb_xhci_irq_msi(0); ++ msi_notify(&xhci->pci_dev, 0); ++ return; + } ++ ++ trace_usb_xhci_irq_intx(1); ++ qemu_set_irq(xhci->irq, 1); + } + + static inline int xhci_running(XHCIState *xhci) +@@ -732,7 +751,7 @@ static void xhci_events_update(XHCIState *xhci) + xhci->erdp_low |= ERDP_EHB; + xhci->iman |= IMAN_IP; + xhci->usbsts |= USBSTS_EINT; +- xhci_irq_update(xhci); ++ xhci_intr_raise(xhci); + } + + if (xhci->er_full && xhci->ev_buffer_put == xhci->ev_buffer_get) { +@@ -796,7 +815,7 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event) + xhci->iman |= IMAN_IP; + xhci->usbsts |= USBSTS_EINT; + +- xhci_irq_update(xhci); ++ xhci_intr_raise(xhci); + } + + static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring, +@@ -2479,13 +2498,13 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) + if (val & USBCMD_HCRST) { + xhci_reset(&xhci->pci_dev.qdev); + } +- xhci_irq_update(xhci); ++ xhci_intx_update(xhci); + break; + + case 0x04: /* USBSTS */ + /* these bits are write-1-to-clear */ + xhci->usbsts &= ~(val & (USBSTS_HSE|USBSTS_EINT|USBSTS_PCD|USBSTS_SRE)); +- xhci_irq_update(xhci); ++ xhci_intx_update(xhci); + break; + + case 0x14: /* DNCTRL */ +@@ -2570,7 +2589,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) + } + xhci->iman &= ~IMAN_IE; + xhci->iman |= val & IMAN_IE; +- xhci_irq_update(xhci); ++ xhci_intx_update(xhci); + break; + case 0x24: /* IMOD */ + xhci->imod = val; diff --git a/0619-xhci-add-msix-support.patch b/0619-xhci-add-msix-support.patch new file mode 100644 index 0000000..00f159b --- /dev/null +++ b/0619-xhci-add-msix-support.patch @@ -0,0 +1,153 @@ +From 30a07a691a444a4c9b7116d50ca1a6e8cf28db5c Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 30 Aug 2012 12:06:59 +0200 +Subject: [PATCH] xhci: add msix support + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- + trace-events | 3 +++ + 2 files changed, 49 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 74a57fe..91c2fb1 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -23,6 +23,7 @@ + #include "hw/usb.h" + #include "hw/pci.h" + #include "hw/msi.h" ++#include "hw/msix.h" + #include "trace.h" + + //#define DEBUG_XHCI +@@ -59,6 +60,8 @@ + #define OFF_OPER LEN_CAP + #define OFF_RUNTIME 0x1000 + #define OFF_DOORBELL 0x2000 ++#define OFF_MSIX_TABLE 0x3000 ++#define OFF_MSIX_PBA 0x3800 + /* must be power of 2 */ + #define LEN_REGS 0x4000 + +@@ -411,6 +414,7 @@ struct XHCIState { + uint32_t erstba_high; + uint32_t erdp_low; + uint32_t erdp_high; ++ bool msix_used; + + int64_t mfindex_start; + QEMUTimer *mfwrap_timer; +@@ -437,6 +441,7 @@ typedef struct XHCIEvRingSeg { + + enum xhci_flags { + XHCI_FLAG_USE_MSI = 1, ++ XHCI_FLAG_USE_MSI_X, + }; + + static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, +@@ -616,7 +621,8 @@ static void xhci_intx_update(XHCIState *xhci) + { + int level = 0; + +- if (msi_enabled(&xhci->pci_dev)) { ++ if (msix_enabled(&xhci->pci_dev) || ++ msi_enabled(&xhci->pci_dev)) { + return; + } + +@@ -630,6 +636,30 @@ static void xhci_intx_update(XHCIState *xhci) + qemu_set_irq(xhci->irq, level); + } + ++static void xhci_msix_update(XHCIState *xhci) ++{ ++ bool enabled; ++ ++ if (!msix_enabled(&xhci->pci_dev)) { ++ return; ++ } ++ ++ enabled = xhci->iman & IMAN_IE; ++ if (enabled == xhci->msix_used) { ++ return; ++ } ++ ++ if (enabled) { ++ trace_usb_xhci_irq_msix_use(0); ++ msix_vector_use(&xhci->pci_dev, 0); ++ xhci->msix_used = true; ++ } else { ++ trace_usb_xhci_irq_msix_unuse(0); ++ msix_vector_unuse(&xhci->pci_dev, 0); ++ xhci->msix_used = false; ++ } ++} ++ + static void xhci_intr_raise(XHCIState *xhci) + { + if (!(xhci->iman & IMAN_IP) || +@@ -641,6 +671,12 @@ static void xhci_intr_raise(XHCIState *xhci) + return; + } + ++ if (msix_enabled(&xhci->pci_dev)) { ++ trace_usb_xhci_irq_msix(0); ++ msix_notify(&xhci->pci_dev, 0); ++ return; ++ } ++ + if (msi_enabled(&xhci->pci_dev)) { + trace_usb_xhci_irq_msi(0); + msi_notify(&xhci->pci_dev, 0); +@@ -2282,6 +2318,7 @@ static void xhci_reset(DeviceState *dev) + xhci->erstba_high = 0; + xhci->erdp_low = 0; + xhci->erdp_high = 0; ++ xhci->msix_used = 0; + + xhci->er_ep_idx = 0; + xhci->er_pcs = 1; +@@ -2590,6 +2627,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) + xhci->iman &= ~IMAN_IE; + xhci->iman |= val & IMAN_IE; + xhci_intx_update(xhci); ++ xhci_msix_update(xhci); + break; + case 0x24: /* IMOD */ + xhci->imod = val; +@@ -2885,6 +2923,12 @@ static int usb_xhci_initfn(struct PCIDevice *dev) + if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) { + msi_init(&xhci->pci_dev, 0x70, MAXINTRS, true, false); + } ++ if (xhci->flags & (1 << XHCI_FLAG_USE_MSI_X)) { ++ msix_init(&xhci->pci_dev, MAXINTRS, ++ &xhci->mem, 0, OFF_MSIX_TABLE, ++ &xhci->mem, 0, OFF_MSIX_PBA, ++ 0x90); ++ } + + return 0; + } +@@ -2896,6 +2940,7 @@ static const VMStateDescription vmstate_xhci = { + + static Property xhci_properties[] = { + DEFINE_PROP_BIT("msi", XHCIState, flags, XHCI_FLAG_USE_MSI, true), ++ DEFINE_PROP_BIT("msix", XHCIState, flags, XHCI_FLAG_USE_MSI_X, true), + DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), + DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), + DEFINE_PROP_END_OF_LIST(), +diff --git a/trace-events b/trace-events +index d978d42..93b05ab 100644 +--- a/trace-events ++++ b/trace-events +@@ -316,6 +316,9 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" + usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x" + usb_xhci_irq_intx(uint32_t level) "level %d" + usb_xhci_irq_msi(uint32_t nr) "nr %d" ++usb_xhci_irq_msix(uint32_t nr) "nr %d" ++usb_xhci_irq_msix_use(uint32_t nr) "nr %d" ++usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d" + usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" + usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" + usb_xhci_slot_enable(uint32_t slotid) "slotid %d" diff --git a/0619-xhci-move-register-update-into-xhci_intr_raise.patch b/0619-xhci-move-register-update-into-xhci_intr_raise.patch deleted file mode 100644 index f89d2a2..0000000 --- a/0619-xhci-move-register-update-into-xhci_intr_raise.patch +++ /dev/null @@ -1,55 +0,0 @@ -From be996e1a852397f4009d08ac803081e1dfbc7326 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 30 Aug 2012 14:04:04 +0200 -Subject: [PATCH] xhci: move register update into xhci_intr_raise - -Now that we have a separate function to raise an IRQ we can move -some comon code into the function. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 777f903..32d22f7 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -662,8 +662,11 @@ static void xhci_msix_update(XHCIState *xhci) - - static void xhci_intr_raise(XHCIState *xhci) - { -- if (!(xhci->iman & IMAN_IP) || -- !(xhci->iman & IMAN_IE)) { -+ xhci->erdp_low |= ERDP_EHB; -+ xhci->iman |= IMAN_IP; -+ xhci->usbsts |= USBSTS_EINT; -+ -+ if (!(xhci->iman & IMAN_IE)) { - return; - } - -@@ -784,9 +787,6 @@ static void xhci_events_update(XHCIState *xhci) - } - - if (do_irq) { -- xhci->erdp_low |= ERDP_EHB; -- xhci->iman |= IMAN_IP; -- xhci->usbsts |= USBSTS_EINT; - xhci_intr_raise(xhci); - } - -@@ -847,10 +847,6 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event) - xhci_write_event(xhci, event); - } - -- xhci->erdp_low |= ERDP_EHB; -- xhci->iman |= IMAN_IP; -- xhci->usbsts |= USBSTS_EINT; -- - xhci_intr_raise(xhci); - } - --- -1.7.12.1 - diff --git a/0620-xhci-add-XHCIInterrupter.patch b/0620-xhci-add-XHCIInterrupter.patch deleted file mode 100644 index 2992970..0000000 --- a/0620-xhci-add-XHCIInterrupter.patch +++ /dev/null @@ -1,642 +0,0 @@ -From 40ddf0dafd6a8171d2a0f960a21d7d99bdf73cd6 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 30 Aug 2012 15:49:03 +0200 -Subject: [PATCH] xhci: add XHCIInterrupter - -Move all state belonging to the (single) interrupter into a separate -struct. First step in adding support for multiple interrupters. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 307 ++++++++++++++++++++++++++++-------------------------- - trace-events | 2 +- - 2 files changed, 161 insertions(+), 148 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 32d22f7..8a14ee8 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -378,6 +378,27 @@ typedef struct XHCIEvent { - uint8_t epid; - } XHCIEvent; - -+typedef struct XHCIInterrupter { -+ uint32_t iman; -+ uint32_t imod; -+ uint32_t erstsz; -+ uint32_t erstba_low; -+ uint32_t erstba_high; -+ uint32_t erdp_low; -+ uint32_t erdp_high; -+ -+ bool msix_used, er_pcs, er_full; -+ -+ dma_addr_t er_start; -+ uint32_t er_size; -+ unsigned int er_ep_idx; -+ -+ XHCIEvent ev_buffer[EV_QUEUE]; -+ unsigned int ev_buffer_put; -+ unsigned int ev_buffer_get; -+ -+} XHCIInterrupter; -+ - struct XHCIState { - PCIDevice pci_dev; - USBBus bus; -@@ -407,27 +428,9 @@ struct XHCIState { - uint32_t numports; - - /* Runtime Registers */ -- uint32_t iman; -- uint32_t imod; -- uint32_t erstsz; -- uint32_t erstba_low; -- uint32_t erstba_high; -- uint32_t erdp_low; -- uint32_t erdp_high; -- bool msix_used; -- - int64_t mfindex_start; - QEMUTimer *mfwrap_timer; -- -- dma_addr_t er_start; -- uint32_t er_size; -- bool er_pcs; -- unsigned int er_ep_idx; -- bool er_full; -- -- XHCIEvent ev_buffer[EV_QUEUE]; -- unsigned int ev_buffer_put; -- unsigned int ev_buffer_get; -+ XHCIInterrupter intr[MAXINTRS]; - - XHCIRing cmd_ring; - }; -@@ -446,8 +449,8 @@ enum xhci_flags { - - static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, - unsigned int epid); --static void xhci_event(XHCIState *xhci, XHCIEvent *event); --static void xhci_write_event(XHCIState *xhci, XHCIEvent *event); -+static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v); -+static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v); - - static const char *TRBType_names[] = { - [TRB_RESERVED] = "TRB_RESERVED", -@@ -573,7 +576,7 @@ static void xhci_mfwrap_timer(void *opaque) - XHCIState *xhci = opaque; - XHCIEvent wrap = { ER_MFINDEX_WRAP, CC_SUCCESS }; - -- xhci_event(xhci, &wrap); -+ xhci_event(xhci, &wrap, 0); - xhci_mfwrap_update(xhci); - } - -@@ -626,8 +629,8 @@ static void xhci_intx_update(XHCIState *xhci) - return; - } - -- if (xhci->iman & IMAN_IP && -- xhci->iman & IMAN_IE && -+ if (xhci->intr[0].iman & IMAN_IP && -+ xhci->intr[0].iman & IMAN_IE && - xhci->usbcmd & USBCMD_INTE) { - level = 1; - } -@@ -636,7 +639,7 @@ static void xhci_intx_update(XHCIState *xhci) - qemu_set_irq(xhci->irq, level); - } - --static void xhci_msix_update(XHCIState *xhci) -+static void xhci_msix_update(XHCIState *xhci, int v) - { - bool enabled; - -@@ -644,29 +647,29 @@ static void xhci_msix_update(XHCIState *xhci) - return; - } - -- enabled = xhci->iman & IMAN_IE; -- if (enabled == xhci->msix_used) { -+ enabled = xhci->intr[v].iman & IMAN_IE; -+ if (enabled == xhci->intr[v].msix_used) { - return; - } - - if (enabled) { -- trace_usb_xhci_irq_msix_use(0); -- msix_vector_use(&xhci->pci_dev, 0); -- xhci->msix_used = true; -+ trace_usb_xhci_irq_msix_use(v); -+ msix_vector_use(&xhci->pci_dev, v); -+ xhci->intr[v].msix_used = true; - } else { -- trace_usb_xhci_irq_msix_unuse(0); -- msix_vector_unuse(&xhci->pci_dev, 0); -- xhci->msix_used = false; -+ trace_usb_xhci_irq_msix_unuse(v); -+ msix_vector_unuse(&xhci->pci_dev, v); -+ xhci->intr[v].msix_used = false; - } - } - --static void xhci_intr_raise(XHCIState *xhci) -+static void xhci_intr_raise(XHCIState *xhci, int v) - { -- xhci->erdp_low |= ERDP_EHB; -- xhci->iman |= IMAN_IP; -+ xhci->intr[v].erdp_low |= ERDP_EHB; -+ xhci->intr[v].iman |= IMAN_IP; - xhci->usbsts |= USBSTS_EINT; - -- if (!(xhci->iman & IMAN_IE)) { -+ if (!(xhci->intr[v].iman & IMAN_IE)) { - return; - } - -@@ -675,24 +678,26 @@ static void xhci_intr_raise(XHCIState *xhci) - } - - if (msix_enabled(&xhci->pci_dev)) { -- trace_usb_xhci_irq_msix(0); -- msix_notify(&xhci->pci_dev, 0); -+ trace_usb_xhci_irq_msix(v); -+ msix_notify(&xhci->pci_dev, v); - return; - } - - if (msi_enabled(&xhci->pci_dev)) { -- trace_usb_xhci_irq_msi(0); -- msi_notify(&xhci->pci_dev, 0); -+ trace_usb_xhci_irq_msi(v); -+ msi_notify(&xhci->pci_dev, v); - return; - } - -- trace_usb_xhci_irq_intx(1); -- qemu_set_irq(xhci->irq, 1); -+ if (v == 0) { -+ trace_usb_xhci_irq_intx(1); -+ qemu_set_irq(xhci->irq, 1); -+ } - } - - static inline int xhci_running(XHCIState *xhci) - { -- return !(xhci->usbsts & USBSTS_HCH) && !xhci->er_full; -+ return !(xhci->usbsts & USBSTS_HCH) && !xhci->intr[0].er_full; - } - - static void xhci_die(XHCIState *xhci) -@@ -701,8 +706,9 @@ static void xhci_die(XHCIState *xhci) - fprintf(stderr, "xhci: asserted controller error\n"); - } - --static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) -+static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v) - { -+ XHCIInterrupter *intr = &xhci->intr[v]; - XHCITRB ev_trb; - dma_addr_t addr; - -@@ -710,27 +716,28 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) - ev_trb.status = cpu_to_le32(event->length | (event->ccode << 24)); - ev_trb.control = (event->slotid << 24) | (event->epid << 16) | - event->flags | (event->type << TRB_TYPE_SHIFT); -- if (xhci->er_pcs) { -+ if (intr->er_pcs) { - ev_trb.control |= TRB_C; - } - ev_trb.control = cpu_to_le32(ev_trb.control); - -- trace_usb_xhci_queue_event(xhci->er_ep_idx, trb_name(&ev_trb), -+ trace_usb_xhci_queue_event(v, intr->er_ep_idx, trb_name(&ev_trb), - event_name(event), ev_trb.parameter, - ev_trb.status, ev_trb.control); - -- addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; -+ addr = intr->er_start + TRB_SIZE*intr->er_ep_idx; - pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE); - -- xhci->er_ep_idx++; -- if (xhci->er_ep_idx >= xhci->er_size) { -- xhci->er_ep_idx = 0; -- xhci->er_pcs = !xhci->er_pcs; -+ intr->er_ep_idx++; -+ if (intr->er_ep_idx >= intr->er_size) { -+ intr->er_ep_idx = 0; -+ intr->er_pcs = !intr->er_pcs; - } - } - --static void xhci_events_update(XHCIState *xhci) -+static void xhci_events_update(XHCIState *xhci, int v) - { -+ XHCIInterrupter *intr = &xhci->intr[v]; - dma_addr_t erdp; - unsigned int dp_idx; - bool do_irq = 0; -@@ -739,115 +746,116 @@ static void xhci_events_update(XHCIState *xhci) - return; - } - -- erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); -- if (erdp < xhci->er_start || -- erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { -+ erdp = xhci_addr64(intr->erdp_low, intr->erdp_high); -+ if (erdp < intr->er_start || -+ erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) { - fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp); -- fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n", -- xhci->er_start, xhci->er_size); -+ fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n", -+ v, intr->er_start, intr->er_size); - xhci_die(xhci); - return; - } -- dp_idx = (erdp - xhci->er_start) / TRB_SIZE; -- assert(dp_idx < xhci->er_size); -+ dp_idx = (erdp - intr->er_start) / TRB_SIZE; -+ assert(dp_idx < intr->er_size); - - /* NEC didn't read section 4.9.4 of the spec (v1.0 p139 top Note) and thus - * deadlocks when the ER is full. Hack it by holding off events until - * the driver decides to free at least half of the ring */ -- if (xhci->er_full) { -- int er_free = dp_idx - xhci->er_ep_idx; -+ if (intr->er_full) { -+ int er_free = dp_idx - intr->er_ep_idx; - if (er_free <= 0) { -- er_free += xhci->er_size; -+ er_free += intr->er_size; - } -- if (er_free < (xhci->er_size/2)) { -+ if (er_free < (intr->er_size/2)) { - DPRINTF("xhci_events_update(): event ring still " - "more than half full (hack)\n"); - return; - } - } - -- while (xhci->ev_buffer_put != xhci->ev_buffer_get) { -- assert(xhci->er_full); -- if (((xhci->er_ep_idx+1) % xhci->er_size) == dp_idx) { -+ while (intr->ev_buffer_put != intr->ev_buffer_get) { -+ assert(intr->er_full); -+ if (((intr->er_ep_idx+1) % intr->er_size) == dp_idx) { - DPRINTF("xhci_events_update(): event ring full again\n"); - #ifndef ER_FULL_HACK - XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR}; -- xhci_write_event(xhci, &full); -+ xhci_write_event(xhci, &full, v); - #endif - do_irq = 1; - break; - } -- XHCIEvent *event = &xhci->ev_buffer[xhci->ev_buffer_get]; -- xhci_write_event(xhci, event); -- xhci->ev_buffer_get++; -+ XHCIEvent *event = &intr->ev_buffer[intr->ev_buffer_get]; -+ xhci_write_event(xhci, event, v); -+ intr->ev_buffer_get++; - do_irq = 1; -- if (xhci->ev_buffer_get == EV_QUEUE) { -- xhci->ev_buffer_get = 0; -+ if (intr->ev_buffer_get == EV_QUEUE) { -+ intr->ev_buffer_get = 0; - } - } - - if (do_irq) { -- xhci_intr_raise(xhci); -+ xhci_intr_raise(xhci, v); - } - -- if (xhci->er_full && xhci->ev_buffer_put == xhci->ev_buffer_get) { -+ if (intr->er_full && intr->ev_buffer_put == intr->ev_buffer_get) { - DPRINTF("xhci_events_update(): event ring no longer full\n"); -- xhci->er_full = 0; -+ intr->er_full = 0; - } - return; - } - --static void xhci_event(XHCIState *xhci, XHCIEvent *event) -+static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v) - { -+ XHCIInterrupter *intr = &xhci->intr[v]; - dma_addr_t erdp; - unsigned int dp_idx; - -- if (xhci->er_full) { -+ if (intr->er_full) { - DPRINTF("xhci_event(): ER full, queueing\n"); -- if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) { -+ if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) { - fprintf(stderr, "xhci: event queue full, dropping event!\n"); - return; - } -- xhci->ev_buffer[xhci->ev_buffer_put++] = *event; -- if (xhci->ev_buffer_put == EV_QUEUE) { -- xhci->ev_buffer_put = 0; -+ intr->ev_buffer[intr->ev_buffer_put++] = *event; -+ if (intr->ev_buffer_put == EV_QUEUE) { -+ intr->ev_buffer_put = 0; - } - return; - } - -- erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); -- if (erdp < xhci->er_start || -- erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { -+ erdp = xhci_addr64(intr->erdp_low, intr->erdp_high); -+ if (erdp < intr->er_start || -+ erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) { - fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp); -- fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n", -- xhci->er_start, xhci->er_size); -+ fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n", -+ v, intr->er_start, intr->er_size); - xhci_die(xhci); - return; - } - -- dp_idx = (erdp - xhci->er_start) / TRB_SIZE; -- assert(dp_idx < xhci->er_size); -+ dp_idx = (erdp - intr->er_start) / TRB_SIZE; -+ assert(dp_idx < intr->er_size); - -- if ((xhci->er_ep_idx+1) % xhci->er_size == dp_idx) { -+ if ((intr->er_ep_idx+1) % intr->er_size == dp_idx) { - DPRINTF("xhci_event(): ER full, queueing\n"); - #ifndef ER_FULL_HACK - XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR}; - xhci_write_event(xhci, &full); - #endif -- xhci->er_full = 1; -- if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) { -+ intr->er_full = 1; -+ if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) { - fprintf(stderr, "xhci: event queue full, dropping event!\n"); - return; - } -- xhci->ev_buffer[xhci->ev_buffer_put++] = *event; -- if (xhci->ev_buffer_put == EV_QUEUE) { -- xhci->ev_buffer_put = 0; -+ intr->ev_buffer[intr->ev_buffer_put++] = *event; -+ if (intr->ev_buffer_put == EV_QUEUE) { -+ intr->ev_buffer_put = 0; - } - } else { -- xhci_write_event(xhci, event); -+ xhci_write_event(xhci, event, v); - } - -- xhci_intr_raise(xhci); -+ xhci_intr_raise(xhci, v); - } - - static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring, -@@ -939,17 +947,18 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) - } - } - --static void xhci_er_reset(XHCIState *xhci) -+static void xhci_er_reset(XHCIState *xhci, int v) - { -+ XHCIInterrupter *intr = &xhci->intr[v]; - XHCIEvRingSeg seg; - - /* cache the (sole) event ring segment location */ -- if (xhci->erstsz != 1) { -- fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", xhci->erstsz); -+ if (intr->erstsz != 1) { -+ fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", intr->erstsz); - xhci_die(xhci); - return; - } -- dma_addr_t erstba = xhci_addr64(xhci->erstba_low, xhci->erstba_high); -+ dma_addr_t erstba = xhci_addr64(intr->erstba_low, intr->erstba_high); - pci_dma_read(&xhci->pci_dev, erstba, &seg, sizeof(seg)); - le32_to_cpus(&seg.addr_low); - le32_to_cpus(&seg.addr_high); -@@ -959,15 +968,15 @@ static void xhci_er_reset(XHCIState *xhci) - xhci_die(xhci); - return; - } -- xhci->er_start = xhci_addr64(seg.addr_low, seg.addr_high); -- xhci->er_size = seg.size; -+ intr->er_start = xhci_addr64(seg.addr_low, seg.addr_high); -+ intr->er_size = seg.size; - -- xhci->er_ep_idx = 0; -- xhci->er_pcs = 1; -- xhci->er_full = 0; -+ intr->er_ep_idx = 0; -+ intr->er_pcs = 1; -+ intr->er_full = 0; - -- DPRINTF("xhci: event ring:" DMA_ADDR_FMT " [%d]\n", -- xhci->er_start, xhci->er_size); -+ DPRINTF("xhci: event ring[%d]:" DMA_ADDR_FMT " [%d]\n", -+ v, intr->er_start, intr->er_size); - } - - static void xhci_run(XHCIState *xhci) -@@ -1368,7 +1377,7 @@ static void xhci_xfer_report(XHCITransfer *xfer) - DPRINTF("xhci_xfer_data: EDTLA=%d\n", event.length); - edtla = 0; - } -- xhci_event(xhci, &event); -+ xhci_event(xhci, &event, 0 /* FIXME */); - reported = 1; - if (xfer->status != CC_SUCCESS) { - return; -@@ -2244,7 +2253,7 @@ static void xhci_process_commands(XHCIState *xhci) - break; - } - event.slotid = slotid; -- xhci_event(xhci, &event); -+ xhci_event(xhci, &event, 0 /* FIXME */); - } - } - -@@ -2274,7 +2283,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) - port->portsc |= PORTSC_CSC; - XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, - port->portnr << 24}; -- xhci_event(xhci, &ev); -+ xhci_event(xhci, &ev, 0 /* FIXME */); - DPRINTF("xhci: port change event for port %d\n", port->portnr); - } - } -@@ -2307,20 +2316,22 @@ static void xhci_reset(DeviceState *dev) - xhci_update_port(xhci, xhci->ports + i, 0); - } - -- xhci->iman = 0; -- xhci->imod = 0; -- xhci->erstsz = 0; -- xhci->erstba_low = 0; -- xhci->erstba_high = 0; -- xhci->erdp_low = 0; -- xhci->erdp_high = 0; -- xhci->msix_used = 0; -+ for (i = 0; i < MAXINTRS; i++) { -+ xhci->intr[i].iman = 0; -+ xhci->intr[i].imod = 0; -+ xhci->intr[i].erstsz = 0; -+ xhci->intr[i].erstba_low = 0; -+ xhci->intr[i].erstba_high = 0; -+ xhci->intr[i].erdp_low = 0; -+ xhci->intr[i].erdp_high = 0; -+ xhci->intr[i].msix_used = 0; - -- xhci->er_ep_idx = 0; -- xhci->er_pcs = 1; -- xhci->er_full = 0; -- xhci->ev_buffer_put = 0; -- xhci->ev_buffer_get = 0; -+ xhci->intr[i].er_ep_idx = 0; -+ xhci->intr[i].er_pcs = 1; -+ xhci->intr[i].er_full = 0; -+ xhci->intr[i].ev_buffer_put = 0; -+ xhci->intr[i].ev_buffer_get = 0; -+ } - - xhci->mfindex_start = qemu_get_clock_ns(vm_clock); - xhci_mfwrap_update(xhci); -@@ -2551,7 +2562,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) - if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) { - XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED}; - xhci->crcr_low &= ~CRCR_CRR; -- xhci_event(xhci, &event); -+ xhci_event(xhci, &event, 0 /* FIXME */); - DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low); - } else { - dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val); -@@ -2575,6 +2586,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) - - static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - { -+ XHCIInterrupter *intr = &xhci->intr[0]; - uint32_t ret; - - switch (reg) { -@@ -2582,25 +2594,25 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - ret = xhci_mfindex_get(xhci) & 0x3fff; - break; - case 0x20: /* IMAN */ -- ret = xhci->iman; -+ ret = intr->iman; - break; - case 0x24: /* IMOD */ -- ret = xhci->imod; -+ ret = intr->imod; - break; - case 0x28: /* ERSTSZ */ -- ret = xhci->erstsz; -+ ret = intr->erstsz; - break; - case 0x30: /* ERSTBA low */ -- ret = xhci->erstba_low; -+ ret = intr->erstba_low; - break; - case 0x34: /* ERSTBA high */ -- ret = xhci->erstba_high; -+ ret = intr->erstba_high; - break; - case 0x38: /* ERDP low */ -- ret = xhci->erdp_low; -+ ret = intr->erdp_low; - break; - case 0x3c: /* ERDP high */ -- ret = xhci->erdp_high; -+ ret = intr->erdp_high; - break; - default: - fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); -@@ -2613,42 +2625,43 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - - static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) - { -+ XHCIInterrupter *intr = &xhci->intr[0]; - trace_usb_xhci_runtime_write(reg, val); - - switch (reg) { - case 0x20: /* IMAN */ - if (val & IMAN_IP) { -- xhci->iman &= ~IMAN_IP; -+ intr->iman &= ~IMAN_IP; - } -- xhci->iman &= ~IMAN_IE; -- xhci->iman |= val & IMAN_IE; -+ intr->iman &= ~IMAN_IE; -+ intr->iman |= val & IMAN_IE; - xhci_intx_update(xhci); -- xhci_msix_update(xhci); -+ xhci_msix_update(xhci, 0); - break; - case 0x24: /* IMOD */ -- xhci->imod = val; -+ intr->imod = val; - break; - case 0x28: /* ERSTSZ */ -- xhci->erstsz = val & 0xffff; -+ intr->erstsz = val & 0xffff; - break; - case 0x30: /* ERSTBA low */ - /* XXX NEC driver bug: it doesn't align this to 64 bytes -- xhci->erstba_low = val & 0xffffffc0; */ -- xhci->erstba_low = val & 0xfffffff0; -+ intr->erstba_low = val & 0xffffffc0; */ -+ intr->erstba_low = val & 0xfffffff0; - break; - case 0x34: /* ERSTBA high */ -- xhci->erstba_high = val; -- xhci_er_reset(xhci); -+ intr->erstba_high = val; -+ xhci_er_reset(xhci, 0); - break; - case 0x38: /* ERDP low */ - if (val & ERDP_EHB) { -- xhci->erdp_low &= ~ERDP_EHB; -+ intr->erdp_low &= ~ERDP_EHB; - } -- xhci->erdp_low = (val & ~ERDP_EHB) | (xhci->erdp_low & ERDP_EHB); -+ intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB); - break; - case 0x3c: /* ERDP high */ -- xhci->erdp_high = val; -- xhci_events_update(xhci); -+ intr->erdp_high = val; -+ xhci_events_update(xhci, 0); - break; - default: - fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); -@@ -2780,7 +2793,7 @@ static void xhci_wakeup(USBPort *usbport) - return; - } - port->portsc |= PORTSC_PLC; -- xhci_event(xhci, &ev); -+ xhci_event(xhci, &ev, 0 /* FIXME */); - } - - static void xhci_complete(USBPort *port, USBPacket *packet) -diff --git a/trace-events b/trace-events -index f86bbda..f5b5097 100644 ---- a/trace-events -+++ b/trace-events -@@ -319,7 +319,7 @@ usb_xhci_irq_msi(uint32_t nr) "nr %d" - usb_xhci_irq_msix(uint32_t nr) "nr %d" - usb_xhci_irq_msix_use(uint32_t nr) "nr %d" - usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d" --usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" -+usb_xhci_queue_event(uint32_t vector, uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "v %d, idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" - usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" - usb_xhci_slot_enable(uint32_t slotid) "slotid %d" - usb_xhci_slot_disable(uint32_t slotid) "slotid %d" --- -1.7.12.1 - diff --git a/0620-xhci-move-register-update-into-xhci_intr_raise.patch b/0620-xhci-move-register-update-into-xhci_intr_raise.patch new file mode 100644 index 0000000..341f5c3 --- /dev/null +++ b/0620-xhci-move-register-update-into-xhci_intr_raise.patch @@ -0,0 +1,52 @@ +From febd3b03f0bf3d108d201232e6f05c1d840f941d Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 30 Aug 2012 14:04:04 +0200 +Subject: [PATCH] xhci: move register update into xhci_intr_raise + +Now that we have a separate function to raise an IRQ we can move +some comon code into the function. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 91c2fb1..ae5620f 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -662,8 +662,11 @@ static void xhci_msix_update(XHCIState *xhci) + + static void xhci_intr_raise(XHCIState *xhci) + { +- if (!(xhci->iman & IMAN_IP) || +- !(xhci->iman & IMAN_IE)) { ++ xhci->erdp_low |= ERDP_EHB; ++ xhci->iman |= IMAN_IP; ++ xhci->usbsts |= USBSTS_EINT; ++ ++ if (!(xhci->iman & IMAN_IE)) { + return; + } + +@@ -784,9 +787,6 @@ static void xhci_events_update(XHCIState *xhci) + } + + if (do_irq) { +- xhci->erdp_low |= ERDP_EHB; +- xhci->iman |= IMAN_IP; +- xhci->usbsts |= USBSTS_EINT; + xhci_intr_raise(xhci); + } + +@@ -847,10 +847,6 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event) + xhci_write_event(xhci, event); + } + +- xhci->erdp_low |= ERDP_EHB; +- xhci->iman |= IMAN_IP; +- xhci->usbsts |= USBSTS_EINT; +- + xhci_intr_raise(xhci); + } + diff --git a/0621-xhci-add-XHCIInterrupter.patch b/0621-xhci-add-XHCIInterrupter.patch new file mode 100644 index 0000000..5d092ac --- /dev/null +++ b/0621-xhci-add-XHCIInterrupter.patch @@ -0,0 +1,639 @@ +From 0d297b79dc199a7670c867e035d20a1f1b4a02e0 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 30 Aug 2012 15:49:03 +0200 +Subject: [PATCH] xhci: add XHCIInterrupter + +Move all state belonging to the (single) interrupter into a separate +struct. First step in adding support for multiple interrupters. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 307 ++++++++++++++++++++++++++++-------------------------- + trace-events | 2 +- + 2 files changed, 161 insertions(+), 148 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index ae5620f..76da7a9 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -378,6 +378,27 @@ typedef struct XHCIEvent { + uint8_t epid; + } XHCIEvent; + ++typedef struct XHCIInterrupter { ++ uint32_t iman; ++ uint32_t imod; ++ uint32_t erstsz; ++ uint32_t erstba_low; ++ uint32_t erstba_high; ++ uint32_t erdp_low; ++ uint32_t erdp_high; ++ ++ bool msix_used, er_pcs, er_full; ++ ++ dma_addr_t er_start; ++ uint32_t er_size; ++ unsigned int er_ep_idx; ++ ++ XHCIEvent ev_buffer[EV_QUEUE]; ++ unsigned int ev_buffer_put; ++ unsigned int ev_buffer_get; ++ ++} XHCIInterrupter; ++ + struct XHCIState { + PCIDevice pci_dev; + USBBus bus; +@@ -407,27 +428,9 @@ struct XHCIState { + uint32_t numports; + + /* Runtime Registers */ +- uint32_t iman; +- uint32_t imod; +- uint32_t erstsz; +- uint32_t erstba_low; +- uint32_t erstba_high; +- uint32_t erdp_low; +- uint32_t erdp_high; +- bool msix_used; +- + int64_t mfindex_start; + QEMUTimer *mfwrap_timer; +- +- dma_addr_t er_start; +- uint32_t er_size; +- bool er_pcs; +- unsigned int er_ep_idx; +- bool er_full; +- +- XHCIEvent ev_buffer[EV_QUEUE]; +- unsigned int ev_buffer_put; +- unsigned int ev_buffer_get; ++ XHCIInterrupter intr[MAXINTRS]; + + XHCIRing cmd_ring; + }; +@@ -446,8 +449,8 @@ enum xhci_flags { + + static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, + unsigned int epid); +-static void xhci_event(XHCIState *xhci, XHCIEvent *event); +-static void xhci_write_event(XHCIState *xhci, XHCIEvent *event); ++static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v); ++static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v); + + static const char *TRBType_names[] = { + [TRB_RESERVED] = "TRB_RESERVED", +@@ -573,7 +576,7 @@ static void xhci_mfwrap_timer(void *opaque) + XHCIState *xhci = opaque; + XHCIEvent wrap = { ER_MFINDEX_WRAP, CC_SUCCESS }; + +- xhci_event(xhci, &wrap); ++ xhci_event(xhci, &wrap, 0); + xhci_mfwrap_update(xhci); + } + +@@ -626,8 +629,8 @@ static void xhci_intx_update(XHCIState *xhci) + return; + } + +- if (xhci->iman & IMAN_IP && +- xhci->iman & IMAN_IE && ++ if (xhci->intr[0].iman & IMAN_IP && ++ xhci->intr[0].iman & IMAN_IE && + xhci->usbcmd & USBCMD_INTE) { + level = 1; + } +@@ -636,7 +639,7 @@ static void xhci_intx_update(XHCIState *xhci) + qemu_set_irq(xhci->irq, level); + } + +-static void xhci_msix_update(XHCIState *xhci) ++static void xhci_msix_update(XHCIState *xhci, int v) + { + bool enabled; + +@@ -644,29 +647,29 @@ static void xhci_msix_update(XHCIState *xhci) + return; + } + +- enabled = xhci->iman & IMAN_IE; +- if (enabled == xhci->msix_used) { ++ enabled = xhci->intr[v].iman & IMAN_IE; ++ if (enabled == xhci->intr[v].msix_used) { + return; + } + + if (enabled) { +- trace_usb_xhci_irq_msix_use(0); +- msix_vector_use(&xhci->pci_dev, 0); +- xhci->msix_used = true; ++ trace_usb_xhci_irq_msix_use(v); ++ msix_vector_use(&xhci->pci_dev, v); ++ xhci->intr[v].msix_used = true; + } else { +- trace_usb_xhci_irq_msix_unuse(0); +- msix_vector_unuse(&xhci->pci_dev, 0); +- xhci->msix_used = false; ++ trace_usb_xhci_irq_msix_unuse(v); ++ msix_vector_unuse(&xhci->pci_dev, v); ++ xhci->intr[v].msix_used = false; + } + } + +-static void xhci_intr_raise(XHCIState *xhci) ++static void xhci_intr_raise(XHCIState *xhci, int v) + { +- xhci->erdp_low |= ERDP_EHB; +- xhci->iman |= IMAN_IP; ++ xhci->intr[v].erdp_low |= ERDP_EHB; ++ xhci->intr[v].iman |= IMAN_IP; + xhci->usbsts |= USBSTS_EINT; + +- if (!(xhci->iman & IMAN_IE)) { ++ if (!(xhci->intr[v].iman & IMAN_IE)) { + return; + } + +@@ -675,24 +678,26 @@ static void xhci_intr_raise(XHCIState *xhci) + } + + if (msix_enabled(&xhci->pci_dev)) { +- trace_usb_xhci_irq_msix(0); +- msix_notify(&xhci->pci_dev, 0); ++ trace_usb_xhci_irq_msix(v); ++ msix_notify(&xhci->pci_dev, v); + return; + } + + if (msi_enabled(&xhci->pci_dev)) { +- trace_usb_xhci_irq_msi(0); +- msi_notify(&xhci->pci_dev, 0); ++ trace_usb_xhci_irq_msi(v); ++ msi_notify(&xhci->pci_dev, v); + return; + } + +- trace_usb_xhci_irq_intx(1); +- qemu_set_irq(xhci->irq, 1); ++ if (v == 0) { ++ trace_usb_xhci_irq_intx(1); ++ qemu_set_irq(xhci->irq, 1); ++ } + } + + static inline int xhci_running(XHCIState *xhci) + { +- return !(xhci->usbsts & USBSTS_HCH) && !xhci->er_full; ++ return !(xhci->usbsts & USBSTS_HCH) && !xhci->intr[0].er_full; + } + + static void xhci_die(XHCIState *xhci) +@@ -701,8 +706,9 @@ static void xhci_die(XHCIState *xhci) + fprintf(stderr, "xhci: asserted controller error\n"); + } + +-static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) ++static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v) + { ++ XHCIInterrupter *intr = &xhci->intr[v]; + XHCITRB ev_trb; + dma_addr_t addr; + +@@ -710,27 +716,28 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) + ev_trb.status = cpu_to_le32(event->length | (event->ccode << 24)); + ev_trb.control = (event->slotid << 24) | (event->epid << 16) | + event->flags | (event->type << TRB_TYPE_SHIFT); +- if (xhci->er_pcs) { ++ if (intr->er_pcs) { + ev_trb.control |= TRB_C; + } + ev_trb.control = cpu_to_le32(ev_trb.control); + +- trace_usb_xhci_queue_event(xhci->er_ep_idx, trb_name(&ev_trb), ++ trace_usb_xhci_queue_event(v, intr->er_ep_idx, trb_name(&ev_trb), + event_name(event), ev_trb.parameter, + ev_trb.status, ev_trb.control); + +- addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; ++ addr = intr->er_start + TRB_SIZE*intr->er_ep_idx; + pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE); + +- xhci->er_ep_idx++; +- if (xhci->er_ep_idx >= xhci->er_size) { +- xhci->er_ep_idx = 0; +- xhci->er_pcs = !xhci->er_pcs; ++ intr->er_ep_idx++; ++ if (intr->er_ep_idx >= intr->er_size) { ++ intr->er_ep_idx = 0; ++ intr->er_pcs = !intr->er_pcs; + } + } + +-static void xhci_events_update(XHCIState *xhci) ++static void xhci_events_update(XHCIState *xhci, int v) + { ++ XHCIInterrupter *intr = &xhci->intr[v]; + dma_addr_t erdp; + unsigned int dp_idx; + bool do_irq = 0; +@@ -739,115 +746,116 @@ static void xhci_events_update(XHCIState *xhci) + return; + } + +- erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); +- if (erdp < xhci->er_start || +- erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { ++ erdp = xhci_addr64(intr->erdp_low, intr->erdp_high); ++ if (erdp < intr->er_start || ++ erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) { + fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp); +- fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n", +- xhci->er_start, xhci->er_size); ++ fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n", ++ v, intr->er_start, intr->er_size); + xhci_die(xhci); + return; + } +- dp_idx = (erdp - xhci->er_start) / TRB_SIZE; +- assert(dp_idx < xhci->er_size); ++ dp_idx = (erdp - intr->er_start) / TRB_SIZE; ++ assert(dp_idx < intr->er_size); + + /* NEC didn't read section 4.9.4 of the spec (v1.0 p139 top Note) and thus + * deadlocks when the ER is full. Hack it by holding off events until + * the driver decides to free at least half of the ring */ +- if (xhci->er_full) { +- int er_free = dp_idx - xhci->er_ep_idx; ++ if (intr->er_full) { ++ int er_free = dp_idx - intr->er_ep_idx; + if (er_free <= 0) { +- er_free += xhci->er_size; ++ er_free += intr->er_size; + } +- if (er_free < (xhci->er_size/2)) { ++ if (er_free < (intr->er_size/2)) { + DPRINTF("xhci_events_update(): event ring still " + "more than half full (hack)\n"); + return; + } + } + +- while (xhci->ev_buffer_put != xhci->ev_buffer_get) { +- assert(xhci->er_full); +- if (((xhci->er_ep_idx+1) % xhci->er_size) == dp_idx) { ++ while (intr->ev_buffer_put != intr->ev_buffer_get) { ++ assert(intr->er_full); ++ if (((intr->er_ep_idx+1) % intr->er_size) == dp_idx) { + DPRINTF("xhci_events_update(): event ring full again\n"); + #ifndef ER_FULL_HACK + XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR}; +- xhci_write_event(xhci, &full); ++ xhci_write_event(xhci, &full, v); + #endif + do_irq = 1; + break; + } +- XHCIEvent *event = &xhci->ev_buffer[xhci->ev_buffer_get]; +- xhci_write_event(xhci, event); +- xhci->ev_buffer_get++; ++ XHCIEvent *event = &intr->ev_buffer[intr->ev_buffer_get]; ++ xhci_write_event(xhci, event, v); ++ intr->ev_buffer_get++; + do_irq = 1; +- if (xhci->ev_buffer_get == EV_QUEUE) { +- xhci->ev_buffer_get = 0; ++ if (intr->ev_buffer_get == EV_QUEUE) { ++ intr->ev_buffer_get = 0; + } + } + + if (do_irq) { +- xhci_intr_raise(xhci); ++ xhci_intr_raise(xhci, v); + } + +- if (xhci->er_full && xhci->ev_buffer_put == xhci->ev_buffer_get) { ++ if (intr->er_full && intr->ev_buffer_put == intr->ev_buffer_get) { + DPRINTF("xhci_events_update(): event ring no longer full\n"); +- xhci->er_full = 0; ++ intr->er_full = 0; + } + return; + } + +-static void xhci_event(XHCIState *xhci, XHCIEvent *event) ++static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v) + { ++ XHCIInterrupter *intr = &xhci->intr[v]; + dma_addr_t erdp; + unsigned int dp_idx; + +- if (xhci->er_full) { ++ if (intr->er_full) { + DPRINTF("xhci_event(): ER full, queueing\n"); +- if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) { ++ if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) { + fprintf(stderr, "xhci: event queue full, dropping event!\n"); + return; + } +- xhci->ev_buffer[xhci->ev_buffer_put++] = *event; +- if (xhci->ev_buffer_put == EV_QUEUE) { +- xhci->ev_buffer_put = 0; ++ intr->ev_buffer[intr->ev_buffer_put++] = *event; ++ if (intr->ev_buffer_put == EV_QUEUE) { ++ intr->ev_buffer_put = 0; + } + return; + } + +- erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); +- if (erdp < xhci->er_start || +- erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { ++ erdp = xhci_addr64(intr->erdp_low, intr->erdp_high); ++ if (erdp < intr->er_start || ++ erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) { + fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp); +- fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n", +- xhci->er_start, xhci->er_size); ++ fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n", ++ v, intr->er_start, intr->er_size); + xhci_die(xhci); + return; + } + +- dp_idx = (erdp - xhci->er_start) / TRB_SIZE; +- assert(dp_idx < xhci->er_size); ++ dp_idx = (erdp - intr->er_start) / TRB_SIZE; ++ assert(dp_idx < intr->er_size); + +- if ((xhci->er_ep_idx+1) % xhci->er_size == dp_idx) { ++ if ((intr->er_ep_idx+1) % intr->er_size == dp_idx) { + DPRINTF("xhci_event(): ER full, queueing\n"); + #ifndef ER_FULL_HACK + XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR}; + xhci_write_event(xhci, &full); + #endif +- xhci->er_full = 1; +- if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) { ++ intr->er_full = 1; ++ if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) { + fprintf(stderr, "xhci: event queue full, dropping event!\n"); + return; + } +- xhci->ev_buffer[xhci->ev_buffer_put++] = *event; +- if (xhci->ev_buffer_put == EV_QUEUE) { +- xhci->ev_buffer_put = 0; ++ intr->ev_buffer[intr->ev_buffer_put++] = *event; ++ if (intr->ev_buffer_put == EV_QUEUE) { ++ intr->ev_buffer_put = 0; + } + } else { +- xhci_write_event(xhci, event); ++ xhci_write_event(xhci, event, v); + } + +- xhci_intr_raise(xhci); ++ xhci_intr_raise(xhci, v); + } + + static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring, +@@ -939,17 +947,18 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) + } + } + +-static void xhci_er_reset(XHCIState *xhci) ++static void xhci_er_reset(XHCIState *xhci, int v) + { ++ XHCIInterrupter *intr = &xhci->intr[v]; + XHCIEvRingSeg seg; + + /* cache the (sole) event ring segment location */ +- if (xhci->erstsz != 1) { +- fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", xhci->erstsz); ++ if (intr->erstsz != 1) { ++ fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", intr->erstsz); + xhci_die(xhci); + return; + } +- dma_addr_t erstba = xhci_addr64(xhci->erstba_low, xhci->erstba_high); ++ dma_addr_t erstba = xhci_addr64(intr->erstba_low, intr->erstba_high); + pci_dma_read(&xhci->pci_dev, erstba, &seg, sizeof(seg)); + le32_to_cpus(&seg.addr_low); + le32_to_cpus(&seg.addr_high); +@@ -959,15 +968,15 @@ static void xhci_er_reset(XHCIState *xhci) + xhci_die(xhci); + return; + } +- xhci->er_start = xhci_addr64(seg.addr_low, seg.addr_high); +- xhci->er_size = seg.size; ++ intr->er_start = xhci_addr64(seg.addr_low, seg.addr_high); ++ intr->er_size = seg.size; + +- xhci->er_ep_idx = 0; +- xhci->er_pcs = 1; +- xhci->er_full = 0; ++ intr->er_ep_idx = 0; ++ intr->er_pcs = 1; ++ intr->er_full = 0; + +- DPRINTF("xhci: event ring:" DMA_ADDR_FMT " [%d]\n", +- xhci->er_start, xhci->er_size); ++ DPRINTF("xhci: event ring[%d]:" DMA_ADDR_FMT " [%d]\n", ++ v, intr->er_start, intr->er_size); + } + + static void xhci_run(XHCIState *xhci) +@@ -1368,7 +1377,7 @@ static void xhci_xfer_report(XHCITransfer *xfer) + DPRINTF("xhci_xfer_data: EDTLA=%d\n", event.length); + edtla = 0; + } +- xhci_event(xhci, &event); ++ xhci_event(xhci, &event, 0 /* FIXME */); + reported = 1; + if (xfer->status != CC_SUCCESS) { + return; +@@ -2244,7 +2253,7 @@ static void xhci_process_commands(XHCIState *xhci) + break; + } + event.slotid = slotid; +- xhci_event(xhci, &event); ++ xhci_event(xhci, &event, 0 /* FIXME */); + } + } + +@@ -2274,7 +2283,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) + port->portsc |= PORTSC_CSC; + XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, + port->portnr << 24}; +- xhci_event(xhci, &ev); ++ xhci_event(xhci, &ev, 0 /* FIXME */); + DPRINTF("xhci: port change event for port %d\n", port->portnr); + } + } +@@ -2307,20 +2316,22 @@ static void xhci_reset(DeviceState *dev) + xhci_update_port(xhci, xhci->ports + i, 0); + } + +- xhci->iman = 0; +- xhci->imod = 0; +- xhci->erstsz = 0; +- xhci->erstba_low = 0; +- xhci->erstba_high = 0; +- xhci->erdp_low = 0; +- xhci->erdp_high = 0; +- xhci->msix_used = 0; ++ for (i = 0; i < MAXINTRS; i++) { ++ xhci->intr[i].iman = 0; ++ xhci->intr[i].imod = 0; ++ xhci->intr[i].erstsz = 0; ++ xhci->intr[i].erstba_low = 0; ++ xhci->intr[i].erstba_high = 0; ++ xhci->intr[i].erdp_low = 0; ++ xhci->intr[i].erdp_high = 0; ++ xhci->intr[i].msix_used = 0; + +- xhci->er_ep_idx = 0; +- xhci->er_pcs = 1; +- xhci->er_full = 0; +- xhci->ev_buffer_put = 0; +- xhci->ev_buffer_get = 0; ++ xhci->intr[i].er_ep_idx = 0; ++ xhci->intr[i].er_pcs = 1; ++ xhci->intr[i].er_full = 0; ++ xhci->intr[i].ev_buffer_put = 0; ++ xhci->intr[i].ev_buffer_get = 0; ++ } + + xhci->mfindex_start = qemu_get_clock_ns(vm_clock); + xhci_mfwrap_update(xhci); +@@ -2551,7 +2562,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) + if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) { + XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED}; + xhci->crcr_low &= ~CRCR_CRR; +- xhci_event(xhci, &event); ++ xhci_event(xhci, &event, 0 /* FIXME */); + DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low); + } else { + dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val); +@@ -2575,6 +2586,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) + + static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + { ++ XHCIInterrupter *intr = &xhci->intr[0]; + uint32_t ret; + + switch (reg) { +@@ -2582,25 +2594,25 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + ret = xhci_mfindex_get(xhci) & 0x3fff; + break; + case 0x20: /* IMAN */ +- ret = xhci->iman; ++ ret = intr->iman; + break; + case 0x24: /* IMOD */ +- ret = xhci->imod; ++ ret = intr->imod; + break; + case 0x28: /* ERSTSZ */ +- ret = xhci->erstsz; ++ ret = intr->erstsz; + break; + case 0x30: /* ERSTBA low */ +- ret = xhci->erstba_low; ++ ret = intr->erstba_low; + break; + case 0x34: /* ERSTBA high */ +- ret = xhci->erstba_high; ++ ret = intr->erstba_high; + break; + case 0x38: /* ERDP low */ +- ret = xhci->erdp_low; ++ ret = intr->erdp_low; + break; + case 0x3c: /* ERDP high */ +- ret = xhci->erdp_high; ++ ret = intr->erdp_high; + break; + default: + fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); +@@ -2613,42 +2625,43 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + + static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) + { ++ XHCIInterrupter *intr = &xhci->intr[0]; + trace_usb_xhci_runtime_write(reg, val); + + switch (reg) { + case 0x20: /* IMAN */ + if (val & IMAN_IP) { +- xhci->iman &= ~IMAN_IP; ++ intr->iman &= ~IMAN_IP; + } +- xhci->iman &= ~IMAN_IE; +- xhci->iman |= val & IMAN_IE; ++ intr->iman &= ~IMAN_IE; ++ intr->iman |= val & IMAN_IE; + xhci_intx_update(xhci); +- xhci_msix_update(xhci); ++ xhci_msix_update(xhci, 0); + break; + case 0x24: /* IMOD */ +- xhci->imod = val; ++ intr->imod = val; + break; + case 0x28: /* ERSTSZ */ +- xhci->erstsz = val & 0xffff; ++ intr->erstsz = val & 0xffff; + break; + case 0x30: /* ERSTBA low */ + /* XXX NEC driver bug: it doesn't align this to 64 bytes +- xhci->erstba_low = val & 0xffffffc0; */ +- xhci->erstba_low = val & 0xfffffff0; ++ intr->erstba_low = val & 0xffffffc0; */ ++ intr->erstba_low = val & 0xfffffff0; + break; + case 0x34: /* ERSTBA high */ +- xhci->erstba_high = val; +- xhci_er_reset(xhci); ++ intr->erstba_high = val; ++ xhci_er_reset(xhci, 0); + break; + case 0x38: /* ERDP low */ + if (val & ERDP_EHB) { +- xhci->erdp_low &= ~ERDP_EHB; ++ intr->erdp_low &= ~ERDP_EHB; + } +- xhci->erdp_low = (val & ~ERDP_EHB) | (xhci->erdp_low & ERDP_EHB); ++ intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB); + break; + case 0x3c: /* ERDP high */ +- xhci->erdp_high = val; +- xhci_events_update(xhci); ++ intr->erdp_high = val; ++ xhci_events_update(xhci, 0); + break; + default: + fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); +@@ -2780,7 +2793,7 @@ static void xhci_wakeup(USBPort *usbport) + return; + } + port->portsc |= PORTSC_PLC; +- xhci_event(xhci, &ev); ++ xhci_event(xhci, &ev, 0 /* FIXME */); + } + + static void xhci_complete(USBPort *port, USBPacket *packet) +diff --git a/trace-events b/trace-events +index 93b05ab..9d39d8d 100644 +--- a/trace-events ++++ b/trace-events +@@ -319,7 +319,7 @@ usb_xhci_irq_msi(uint32_t nr) "nr %d" + usb_xhci_irq_msix(uint32_t nr) "nr %d" + usb_xhci_irq_msix_use(uint32_t nr) "nr %d" + usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d" +-usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" ++usb_xhci_queue_event(uint32_t vector, uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "v %d, idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x" + usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x" + usb_xhci_slot_enable(uint32_t slotid) "slotid %d" + usb_xhci_slot_disable(uint32_t slotid) "slotid %d" diff --git a/0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch b/0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch deleted file mode 100644 index d753d08..0000000 --- a/0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 670eba790c368e9c37b0c964d94e0ff7f0d0c443 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 30 Aug 2012 17:15:12 +0200 -Subject: [PATCH] xhci: prepare xhci_runtime_{read,write} for multiple - interrupters - -Prepare xhci runtime register access function for multiple interrupters. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 100 +++++++++++++++++++++++++++++++----------------------- - 1 file changed, 57 insertions(+), 43 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 8a14ee8..6b3ff16 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -2586,37 +2586,43 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) - - static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - { -- XHCIInterrupter *intr = &xhci->intr[0]; -- uint32_t ret; -+ uint32_t ret = 0; - -- switch (reg) { -- case 0x00: /* MFINDEX */ -- ret = xhci_mfindex_get(xhci) & 0x3fff; -- break; -- case 0x20: /* IMAN */ -- ret = intr->iman; -- break; -- case 0x24: /* IMOD */ -- ret = intr->imod; -- break; -- case 0x28: /* ERSTSZ */ -- ret = intr->erstsz; -- break; -- case 0x30: /* ERSTBA low */ -- ret = intr->erstba_low; -- break; -- case 0x34: /* ERSTBA high */ -- ret = intr->erstba_high; -- break; -- case 0x38: /* ERDP low */ -- ret = intr->erdp_low; -- break; -- case 0x3c: /* ERDP high */ -- ret = intr->erdp_high; -- break; -- default: -- fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); -- ret = 0; -+ if (reg < 0x20) { -+ switch (reg) { -+ case 0x00: /* MFINDEX */ -+ ret = xhci_mfindex_get(xhci) & 0x3fff; -+ break; -+ default: -+ fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); -+ break; -+ } -+ } else { -+ int v = (reg - 0x20) / 0x20; -+ XHCIInterrupter *intr = &xhci->intr[v]; -+ switch (reg & 0x1f) { -+ case 0x00: /* IMAN */ -+ ret = intr->iman; -+ break; -+ case 0x04: /* IMOD */ -+ ret = intr->imod; -+ break; -+ case 0x08: /* ERSTSZ */ -+ ret = intr->erstsz; -+ break; -+ case 0x10: /* ERSTBA low */ -+ ret = intr->erstba_low; -+ break; -+ case 0x14: /* ERSTBA high */ -+ ret = intr->erstba_high; -+ break; -+ case 0x18: /* ERDP low */ -+ ret = intr->erdp_low; -+ break; -+ case 0x1c: /* ERDP high */ -+ ret = intr->erdp_high; -+ break; -+ } - } - - trace_usb_xhci_runtime_read(reg, ret); -@@ -2625,43 +2631,51 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - - static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) - { -- XHCIInterrupter *intr = &xhci->intr[0]; -+ int v = (reg - 0x20) / 0x20; -+ XHCIInterrupter *intr = &xhci->intr[v]; - trace_usb_xhci_runtime_write(reg, val); - -- switch (reg) { -- case 0x20: /* IMAN */ -+ if (reg < 0x20) { -+ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); -+ return; -+ } -+ -+ switch (reg & 0x1f) { -+ case 0x00: /* IMAN */ - if (val & IMAN_IP) { - intr->iman &= ~IMAN_IP; - } - intr->iman &= ~IMAN_IE; - intr->iman |= val & IMAN_IE; -- xhci_intx_update(xhci); -- xhci_msix_update(xhci, 0); -+ if (v == 0) { -+ xhci_intx_update(xhci); -+ } -+ xhci_msix_update(xhci, v); - break; -- case 0x24: /* IMOD */ -+ case 0x04: /* IMOD */ - intr->imod = val; - break; -- case 0x28: /* ERSTSZ */ -+ case 0x08: /* ERSTSZ */ - intr->erstsz = val & 0xffff; - break; -- case 0x30: /* ERSTBA low */ -+ case 0x10: /* ERSTBA low */ - /* XXX NEC driver bug: it doesn't align this to 64 bytes - intr->erstba_low = val & 0xffffffc0; */ - intr->erstba_low = val & 0xfffffff0; - break; -- case 0x34: /* ERSTBA high */ -+ case 0x14: /* ERSTBA high */ - intr->erstba_high = val; -- xhci_er_reset(xhci, 0); -+ xhci_er_reset(xhci, v); - break; -- case 0x38: /* ERDP low */ -+ case 0x18: /* ERDP low */ - if (val & ERDP_EHB) { - intr->erdp_low &= ~ERDP_EHB; - } - intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB); - break; -- case 0x3c: /* ERDP high */ -+ case 0x1c: /* ERDP high */ - intr->erdp_high = val; -- xhci_events_update(xhci, 0); -+ xhci_events_update(xhci, v); - break; - default: - fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); --- -1.7.12.1 - diff --git a/0622-xhci-pick-target-interrupter.patch b/0622-xhci-pick-target-interrupter.patch deleted file mode 100644 index e336b49..0000000 --- a/0622-xhci-pick-target-interrupter.patch +++ /dev/null @@ -1,93 +0,0 @@ -From d6968ced27f697b26d7a1d5b44f15eeb300a9fd6 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 31 Aug 2012 15:30:51 +0200 -Subject: [PATCH] xhci: pick target interrupter - -Pick the correct interrupter when queuing an event. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 22 ++++++++++++++++------ - 1 file changed, 16 insertions(+), 6 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 6b3ff16..3b03c6c 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -264,6 +264,10 @@ typedef enum TRBCCode { - - #define TRB_LK_TC (1<<1) - -+#define TRB_INTR_SHIFT 22 -+#define TRB_INTR_MASK 0x3ff -+#define TRB_INTR(t) (((t).status >> TRB_INTR_SHIFT) & TRB_INTR_MASK) -+ - #define EP_TYPE_MASK 0x7 - #define EP_TYPE_SHIFT 3 - -@@ -806,10 +810,16 @@ static void xhci_events_update(XHCIState *xhci, int v) - - static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v) - { -- XHCIInterrupter *intr = &xhci->intr[v]; -+ XHCIInterrupter *intr; - dma_addr_t erdp; - unsigned int dp_idx; - -+ if (v >= MAXINTRS) { -+ DPRINTF("intr nr out of range (%d >= %d)\n", v, MAXINTRS); -+ return; -+ } -+ intr = &xhci->intr[v]; -+ - if (intr->er_full) { - DPRINTF("xhci_event(): ER full, queueing\n"); - if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) { -@@ -1377,7 +1387,7 @@ static void xhci_xfer_report(XHCITransfer *xfer) - DPRINTF("xhci_xfer_data: EDTLA=%d\n", event.length); - edtla = 0; - } -- xhci_event(xhci, &event, 0 /* FIXME */); -+ xhci_event(xhci, &event, TRB_INTR(*trb)); - reported = 1; - if (xfer->status != CC_SUCCESS) { - return; -@@ -2253,7 +2263,7 @@ static void xhci_process_commands(XHCIState *xhci) - break; - } - event.slotid = slotid; -- xhci_event(xhci, &event, 0 /* FIXME */); -+ xhci_event(xhci, &event, 0); - } - } - -@@ -2283,7 +2293,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) - port->portsc |= PORTSC_CSC; - XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, - port->portnr << 24}; -- xhci_event(xhci, &ev, 0 /* FIXME */); -+ xhci_event(xhci, &ev, 0); - DPRINTF("xhci: port change event for port %d\n", port->portnr); - } - } -@@ -2562,7 +2572,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) - if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) { - XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED}; - xhci->crcr_low &= ~CRCR_CRR; -- xhci_event(xhci, &event, 0 /* FIXME */); -+ xhci_event(xhci, &event, 0); - DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low); - } else { - dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val); -@@ -2807,7 +2817,7 @@ static void xhci_wakeup(USBPort *usbport) - return; - } - port->portsc |= PORTSC_PLC; -- xhci_event(xhci, &ev, 0 /* FIXME */); -+ xhci_event(xhci, &ev, 0); - } - - static void xhci_complete(USBPort *port, USBPacket *packet) --- -1.7.12.1 - diff --git a/0622-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch b/0622-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch new file mode 100644 index 0000000..15ce4f7 --- /dev/null +++ b/0622-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch @@ -0,0 +1,156 @@ +From b4457799e9610602d20382843c1d2bde4ce475dd Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 30 Aug 2012 17:15:12 +0200 +Subject: [PATCH] xhci: prepare xhci_runtime_{read,write} for multiple + interrupters + +Prepare xhci runtime register access function for multiple interrupters. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 100 +++++++++++++++++++++++++++++++----------------------- + 1 file changed, 57 insertions(+), 43 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 76da7a9..df2ea22 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -2586,37 +2586,43 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) + + static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + { +- XHCIInterrupter *intr = &xhci->intr[0]; +- uint32_t ret; ++ uint32_t ret = 0; + +- switch (reg) { +- case 0x00: /* MFINDEX */ +- ret = xhci_mfindex_get(xhci) & 0x3fff; +- break; +- case 0x20: /* IMAN */ +- ret = intr->iman; +- break; +- case 0x24: /* IMOD */ +- ret = intr->imod; +- break; +- case 0x28: /* ERSTSZ */ +- ret = intr->erstsz; +- break; +- case 0x30: /* ERSTBA low */ +- ret = intr->erstba_low; +- break; +- case 0x34: /* ERSTBA high */ +- ret = intr->erstba_high; +- break; +- case 0x38: /* ERDP low */ +- ret = intr->erdp_low; +- break; +- case 0x3c: /* ERDP high */ +- ret = intr->erdp_high; +- break; +- default: +- fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); +- ret = 0; ++ if (reg < 0x20) { ++ switch (reg) { ++ case 0x00: /* MFINDEX */ ++ ret = xhci_mfindex_get(xhci) & 0x3fff; ++ break; ++ default: ++ fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); ++ break; ++ } ++ } else { ++ int v = (reg - 0x20) / 0x20; ++ XHCIInterrupter *intr = &xhci->intr[v]; ++ switch (reg & 0x1f) { ++ case 0x00: /* IMAN */ ++ ret = intr->iman; ++ break; ++ case 0x04: /* IMOD */ ++ ret = intr->imod; ++ break; ++ case 0x08: /* ERSTSZ */ ++ ret = intr->erstsz; ++ break; ++ case 0x10: /* ERSTBA low */ ++ ret = intr->erstba_low; ++ break; ++ case 0x14: /* ERSTBA high */ ++ ret = intr->erstba_high; ++ break; ++ case 0x18: /* ERDP low */ ++ ret = intr->erdp_low; ++ break; ++ case 0x1c: /* ERDP high */ ++ ret = intr->erdp_high; ++ break; ++ } + } + + trace_usb_xhci_runtime_read(reg, ret); +@@ -2625,43 +2631,51 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + + static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) + { +- XHCIInterrupter *intr = &xhci->intr[0]; ++ int v = (reg - 0x20) / 0x20; ++ XHCIInterrupter *intr = &xhci->intr[v]; + trace_usb_xhci_runtime_write(reg, val); + +- switch (reg) { +- case 0x20: /* IMAN */ ++ if (reg < 0x20) { ++ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); ++ return; ++ } ++ ++ switch (reg & 0x1f) { ++ case 0x00: /* IMAN */ + if (val & IMAN_IP) { + intr->iman &= ~IMAN_IP; + } + intr->iman &= ~IMAN_IE; + intr->iman |= val & IMAN_IE; +- xhci_intx_update(xhci); +- xhci_msix_update(xhci, 0); ++ if (v == 0) { ++ xhci_intx_update(xhci); ++ } ++ xhci_msix_update(xhci, v); + break; +- case 0x24: /* IMOD */ ++ case 0x04: /* IMOD */ + intr->imod = val; + break; +- case 0x28: /* ERSTSZ */ ++ case 0x08: /* ERSTSZ */ + intr->erstsz = val & 0xffff; + break; +- case 0x30: /* ERSTBA low */ ++ case 0x10: /* ERSTBA low */ + /* XXX NEC driver bug: it doesn't align this to 64 bytes + intr->erstba_low = val & 0xffffffc0; */ + intr->erstba_low = val & 0xfffffff0; + break; +- case 0x34: /* ERSTBA high */ ++ case 0x14: /* ERSTBA high */ + intr->erstba_high = val; +- xhci_er_reset(xhci, 0); ++ xhci_er_reset(xhci, v); + break; +- case 0x38: /* ERDP low */ ++ case 0x18: /* ERDP low */ + if (val & ERDP_EHB) { + intr->erdp_low &= ~ERDP_EHB; + } + intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB); + break; +- case 0x3c: /* ERDP high */ ++ case 0x1c: /* ERDP high */ + intr->erdp_high = val; +- xhci_events_update(xhci, 0); ++ xhci_events_update(xhci, v); + break; + default: + fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); diff --git a/0623-xhci-pick-target-interrupter.patch b/0623-xhci-pick-target-interrupter.patch new file mode 100644 index 0000000..7b6781f --- /dev/null +++ b/0623-xhci-pick-target-interrupter.patch @@ -0,0 +1,90 @@ +From ebb89c9a420f2aa87796f377992ac403adcab309 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 31 Aug 2012 15:30:51 +0200 +Subject: [PATCH] xhci: pick target interrupter + +Pick the correct interrupter when queuing an event. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index df2ea22..9667c0d 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -264,6 +264,10 @@ typedef enum TRBCCode { + + #define TRB_LK_TC (1<<1) + ++#define TRB_INTR_SHIFT 22 ++#define TRB_INTR_MASK 0x3ff ++#define TRB_INTR(t) (((t).status >> TRB_INTR_SHIFT) & TRB_INTR_MASK) ++ + #define EP_TYPE_MASK 0x7 + #define EP_TYPE_SHIFT 3 + +@@ -806,10 +810,16 @@ static void xhci_events_update(XHCIState *xhci, int v) + + static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v) + { +- XHCIInterrupter *intr = &xhci->intr[v]; ++ XHCIInterrupter *intr; + dma_addr_t erdp; + unsigned int dp_idx; + ++ if (v >= MAXINTRS) { ++ DPRINTF("intr nr out of range (%d >= %d)\n", v, MAXINTRS); ++ return; ++ } ++ intr = &xhci->intr[v]; ++ + if (intr->er_full) { + DPRINTF("xhci_event(): ER full, queueing\n"); + if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) { +@@ -1377,7 +1387,7 @@ static void xhci_xfer_report(XHCITransfer *xfer) + DPRINTF("xhci_xfer_data: EDTLA=%d\n", event.length); + edtla = 0; + } +- xhci_event(xhci, &event, 0 /* FIXME */); ++ xhci_event(xhci, &event, TRB_INTR(*trb)); + reported = 1; + if (xfer->status != CC_SUCCESS) { + return; +@@ -2253,7 +2263,7 @@ static void xhci_process_commands(XHCIState *xhci) + break; + } + event.slotid = slotid; +- xhci_event(xhci, &event, 0 /* FIXME */); ++ xhci_event(xhci, &event, 0); + } + } + +@@ -2283,7 +2293,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) + port->portsc |= PORTSC_CSC; + XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, + port->portnr << 24}; +- xhci_event(xhci, &ev, 0 /* FIXME */); ++ xhci_event(xhci, &ev, 0); + DPRINTF("xhci: port change event for port %d\n", port->portnr); + } + } +@@ -2562,7 +2572,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) + if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) { + XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED}; + xhci->crcr_low &= ~CRCR_CRR; +- xhci_event(xhci, &event, 0 /* FIXME */); ++ xhci_event(xhci, &event, 0); + DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low); + } else { + dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val); +@@ -2807,7 +2817,7 @@ static void xhci_wakeup(USBPort *usbport) + return; + } + port->portsc |= PORTSC_PLC; +- xhci_event(xhci, &ev, 0 /* FIXME */); ++ xhci_event(xhci, &ev, 0); + } + + static void xhci_complete(USBPort *port, USBPacket *packet) diff --git a/0623-xhci-support-multiple-interrupters.patch b/0623-xhci-support-multiple-interrupters.patch deleted file mode 100644 index 0d8ffbd..0000000 --- a/0623-xhci-support-multiple-interrupters.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4e4d4191a40b5cbcd6f967ed105eea559104cd8a Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 4 Sep 2012 12:56:55 +0200 -Subject: [PATCH] xhci: support multiple interrupters - -Everything is in place, flip the big switch now -and enable support for multiple interrupters. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 3b03c6c..4992705 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -42,7 +42,7 @@ - - #define MAXPORTS (MAXPORTS_2+MAXPORTS_3) - #define MAXSLOTS MAXPORTS --#define MAXINTRS 1 /* MAXPORTS */ -+#define MAXINTRS MAXPORTS - - #define TD_QUEUE 24 - -@@ -75,10 +75,6 @@ - # error Increase LEN_REGS - #endif - --#if MAXINTRS > 1 --# error TODO: only one interrupter supported --#endif -- - /* bit definitions */ - #define USBCMD_RS (1<<0) - #define USBCMD_HCRST (1<<1) --- -1.7.12.1 - diff --git a/0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch b/0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch deleted file mode 100644 index ec23202..0000000 --- a/0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch +++ /dev/null @@ -1,280 +0,0 @@ -From d2efc9f3dc62810ef6075f8759c9856016447c14 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 4 Sep 2012 14:42:20 +0200 -Subject: [PATCH] xhci: kill xhci_mem_{read,write} dispatcher functions - -... and register subregions instead, so we offload the dispatching -to the the memory subsystem which is designed to handle it. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb/hcd-xhci.c | 140 +++++++++++++++++++++++++++++------------------------- - 1 file changed, 75 insertions(+), 65 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 4992705..4ba9464 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -404,6 +404,10 @@ struct XHCIState { - USBBus bus; - qemu_irq irq; - MemoryRegion mem; -+ MemoryRegion mem_cap; -+ MemoryRegion mem_oper; -+ MemoryRegion mem_runtime; -+ MemoryRegion mem_doorbell; - const char *name; - unsigned int devaddr; - -@@ -2343,8 +2347,9 @@ static void xhci_reset(DeviceState *dev) - xhci_mfwrap_update(xhci); - } - --static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) -+static uint64_t xhci_cap_read(void *ptr, target_phys_addr_t reg, unsigned size) - { -+ XHCIState *xhci = ptr; - uint32_t ret; - - switch (reg) { -@@ -2401,7 +2406,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) - ret = 0x00000000; /* reserved */ - break; - default: -- fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", reg); -+ fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", (int)reg); - ret = 0; - } - -@@ -2482,8 +2487,9 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) - } - } - --static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) -+static uint64_t xhci_oper_read(void *ptr, target_phys_addr_t reg, unsigned size) - { -+ XHCIState *xhci = ptr; - uint32_t ret; - - if (reg >= 0x400) { -@@ -2519,7 +2525,7 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) - ret = xhci->config; - break; - default: -- fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", reg); -+ fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", (int)reg); - ret = 0; - } - -@@ -2527,8 +2533,11 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) - return ret; - } - --static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) -+static void xhci_oper_write(void *ptr, target_phys_addr_t reg, -+ uint64_t val, unsigned size) - { -+ XHCIState *xhci = ptr; -+ - if (reg >= 0x400) { - xhci_port_write(xhci, reg - 0x400, val); - return; -@@ -2586,12 +2595,14 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) - xhci->config = val & 0xff; - break; - default: -- fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); -+ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg); - } - } - --static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) -+static uint64_t xhci_runtime_read(void *ptr, target_phys_addr_t reg, -+ unsigned size) - { -+ XHCIState *xhci = ptr; - uint32_t ret = 0; - - if (reg < 0x20) { -@@ -2600,7 +2611,8 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - ret = xhci_mfindex_get(xhci) & 0x3fff; - break; - default: -- fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); -+ fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", -+ (int)reg); - break; - } - } else { -@@ -2635,14 +2647,16 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) - return ret; - } - --static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) -+static void xhci_runtime_write(void *ptr, target_phys_addr_t reg, -+ uint64_t val, unsigned size) - { -+ XHCIState *xhci = ptr; - int v = (reg - 0x20) / 0x20; - XHCIInterrupter *intr = &xhci->intr[v]; - trace_usb_xhci_runtime_write(reg, val); - - if (reg < 0x20) { -- fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); -+ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg); - return; - } - -@@ -2684,19 +2698,24 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) - xhci_events_update(xhci, v); - break; - default: -- fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); -+ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", -+ (int)reg); - } - } - --static uint32_t xhci_doorbell_read(XHCIState *xhci, uint32_t reg) -+static uint64_t xhci_doorbell_read(void *ptr, target_phys_addr_t reg, -+ unsigned size) - { - /* doorbells always read as 0 */ - trace_usb_xhci_doorbell_read(reg, 0); - return 0; - } - --static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val) -+static void xhci_doorbell_write(void *ptr, target_phys_addr_t reg, -+ uint64_t val, unsigned size) - { -+ XHCIState *xhci = ptr; -+ - trace_usb_xhci_doorbell_write(reg, val); - - if (!xhci_running(xhci)) { -@@ -2710,69 +2729,47 @@ static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val) - if (val == 0) { - xhci_process_commands(xhci); - } else { -- fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", val); -+ fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", -+ (uint32_t)val); - } - } else { - if (reg > MAXSLOTS) { -- fprintf(stderr, "xhci: bad doorbell %d\n", reg); -+ fprintf(stderr, "xhci: bad doorbell %d\n", (int)reg); - } else if (val > 31) { -- fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", reg, val); -+ fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", -+ (int)reg, (uint32_t)val); - } else { - xhci_kick_ep(xhci, reg, val); - } - } - } - --static uint64_t xhci_mem_read(void *ptr, target_phys_addr_t addr, -- unsigned size) --{ -- XHCIState *xhci = ptr; -- -- /* Only aligned reads are allowed on xHCI */ -- if (addr & 3) { -- fprintf(stderr, "xhci_mem_read: Mis-aligned read\n"); -- return 0; -- } -- -- if (addr < LEN_CAP) { -- return xhci_cap_read(xhci, addr); -- } else if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) { -- return xhci_oper_read(xhci, addr - OFF_OPER); -- } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) { -- return xhci_runtime_read(xhci, addr - OFF_RUNTIME); -- } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) { -- return xhci_doorbell_read(xhci, addr - OFF_DOORBELL); -- } else { -- fprintf(stderr, "xhci_mem_read: Bad offset %x\n", (int)addr); -- return 0; -- } --} -- --static void xhci_mem_write(void *ptr, target_phys_addr_t addr, -- uint64_t val, unsigned size) --{ -- XHCIState *xhci = ptr; -+static const MemoryRegionOps xhci_cap_ops = { -+ .read = xhci_cap_read, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; - -- /* Only aligned writes are allowed on xHCI */ -- if (addr & 3) { -- fprintf(stderr, "xhci_mem_write: Mis-aligned write\n"); -- return; -- } -+static const MemoryRegionOps xhci_oper_ops = { -+ .read = xhci_oper_read, -+ .write = xhci_oper_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; - -- if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) { -- xhci_oper_write(xhci, addr - OFF_OPER, val); -- } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) { -- xhci_runtime_write(xhci, addr - OFF_RUNTIME, val); -- } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) { -- xhci_doorbell_write(xhci, addr - OFF_DOORBELL, val); -- } else { -- fprintf(stderr, "xhci_mem_write: Bad offset %x\n", (int)addr); -- } --} -+static const MemoryRegionOps xhci_runtime_ops = { -+ .read = xhci_runtime_read, -+ .write = xhci_runtime_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; - --static const MemoryRegionOps xhci_mem_ops = { -- .read = xhci_mem_read, -- .write = xhci_mem_write, -+static const MemoryRegionOps xhci_doorbell_ops = { -+ .read = xhci_doorbell_read, -+ .write = xhci_doorbell_write, - .valid.min_access_size = 1, - .valid.max_access_size = 4, - .impl.min_access_size = 4, -@@ -2940,8 +2937,21 @@ static int usb_xhci_initfn(struct PCIDevice *dev) - - xhci->irq = xhci->pci_dev.irq[0]; - -- memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci, -- "xhci", LEN_REGS); -+ memory_region_init(&xhci->mem, "xhci", LEN_REGS); -+ memory_region_init_io(&xhci->mem_cap, &xhci_cap_ops, xhci, -+ "capabilities", LEN_CAP); -+ memory_region_init_io(&xhci->mem_oper, &xhci_oper_ops, xhci, -+ "operational", 0x400 + 0x10 * xhci->numports); -+ memory_region_init_io(&xhci->mem_runtime, &xhci_runtime_ops, xhci, -+ "runtime", LEN_RUNTIME); -+ memory_region_init_io(&xhci->mem_doorbell, &xhci_doorbell_ops, xhci, -+ "doorbell", LEN_DOORBELL); -+ -+ memory_region_add_subregion(&xhci->mem, 0, &xhci->mem_cap); -+ memory_region_add_subregion(&xhci->mem, OFF_OPER, &xhci->mem_oper); -+ memory_region_add_subregion(&xhci->mem, OFF_RUNTIME, &xhci->mem_runtime); -+ memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell); -+ - pci_register_bar(&xhci->pci_dev, 0, - PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64, - &xhci->mem); --- -1.7.12.1 - diff --git a/0624-xhci-support-multiple-interrupters.patch b/0624-xhci-support-multiple-interrupters.patch new file mode 100644 index 0000000..d83f1e9 --- /dev/null +++ b/0624-xhci-support-multiple-interrupters.patch @@ -0,0 +1,37 @@ +From bda96cc71d34d4c3163455c9ea570f62e9c745f4 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 4 Sep 2012 12:56:55 +0200 +Subject: [PATCH] xhci: support multiple interrupters + +Everything is in place, flip the big switch now +and enable support for multiple interrupters. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 9667c0d..874b545 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -42,7 +42,7 @@ + + #define MAXPORTS (MAXPORTS_2+MAXPORTS_3) + #define MAXSLOTS MAXPORTS +-#define MAXINTRS 1 /* MAXPORTS */ ++#define MAXINTRS MAXPORTS + + #define TD_QUEUE 24 + +@@ -75,10 +75,6 @@ + # error Increase LEN_REGS + #endif + +-#if MAXINTRS > 1 +-# error TODO: only one interrupter supported +-#endif +- + /* bit definitions */ + #define USBCMD_RS (1<<0) + #define USBCMD_HCRST (1<<1) diff --git a/0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch b/0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch deleted file mode 100644 index 1f0e575..0000000 --- a/0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 5b44a6c9c102b69690adcc2c5be886857ea35ebd Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 4 Sep 2012 14:18:34 +0200 -Subject: [PATCH] usb-redir: Change cancelled packet code into a generic - packet-id queue - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 102 +++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 71 insertions(+), 31 deletions(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index f183263..e2b8159 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -43,7 +43,6 @@ - #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f)) - #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f)) - --typedef struct Cancelled Cancelled; - typedef struct USBRedirDevice USBRedirDevice; - - /* Struct to hold buffered packets (iso or int input packets) */ -@@ -69,6 +68,18 @@ struct endp_data { - int bufpq_target_size; - }; - -+struct PacketIdQueueEntry { -+ uint64_t id; -+ QTAILQ_ENTRY(PacketIdQueueEntry)next; -+}; -+ -+struct PacketIdQueue { -+ USBRedirDevice *dev; -+ const char *name; -+ QTAILQ_HEAD(, PacketIdQueueEntry) head; -+ int size; -+}; -+ - struct USBRedirDevice { - USBDevice dev; - /* Properties */ -@@ -86,7 +97,7 @@ struct USBRedirDevice { - int64_t next_attach_time; - struct usbredirparser *parser; - struct endp_data endpoint[MAX_ENDPOINTS]; -- QTAILQ_HEAD(, Cancelled) cancelled; -+ struct PacketIdQueue cancelled; - /* Data for device filtering */ - struct usb_redir_device_connect_header device_info; - struct usb_redir_interface_info_header interface_info; -@@ -94,11 +105,6 @@ struct USBRedirDevice { - int filter_rules_count; - }; - --struct Cancelled { -- uint64_t id; -- QTAILQ_ENTRY(Cancelled)next; --}; -- - static void usbredir_hello(void *priv, struct usb_redir_hello_header *h); - static void usbredir_device_connect(void *priv, - struct usb_redir_device_connect_header *device_connect); -@@ -251,37 +257,75 @@ static int usbredir_write(void *priv, uint8_t *data, int count) - * Cancelled and buffered packets helpers - */ - --static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) -+static void packet_id_queue_init(struct PacketIdQueue *q, -+ USBRedirDevice *dev, const char *name) - { -- USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -- Cancelled *c; -+ q->dev = dev; -+ q->name = name; -+ QTAILQ_INIT(&q->head); -+ q->size = 0; -+} -+ -+static void packet_id_queue_add(struct PacketIdQueue *q, uint64_t id) -+{ -+ USBRedirDevice *dev = q->dev; -+ struct PacketIdQueueEntry *e; -+ -+ DPRINTF("adding packet id %"PRIu64" to %s queue\n", id, q->name); -+ -+ e = g_malloc0(sizeof(struct PacketIdQueueEntry)); -+ e->id = id; -+ QTAILQ_INSERT_TAIL(&q->head, e, next); -+ q->size++; -+} -+ -+static int packet_id_queue_remove(struct PacketIdQueue *q, uint64_t id) -+{ -+ USBRedirDevice *dev = q->dev; -+ struct PacketIdQueueEntry *e; -+ -+ QTAILQ_FOREACH(e, &q->head, next) { -+ if (e->id == id) { -+ DPRINTF("removing packet id %"PRIu64" from %s queue\n", -+ id, q->name); -+ QTAILQ_REMOVE(&q->head, e, next); -+ q->size--; -+ g_free(e); -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+static void packet_id_queue_empty(struct PacketIdQueue *q) -+{ -+ USBRedirDevice *dev = q->dev; -+ struct PacketIdQueueEntry *e, *next_e; - -- DPRINTF("cancel packet id %"PRIu64"\n", p->id); -+ DPRINTF("removing %d packet-ids from %s queue\n", q->size, q->name); - -- c = g_malloc0(sizeof(Cancelled)); -- c->id = p->id; -- QTAILQ_INSERT_TAIL(&dev->cancelled, c, next); -+ QTAILQ_FOREACH_SAFE(e, &q->head, next, next_e) { -+ QTAILQ_REMOVE(&q->head, e, next); -+ g_free(e); -+ } -+ q->size = 0; -+} - -+static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) -+{ -+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -+ -+ packet_id_queue_add(&dev->cancelled, p->id); - usbredirparser_send_cancel_data_packet(dev->parser, p->id); - usbredirparser_do_write(dev->parser); - } - - static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id) - { -- Cancelled *c; -- - if (!dev->dev.attached) { - return 1; /* Treat everything as cancelled after a disconnect */ - } -- -- QTAILQ_FOREACH(c, &dev->cancelled, next) { -- if (c->id == id) { -- QTAILQ_REMOVE(&dev->cancelled, c, next); -- g_free(c); -- return 1; -- } -- } -- return 0; -+ return packet_id_queue_remove(&dev->cancelled, id); - } - - static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev, -@@ -937,7 +981,7 @@ static int usbredir_initfn(USBDevice *udev) - dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev); - dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev); - -- QTAILQ_INIT(&dev->cancelled); -+ packet_id_queue_init(&dev->cancelled, dev, "cancelled"); - for (i = 0; i < MAX_ENDPOINTS; i++) { - QTAILQ_INIT(&dev->endpoint[i].bufpq); - } -@@ -955,13 +999,9 @@ static int usbredir_initfn(USBDevice *udev) - - static void usbredir_cleanup_device_queues(USBRedirDevice *dev) - { -- Cancelled *c, *next_c; - int i; - -- QTAILQ_FOREACH_SAFE(c, &dev->cancelled, next, next_c) { -- QTAILQ_REMOVE(&dev->cancelled, c, next); -- g_free(c); -- } -+ packet_id_queue_empty(&dev->cancelled); - for (i = 0; i < MAX_ENDPOINTS; i++) { - usbredir_free_bufpq(dev, I2EP(i)); - } --- -1.7.12.1 - diff --git a/0625-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch b/0625-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch new file mode 100644 index 0000000..3de9f67 --- /dev/null +++ b/0625-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch @@ -0,0 +1,277 @@ +From f9b8c1e3044cb4c221ea0c971630bf1f348af848 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 4 Sep 2012 14:42:20 +0200 +Subject: [PATCH] xhci: kill xhci_mem_{read,write} dispatcher functions + +... and register subregions instead, so we offload the dispatching +to the the memory subsystem which is designed to handle it. + +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 140 +++++++++++++++++++++++++++++------------------------- + 1 file changed, 75 insertions(+), 65 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 874b545..2c799fb 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -404,6 +404,10 @@ struct XHCIState { + USBBus bus; + qemu_irq irq; + MemoryRegion mem; ++ MemoryRegion mem_cap; ++ MemoryRegion mem_oper; ++ MemoryRegion mem_runtime; ++ MemoryRegion mem_doorbell; + const char *name; + unsigned int devaddr; + +@@ -2343,8 +2347,9 @@ static void xhci_reset(DeviceState *dev) + xhci_mfwrap_update(xhci); + } + +-static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) ++static uint64_t xhci_cap_read(void *ptr, target_phys_addr_t reg, unsigned size) + { ++ XHCIState *xhci = ptr; + uint32_t ret; + + switch (reg) { +@@ -2401,7 +2406,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) + ret = 0x00000000; /* reserved */ + break; + default: +- fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", reg); ++ fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", (int)reg); + ret = 0; + } + +@@ -2482,8 +2487,9 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) + } + } + +-static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) ++static uint64_t xhci_oper_read(void *ptr, target_phys_addr_t reg, unsigned size) + { ++ XHCIState *xhci = ptr; + uint32_t ret; + + if (reg >= 0x400) { +@@ -2519,7 +2525,7 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) + ret = xhci->config; + break; + default: +- fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", reg); ++ fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", (int)reg); + ret = 0; + } + +@@ -2527,8 +2533,11 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) + return ret; + } + +-static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) ++static void xhci_oper_write(void *ptr, target_phys_addr_t reg, ++ uint64_t val, unsigned size) + { ++ XHCIState *xhci = ptr; ++ + if (reg >= 0x400) { + xhci_port_write(xhci, reg - 0x400, val); + return; +@@ -2586,12 +2595,14 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) + xhci->config = val & 0xff; + break; + default: +- fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); ++ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg); + } + } + +-static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) ++static uint64_t xhci_runtime_read(void *ptr, target_phys_addr_t reg, ++ unsigned size) + { ++ XHCIState *xhci = ptr; + uint32_t ret = 0; + + if (reg < 0x20) { +@@ -2600,7 +2611,8 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + ret = xhci_mfindex_get(xhci) & 0x3fff; + break; + default: +- fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); ++ fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", ++ (int)reg); + break; + } + } else { +@@ -2635,14 +2647,16 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) + return ret; + } + +-static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) ++static void xhci_runtime_write(void *ptr, target_phys_addr_t reg, ++ uint64_t val, unsigned size) + { ++ XHCIState *xhci = ptr; + int v = (reg - 0x20) / 0x20; + XHCIInterrupter *intr = &xhci->intr[v]; + trace_usb_xhci_runtime_write(reg, val); + + if (reg < 0x20) { +- fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); ++ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg); + return; + } + +@@ -2684,19 +2698,24 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) + xhci_events_update(xhci, v); + break; + default: +- fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); ++ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", ++ (int)reg); + } + } + +-static uint32_t xhci_doorbell_read(XHCIState *xhci, uint32_t reg) ++static uint64_t xhci_doorbell_read(void *ptr, target_phys_addr_t reg, ++ unsigned size) + { + /* doorbells always read as 0 */ + trace_usb_xhci_doorbell_read(reg, 0); + return 0; + } + +-static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val) ++static void xhci_doorbell_write(void *ptr, target_phys_addr_t reg, ++ uint64_t val, unsigned size) + { ++ XHCIState *xhci = ptr; ++ + trace_usb_xhci_doorbell_write(reg, val); + + if (!xhci_running(xhci)) { +@@ -2710,69 +2729,47 @@ static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val) + if (val == 0) { + xhci_process_commands(xhci); + } else { +- fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", val); ++ fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", ++ (uint32_t)val); + } + } else { + if (reg > MAXSLOTS) { +- fprintf(stderr, "xhci: bad doorbell %d\n", reg); ++ fprintf(stderr, "xhci: bad doorbell %d\n", (int)reg); + } else if (val > 31) { +- fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", reg, val); ++ fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", ++ (int)reg, (uint32_t)val); + } else { + xhci_kick_ep(xhci, reg, val); + } + } + } + +-static uint64_t xhci_mem_read(void *ptr, target_phys_addr_t addr, +- unsigned size) +-{ +- XHCIState *xhci = ptr; +- +- /* Only aligned reads are allowed on xHCI */ +- if (addr & 3) { +- fprintf(stderr, "xhci_mem_read: Mis-aligned read\n"); +- return 0; +- } +- +- if (addr < LEN_CAP) { +- return xhci_cap_read(xhci, addr); +- } else if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) { +- return xhci_oper_read(xhci, addr - OFF_OPER); +- } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) { +- return xhci_runtime_read(xhci, addr - OFF_RUNTIME); +- } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) { +- return xhci_doorbell_read(xhci, addr - OFF_DOORBELL); +- } else { +- fprintf(stderr, "xhci_mem_read: Bad offset %x\n", (int)addr); +- return 0; +- } +-} +- +-static void xhci_mem_write(void *ptr, target_phys_addr_t addr, +- uint64_t val, unsigned size) +-{ +- XHCIState *xhci = ptr; ++static const MemoryRegionOps xhci_cap_ops = { ++ .read = xhci_cap_read, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; + +- /* Only aligned writes are allowed on xHCI */ +- if (addr & 3) { +- fprintf(stderr, "xhci_mem_write: Mis-aligned write\n"); +- return; +- } ++static const MemoryRegionOps xhci_oper_ops = { ++ .read = xhci_oper_read, ++ .write = xhci_oper_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; + +- if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) { +- xhci_oper_write(xhci, addr - OFF_OPER, val); +- } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) { +- xhci_runtime_write(xhci, addr - OFF_RUNTIME, val); +- } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) { +- xhci_doorbell_write(xhci, addr - OFF_DOORBELL, val); +- } else { +- fprintf(stderr, "xhci_mem_write: Bad offset %x\n", (int)addr); +- } +-} ++static const MemoryRegionOps xhci_runtime_ops = { ++ .read = xhci_runtime_read, ++ .write = xhci_runtime_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; + +-static const MemoryRegionOps xhci_mem_ops = { +- .read = xhci_mem_read, +- .write = xhci_mem_write, ++static const MemoryRegionOps xhci_doorbell_ops = { ++ .read = xhci_doorbell_read, ++ .write = xhci_doorbell_write, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 4, +@@ -2940,8 +2937,21 @@ static int usb_xhci_initfn(struct PCIDevice *dev) + + xhci->irq = xhci->pci_dev.irq[0]; + +- memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci, +- "xhci", LEN_REGS); ++ memory_region_init(&xhci->mem, "xhci", LEN_REGS); ++ memory_region_init_io(&xhci->mem_cap, &xhci_cap_ops, xhci, ++ "capabilities", LEN_CAP); ++ memory_region_init_io(&xhci->mem_oper, &xhci_oper_ops, xhci, ++ "operational", 0x400 + 0x10 * xhci->numports); ++ memory_region_init_io(&xhci->mem_runtime, &xhci_runtime_ops, xhci, ++ "runtime", LEN_RUNTIME); ++ memory_region_init_io(&xhci->mem_doorbell, &xhci_doorbell_ops, xhci, ++ "doorbell", LEN_DOORBELL); ++ ++ memory_region_add_subregion(&xhci->mem, 0, &xhci->mem_cap); ++ memory_region_add_subregion(&xhci->mem, OFF_OPER, &xhci->mem_oper); ++ memory_region_add_subregion(&xhci->mem, OFF_RUNTIME, &xhci->mem_runtime); ++ memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell); ++ + pci_register_bar(&xhci->pci_dev, 0, + PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64, + &xhci->mem); diff --git a/0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch b/0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch deleted file mode 100644 index e0e58c1..0000000 --- a/0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 9a38bd644b97a4a3ae92c9246bdcdd09ba937ae8 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 4 Sep 2012 17:03:54 +0200 -Subject: [PATCH] usb-redir: Add an already_in_flight packet-id queue - -After a live migration, the usb-hcd will re-queue all packets by -walking over the schedule in the guest memory again, but requests which -were encountered on the migration source before will already be in flight, -so these should *not* be re-send to the usbredir-host. - -This patch adds an already in flight packet ud queue, which will be filled by -the source before migration and then moved over to the migration dest, any -async handled packets are then checked against this queue to avoid sending -the same packet to the usbredir-host twice. - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index e2b8159..cdd705f 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -98,6 +98,7 @@ struct USBRedirDevice { - struct usbredirparser *parser; - struct endp_data endpoint[MAX_ENDPOINTS]; - struct PacketIdQueue cancelled; -+ struct PacketIdQueue already_in_flight; - /* Data for device filtering */ - struct usb_redir_device_connect_header device_info; - struct usb_redir_interface_info_header interface_info; -@@ -328,6 +329,34 @@ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id) - return packet_id_queue_remove(&dev->cancelled, id); - } - -+static void usbredir_fill_already_in_flight_from_ep(USBRedirDevice *dev, -+ struct USBEndpoint *ep) -+{ -+ static USBPacket *p; -+ -+ QTAILQ_FOREACH(p, &ep->queue, queue) { -+ packet_id_queue_add(&dev->already_in_flight, p->id); -+ } -+} -+ -+static void usbredir_fill_already_in_flight(USBRedirDevice *dev) -+{ -+ int ep; -+ struct USBDevice *udev = &dev->dev; -+ -+ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_ctl); -+ -+ for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { -+ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_in[ep]); -+ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_out[ep]); -+ } -+} -+ -+static int usbredir_already_in_flight(USBRedirDevice *dev, uint64_t id) -+{ -+ return packet_id_queue_remove(&dev->already_in_flight, id); -+} -+ - static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev, - uint8_t ep, uint64_t id) - { -@@ -543,6 +572,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p, - - DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, p->iov.size, p->id); - -+ if (usbredir_already_in_flight(dev, p->id)) { -+ return USB_RET_ASYNC; -+ } -+ - bulk_packet.endpoint = ep; - bulk_packet.length = p->iov.size; - bulk_packet.stream_id = 0; -@@ -623,6 +656,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev, - DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep, - p->iov.size, p->id); - -+ if (usbredir_already_in_flight(dev, p->id)) { -+ return USB_RET_ASYNC; -+ } -+ - interrupt_packet.endpoint = ep; - interrupt_packet.length = p->iov.size; - -@@ -765,6 +802,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p, - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); - struct usb_redir_control_packet_header control_packet; - -+ if (usbredir_already_in_flight(dev, p->id)) { -+ return USB_RET_ASYNC; -+ } -+ - /* Special cases for certain standard device requests */ - switch (request) { - case DeviceOutRequest | USB_REQ_SET_ADDRESS: -@@ -982,6 +1023,7 @@ static int usbredir_initfn(USBDevice *udev) - dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev); - - packet_id_queue_init(&dev->cancelled, dev, "cancelled"); -+ packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight"); - for (i = 0; i < MAX_ENDPOINTS; i++) { - QTAILQ_INIT(&dev->endpoint[i].bufpq); - } -@@ -1002,6 +1044,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev) - int i; - - packet_id_queue_empty(&dev->cancelled); -+ packet_id_queue_empty(&dev->already_in_flight); - for (i = 0; i < MAX_ENDPOINTS; i++) { - usbredir_free_bufpq(dev, I2EP(i)); - } --- -1.7.12.1 - diff --git a/0626-usb-redir-Change-cancelled-packet-code-into-a-generi.patch b/0626-usb-redir-Change-cancelled-packet-code-into-a-generi.patch new file mode 100644 index 0000000..c4cab7c --- /dev/null +++ b/0626-usb-redir-Change-cancelled-packet-code-into-a-generi.patch @@ -0,0 +1,181 @@ +From 3ee0b38d21a4ced7e7040666b523ab711bb4b20c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 4 Sep 2012 14:18:34 +0200 +Subject: [PATCH] usb-redir: Change cancelled packet code into a generic + packet-id queue + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 102 +++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 71 insertions(+), 31 deletions(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index f183263..e2b8159 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -43,7 +43,6 @@ + #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f)) + #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f)) + +-typedef struct Cancelled Cancelled; + typedef struct USBRedirDevice USBRedirDevice; + + /* Struct to hold buffered packets (iso or int input packets) */ +@@ -69,6 +68,18 @@ struct endp_data { + int bufpq_target_size; + }; + ++struct PacketIdQueueEntry { ++ uint64_t id; ++ QTAILQ_ENTRY(PacketIdQueueEntry)next; ++}; ++ ++struct PacketIdQueue { ++ USBRedirDevice *dev; ++ const char *name; ++ QTAILQ_HEAD(, PacketIdQueueEntry) head; ++ int size; ++}; ++ + struct USBRedirDevice { + USBDevice dev; + /* Properties */ +@@ -86,7 +97,7 @@ struct USBRedirDevice { + int64_t next_attach_time; + struct usbredirparser *parser; + struct endp_data endpoint[MAX_ENDPOINTS]; +- QTAILQ_HEAD(, Cancelled) cancelled; ++ struct PacketIdQueue cancelled; + /* Data for device filtering */ + struct usb_redir_device_connect_header device_info; + struct usb_redir_interface_info_header interface_info; +@@ -94,11 +105,6 @@ struct USBRedirDevice { + int filter_rules_count; + }; + +-struct Cancelled { +- uint64_t id; +- QTAILQ_ENTRY(Cancelled)next; +-}; +- + static void usbredir_hello(void *priv, struct usb_redir_hello_header *h); + static void usbredir_device_connect(void *priv, + struct usb_redir_device_connect_header *device_connect); +@@ -251,37 +257,75 @@ static int usbredir_write(void *priv, uint8_t *data, int count) + * Cancelled and buffered packets helpers + */ + +-static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) ++static void packet_id_queue_init(struct PacketIdQueue *q, ++ USBRedirDevice *dev, const char *name) + { +- USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); +- Cancelled *c; ++ q->dev = dev; ++ q->name = name; ++ QTAILQ_INIT(&q->head); ++ q->size = 0; ++} ++ ++static void packet_id_queue_add(struct PacketIdQueue *q, uint64_t id) ++{ ++ USBRedirDevice *dev = q->dev; ++ struct PacketIdQueueEntry *e; ++ ++ DPRINTF("adding packet id %"PRIu64" to %s queue\n", id, q->name); ++ ++ e = g_malloc0(sizeof(struct PacketIdQueueEntry)); ++ e->id = id; ++ QTAILQ_INSERT_TAIL(&q->head, e, next); ++ q->size++; ++} ++ ++static int packet_id_queue_remove(struct PacketIdQueue *q, uint64_t id) ++{ ++ USBRedirDevice *dev = q->dev; ++ struct PacketIdQueueEntry *e; ++ ++ QTAILQ_FOREACH(e, &q->head, next) { ++ if (e->id == id) { ++ DPRINTF("removing packet id %"PRIu64" from %s queue\n", ++ id, q->name); ++ QTAILQ_REMOVE(&q->head, e, next); ++ q->size--; ++ g_free(e); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++static void packet_id_queue_empty(struct PacketIdQueue *q) ++{ ++ USBRedirDevice *dev = q->dev; ++ struct PacketIdQueueEntry *e, *next_e; + +- DPRINTF("cancel packet id %"PRIu64"\n", p->id); ++ DPRINTF("removing %d packet-ids from %s queue\n", q->size, q->name); + +- c = g_malloc0(sizeof(Cancelled)); +- c->id = p->id; +- QTAILQ_INSERT_TAIL(&dev->cancelled, c, next); ++ QTAILQ_FOREACH_SAFE(e, &q->head, next, next_e) { ++ QTAILQ_REMOVE(&q->head, e, next); ++ g_free(e); ++ } ++ q->size = 0; ++} + ++static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) ++{ ++ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); ++ ++ packet_id_queue_add(&dev->cancelled, p->id); + usbredirparser_send_cancel_data_packet(dev->parser, p->id); + usbredirparser_do_write(dev->parser); + } + + static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id) + { +- Cancelled *c; +- + if (!dev->dev.attached) { + return 1; /* Treat everything as cancelled after a disconnect */ + } +- +- QTAILQ_FOREACH(c, &dev->cancelled, next) { +- if (c->id == id) { +- QTAILQ_REMOVE(&dev->cancelled, c, next); +- g_free(c); +- return 1; +- } +- } +- return 0; ++ return packet_id_queue_remove(&dev->cancelled, id); + } + + static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev, +@@ -937,7 +981,7 @@ static int usbredir_initfn(USBDevice *udev) + dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev); + dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev); + +- QTAILQ_INIT(&dev->cancelled); ++ packet_id_queue_init(&dev->cancelled, dev, "cancelled"); + for (i = 0; i < MAX_ENDPOINTS; i++) { + QTAILQ_INIT(&dev->endpoint[i].bufpq); + } +@@ -955,13 +999,9 @@ static int usbredir_initfn(USBDevice *udev) + + static void usbredir_cleanup_device_queues(USBRedirDevice *dev) + { +- Cancelled *c, *next_c; + int i; + +- QTAILQ_FOREACH_SAFE(c, &dev->cancelled, next, next_c) { +- QTAILQ_REMOVE(&dev->cancelled, c, next); +- g_free(c); +- } ++ packet_id_queue_empty(&dev->cancelled); + for (i = 0; i < MAX_ENDPOINTS; i++) { + usbredir_free_bufpq(dev, I2EP(i)); + } diff --git a/0627-usb-redir-Add-an-already_in_flight-packet-id-queue.patch b/0627-usb-redir-Add-an-already_in_flight-packet-id-queue.patch new file mode 100644 index 0000000..5eb0046 --- /dev/null +++ b/0627-usb-redir-Add-an-already_in_flight-packet-id-queue.patch @@ -0,0 +1,116 @@ +From 7f3022f4ee2f83aeb0a1eea265f4bf9b4401096e Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 4 Sep 2012 17:03:54 +0200 +Subject: [PATCH] usb-redir: Add an already_in_flight packet-id queue + +After a live migration, the usb-hcd will re-queue all packets by +walking over the schedule in the guest memory again, but requests which +were encountered on the migration source before will already be in flight, +so these should *not* be re-send to the usbredir-host. + +This patch adds an already in flight packet ud queue, which will be filled by +the source before migration and then moved over to the migration dest, any +async handled packets are then checked against this queue to avoid sending +the same packet to the usbredir-host twice. + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index e2b8159..cdd705f 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -98,6 +98,7 @@ struct USBRedirDevice { + struct usbredirparser *parser; + struct endp_data endpoint[MAX_ENDPOINTS]; + struct PacketIdQueue cancelled; ++ struct PacketIdQueue already_in_flight; + /* Data for device filtering */ + struct usb_redir_device_connect_header device_info; + struct usb_redir_interface_info_header interface_info; +@@ -328,6 +329,34 @@ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id) + return packet_id_queue_remove(&dev->cancelled, id); + } + ++static void usbredir_fill_already_in_flight_from_ep(USBRedirDevice *dev, ++ struct USBEndpoint *ep) ++{ ++ static USBPacket *p; ++ ++ QTAILQ_FOREACH(p, &ep->queue, queue) { ++ packet_id_queue_add(&dev->already_in_flight, p->id); ++ } ++} ++ ++static void usbredir_fill_already_in_flight(USBRedirDevice *dev) ++{ ++ int ep; ++ struct USBDevice *udev = &dev->dev; ++ ++ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_ctl); ++ ++ for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { ++ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_in[ep]); ++ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_out[ep]); ++ } ++} ++ ++static int usbredir_already_in_flight(USBRedirDevice *dev, uint64_t id) ++{ ++ return packet_id_queue_remove(&dev->already_in_flight, id); ++} ++ + static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev, + uint8_t ep, uint64_t id) + { +@@ -543,6 +572,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p, + + DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, p->iov.size, p->id); + ++ if (usbredir_already_in_flight(dev, p->id)) { ++ return USB_RET_ASYNC; ++ } ++ + bulk_packet.endpoint = ep; + bulk_packet.length = p->iov.size; + bulk_packet.stream_id = 0; +@@ -623,6 +656,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev, + DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep, + p->iov.size, p->id); + ++ if (usbredir_already_in_flight(dev, p->id)) { ++ return USB_RET_ASYNC; ++ } ++ + interrupt_packet.endpoint = ep; + interrupt_packet.length = p->iov.size; + +@@ -765,6 +802,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p, + USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + struct usb_redir_control_packet_header control_packet; + ++ if (usbredir_already_in_flight(dev, p->id)) { ++ return USB_RET_ASYNC; ++ } ++ + /* Special cases for certain standard device requests */ + switch (request) { + case DeviceOutRequest | USB_REQ_SET_ADDRESS: +@@ -982,6 +1023,7 @@ static int usbredir_initfn(USBDevice *udev) + dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev); + + packet_id_queue_init(&dev->cancelled, dev, "cancelled"); ++ packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight"); + for (i = 0; i < MAX_ENDPOINTS; i++) { + QTAILQ_INIT(&dev->endpoint[i].bufpq); + } +@@ -1002,6 +1044,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev) + int i; + + packet_id_queue_empty(&dev->cancelled); ++ packet_id_queue_empty(&dev->already_in_flight); + for (i = 0; i < MAX_ENDPOINTS; i++) { + usbredir_free_bufpq(dev, I2EP(i)); + } diff --git a/0627-usb-redir-Store-max_packet_size-in-endp_data.patch b/0627-usb-redir-Store-max_packet_size-in-endp_data.patch deleted file mode 100644 index 2c44744..0000000 --- a/0627-usb-redir-Store-max_packet_size-in-endp_data.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c41be182adcd7026fcf76250fc3a64cec8a2c903 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 6 Sep 2012 20:52:36 +0200 -Subject: [PATCH] usb-redir: Store max_packet_size in endp_data - -So that we've a place to migrate it to / from to allow restoring it after -migration. - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index cdd705f..6eb3c6d 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -57,6 +57,7 @@ struct endp_data { - uint8_t type; - uint8_t interval; - uint8_t interface; /* bInterfaceNumber this ep belongs to */ -+ uint16_t max_packet_size; /* In bytes, not wMaxPacketSize format !! */ - uint8_t iso_started; - uint8_t iso_error; /* For reporting iso errors to the HC */ - uint8_t interrupt_started; -@@ -1300,7 +1301,8 @@ static void usbredir_ep_info(void *priv, - usb_ep->ifnum = dev->endpoint[i].interface; - if (usbredirparser_peer_has_cap(dev->parser, - usb_redir_cap_ep_info_max_packet_size)) { -- usb_ep->max_packet_size = ep_info->max_packet_size[i]; -+ dev->endpoint[i].max_packet_size = -+ usb_ep->max_packet_size = ep_info->max_packet_size[i]; - } - if (ep_info->type[i] == usb_redir_type_bulk) { - usb_ep->pipeline = true; --- -1.7.12.1 - diff --git a/0628-usb-redir-Add-support-for-migration.patch b/0628-usb-redir-Add-support-for-migration.patch deleted file mode 100644 index 52d9002..0000000 --- a/0628-usb-redir-Add-support-for-migration.patch +++ /dev/null @@ -1,429 +0,0 @@ -From a056ffda5a57d7169268e49a3e42c7d79c8f7c48 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 5 Sep 2012 09:21:44 +0200 -Subject: [PATCH] usb-redir: Add support for migration - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 346 insertions(+), 3 deletions(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 6eb3c6d..b7387b6 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -65,8 +65,8 @@ struct endp_data { - uint8_t bufpq_prefilled; - uint8_t bufpq_dropping_packets; - QTAILQ_HEAD(, buf_packet) bufpq; -- int bufpq_size; -- int bufpq_target_size; -+ int32_t bufpq_size; -+ int32_t bufpq_target_size; - }; - - struct PacketIdQueueEntry { -@@ -243,6 +243,11 @@ static int usbredir_write(void *priv, uint8_t *data, int count) - return 0; - } - -+ /* Don't send new data to the chardev until our state is fully synced */ -+ if (!runstate_check(RUN_STATE_RUNNING)) { -+ return 0; -+ } -+ - r = qemu_chr_fe_write(dev->cs, data, count); - - if (r < 0) { -@@ -870,6 +875,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev) - { - uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, }; - char version[32]; -+ int flags = 0; - - /* Make sure any pending closes are handled (no-op if none pending) */ - usbredir_chardev_close_bh(dev); -@@ -902,7 +908,12 @@ static void usbredir_chardev_open(USBRedirDevice *dev) - usbredirparser_caps_set_cap(caps, usb_redir_cap_filter); - usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size); - usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids); -- usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0); -+ -+ if (runstate_check(RUN_STATE_INMIGRATE)) { -+ flags |= usbredirparser_fl_no_hello; -+ } -+ usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, -+ flags); - usbredirparser_do_write(dev->parser); - } - -@@ -948,6 +959,11 @@ static int usbredir_chardev_can_read(void *opaque) - return 0; - } - -+ /* Don't read new data from the chardev until our state is fully synced */ -+ if (!runstate_check(RUN_STATE_RUNNING)) { -+ return 0; -+ } -+ - /* usbredir_parser_do_read will consume *all* data we give it */ - return 1024 * 1024; - } -@@ -999,6 +1015,15 @@ static const QemuChrHandlers usbredir_chr_handlers = { - * init + destroy - */ - -+static void usbredir_vm_state_change(void *priv, int running, RunState state) -+{ -+ USBRedirDevice *dev = priv; -+ -+ if (state == RUN_STATE_RUNNING && dev->parser != NULL) { -+ usbredirparser_do_write(dev->parser); /* Flush any pending writes */ -+ } -+} -+ - static int usbredir_initfn(USBDevice *udev) - { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -@@ -1036,6 +1061,7 @@ static int usbredir_initfn(USBDevice *udev) - qemu_chr_fe_open(dev->cs); - qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev); - -+ qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev); - add_boot_device_path(dev->bootindex, &udev->qdev, NULL); - return 0; - } -@@ -1525,6 +1551,322 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id, - } - } - -+/* -+ * Migration code -+ */ -+ -+static void usbredir_pre_save(void *priv) -+{ -+ USBRedirDevice *dev = priv; -+ -+ usbredir_fill_already_in_flight(dev); -+} -+ -+static int usbredir_post_load(void *priv, int version_id) -+{ -+ USBRedirDevice *dev = priv; -+ struct USBEndpoint *usb_ep; -+ int i; -+ -+ switch (dev->device_info.speed) { -+ case usb_redir_speed_low: -+ dev->dev.speed = USB_SPEED_LOW; -+ break; -+ case usb_redir_speed_full: -+ dev->dev.speed = USB_SPEED_FULL; -+ break; -+ case usb_redir_speed_high: -+ dev->dev.speed = USB_SPEED_HIGH; -+ break; -+ case usb_redir_speed_super: -+ dev->dev.speed = USB_SPEED_SUPER; -+ break; -+ default: -+ dev->dev.speed = USB_SPEED_FULL; -+ } -+ dev->dev.speedmask = (1 << dev->dev.speed); -+ -+ for (i = 0; i < MAX_ENDPOINTS; i++) { -+ usb_ep = usb_ep_get(&dev->dev, -+ (i & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT, -+ i & 0x0f); -+ usb_ep->type = dev->endpoint[i].type; -+ usb_ep->ifnum = dev->endpoint[i].interface; -+ usb_ep->max_packet_size = dev->endpoint[i].max_packet_size; -+ if (dev->endpoint[i].type == usb_redir_type_bulk) { -+ usb_ep->pipeline = true; -+ } -+ } -+ return 0; -+} -+ -+/* For usbredirparser migration */ -+static void usbredir_put_parser(QEMUFile *f, void *priv, size_t unused) -+{ -+ USBRedirDevice *dev = priv; -+ uint8_t *data; -+ int len; -+ -+ if (dev->parser == NULL) { -+ qemu_put_be32(f, 0); -+ return; -+ } -+ -+ usbredirparser_serialize(dev->parser, &data, &len); -+ qemu_oom_check(data); -+ -+ qemu_put_be32(f, len); -+ qemu_put_buffer(f, data, len); -+ -+ free(data); -+} -+ -+static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused) -+{ -+ USBRedirDevice *dev = priv; -+ uint8_t *data; -+ int len, ret; -+ -+ len = qemu_get_be32(f); -+ if (len == 0) { -+ return 0; -+ } -+ -+ /* -+ * Our chardev should be open already at this point, otherwise -+ * the usbredir channel will be broken (ie spice without seamless) -+ */ -+ if (dev->parser == NULL) { -+ ERROR("get_parser called with closed chardev, failing migration\n"); -+ return -1; -+ } -+ -+ data = g_malloc(len); -+ qemu_get_buffer(f, data, len); -+ -+ ret = usbredirparser_unserialize(dev->parser, data, len); -+ -+ g_free(data); -+ -+ return ret; -+} -+ -+static const VMStateInfo usbredir_parser_vmstate_info = { -+ .name = "usb-redir-parser", -+ .put = usbredir_put_parser, -+ .get = usbredir_get_parser, -+}; -+ -+ -+/* For buffered packets (iso/irq) queue migration */ -+static void usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused) -+{ -+ struct endp_data *endp = priv; -+ struct buf_packet *bufp; -+ int remain = endp->bufpq_size; -+ -+ qemu_put_be32(f, endp->bufpq_size); -+ QTAILQ_FOREACH(bufp, &endp->bufpq, next) { -+ qemu_put_be32(f, bufp->len); -+ qemu_put_be32(f, bufp->status); -+ qemu_put_buffer(f, bufp->data, bufp->len); -+ remain--; -+ } -+ assert(remain == 0); -+} -+ -+static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused) -+{ -+ struct endp_data *endp = priv; -+ struct buf_packet *bufp; -+ int i; -+ -+ endp->bufpq_size = qemu_get_be32(f); -+ for (i = 0; i < endp->bufpq_size; i++) { -+ bufp = g_malloc(sizeof(struct buf_packet)); -+ bufp->len = qemu_get_be32(f); -+ bufp->status = qemu_get_be32(f); -+ bufp->data = qemu_oom_check(malloc(bufp->len)); /* regular malloc! */ -+ qemu_get_buffer(f, bufp->data, bufp->len); -+ QTAILQ_INSERT_TAIL(&endp->bufpq, bufp, next); -+ } -+ return 0; -+} -+ -+static const VMStateInfo usbredir_ep_bufpq_vmstate_info = { -+ .name = "usb-redir-bufpq", -+ .put = usbredir_put_bufpq, -+ .get = usbredir_get_bufpq, -+}; -+ -+ -+/* For endp_data migration */ -+static const VMStateDescription usbredir_ep_vmstate = { -+ .name = "usb-redir-ep", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField []) { -+ VMSTATE_UINT8(type, struct endp_data), -+ VMSTATE_UINT8(interval, struct endp_data), -+ VMSTATE_UINT8(interface, struct endp_data), -+ VMSTATE_UINT16(max_packet_size, struct endp_data), -+ VMSTATE_UINT8(iso_started, struct endp_data), -+ VMSTATE_UINT8(iso_error, struct endp_data), -+ VMSTATE_UINT8(interrupt_started, struct endp_data), -+ VMSTATE_UINT8(interrupt_error, struct endp_data), -+ VMSTATE_UINT8(bufpq_prefilled, struct endp_data), -+ VMSTATE_UINT8(bufpq_dropping_packets, struct endp_data), -+ { -+ .name = "bufpq", -+ .version_id = 0, -+ .field_exists = NULL, -+ .size = 0, -+ .info = &usbredir_ep_bufpq_vmstate_info, -+ .flags = VMS_SINGLE, -+ .offset = 0, -+ }, -+ VMSTATE_INT32(bufpq_target_size, struct endp_data), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+ -+/* For PacketIdQueue migration */ -+static void usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused) -+{ -+ struct PacketIdQueue *q = priv; -+ USBRedirDevice *dev = q->dev; -+ struct PacketIdQueueEntry *e; -+ int remain = q->size; -+ -+ DPRINTF("put_packet_id_q %s size %d\n", q->name, q->size); -+ qemu_put_be32(f, q->size); -+ QTAILQ_FOREACH(e, &q->head, next) { -+ qemu_put_be64(f, e->id); -+ remain--; -+ } -+ assert(remain == 0); -+} -+ -+static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused) -+{ -+ struct PacketIdQueue *q = priv; -+ USBRedirDevice *dev = q->dev; -+ int i, size; -+ uint64_t id; -+ -+ size = qemu_get_be32(f); -+ DPRINTF("get_packet_id_q %s size %d\n", q->name, size); -+ for (i = 0; i < size; i++) { -+ id = qemu_get_be64(f); -+ packet_id_queue_add(q, id); -+ } -+ assert(q->size == size); -+ return 0; -+} -+ -+static const VMStateInfo usbredir_ep_packet_id_q_vmstate_info = { -+ .name = "usb-redir-packet-id-q", -+ .put = usbredir_put_packet_id_q, -+ .get = usbredir_get_packet_id_q, -+}; -+ -+static const VMStateDescription usbredir_ep_packet_id_queue_vmstate = { -+ .name = "usb-redir-packet-id-queue", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField []) { -+ { -+ .name = "queue", -+ .version_id = 0, -+ .field_exists = NULL, -+ .size = 0, -+ .info = &usbredir_ep_packet_id_q_vmstate_info, -+ .flags = VMS_SINGLE, -+ .offset = 0, -+ }, -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+ -+/* For usb_redir_device_connect_header migration */ -+static const VMStateDescription usbredir_device_info_vmstate = { -+ .name = "usb-redir-device-info", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField []) { -+ VMSTATE_UINT8(speed, struct usb_redir_device_connect_header), -+ VMSTATE_UINT8(device_class, struct usb_redir_device_connect_header), -+ VMSTATE_UINT8(device_subclass, struct usb_redir_device_connect_header), -+ VMSTATE_UINT8(device_protocol, struct usb_redir_device_connect_header), -+ VMSTATE_UINT16(vendor_id, struct usb_redir_device_connect_header), -+ VMSTATE_UINT16(product_id, struct usb_redir_device_connect_header), -+ VMSTATE_UINT16(device_version_bcd, -+ struct usb_redir_device_connect_header), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+ -+/* For usb_redir_interface_info_header migration */ -+static const VMStateDescription usbredir_interface_info_vmstate = { -+ .name = "usb-redir-interface-info", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField []) { -+ VMSTATE_UINT32(interface_count, -+ struct usb_redir_interface_info_header), -+ VMSTATE_UINT8_ARRAY(interface, -+ struct usb_redir_interface_info_header, 32), -+ VMSTATE_UINT8_ARRAY(interface_class, -+ struct usb_redir_interface_info_header, 32), -+ VMSTATE_UINT8_ARRAY(interface_subclass, -+ struct usb_redir_interface_info_header, 32), -+ VMSTATE_UINT8_ARRAY(interface_protocol, -+ struct usb_redir_interface_info_header, 32), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+ -+/* And finally the USBRedirDevice vmstate itself */ -+static const VMStateDescription usbredir_vmstate = { -+ .name = "usb-redir", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = usbredir_pre_save, -+ .post_load = usbredir_post_load, -+ .fields = (VMStateField []) { -+ VMSTATE_USB_DEVICE(dev, USBRedirDevice), -+ VMSTATE_TIMER(attach_timer, USBRedirDevice), -+ { -+ .name = "parser", -+ .version_id = 0, -+ .field_exists = NULL, -+ .size = 0, -+ .info = &usbredir_parser_vmstate_info, -+ .flags = VMS_SINGLE, -+ .offset = 0, -+ }, -+ VMSTATE_STRUCT_ARRAY(endpoint, USBRedirDevice, MAX_ENDPOINTS, 1, -+ usbredir_ep_vmstate, struct endp_data), -+ VMSTATE_STRUCT(cancelled, USBRedirDevice, 1, -+ usbredir_ep_packet_id_queue_vmstate, -+ struct PacketIdQueue), -+ VMSTATE_STRUCT(already_in_flight, USBRedirDevice, 1, -+ usbredir_ep_packet_id_queue_vmstate, -+ struct PacketIdQueue), -+ VMSTATE_STRUCT(device_info, USBRedirDevice, 1, -+ usbredir_device_info_vmstate, -+ struct usb_redir_device_connect_header), -+ VMSTATE_STRUCT(interface_info, USBRedirDevice, 1, -+ usbredir_interface_info_vmstate, -+ struct usb_redir_interface_info_header), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ - static Property usbredir_properties[] = { - DEFINE_PROP_CHR("chardev", USBRedirDevice, cs), - DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0), -@@ -1545,6 +1887,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data) - uc->handle_reset = usbredir_handle_reset; - uc->handle_data = usbredir_handle_data; - uc->handle_control = usbredir_handle_control; -+ dc->vmsd = &usbredir_vmstate; - dc->props = usbredir_properties; - } - --- -1.7.12.1 - diff --git a/0628-usb-redir-Store-max_packet_size-in-endp_data.patch b/0628-usb-redir-Store-max_packet_size-in-endp_data.patch new file mode 100644 index 0000000..e38b41a --- /dev/null +++ b/0628-usb-redir-Store-max_packet_size-in-endp_data.patch @@ -0,0 +1,35 @@ +From 92685f7fb2b97236018aa8aed9fc9fd8f5644346 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 6 Sep 2012 20:52:36 +0200 +Subject: [PATCH] usb-redir: Store max_packet_size in endp_data + +So that we've a place to migrate it to / from to allow restoring it after +migration. + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index cdd705f..6eb3c6d 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -57,6 +57,7 @@ struct endp_data { + uint8_t type; + uint8_t interval; + uint8_t interface; /* bInterfaceNumber this ep belongs to */ ++ uint16_t max_packet_size; /* In bytes, not wMaxPacketSize format !! */ + uint8_t iso_started; + uint8_t iso_error; /* For reporting iso errors to the HC */ + uint8_t interrupt_started; +@@ -1300,7 +1301,8 @@ static void usbredir_ep_info(void *priv, + usb_ep->ifnum = dev->endpoint[i].interface; + if (usbredirparser_peer_has_cap(dev->parser, + usb_redir_cap_ep_info_max_packet_size)) { +- usb_ep->max_packet_size = ep_info->max_packet_size[i]; ++ dev->endpoint[i].max_packet_size = ++ usb_ep->max_packet_size = ep_info->max_packet_size[i]; + } + if (ep_info->type[i] == usb_redir_type_bulk) { + usb_ep->pipeline = true; diff --git a/0629-usb-redir-Add-chardev-open-close-debug-logging.patch b/0629-usb-redir-Add-chardev-open-close-debug-logging.patch deleted file mode 100644 index 5e8305d..0000000 --- a/0629-usb-redir-Add-chardev-open-close-debug-logging.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 5a717110d859cbd989634e8acdcedd800ee2be74 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 5 Sep 2012 15:56:57 +0200 -Subject: [PATCH] usb-redir: Add chardev open / close debug logging - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index b7387b6..57e6289 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -866,6 +866,7 @@ static void usbredir_chardev_close_bh(void *opaque) - usbredir_device_disconnect(dev); - - if (dev->parser) { -+ DPRINTF("destroying usbredirparser\n"); - usbredirparser_destroy(dev->parser); - dev->parser = NULL; - } -@@ -881,6 +882,8 @@ static void usbredir_chardev_open(USBRedirDevice *dev) - usbredir_chardev_close_bh(dev); - qemu_bh_cancel(dev->chardev_close_bh); - -+ DPRINTF("creating usbredirparser\n"); -+ - dev->parser = qemu_oom_check(usbredirparser_create()); - dev->parser->priv = dev; - dev->parser->log_func = usbredir_log; -@@ -989,9 +992,11 @@ static void usbredir_chardev_event(void *opaque, int event) - - switch (event) { - case CHR_EVENT_OPENED: -+ DPRINTF("chardev open\n"); - usbredir_chardev_open(dev); - break; - case CHR_EVENT_CLOSED: -+ DPRINTF("chardev close\n"); - qemu_bh_schedule(dev->chardev_close_bh); - break; - } -@@ -1250,6 +1255,7 @@ static void usbredir_device_disconnect(void *priv) - qemu_del_timer(dev->attach_timer); - - if (dev->dev.attached) { -+ DPRINTF("detaching device\n"); - usb_device_detach(&dev->dev); - /* - * Delay next usb device attach to give the guest a chance to see --- -1.7.12.1 - diff --git a/0629-usb-redir-Add-support-for-migration.patch b/0629-usb-redir-Add-support-for-migration.patch new file mode 100644 index 0000000..5f20a5f --- /dev/null +++ b/0629-usb-redir-Add-support-for-migration.patch @@ -0,0 +1,426 @@ +From 89d5a2bf3ecb98ba5bfaf1fd6c63924aeb1b6208 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 5 Sep 2012 09:21:44 +0200 +Subject: [PATCH] usb-redir: Add support for migration + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 346 insertions(+), 3 deletions(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 6eb3c6d..b7387b6 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -65,8 +65,8 @@ struct endp_data { + uint8_t bufpq_prefilled; + uint8_t bufpq_dropping_packets; + QTAILQ_HEAD(, buf_packet) bufpq; +- int bufpq_size; +- int bufpq_target_size; ++ int32_t bufpq_size; ++ int32_t bufpq_target_size; + }; + + struct PacketIdQueueEntry { +@@ -243,6 +243,11 @@ static int usbredir_write(void *priv, uint8_t *data, int count) + return 0; + } + ++ /* Don't send new data to the chardev until our state is fully synced */ ++ if (!runstate_check(RUN_STATE_RUNNING)) { ++ return 0; ++ } ++ + r = qemu_chr_fe_write(dev->cs, data, count); + + if (r < 0) { +@@ -870,6 +875,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev) + { + uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, }; + char version[32]; ++ int flags = 0; + + /* Make sure any pending closes are handled (no-op if none pending) */ + usbredir_chardev_close_bh(dev); +@@ -902,7 +908,12 @@ static void usbredir_chardev_open(USBRedirDevice *dev) + usbredirparser_caps_set_cap(caps, usb_redir_cap_filter); + usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size); + usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids); +- usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0); ++ ++ if (runstate_check(RUN_STATE_INMIGRATE)) { ++ flags |= usbredirparser_fl_no_hello; ++ } ++ usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, ++ flags); + usbredirparser_do_write(dev->parser); + } + +@@ -948,6 +959,11 @@ static int usbredir_chardev_can_read(void *opaque) + return 0; + } + ++ /* Don't read new data from the chardev until our state is fully synced */ ++ if (!runstate_check(RUN_STATE_RUNNING)) { ++ return 0; ++ } ++ + /* usbredir_parser_do_read will consume *all* data we give it */ + return 1024 * 1024; + } +@@ -999,6 +1015,15 @@ static const QemuChrHandlers usbredir_chr_handlers = { + * init + destroy + */ + ++static void usbredir_vm_state_change(void *priv, int running, RunState state) ++{ ++ USBRedirDevice *dev = priv; ++ ++ if (state == RUN_STATE_RUNNING && dev->parser != NULL) { ++ usbredirparser_do_write(dev->parser); /* Flush any pending writes */ ++ } ++} ++ + static int usbredir_initfn(USBDevice *udev) + { + USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); +@@ -1036,6 +1061,7 @@ static int usbredir_initfn(USBDevice *udev) + qemu_chr_fe_open(dev->cs); + qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev); + ++ qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev); + add_boot_device_path(dev->bootindex, &udev->qdev, NULL); + return 0; + } +@@ -1525,6 +1551,322 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id, + } + } + ++/* ++ * Migration code ++ */ ++ ++static void usbredir_pre_save(void *priv) ++{ ++ USBRedirDevice *dev = priv; ++ ++ usbredir_fill_already_in_flight(dev); ++} ++ ++static int usbredir_post_load(void *priv, int version_id) ++{ ++ USBRedirDevice *dev = priv; ++ struct USBEndpoint *usb_ep; ++ int i; ++ ++ switch (dev->device_info.speed) { ++ case usb_redir_speed_low: ++ dev->dev.speed = USB_SPEED_LOW; ++ break; ++ case usb_redir_speed_full: ++ dev->dev.speed = USB_SPEED_FULL; ++ break; ++ case usb_redir_speed_high: ++ dev->dev.speed = USB_SPEED_HIGH; ++ break; ++ case usb_redir_speed_super: ++ dev->dev.speed = USB_SPEED_SUPER; ++ break; ++ default: ++ dev->dev.speed = USB_SPEED_FULL; ++ } ++ dev->dev.speedmask = (1 << dev->dev.speed); ++ ++ for (i = 0; i < MAX_ENDPOINTS; i++) { ++ usb_ep = usb_ep_get(&dev->dev, ++ (i & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT, ++ i & 0x0f); ++ usb_ep->type = dev->endpoint[i].type; ++ usb_ep->ifnum = dev->endpoint[i].interface; ++ usb_ep->max_packet_size = dev->endpoint[i].max_packet_size; ++ if (dev->endpoint[i].type == usb_redir_type_bulk) { ++ usb_ep->pipeline = true; ++ } ++ } ++ return 0; ++} ++ ++/* For usbredirparser migration */ ++static void usbredir_put_parser(QEMUFile *f, void *priv, size_t unused) ++{ ++ USBRedirDevice *dev = priv; ++ uint8_t *data; ++ int len; ++ ++ if (dev->parser == NULL) { ++ qemu_put_be32(f, 0); ++ return; ++ } ++ ++ usbredirparser_serialize(dev->parser, &data, &len); ++ qemu_oom_check(data); ++ ++ qemu_put_be32(f, len); ++ qemu_put_buffer(f, data, len); ++ ++ free(data); ++} ++ ++static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused) ++{ ++ USBRedirDevice *dev = priv; ++ uint8_t *data; ++ int len, ret; ++ ++ len = qemu_get_be32(f); ++ if (len == 0) { ++ return 0; ++ } ++ ++ /* ++ * Our chardev should be open already at this point, otherwise ++ * the usbredir channel will be broken (ie spice without seamless) ++ */ ++ if (dev->parser == NULL) { ++ ERROR("get_parser called with closed chardev, failing migration\n"); ++ return -1; ++ } ++ ++ data = g_malloc(len); ++ qemu_get_buffer(f, data, len); ++ ++ ret = usbredirparser_unserialize(dev->parser, data, len); ++ ++ g_free(data); ++ ++ return ret; ++} ++ ++static const VMStateInfo usbredir_parser_vmstate_info = { ++ .name = "usb-redir-parser", ++ .put = usbredir_put_parser, ++ .get = usbredir_get_parser, ++}; ++ ++ ++/* For buffered packets (iso/irq) queue migration */ ++static void usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused) ++{ ++ struct endp_data *endp = priv; ++ struct buf_packet *bufp; ++ int remain = endp->bufpq_size; ++ ++ qemu_put_be32(f, endp->bufpq_size); ++ QTAILQ_FOREACH(bufp, &endp->bufpq, next) { ++ qemu_put_be32(f, bufp->len); ++ qemu_put_be32(f, bufp->status); ++ qemu_put_buffer(f, bufp->data, bufp->len); ++ remain--; ++ } ++ assert(remain == 0); ++} ++ ++static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused) ++{ ++ struct endp_data *endp = priv; ++ struct buf_packet *bufp; ++ int i; ++ ++ endp->bufpq_size = qemu_get_be32(f); ++ for (i = 0; i < endp->bufpq_size; i++) { ++ bufp = g_malloc(sizeof(struct buf_packet)); ++ bufp->len = qemu_get_be32(f); ++ bufp->status = qemu_get_be32(f); ++ bufp->data = qemu_oom_check(malloc(bufp->len)); /* regular malloc! */ ++ qemu_get_buffer(f, bufp->data, bufp->len); ++ QTAILQ_INSERT_TAIL(&endp->bufpq, bufp, next); ++ } ++ return 0; ++} ++ ++static const VMStateInfo usbredir_ep_bufpq_vmstate_info = { ++ .name = "usb-redir-bufpq", ++ .put = usbredir_put_bufpq, ++ .get = usbredir_get_bufpq, ++}; ++ ++ ++/* For endp_data migration */ ++static const VMStateDescription usbredir_ep_vmstate = { ++ .name = "usb-redir-ep", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField []) { ++ VMSTATE_UINT8(type, struct endp_data), ++ VMSTATE_UINT8(interval, struct endp_data), ++ VMSTATE_UINT8(interface, struct endp_data), ++ VMSTATE_UINT16(max_packet_size, struct endp_data), ++ VMSTATE_UINT8(iso_started, struct endp_data), ++ VMSTATE_UINT8(iso_error, struct endp_data), ++ VMSTATE_UINT8(interrupt_started, struct endp_data), ++ VMSTATE_UINT8(interrupt_error, struct endp_data), ++ VMSTATE_UINT8(bufpq_prefilled, struct endp_data), ++ VMSTATE_UINT8(bufpq_dropping_packets, struct endp_data), ++ { ++ .name = "bufpq", ++ .version_id = 0, ++ .field_exists = NULL, ++ .size = 0, ++ .info = &usbredir_ep_bufpq_vmstate_info, ++ .flags = VMS_SINGLE, ++ .offset = 0, ++ }, ++ VMSTATE_INT32(bufpq_target_size, struct endp_data), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++/* For PacketIdQueue migration */ ++static void usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused) ++{ ++ struct PacketIdQueue *q = priv; ++ USBRedirDevice *dev = q->dev; ++ struct PacketIdQueueEntry *e; ++ int remain = q->size; ++ ++ DPRINTF("put_packet_id_q %s size %d\n", q->name, q->size); ++ qemu_put_be32(f, q->size); ++ QTAILQ_FOREACH(e, &q->head, next) { ++ qemu_put_be64(f, e->id); ++ remain--; ++ } ++ assert(remain == 0); ++} ++ ++static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused) ++{ ++ struct PacketIdQueue *q = priv; ++ USBRedirDevice *dev = q->dev; ++ int i, size; ++ uint64_t id; ++ ++ size = qemu_get_be32(f); ++ DPRINTF("get_packet_id_q %s size %d\n", q->name, size); ++ for (i = 0; i < size; i++) { ++ id = qemu_get_be64(f); ++ packet_id_queue_add(q, id); ++ } ++ assert(q->size == size); ++ return 0; ++} ++ ++static const VMStateInfo usbredir_ep_packet_id_q_vmstate_info = { ++ .name = "usb-redir-packet-id-q", ++ .put = usbredir_put_packet_id_q, ++ .get = usbredir_get_packet_id_q, ++}; ++ ++static const VMStateDescription usbredir_ep_packet_id_queue_vmstate = { ++ .name = "usb-redir-packet-id-queue", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField []) { ++ { ++ .name = "queue", ++ .version_id = 0, ++ .field_exists = NULL, ++ .size = 0, ++ .info = &usbredir_ep_packet_id_q_vmstate_info, ++ .flags = VMS_SINGLE, ++ .offset = 0, ++ }, ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++/* For usb_redir_device_connect_header migration */ ++static const VMStateDescription usbredir_device_info_vmstate = { ++ .name = "usb-redir-device-info", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField []) { ++ VMSTATE_UINT8(speed, struct usb_redir_device_connect_header), ++ VMSTATE_UINT8(device_class, struct usb_redir_device_connect_header), ++ VMSTATE_UINT8(device_subclass, struct usb_redir_device_connect_header), ++ VMSTATE_UINT8(device_protocol, struct usb_redir_device_connect_header), ++ VMSTATE_UINT16(vendor_id, struct usb_redir_device_connect_header), ++ VMSTATE_UINT16(product_id, struct usb_redir_device_connect_header), ++ VMSTATE_UINT16(device_version_bcd, ++ struct usb_redir_device_connect_header), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++/* For usb_redir_interface_info_header migration */ ++static const VMStateDescription usbredir_interface_info_vmstate = { ++ .name = "usb-redir-interface-info", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField []) { ++ VMSTATE_UINT32(interface_count, ++ struct usb_redir_interface_info_header), ++ VMSTATE_UINT8_ARRAY(interface, ++ struct usb_redir_interface_info_header, 32), ++ VMSTATE_UINT8_ARRAY(interface_class, ++ struct usb_redir_interface_info_header, 32), ++ VMSTATE_UINT8_ARRAY(interface_subclass, ++ struct usb_redir_interface_info_header, 32), ++ VMSTATE_UINT8_ARRAY(interface_protocol, ++ struct usb_redir_interface_info_header, 32), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++/* And finally the USBRedirDevice vmstate itself */ ++static const VMStateDescription usbredir_vmstate = { ++ .name = "usb-redir", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = usbredir_pre_save, ++ .post_load = usbredir_post_load, ++ .fields = (VMStateField []) { ++ VMSTATE_USB_DEVICE(dev, USBRedirDevice), ++ VMSTATE_TIMER(attach_timer, USBRedirDevice), ++ { ++ .name = "parser", ++ .version_id = 0, ++ .field_exists = NULL, ++ .size = 0, ++ .info = &usbredir_parser_vmstate_info, ++ .flags = VMS_SINGLE, ++ .offset = 0, ++ }, ++ VMSTATE_STRUCT_ARRAY(endpoint, USBRedirDevice, MAX_ENDPOINTS, 1, ++ usbredir_ep_vmstate, struct endp_data), ++ VMSTATE_STRUCT(cancelled, USBRedirDevice, 1, ++ usbredir_ep_packet_id_queue_vmstate, ++ struct PacketIdQueue), ++ VMSTATE_STRUCT(already_in_flight, USBRedirDevice, 1, ++ usbredir_ep_packet_id_queue_vmstate, ++ struct PacketIdQueue), ++ VMSTATE_STRUCT(device_info, USBRedirDevice, 1, ++ usbredir_device_info_vmstate, ++ struct usb_redir_device_connect_header), ++ VMSTATE_STRUCT(interface_info, USBRedirDevice, 1, ++ usbredir_interface_info_vmstate, ++ struct usb_redir_interface_info_header), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static Property usbredir_properties[] = { + DEFINE_PROP_CHR("chardev", USBRedirDevice, cs), + DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0), +@@ -1545,6 +1887,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data) + uc->handle_reset = usbredir_handle_reset; + uc->handle_data = usbredir_handle_data; + uc->handle_control = usbredir_handle_control; ++ dc->vmsd = &usbredir_vmstate; + dc->props = usbredir_properties; + } + diff --git a/0630-usb-redir-Add-chardev-open-close-debug-logging.patch b/0630-usb-redir-Add-chardev-open-close-debug-logging.patch new file mode 100644 index 0000000..d1cf2ab --- /dev/null +++ b/0630-usb-redir-Add-chardev-open-close-debug-logging.patch @@ -0,0 +1,51 @@ +From 9737abf4265d394434982e8f7db230084cf036cb Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 5 Sep 2012 15:56:57 +0200 +Subject: [PATCH] usb-redir: Add chardev open / close debug logging + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index b7387b6..57e6289 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -866,6 +866,7 @@ static void usbredir_chardev_close_bh(void *opaque) + usbredir_device_disconnect(dev); + + if (dev->parser) { ++ DPRINTF("destroying usbredirparser\n"); + usbredirparser_destroy(dev->parser); + dev->parser = NULL; + } +@@ -881,6 +882,8 @@ static void usbredir_chardev_open(USBRedirDevice *dev) + usbredir_chardev_close_bh(dev); + qemu_bh_cancel(dev->chardev_close_bh); + ++ DPRINTF("creating usbredirparser\n"); ++ + dev->parser = qemu_oom_check(usbredirparser_create()); + dev->parser->priv = dev; + dev->parser->log_func = usbredir_log; +@@ -989,9 +992,11 @@ static void usbredir_chardev_event(void *opaque, int event) + + switch (event) { + case CHR_EVENT_OPENED: ++ DPRINTF("chardev open\n"); + usbredir_chardev_open(dev); + break; + case CHR_EVENT_CLOSED: ++ DPRINTF("chardev close\n"); + qemu_bh_schedule(dev->chardev_close_bh); + break; + } +@@ -1250,6 +1255,7 @@ static void usbredir_device_disconnect(void *priv) + qemu_del_timer(dev->attach_timer); + + if (dev->dev.attached) { ++ DPRINTF("detaching device\n"); + usb_device_detach(&dev->dev); + /* + * Delay next usb device attach to give the guest a chance to see diff --git a/0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch b/0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch deleted file mode 100644 index 4ffc46b..0000000 --- a/0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b95fb22d2799ed07c55bccbd7ffa3cb19fb7feb3 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 10 Sep 2012 13:49:46 +0200 -Subject: [PATCH] usb-redir: Revert usb-redir part of commit 93bfef4c - -Commit 93bfef4c6e4b23caea9d51e1099d06433d8835a4 makes qemu-devices -which report the qemu version string to the guest in some way use a -qemu_get_version function which reports a machine-specific version string. - -However usb-redir does not expose the qemu version to the guest, only to -the usbredir-host as part of the initial handshake. This can then be logged -on the usbredir-host side for debugging purposes and is otherwise completely -unused! For debugging purposes it is important to have the real qemu version -in there, rather then the machine-specific version. - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 57e6289..78e93a7 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -875,7 +875,6 @@ static void usbredir_chardev_close_bh(void *opaque) - static void usbredir_chardev_open(USBRedirDevice *dev) - { - uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, }; -- char version[32]; - int flags = 0; - - /* Make sure any pending closes are handled (no-op if none pending) */ --- -1.7.12.1 - diff --git a/0631-ehci-Fix-interrupt-packet-MULT-handling.patch b/0631-ehci-Fix-interrupt-packet-MULT-handling.patch deleted file mode 100644 index 17abd7f..0000000 --- a/0631-ehci-Fix-interrupt-packet-MULT-handling.patch +++ /dev/null @@ -1,131 +0,0 @@ -From d6fe9953a8277a54ae7f4cefa192b49d9bf99e3d Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 20 Sep 2012 16:55:02 +0200 -Subject: [PATCH] ehci: Fix interrupt packet MULT handling - -There are several issues with our handling of the MULT epcap field -of interrupt qhs, which this patch fixes. - -1) When we don't execute a transaction because of the transaction counter -being 0, p->async stays EHCI_ASYNC_NONE, and the next time we process the -same qtd we hit an assert in ehci_state_fetchqtd because of this. Even though -I believe that this is caused by 3 below, this patch still removes the assert, -as that can still happen without 3, when multiple packets are queued for the -same interrupt ep. - -2) We only *check* the transaction counter from ehci_state_execute, any -packets queued up by fill_queue bypass this check. This is fixed by not calling -fill_queue for interrupt packets. - -3) Some versions of Windows set the MULT field of the qh to 0, which is a -clear violation of the EHCI spec, but still they do it. This means that we -will never execute a qtd for these, making interrupt ep-s on USB-2 devices -not work, and after recent changes, triggering 1). - -So far we've stored the transaction counter in our copy of the mult field, -but with this beginnig at 0 already when dealing with these version of windows -this won't work. So this patch adds a transact_ctr field to our qh struct, -and sets this to the MULT field value on fetchqh. When the MULT field value -is 0, we set it to 4. Assuming that windows gets way with setting it to 0, -by the actual hardware going horizontal on a 1 -> 0 transition, which will -give it 4 transactions (MULT goes from 0 - 3). - -Note that we cannot stop on detecting the 1 -> 0 transition, as our decrement -of the transaction counter, and checking for it are done in 2 different places. - -Reported-by: Shawn Starr -Signed-off-by: Hans de Goede ---- - hw/usb/hcd-ehci.c | 39 +++++++++++++++++++-------------------- - 1 file changed, 19 insertions(+), 20 deletions(-) - -diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c -index 6a5da84..46f6d99 100644 ---- a/hw/usb/hcd-ehci.c -+++ b/hw/usb/hcd-ehci.c -@@ -373,6 +373,7 @@ struct EHCIQueue { - uint32_t seen; - uint64_t ts; - int async; -+ int transact_ctr; - - /* cached data from guest - needs to be flushed - * when guest removes an entry (doorbell, handshake sequence) -@@ -1837,6 +1838,10 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) - } - q->qh = qh; - -+ q->transact_ctr = get_field(q->qh.epcap, QH_EPCAP_MULT); -+ if (q->transact_ctr == 0) /* Guest bug in some versions of windows */ -+ q->transact_ctr = 4; -+ - if (q->dev == NULL) { - q->dev = ehci_find_device(q->ehci, devaddr); - } -@@ -2014,11 +2019,8 @@ static int ehci_state_fetchqtd(EHCIQueue *q) - } else if (p != NULL) { - switch (p->async) { - case EHCI_ASYNC_NONE: -- /* Should never happen packet should at least be initialized */ -- assert(0); -- break; - case EHCI_ASYNC_INITIALIZED: -- /* Previously nacked packet (likely interrupt ep) */ -+ /* Not yet executed (MULT), or previously nacked (int) packet */ - ehci_set_state(q->ehci, q->async, EST_EXECUTE); - break; - case EHCI_ASYNC_INFLIGHT: -@@ -2107,15 +2109,12 @@ static int ehci_state_execute(EHCIQueue *q) - - // TODO verify enough time remains in the uframe as in 4.4.1.1 - // TODO write back ptr to async list when done or out of time -- // TODO Windows does not seem to ever set the MULT field - -- if (!q->async) { -- int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); -- if (!transactCtr) { -- ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); -- again = 1; -- goto out; -- } -+ /* 4.10.3, bottom of page 82, go horizontal on transaction counter == 0 */ -+ if (!q->async && q->transact_ctr == 0) { -+ ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); -+ again = 1; -+ goto out; - } - - if (q->async) { -@@ -2132,7 +2131,11 @@ static int ehci_state_execute(EHCIQueue *q) - trace_usb_ehci_packet_action(p->queue, p, "async"); - p->async = EHCI_ASYNC_INFLIGHT; - ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); -- again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1; -+ if (q->async) { -+ again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1; -+ } else { -+ again = 1; -+ } - goto out; - } - -@@ -2152,13 +2155,9 @@ static int ehci_state_executing(EHCIQueue *q) - - ehci_execute_complete(q); - -- // 4.10.3 -- if (!q->async) { -- int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); -- transactCtr--; -- set_field(&q->qh.epcap, transactCtr, QH_EPCAP_MULT); -- // 4.10.3, bottom of page 82, should exit this state when transaction -- // counter decrements to 0 -+ /* 4.10.3 */ -+ if (!q->async && q->transact_ctr > 0) { -+ q->transact_ctr--; - } - - /* 4.10.5 */ --- -1.7.12.1 - diff --git a/0631-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch b/0631-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch new file mode 100644 index 0000000..53d2405 --- /dev/null +++ b/0631-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch @@ -0,0 +1,32 @@ +From a272467564b3915d36b85523ad7c2abf04a164a3 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 10 Sep 2012 13:49:46 +0200 +Subject: [PATCH] usb-redir: Revert usb-redir part of commit 93bfef4c + +Commit 93bfef4c6e4b23caea9d51e1099d06433d8835a4 makes qemu-devices +which report the qemu version string to the guest in some way use a +qemu_get_version function which reports a machine-specific version string. + +However usb-redir does not expose the qemu version to the guest, only to +the usbredir-host as part of the initial handshake. This can then be logged +on the usbredir-host side for debugging purposes and is otherwise completely +unused! For debugging purposes it is important to have the real qemu version +in there, rather then the machine-specific version. + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 57e6289..78e93a7 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -875,7 +875,6 @@ static void usbredir_chardev_close_bh(void *opaque) + static void usbredir_chardev_open(USBRedirDevice *dev) + { + uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, }; +- char version[32]; + int flags = 0; + + /* Make sure any pending closes are handled (no-op if none pending) */ diff --git a/0632-ehci-Fix-interrupt-packet-MULT-handling.patch b/0632-ehci-Fix-interrupt-packet-MULT-handling.patch new file mode 100644 index 0000000..71fd7c9 --- /dev/null +++ b/0632-ehci-Fix-interrupt-packet-MULT-handling.patch @@ -0,0 +1,128 @@ +From dc9b6b076e03412e67597c207f2202493e37db06 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 20 Sep 2012 16:55:02 +0200 +Subject: [PATCH] ehci: Fix interrupt packet MULT handling + +There are several issues with our handling of the MULT epcap field +of interrupt qhs, which this patch fixes. + +1) When we don't execute a transaction because of the transaction counter +being 0, p->async stays EHCI_ASYNC_NONE, and the next time we process the +same qtd we hit an assert in ehci_state_fetchqtd because of this. Even though +I believe that this is caused by 3 below, this patch still removes the assert, +as that can still happen without 3, when multiple packets are queued for the +same interrupt ep. + +2) We only *check* the transaction counter from ehci_state_execute, any +packets queued up by fill_queue bypass this check. This is fixed by not calling +fill_queue for interrupt packets. + +3) Some versions of Windows set the MULT field of the qh to 0, which is a +clear violation of the EHCI spec, but still they do it. This means that we +will never execute a qtd for these, making interrupt ep-s on USB-2 devices +not work, and after recent changes, triggering 1). + +So far we've stored the transaction counter in our copy of the mult field, +but with this beginnig at 0 already when dealing with these version of windows +this won't work. So this patch adds a transact_ctr field to our qh struct, +and sets this to the MULT field value on fetchqh. When the MULT field value +is 0, we set it to 4. Assuming that windows gets way with setting it to 0, +by the actual hardware going horizontal on a 1 -> 0 transition, which will +give it 4 transactions (MULT goes from 0 - 3). + +Note that we cannot stop on detecting the 1 -> 0 transition, as our decrement +of the transaction counter, and checking for it are done in 2 different places. + +Reported-by: Shawn Starr +Signed-off-by: Hans de Goede +--- + hw/usb/hcd-ehci.c | 39 +++++++++++++++++++-------------------- + 1 file changed, 19 insertions(+), 20 deletions(-) + +diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c +index 6a5da84..46f6d99 100644 +--- a/hw/usb/hcd-ehci.c ++++ b/hw/usb/hcd-ehci.c +@@ -373,6 +373,7 @@ struct EHCIQueue { + uint32_t seen; + uint64_t ts; + int async; ++ int transact_ctr; + + /* cached data from guest - needs to be flushed + * when guest removes an entry (doorbell, handshake sequence) +@@ -1837,6 +1838,10 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) + } + q->qh = qh; + ++ q->transact_ctr = get_field(q->qh.epcap, QH_EPCAP_MULT); ++ if (q->transact_ctr == 0) /* Guest bug in some versions of windows */ ++ q->transact_ctr = 4; ++ + if (q->dev == NULL) { + q->dev = ehci_find_device(q->ehci, devaddr); + } +@@ -2014,11 +2019,8 @@ static int ehci_state_fetchqtd(EHCIQueue *q) + } else if (p != NULL) { + switch (p->async) { + case EHCI_ASYNC_NONE: +- /* Should never happen packet should at least be initialized */ +- assert(0); +- break; + case EHCI_ASYNC_INITIALIZED: +- /* Previously nacked packet (likely interrupt ep) */ ++ /* Not yet executed (MULT), or previously nacked (int) packet */ + ehci_set_state(q->ehci, q->async, EST_EXECUTE); + break; + case EHCI_ASYNC_INFLIGHT: +@@ -2107,15 +2109,12 @@ static int ehci_state_execute(EHCIQueue *q) + + // TODO verify enough time remains in the uframe as in 4.4.1.1 + // TODO write back ptr to async list when done or out of time +- // TODO Windows does not seem to ever set the MULT field + +- if (!q->async) { +- int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); +- if (!transactCtr) { +- ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); +- again = 1; +- goto out; +- } ++ /* 4.10.3, bottom of page 82, go horizontal on transaction counter == 0 */ ++ if (!q->async && q->transact_ctr == 0) { ++ ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); ++ again = 1; ++ goto out; + } + + if (q->async) { +@@ -2132,7 +2131,11 @@ static int ehci_state_execute(EHCIQueue *q) + trace_usb_ehci_packet_action(p->queue, p, "async"); + p->async = EHCI_ASYNC_INFLIGHT; + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); +- again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1; ++ if (q->async) { ++ again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1; ++ } else { ++ again = 1; ++ } + goto out; + } + +@@ -2152,13 +2155,9 @@ static int ehci_state_executing(EHCIQueue *q) + + ehci_execute_complete(q); + +- // 4.10.3 +- if (!q->async) { +- int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); +- transactCtr--; +- set_field(&q->qh.epcap, transactCtr, QH_EPCAP_MULT); +- // 4.10.3, bottom of page 82, should exit this state when transaction +- // counter decrements to 0 ++ /* 4.10.3 */ ++ if (!q->async && q->transact_ctr > 0) { ++ q->transact_ctr--; + } + + /* 4.10.5 */ diff --git a/0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch b/0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch deleted file mode 100644 index a8bebbd..0000000 --- a/0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 79467d7c3fe963b39b00c884a5624cb1e754db9d Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 25 Sep 2012 13:22:21 +0200 -Subject: [PATCH] usb-redir: Adjust pkg-config check for usbredirparser .pc - file rename (v2) - -The usbredir 0.5 release introduced the new API for 64 bit packet ids, but -it kept the libusbredirparser.pc name as is, meaning that older versions of -qemu will still have their pkg-config check for usbredirparser fulfilled, -and build with the usb-redir device. Due to the API change there will be -some compiler warnings, but the build will succeed, however the usb-redir -device will be broken on 32 bit machines. - -To solve this a new usbredir-0.5.2 release is coming, which renames the -libusbredirparser.pc file to libusbredirparser-0.5.pc, so that it will no -longer fulfill the pkg-config check of the qemu-1.2 and older releases, -stopping the (silent) breakage. This patch adjusts qemu master's configure -to properly detect the new usbredir release. - -Changes in v2: --Not only use the new .pc name in the check but also when getting cflags - and libs! - -Signed-off-by: Hans de Goede ---- - configure | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/configure b/configure -index 2c4469f..f019526 100755 ---- a/configure -+++ b/configure -@@ -2758,10 +2758,10 @@ fi - - # check for usbredirparser for usb network redirection support - if test "$usb_redir" != "no" ; then -- if $pkg_config --atleast-version=0.5 libusbredirparser >/dev/null 2>&1 ; then -+ if $pkg_config --atleast-version=0.5 libusbredirparser-0.5 >/dev/null 2>&1 ; then - usb_redir="yes" -- usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null) -- usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null) -+ usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5 2>/dev/null) -+ usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5 2>/dev/null) - QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags" - libs_softmmu="$libs_softmmu $usb_redir_libs" - else --- -1.7.12.1 - diff --git a/0633-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch b/0633-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch new file mode 100644 index 0000000..45bf71c --- /dev/null +++ b/0633-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch @@ -0,0 +1,46 @@ +From 93e27ddf8c5e60eb932528cf1c560d81be108f96 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 25 Sep 2012 13:22:21 +0200 +Subject: [PATCH] usb-redir: Adjust pkg-config check for usbredirparser .pc + file rename (v2) + +The usbredir 0.5 release introduced the new API for 64 bit packet ids, but +it kept the libusbredirparser.pc name as is, meaning that older versions of +qemu will still have their pkg-config check for usbredirparser fulfilled, +and build with the usb-redir device. Due to the API change there will be +some compiler warnings, but the build will succeed, however the usb-redir +device will be broken on 32 bit machines. + +To solve this a new usbredir-0.5.2 release is coming, which renames the +libusbredirparser.pc file to libusbredirparser-0.5.pc, so that it will no +longer fulfill the pkg-config check of the qemu-1.2 and older releases, +stopping the (silent) breakage. This patch adjusts qemu master's configure +to properly detect the new usbredir release. + +Changes in v2: +-Not only use the new .pc name in the check but also when getting cflags + and libs! + +Signed-off-by: Hans de Goede +--- + configure | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/configure b/configure +index d43d61a..8dac47b 100755 +--- a/configure ++++ b/configure +@@ -2757,10 +2757,10 @@ fi + + # check for usbredirparser for usb network redirection support + if test "$usb_redir" != "no" ; then +- if $pkg_config --atleast-version=0.5 libusbredirparser >/dev/null 2>&1 ; then ++ if $pkg_config --atleast-version=0.5 libusbredirparser-0.5 >/dev/null 2>&1 ; then + usb_redir="yes" +- usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null) +- usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null) ++ usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5 2>/dev/null) ++ usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5 2>/dev/null) + QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags" + libs_softmmu="$libs_softmmu $usb_redir_libs" + else diff --git a/0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch b/0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch deleted file mode 100644 index f39bc12..0000000 --- a/0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 9ebfb490e04e1fe5466a4d31df17c5e6283236cb Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 27 Sep 2012 16:59:50 +0200 -Subject: [PATCH] usb-redir: Change usbredir_open_chardev into - usbredir_create_parser - -As we need to create the parser at more places. - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 78e93a7..5d16aff 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -872,15 +872,11 @@ static void usbredir_chardev_close_bh(void *opaque) - } - } - --static void usbredir_chardev_open(USBRedirDevice *dev) -+static void usbredir_create_parser(USBRedirDevice *dev) - { - uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, }; - int flags = 0; - -- /* Make sure any pending closes are handled (no-op if none pending) */ -- usbredir_chardev_close_bh(dev); -- qemu_bh_cancel(dev->chardev_close_bh); -- - DPRINTF("creating usbredirparser\n"); - - dev->parser = qemu_oom_check(usbredirparser_create()); -@@ -992,7 +988,10 @@ static void usbredir_chardev_event(void *opaque, int event) - switch (event) { - case CHR_EVENT_OPENED: - DPRINTF("chardev open\n"); -- usbredir_chardev_open(dev); -+ /* Make sure any pending closes are handled (no-op if none pending) */ -+ usbredir_chardev_close_bh(dev); -+ qemu_bh_cancel(dev->chardev_close_bh); -+ usbredir_create_parser(dev); - break; - case CHR_EVENT_CLOSED: - DPRINTF("chardev close\n"); --- -1.7.12.1 - diff --git a/0634-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch b/0634-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch new file mode 100644 index 0000000..34cbc35 --- /dev/null +++ b/0634-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch @@ -0,0 +1,46 @@ +From 0e80029894a26f26a6641de5074ff680d98a6ffa Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 27 Sep 2012 16:59:50 +0200 +Subject: [PATCH] usb-redir: Change usbredir_open_chardev into + usbredir_create_parser + +As we need to create the parser at more places. + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 78e93a7..5d16aff 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -872,15 +872,11 @@ static void usbredir_chardev_close_bh(void *opaque) + } + } + +-static void usbredir_chardev_open(USBRedirDevice *dev) ++static void usbredir_create_parser(USBRedirDevice *dev) + { + uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, }; + int flags = 0; + +- /* Make sure any pending closes are handled (no-op if none pending) */ +- usbredir_chardev_close_bh(dev); +- qemu_bh_cancel(dev->chardev_close_bh); +- + DPRINTF("creating usbredirparser\n"); + + dev->parser = qemu_oom_check(usbredirparser_create()); +@@ -992,7 +988,10 @@ static void usbredir_chardev_event(void *opaque, int event) + switch (event) { + case CHR_EVENT_OPENED: + DPRINTF("chardev open\n"); +- usbredir_chardev_open(dev); ++ /* Make sure any pending closes are handled (no-op if none pending) */ ++ usbredir_chardev_close_bh(dev); ++ qemu_bh_cancel(dev->chardev_close_bh); ++ usbredir_create_parser(dev); + break; + case CHR_EVENT_CLOSED: + DPRINTF("chardev close\n"); diff --git a/0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch b/0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch deleted file mode 100644 index a222747..0000000 --- a/0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch +++ /dev/null @@ -1,42 +0,0 @@ -From c57b03073357e813ade4b3b34f6c1e3c0de394c2 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 27 Sep 2012 16:57:41 +0200 -Subject: [PATCH] usb-redir: Don't make migration fail in none seamless case - -Instead simple disconnect the device like host redirection does on -migration. - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 5d16aff..022ba42 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -1637,12 +1637,17 @@ static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused) - } - - /* -- * Our chardev should be open already at this point, otherwise -- * the usbredir channel will be broken (ie spice without seamless) -+ * If our chardev is not open already at this point the usbredir connection -+ * has been broken (non seamless migration, or restore from disk). -+ * -+ * In this case create a temporary parser to receive the migration data, -+ * and schedule the close_bh to report the device as disconnected to the -+ * guest and to destroy the parser again. - */ - if (dev->parser == NULL) { -- ERROR("get_parser called with closed chardev, failing migration\n"); -- return -1; -+ WARNING("usb-redir connection broken during migration\n"); -+ usbredir_create_parser(dev); -+ qemu_bh_schedule(dev->chardev_close_bh); - } - - data = g_malloc(len); --- -1.7.12.1 - diff --git a/0635-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch b/0635-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch new file mode 100644 index 0000000..3787e29 --- /dev/null +++ b/0635-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch @@ -0,0 +1,39 @@ +From 11da0c283915f9e3d3da42451d218c26efef4671 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 27 Sep 2012 16:57:41 +0200 +Subject: [PATCH] usb-redir: Don't make migration fail in none seamless case + +Instead simple disconnect the device like host redirection does on +migration. + +Signed-off-by: Hans de Goede +--- + hw/usb/redirect.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 5d16aff..022ba42 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -1637,12 +1637,17 @@ static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused) + } + + /* +- * Our chardev should be open already at this point, otherwise +- * the usbredir channel will be broken (ie spice without seamless) ++ * If our chardev is not open already at this point the usbredir connection ++ * has been broken (non seamless migration, or restore from disk). ++ * ++ * In this case create a temporary parser to receive the migration data, ++ * and schedule the close_bh to report the device as disconnected to the ++ * guest and to destroy the parser again. + */ + if (dev->parser == NULL) { +- ERROR("get_parser called with closed chardev, failing migration\n"); +- return -1; ++ WARNING("usb-redir connection broken during migration\n"); ++ usbredir_create_parser(dev); ++ qemu_bh_schedule(dev->chardev_close_bh); + } + + data = g_malloc(len); diff --git a/0701-mips-Fix-link-error-with-piix4_pm_init.patch b/0701-mips-Fix-link-error-with-piix4_pm_init.patch new file mode 100644 index 0000000..f62a389 --- /dev/null +++ b/0701-mips-Fix-link-error-with-piix4_pm_init.patch @@ -0,0 +1,27 @@ +From a1cbcc0757b08e07a49fe9c8ba003ae47cf72614 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Mon, 6 Aug 2012 17:12:40 -0400 +Subject: [PATCH] mips: Fix link error with 'piix4_pm_init' + + LINK mips-softmmu/qemu-system-mips + LINK m68k-softmmu/qemu-system-m68k +hw/mips/../mips_malta.o: In function `mips_malta_init': +/home/crobinso/qemu-kvm/hw/mips/../mips_malta.c:961: undefined reference to `piix4_pm_init' + +Signed-off-by: Cole Robinson +--- + hw/mips/Makefile.objs | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs +index 29a5d0d..89af0e9 100644 +--- a/hw/mips/Makefile.objs ++++ b/hw/mips/Makefile.objs +@@ -1,6 +1,7 @@ + obj-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o + obj-y += mips_addr.o mips_timer.o mips_int.o + obj-y += gt64xxx.o mc146818rtc.o ++obj-y += acpi.o acpi_piix4.o + obj-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o + + obj-y := $(addprefix ../,$(obj-y)) diff --git a/0702-configure-Add-disable-kvm-options.patch b/0702-configure-Add-disable-kvm-options.patch new file mode 100644 index 0000000..9c48a3e --- /dev/null +++ b/0702-configure-Add-disable-kvm-options.patch @@ -0,0 +1,69 @@ +From b303845e11bd656915198589294a0660002e6814 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Mon, 13 Aug 2012 18:39:54 -0400 +Subject: [PATCH] configure: Add --disable-kvm-options + +In Fedora, our qemu package is based on qemu-kvm, and we go to convoluted +lengths to provide a qemu-kvm binary with KVM on by default, but all +qemu-system-* with KVM off by default (using ./configure --disable-kvm) + +For qemu-system*, what we really want is upstream qemu symantics of TCG +by default, but the opt in option for KVM. CONFIG_KVM_OPTIONS fits the +bill, so let's expose it through ./configure. This will also simplify +our packaging for non-x86 KVM. + +Signed-off-by: Cole Robinson +--- + configure | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/configure b/configure +index 8dac47b..1668f30 100755 +--- a/configure ++++ b/configure +@@ -210,6 +210,7 @@ bsd_user="no" + guest_base="" + uname_release="" + mixemu="no" ++kvmoptions="yes" + aix="no" + blobs="yes" + pkgversion=" ($(kvm_version))" +@@ -732,6 +733,8 @@ for opt do + ;; + --enable-kvm) kvm="yes" + ;; ++ --disable-kvm-options) kvmoptions="no" ++ ;; + --disable-tcg-interpreter) tcg_interpreter="no" + ;; + --enable-tcg-interpreter) tcg_interpreter="yes" +@@ -1080,6 +1083,8 @@ echo " --enable-bluez enable bluez stack connectivity" + echo " --disable-slirp disable SLIRP userspace network connectivity" + echo " --disable-kvm disable KVM acceleration support" + echo " --enable-kvm enable KVM acceleration support" ++echo " --disable-kvm-options if KVM is enabled, default to KVM=off, and" ++echo " remove non-upstream cli options" + echo " --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)" + echo " --disable-nptl disable usermode NPTL support" + echo " --enable-nptl enable usermode NPTL support" +@@ -3159,6 +3164,7 @@ echo "ATTR/XATTR support $attr" + echo "Install blobs $blobs" + echo "KVM support $kvm" + echo "TCG interpreter $tcg_interpreter" ++echo "KVM CLI options $kvmoptions" + echo "fdt support $fdt" + echo "preadv support $preadv" + echo "fdatasync $fdatasync" +@@ -3892,7 +3898,10 @@ case "$target_arch2" in + \( "$target_arch2" = "x86_64" -a "$cpu" = "i386" \) -o \ + \( "$target_arch2" = "i386" -a "$cpu" = "x86_64" \) \) ; then + echo "CONFIG_KVM=y" >> $config_target_mak +- echo "CONFIG_KVM_OPTIONS=y" >> $config_host_mak ++ ++ if test "$kvmoptions" = "yes" ; then ++ echo "CONFIG_KVM_OPTIONS=y" >> $config_host_mak ++ fi + if test "$vhost_net" = "yes" ; then + echo "CONFIG_VHOST_NET=y" >> $config_target_mak + fi diff --git a/0703-arm_boot-Change-initrd-load-address-to-halfway-throu.patch b/0703-arm_boot-Change-initrd-load-address-to-halfway-throu.patch new file mode 100644 index 0000000..fcfadc8 --- /dev/null +++ b/0703-arm_boot-Change-initrd-load-address-to-halfway-throu.patch @@ -0,0 +1,134 @@ +From 8a139a56e82b6adec8dd6ea111f39d19367febfc Mon Sep 17 00:00:00 2001 +From: Peter Maydell +Date: Fri, 26 Oct 2012 16:29:38 +0100 +Subject: [PATCH] arm_boot: Change initrd load address to "halfway through RAM" + +To avoid continually having to bump the initrd load address +to account for larger kernel images, put the initrd halfway +through RAM. This allows large kernels on new boards with lots +of RAM to work OK, without breaking existing usecases for +boards with only 32MB of RAM. + +Note that this change fixes in passing a bug where we were +passing an overly large max_size to load_image_targphys() +for the initrd, which meant that we wouldn't correctly refuse +to load an enormous initrd that didn't actually fit into RAM. + +Signed-off-by: Peter Maydell +--- + hw/arm-misc.h | 1 + + hw/arm_boot.c | 41 ++++++++++++++++++++++++++--------------- + 2 files changed, 27 insertions(+), 15 deletions(-) + +diff --git a/hw/arm-misc.h b/hw/arm-misc.h +index bdd8fec..0f7deb5 100644 +--- a/hw/arm-misc.h ++++ b/hw/arm-misc.h +@@ -56,6 +56,7 @@ struct arm_boot_info { + const struct arm_boot_info *info); + /* Used internally by arm_boot.c */ + int is_linux; ++ target_phys_addr_t initrd_start; + target_phys_addr_t initrd_size; + target_phys_addr_t entry; + }; +diff --git a/hw/arm_boot.c b/hw/arm_boot.c +index a6e9143..920c337 100644 +--- a/hw/arm_boot.c ++++ b/hw/arm_boot.c +@@ -18,7 +18,6 @@ + + #define KERNEL_ARGS_ADDR 0x100 + #define KERNEL_LOAD_ADDR 0x00010000 +-#define INITRD_LOAD_ADDR 0x00d00000 + + /* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */ + static uint32_t bootloader[] = { +@@ -109,7 +108,7 @@ static void set_kernel_args(const struct arm_boot_info *info) + /* ATAG_INITRD2 */ + WRITE_WORD(p, 4); + WRITE_WORD(p, 0x54420005); +- WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR); ++ WRITE_WORD(p, info->initrd_start); + WRITE_WORD(p, initrd_size); + } + if (info->kernel_cmdline && *info->kernel_cmdline) { +@@ -185,10 +184,11 @@ static void set_kernel_args_old(const struct arm_boot_info *info) + /* pages_in_vram */ + WRITE_WORD(p, 0); + /* initrd_start */ +- if (initrd_size) +- WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR); +- else ++ if (initrd_size) { ++ WRITE_WORD(p, info->initrd_start); ++ } else { + WRITE_WORD(p, 0); ++ } + /* initrd_size */ + WRITE_WORD(p, initrd_size); + /* rd_start */ +@@ -281,14 +281,13 @@ static int load_dtb(target_phys_addr_t addr, const struct arm_boot_info *binfo) + + if (binfo->initrd_size) { + rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", +- binfo->loader_start + INITRD_LOAD_ADDR); ++ binfo->initrd_start); + if (rc < 0) { + fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); + } + + rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", +- binfo->loader_start + INITRD_LOAD_ADDR + +- binfo->initrd_size); ++ binfo->initrd_start + binfo->initrd_size); + if (rc < 0) { + fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); + } +@@ -375,6 +374,19 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) + big_endian = 0; + #endif + ++ /* We want to put the initrd far enough into RAM that when the ++ * kernel is uncompressed it will not clobber the initrd. However ++ * on boards without much RAM we must ensure that we still leave ++ * enough room for a decent sized initrd, and on boards with large ++ * amounts of RAM we must avoid the initrd being so far up in RAM ++ * that it is outside lowmem and inaccessible to the kernel. ++ * So for boards with less than 256MB of RAM we put the initrd ++ * halfway into RAM, and for boards with 256MB of RAM or more we put ++ * the initrd at 128MB. ++ */ ++ info->initrd_start = info->loader_start + ++ MIN(info->ram_size / 2, 128 * 1024 * 1024); ++ + /* Assume that raw images are linux kernels, and ELF images are not. */ + kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry, + NULL, NULL, big_endian, ELF_MACHINE, 1); +@@ -398,10 +410,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) + if (is_linux) { + if (info->initrd_filename) { + initrd_size = load_image_targphys(info->initrd_filename, +- info->loader_start +- + INITRD_LOAD_ADDR, +- info->ram_size +- - INITRD_LOAD_ADDR); ++ info->initrd_start, ++ info->ram_size - ++ info->initrd_start); + if (initrd_size < 0) { + fprintf(stderr, "qemu: could not load initrd '%s'\n", + info->initrd_filename); +@@ -419,9 +430,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) + */ + if (info->dtb_filename) { + /* Place the DTB after the initrd in memory */ +- target_phys_addr_t dtb_start = TARGET_PAGE_ALIGN(info->loader_start +- + INITRD_LOAD_ADDR +- + initrd_size); ++ target_phys_addr_t dtb_start = TARGET_PAGE_ALIGN( ++ info->initrd_start + ++ initrd_size); + if (load_dtb(dtb_start, info)) { + exit(1); + } diff --git a/0704-dtrace-backend-add-function-to-reserved-words.patch b/0704-dtrace-backend-add-function-to-reserved-words.patch new file mode 100644 index 0000000..fa54432 --- /dev/null +++ b/0704-dtrace-backend-add-function-to-reserved-words.patch @@ -0,0 +1,24 @@ +From 63d0a6cd71a0e3b6ba1a9cb4e1ba880121840a7e Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Sun, 2 Sep 2012 02:04:16 +0300 +Subject: [PATCH] dtrace backend: add function to reserved words + +Signed-off-by: Alon Levy +Signed-off-by: Stefan Hajnoczi +--- + scripts/tracetool/backend/dtrace.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py +index 9cab75c..6be7047 100644 +--- a/scripts/tracetool/backend/dtrace.py ++++ b/scripts/tracetool/backend/dtrace.py +@@ -87,7 +87,7 @@ def stap(events): + if len(e.args) > 0: + for name in e.args.names(): + # Append underscore to reserved keywords +- if name in ('limit', 'in', 'next', 'self'): ++ if name in ('limit', 'in', 'next', 'self', 'function'): + name += '_' + out(' %s = $arg%d;' % (name, i)) + i += 1 diff --git a/0705-libcacard-fix-missing-symbols-in-libcacard.so.patch b/0705-libcacard-fix-missing-symbols-in-libcacard.so.patch new file mode 100644 index 0000000..157f97f --- /dev/null +++ b/0705-libcacard-fix-missing-symbols-in-libcacard.so.patch @@ -0,0 +1,22 @@ +From 9fbc22fddb14b1e474807bc02ab31e35af25d3a3 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Wed, 28 Nov 2012 16:38:43 +0200 +Subject: [PATCH] libcacard: fix missing symbols in libcacard.so + +--- + libcacard/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libcacard/Makefile b/libcacard/Makefile +index 63990b7..9ce3117 100644 +--- a/libcacard/Makefile ++++ b/libcacard/Makefile +@@ -7,7 +7,7 @@ libcacard_includedir=$(includedir)/cacard + $(call set-vpath, $(SRC_PATH)) + + # objects linked into a shared library, built with libtool with -fPIC if required +-QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o $(trace-obj-y) ++QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o iov.o cutils.o qemu-user.o $(trace-obj-y) + QEMU_OBJS_LIB=$(patsubst %.o,%.lo,$(QEMU_OBJS)) + + QEMU_CFLAGS+=-I../ diff --git a/0706-configure-move-vscclient-binary-under-libcacard.patch b/0706-configure-move-vscclient-binary-under-libcacard.patch new file mode 100644 index 0000000..1bc1b28 --- /dev/null +++ b/0706-configure-move-vscclient-binary-under-libcacard.patch @@ -0,0 +1,90 @@ +From 5f3abf0f58996748f93daff1542d9bbd99789196 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Thu, 29 Nov 2012 14:11:19 +0200 +Subject: [PATCH] configure: move vscclient binary under libcacard + +build rule is in top level Makefile like other tools. + +build rule also exists in libcacard for installation purposes. This was +fixed in a better way in 1.3.0-rc2 +--- + Makefile | 4 ++-- + Makefile.objs | 11 ++++++----- + configure | 2 +- + libcacard/Makefile | 6 +++++- + 4 files changed, 14 insertions(+), 9 deletions(-) + +diff --git a/Makefile b/Makefile +index dd11e3c..13c1693 100644 +--- a/Makefile ++++ b/Makefile +@@ -168,8 +168,8 @@ qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) + + qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o + +-vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) $(tools-obj-y) qemu-timer-common.o libcacard/vscclient.o +- $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@") ++libcacard/vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o iov.o cutils.o qemu-user.o libcacard/vscclient.o ++libcacard/vscclient$(EXESUF): LIBS += $(libcacard_libs) + + fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o oslib-posix.o $(trace-obj-y) + fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap +diff --git a/Makefile.objs b/Makefile.objs +index 4412757..92d6b4a 100644 +--- a/Makefile.objs ++++ b/Makefile.objs +@@ -206,11 +206,12 @@ $(trace-obj-y): $(GENERATED_HEADERS) + ###################################################################### + # smartcard + +-libcacard-y += libcacard/cac.o libcacard/event.o +-libcacard-y += libcacard/vcard.o libcacard/vreader.o +-libcacard-y += libcacard/vcard_emul_nss.o +-libcacard-y += libcacard/vcard_emul_type.o +-libcacard-y += libcacard/card_7816.o ++libcacard-base-y += cac.o event.o ++libcacard-base-y += vcard.o vreader.o ++libcacard-base-y += vcard_emul_nss.o ++libcacard-base-y += vcard_emul_type.o ++libcacard-base-y += card_7816.o ++libcacard-y = $(addprefix libcacard/,$(libcacard-base-y)) + + common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y) + +diff --git a/configure b/configure +index 1668f30..6af2806 100755 +--- a/configure ++++ b/configure +@@ -3078,7 +3078,7 @@ if test "$softmmu" = yes ; then + fi + fi + if test "$smartcard_nss" = "yes" ; then +- tools="vscclient\$(EXESUF) $tools" ++ tools="libcacard/vscclient\$(EXESUF) $tools" + fi + fi + +diff --git a/libcacard/Makefile b/libcacard/Makefile +index 9ce3117..88ed064 100644 +--- a/libcacard/Makefile ++++ b/libcacard/Makefile +@@ -44,6 +44,10 @@ libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in + < $(libcacard_srcpath)/libcacard.pc.in > libcacard.pc,\ + " GEN $@") + ++VSCCLIENT_QEMU_OBJS=$(addprefix ../,$(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o iov.o cutils.o qemu-user.o) ++vscclient$(EXESUF): $(VSCCLIENT_QEMU_OBJS) $(libcacard-base-y) vscclient.o ++vscclient$(EXESUF): LIBS += $(libcacard_libs) ++ + .PHONY: install-libcacard + + install-libcacard: libcacard.pc libcacard.la vscclient +@@ -51,7 +55,7 @@ install-libcacard: libcacard.pc libcacard.la vscclient + $(INSTALL_DIR) "$(DESTDIR)$(libdir)/pkgconfig" + $(INSTALL_DIR) "$(DESTDIR)$(libcacard_includedir)" + $(INSTALL_DIR) "$(DESTDIR)$(bindir)" +- $(LIBTOOL) --mode=install $(INSTALL_PROG) vscclient "$(DESTDIR)$(bindir)" ++ $(LIBTOOL) --mode=install $(INSTALL_PROG) vscclient$(EXESUF) "$(DESTDIR)$(bindir)" + $(LIBTOOL) --mode=install $(INSTALL_DATA) libcacard.la "$(DESTDIR)$(libdir)" + $(LIBTOOL) --mode=install $(INSTALL_DATA) libcacard.pc "$(DESTDIR)$(libdir)/pkgconfig" + for inc in *.h; do \ diff --git a/0707-libcacard-fix-missing-symbol-in-libcacard.so.patch b/0707-libcacard-fix-missing-symbol-in-libcacard.so.patch new file mode 100644 index 0000000..aef8085 --- /dev/null +++ b/0707-libcacard-fix-missing-symbol-in-libcacard.so.patch @@ -0,0 +1,30 @@ +From c2cd586f8a83e20fd264cd53ba1120979779c34b Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Wed, 28 Nov 2012 11:16:26 +0200 +Subject: [PATCH] libcacard: fix missing symbol in libcacard.so + +Before patch: +$ make libcacard.la +$ nm ./libcacard/.libs/libcacard.so.0.0.0 | grep " U " | \ + egrep -v "(g_)|(GLIBC)|(SECMOD)|(PK11)|(CERT)|(NSS)|(PORT)|(PR)" + U error_set + +Signed-off-by: Alon Levy +Signed-off-by: Paolo Bonzini +--- + libcacard/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libcacard/Makefile b/libcacard/Makefile +index 88ed064..7973f8d 100644 +--- a/libcacard/Makefile ++++ b/libcacard/Makefile +@@ -7,7 +7,7 @@ libcacard_includedir=$(includedir)/cacard + $(call set-vpath, $(SRC_PATH)) + + # objects linked into a shared library, built with libtool with -fPIC if required +-QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o iov.o cutils.o qemu-user.o $(trace-obj-y) ++QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o error.o iov.o cutils.o qemu-user.o $(trace-obj-y) + QEMU_OBJS_LIB=$(patsubst %.o,%.lo,$(QEMU_OBJS)) + + QEMU_CFLAGS+=-I../ diff --git a/0708-seccomp-adding-new-syscalls-bugzilla-855162.patch b/0708-seccomp-adding-new-syscalls-bugzilla-855162.patch new file mode 100644 index 0000000..0136558 --- /dev/null +++ b/0708-seccomp-adding-new-syscalls-bugzilla-855162.patch @@ -0,0 +1,238 @@ +From 83df794bc330e0c71d2d2f1f6d51103b53393f9c Mon Sep 17 00:00:00 2001 +From: Eduardo Otubo +Date: Thu, 29 Nov 2012 13:56:41 -0200 +Subject: [PATCH] seccomp: adding new syscalls (bugzilla 855162) + +According to the bug 855162[0] - there's the need of adding new syscalls +to the whitelist when using Qemu with Libvirt. + +[0] - https://bugzilla.redhat.com/show_bug.cgi?id=855162 + +Reported-by: Paul Moore +Tested-by: Paul Moore +Signed-off-by: Eduardo Otubo +Signed-off-by: Corey Bryant +Signed-off-by: Anthony Liguori +--- + qemu-seccomp.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 139 insertions(+), 17 deletions(-) + +diff --git a/qemu-seccomp.c b/qemu-seccomp.c +index 64329a3..2a71d6f 100644 +--- a/qemu-seccomp.c ++++ b/qemu-seccomp.c +@@ -26,8 +26,12 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { + { SCMP_SYS(timer_gettime), 254 }, + { SCMP_SYS(futex), 253 }, + { SCMP_SYS(select), 252 }, ++#if defined(__x86_64__) + { SCMP_SYS(recvfrom), 251 }, + { SCMP_SYS(sendto), 250 }, ++#elif defined(__i386__) ++ { SCMP_SYS(socketcall), 250 }, ++#endif + { SCMP_SYS(read), 249 }, + { SCMP_SYS(brk), 248 }, + { SCMP_SYS(clone), 247 }, +@@ -36,15 +40,30 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { + { SCMP_SYS(execve), 245 }, + { SCMP_SYS(open), 245 }, + { SCMP_SYS(ioctl), 245 }, ++#if defined(__x86_64__) ++ { SCMP_SYS(socket), 245 }, ++ { SCMP_SYS(setsockopt), 245 }, + { SCMP_SYS(recvmsg), 245 }, + { SCMP_SYS(sendmsg), 245 }, + { SCMP_SYS(accept), 245 }, + { SCMP_SYS(connect), 245 }, ++ { SCMP_SYS(socketpair), 245 }, ++ { SCMP_SYS(bind), 245 }, ++ { SCMP_SYS(listen), 245 }, ++ { SCMP_SYS(semget), 245 }, ++#elif defined(__i386__) ++ { SCMP_SYS(ipc), 245 }, ++#endif + { SCMP_SYS(gettimeofday), 245 }, + { SCMP_SYS(readlink), 245 }, + { SCMP_SYS(access), 245 }, + { SCMP_SYS(prctl), 245 }, + { SCMP_SYS(signalfd), 245 }, ++ { SCMP_SYS(getrlimit), 245 }, ++ { SCMP_SYS(set_tid_address), 245 }, ++ { SCMP_SYS(statfs), 245 }, ++ { SCMP_SYS(unlink), 245 }, ++ { SCMP_SYS(wait4), 245 }, + #if defined(__i386__) + { SCMP_SYS(fcntl64), 245 }, + { SCMP_SYS(fstat64), 245 }, +@@ -56,30 +75,33 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { + { SCMP_SYS(sigreturn), 245 }, + { SCMP_SYS(_newselect), 245 }, + { SCMP_SYS(_llseek), 245 }, +- { SCMP_SYS(mmap2), 245}, ++ { SCMP_SYS(mmap2), 245 }, + { SCMP_SYS(sigprocmask), 245 }, +-#elif defined(__x86_64__) +- { SCMP_SYS(sched_getparam), 245}, +- { SCMP_SYS(sched_getscheduler), 245}, +- { SCMP_SYS(fstat), 245}, +- { SCMP_SYS(clock_getres), 245}, +- { SCMP_SYS(sched_get_priority_min), 245}, +- { SCMP_SYS(sched_get_priority_max), 245}, +- { SCMP_SYS(stat), 245}, +- { SCMP_SYS(socket), 245}, +- { SCMP_SYS(setsockopt), 245}, +- { SCMP_SYS(uname), 245}, +- { SCMP_SYS(semget), 245}, + #endif ++ { SCMP_SYS(sched_getparam), 245 }, ++ { SCMP_SYS(sched_getscheduler), 245 }, ++ { SCMP_SYS(fstat), 245 }, ++ { SCMP_SYS(clock_getres), 245 }, ++ { SCMP_SYS(sched_get_priority_min), 245 }, ++ { SCMP_SYS(sched_get_priority_max), 245 }, ++ { SCMP_SYS(stat), 245 }, ++ { SCMP_SYS(uname), 245 }, + { SCMP_SYS(eventfd2), 245 }, + { SCMP_SYS(dup), 245 }, ++ { SCMP_SYS(dup2), 245 }, ++ { SCMP_SYS(dup3), 245 }, + { SCMP_SYS(gettid), 245 }, ++ { SCMP_SYS(getgid), 245 }, ++ { SCMP_SYS(getegid), 245 }, ++ { SCMP_SYS(getuid), 245 }, ++ { SCMP_SYS(geteuid), 245 }, + { SCMP_SYS(timer_create), 245 }, + { SCMP_SYS(exit), 245 }, + { SCMP_SYS(clock_gettime), 245 }, + { SCMP_SYS(time), 245 }, + { SCMP_SYS(restart_syscall), 245 }, + { SCMP_SYS(pwrite64), 245 }, ++ { SCMP_SYS(nanosleep), 245 }, + { SCMP_SYS(chown), 245 }, + { SCMP_SYS(openat), 245 }, + { SCMP_SYS(getdents), 245 }, +@@ -93,8 +115,6 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { + { SCMP_SYS(lseek), 245 }, + { SCMP_SYS(pselect6), 245 }, + { SCMP_SYS(fork), 245 }, +- { SCMP_SYS(bind), 245 }, +- { SCMP_SYS(listen), 245 }, + { SCMP_SYS(eventfd), 245 }, + { SCMP_SYS(rt_sigprocmask), 245 }, + { SCMP_SYS(write), 244 }, +@@ -104,10 +124,112 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { + { SCMP_SYS(pipe2), 242 }, + { SCMP_SYS(munmap), 242 }, + { SCMP_SYS(mremap), 242 }, ++ { SCMP_SYS(fdatasync), 242 }, ++ { SCMP_SYS(close), 242 }, ++ { SCMP_SYS(rt_sigpending), 242 }, ++ { SCMP_SYS(rt_sigtimedwait), 242 }, ++ { SCMP_SYS(readv), 242 }, ++ { SCMP_SYS(writev), 242 }, ++ { SCMP_SYS(preadv), 242 }, ++ { SCMP_SYS(pwritev), 242 }, ++ { SCMP_SYS(setrlimit), 242 }, ++ { SCMP_SYS(ftruncate), 242 }, ++ { SCMP_SYS(lstat), 242 }, ++ { SCMP_SYS(pipe), 242 }, ++ { SCMP_SYS(umask), 242 }, ++ { SCMP_SYS(chdir), 242 }, ++ { SCMP_SYS(setitimer), 242 }, ++ { SCMP_SYS(setsid), 242 }, ++ { SCMP_SYS(poll), 242 }, ++ { SCMP_SYS(epoll_create), 242 }, ++ { SCMP_SYS(epoll_ctl), 242 }, ++ { SCMP_SYS(epoll_wait), 242 }, ++#if defined(__i386__) ++ { SCMP_SYS(waitpid), 242 }, ++#elif defined(__x86_64__) + { SCMP_SYS(getsockname), 242 }, + { SCMP_SYS(getpeername), 242 }, +- { SCMP_SYS(fdatasync), 242 }, +- { SCMP_SYS(close), 242 } ++ { SCMP_SYS(accept4), 242 }, ++ { SCMP_SYS(newfstatat), 241 }, ++ { SCMP_SYS(shutdown), 241 }, ++ { SCMP_SYS(getsockopt), 241 }, ++ { SCMP_SYS(semctl), 241 }, ++ { SCMP_SYS(semop), 241 }, ++ { SCMP_SYS(semtimedop), 241 }, ++ { SCMP_SYS(epoll_ctl_old), 241 }, ++ { SCMP_SYS(epoll_wait_old), 241 }, ++#endif ++ { SCMP_SYS(epoll_pwait), 241 }, ++ { SCMP_SYS(epoll_create1), 241 }, ++ { SCMP_SYS(ppoll), 241 }, ++ { SCMP_SYS(creat), 241 }, ++ { SCMP_SYS(link), 241 }, ++ { SCMP_SYS(getpid), 241 }, ++ { SCMP_SYS(getppid), 241 }, ++ { SCMP_SYS(getpgrp), 241 }, ++ { SCMP_SYS(getpgid), 241 }, ++ { SCMP_SYS(getsid), 241 }, ++ { SCMP_SYS(getdents64), 241 }, ++ { SCMP_SYS(getresuid), 241 }, ++ { SCMP_SYS(getresgid), 241 }, ++ { SCMP_SYS(getgroups), 241 }, ++#if defined(__i386__) ++ { SCMP_SYS(getresuid32), 241 }, ++ { SCMP_SYS(getresgid32), 241 }, ++ { SCMP_SYS(getgroups32), 241 }, ++ { SCMP_SYS(signal), 241 }, ++ { SCMP_SYS(sigaction), 241 }, ++ { SCMP_SYS(sigsuspend), 241 }, ++ { SCMP_SYS(sigpending), 241 }, ++ { SCMP_SYS(truncate64), 241 }, ++ { SCMP_SYS(ftruncate64), 241 }, ++ { SCMP_SYS(fchown32), 241 }, ++ { SCMP_SYS(chown32), 241 }, ++ { SCMP_SYS(lchown32), 241 }, ++ { SCMP_SYS(statfs64), 241 }, ++ { SCMP_SYS(fstatfs64), 241 }, ++ { SCMP_SYS(fstatat64), 241 }, ++ { SCMP_SYS(lstat64), 241 }, ++ { SCMP_SYS(sendfile64), 241 }, ++ { SCMP_SYS(ugetrlimit), 241 }, ++#endif ++ { SCMP_SYS(alarm), 241 }, ++ { SCMP_SYS(rt_sigsuspend), 241 }, ++ { SCMP_SYS(rt_sigqueueinfo), 241 }, ++ { SCMP_SYS(rt_tgsigqueueinfo), 241 }, ++ { SCMP_SYS(sigaltstack), 241 }, ++ { SCMP_SYS(signalfd4), 241 }, ++ { SCMP_SYS(truncate), 241 }, ++ { SCMP_SYS(fchown), 241 }, ++ { SCMP_SYS(lchown), 241 }, ++ { SCMP_SYS(fchownat), 241 }, ++ { SCMP_SYS(fstatfs), 241 }, ++ { SCMP_SYS(sendfile), 241 }, ++ { SCMP_SYS(getitimer), 241 }, ++ { SCMP_SYS(syncfs), 241 }, ++ { SCMP_SYS(fsync), 241 }, ++ { SCMP_SYS(fchdir), 241 }, ++ { SCMP_SYS(flock), 241 }, ++ { SCMP_SYS(msync), 241 }, ++ { SCMP_SYS(sched_setparam), 241 }, ++ { SCMP_SYS(sched_setscheduler), 241 }, ++ { SCMP_SYS(sched_yield), 241 }, ++ { SCMP_SYS(sched_rr_get_interval), 241 }, ++ { SCMP_SYS(sched_setaffinity), 241 }, ++ { SCMP_SYS(sched_getaffinity), 241 }, ++ { SCMP_SYS(readahead), 241 }, ++ { SCMP_SYS(timer_getoverrun), 241 }, ++ { SCMP_SYS(unlinkat), 241 }, ++ { SCMP_SYS(readlinkat), 241 }, ++ { SCMP_SYS(faccessat), 241 }, ++ { SCMP_SYS(get_robust_list), 241 }, ++ { SCMP_SYS(splice), 241 }, ++ { SCMP_SYS(vmsplice), 241 }, ++ { SCMP_SYS(getcpu), 241 }, ++ { SCMP_SYS(sendmmsg), 241 }, ++ { SCMP_SYS(recvmmsg), 241 }, ++ { SCMP_SYS(prlimit64), 241 }, ++ { SCMP_SYS(waitid), 241 } + }; + + int seccomp_start(void) diff --git a/0709-e1000-Discard-oversized-packets-based-on-SBP-LPE.patch b/0709-e1000-Discard-oversized-packets-based-on-SBP-LPE.patch new file mode 100644 index 0000000..db61c68 --- /dev/null +++ b/0709-e1000-Discard-oversized-packets-based-on-SBP-LPE.patch @@ -0,0 +1,39 @@ +From e633e19df6e1d33dd9ce88fba2896082b1efbeec Mon Sep 17 00:00:00 2001 +From: Michael Contreras +Date: Wed, 5 Dec 2012 13:31:30 -0500 +Subject: [PATCH] e1000: Discard oversized packets based on SBP|LPE + +Discard packets longer than 16384 when !SBP to match the hardware behavior. + +Signed-off-by: Michael Contreras +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Cole Robinson +--- + hw/e1000.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/hw/e1000.c b/hw/e1000.c +index b1d8508..fa3d4dc 100644 +--- a/hw/e1000.c ++++ b/hw/e1000.c +@@ -61,6 +61,8 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL); + + /* this is the size past which hardware will drop packets when setting LPE=0 */ + #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 ++/* this is the size past which hardware will drop packets when setting LPE=1 */ ++#define MAXIMUM_ETHERNET_LPE_SIZE 16384 + + /* + * HW models: +@@ -799,8 +801,9 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size) + } + + /* Discard oversized packets if !LPE and !SBP. */ +- if (size > MAXIMUM_ETHERNET_VLAN_SIZE +- && !(s->mac_reg[RCTL] & E1000_RCTL_LPE) ++ if ((size > MAXIMUM_ETHERNET_LPE_SIZE || ++ (size > MAXIMUM_ETHERNET_VLAN_SIZE ++ && !(s->mac_reg[RCTL] & E1000_RCTL_LPE))) + && !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) { + return size; + } diff --git a/0710-Revert-serial-fix-retry-logic.patch b/0710-Revert-serial-fix-retry-logic.patch new file mode 100644 index 0000000..5d6285e --- /dev/null +++ b/0710-Revert-serial-fix-retry-logic.patch @@ -0,0 +1,67 @@ +From 90f23b109c482f23d04a943d1e41f79b33ce028a Mon Sep 17 00:00:00 2001 +From: Michael Tokarev +Date: Wed, 19 Sep 2012 12:08:31 +0400 +Subject: [PATCH] Revert "serial: fix retry logic" + +This reverts commit 67c5322d7000fd105a926eec44bc1765b7d70bdd: + + I'm not sure if the retry logic has ever worked when not using FIFO mode. I + found this while writing a test case although code inspection confirms it is + definitely broken. + + The TSR retry logic will never actually happen because it is guarded by an + 'if (s->tsr_rety > 0)' but this is the only place that can ever make the + variable greater than zero. That effectively makes the retry logic an 'if (0) + + I believe this is a typo and the intention was >= 0. Once this is fixed thoug + I see double transmits with my test case. This is because in the non FIFO + case, serial_xmit may get invoked while LSR.THRE is still high because the + character was processed but the retransmit timer was still active. + + We can handle this by simply checking for LSR.THRE and returning early. It's + possible that the FIFO paths also need some attention. + + Cc: Stefano Stabellini + Signed-off-by: Anthony Liguori + +Even if the previous logic was never worked, new logic breaks stuff - +namely, + + qemu -enable-kvm -nographic -kernel /boot/vmlinuz-$(uname -r) -append console=ttyS0 -serial pty + +the above command will cause the virtual machine to stuck at startup +using 100% CPU till one connects to the pty and sends any char to it. + +Note this is rather typical invocation for various headless virtual +machines by libvirt. + +So revert this change for now, till a better solution will be found. + +Signed-off-by: Michael Tokarev +Signed-off-by: Anthony Liguori +--- + hw/serial.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/hw/serial.c b/hw/serial.c +index 056d823..c9fccf7 100644 +--- a/hw/serial.c ++++ b/hw/serial.c +@@ -327,8 +327,6 @@ static void serial_xmit(void *opaque) + s->tsr = fifo_get(s,XMIT_FIFO); + if (!s->xmit_fifo.count) + s->lsr |= UART_LSR_THRE; +- } else if ((s->lsr & UART_LSR_THRE)) { +- return; + } else { + s->tsr = s->thr; + s->lsr |= UART_LSR_THRE; +@@ -340,7 +338,7 @@ static void serial_xmit(void *opaque) + /* in loopback mode, say that we just received a char */ + serial_receive1(s, &s->tsr, 1); + } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) { +- if ((s->tsr_retry >= 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) { ++ if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) { + s->tsr_retry++; + qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time); + return; diff --git a/0711-scsi-fix-segfault-with-0-byte-disk.patch b/0711-scsi-fix-segfault-with-0-byte-disk.patch new file mode 100644 index 0000000..b2d5fbc --- /dev/null +++ b/0711-scsi-fix-segfault-with-0-byte-disk.patch @@ -0,0 +1,37 @@ +From ca525ebda9b0869bddd602c7ac2884ef5cf96507 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 10 Jan 2013 15:08:05 +0100 +Subject: [PATCH] scsi: fix segfault with 0-byte disk + +When a 0-sized disk is found, READ CAPACITY will return a +LUN NOT READY error. However, because it returns -1 instead +of zero, the HBA will call scsi_req_continue. This will +typically cause a segmentation fault or an assertion failure. + +Signed-off-by: Paolo Bonzini +--- + hw/scsi-disk.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c +index 7ed1bde..fbca538 100644 +--- a/hw/scsi-disk.c ++++ b/hw/scsi-disk.c +@@ -1683,7 +1683,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + if (!nb_sectors) { + scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); +- return -1; ++ return 0; + } + if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) { + goto illegal_request; +@@ -1750,7 +1750,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + if (!nb_sectors) { + scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); +- return -1; ++ return 0; + } + if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) { + goto illegal_request; diff --git a/0712-iscsi-look-for-pkg-config-file-too.patch b/0712-iscsi-look-for-pkg-config-file-too.patch new file mode 100644 index 0000000..8c60ee3 --- /dev/null +++ b/0712-iscsi-look-for-pkg-config-file-too.patch @@ -0,0 +1,36 @@ +From: Paolo Bonzini +Subject: [PATCH 3/6] iscsi: look for pkg-config file too +Date: Tue, 5 Mar 2013 18:05:22 +0100 + +Due to library conflicts, Fedora will have to put libiscsi in +/usr/lib/iscsi. Simplify configuration by using a pkg-config +file. The Fedora package will distribute one, and the patch +to add it has been sent to upstream libiscsi as well. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + configure | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/configure b/configure +index 2f98c5a..a9a7c99 100755 +--- a/configure ++++ b/configure +@@ -2803,7 +2803,13 @@ if test "$libiscsi" != "no" ; then + #include + int main(void) { iscsi_unmap_sync(NULL,0,0,0,NULL,0); return 0; } + EOF +- if compile_prog "" "-liscsi" ; then ++ if $pkg_config --atleast-version=1.7.0 libiscsi --modversion >/dev/null 2>&1; then ++ libiscsi="yes" ++ libiscsi_cflags=$($pkg_config --cflags libiscsi 2>/dev/null) ++ libiscsi_libs=$($pkg_config --libs libiscsi 2>/dev/null) ++ CFLAGS="$CFLAGS $libiscsi_cflags" ++ LIBS="$LIBS $libiscsi_libs" ++ elif compile_prog "" "-liscsi" ; then + libiscsi="yes" + LIBS="$LIBS -liscsi" + else +-- +1.8.1.2 diff --git a/0800-mips-Fix-link-error-with-piix4_pm_init.patch b/0800-mips-Fix-link-error-with-piix4_pm_init.patch deleted file mode 100644 index 3ceb891..0000000 --- a/0800-mips-Fix-link-error-with-piix4_pm_init.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 5196eaa783b83110e6a8b99bfeb244b758b6e9c7 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Mon, 6 Aug 2012 17:12:40 -0400 -Subject: [PATCH] mips: Fix link error with 'piix4_pm_init' - - LINK mips-softmmu/qemu-system-mips - LINK m68k-softmmu/qemu-system-m68k -hw/mips/../mips_malta.o: In function `mips_malta_init': -/home/crobinso/qemu-kvm/hw/mips/../mips_malta.c:961: undefined reference to `piix4_pm_init' - -Signed-off-by: Cole Robinson ---- - hw/mips/Makefile.objs | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs -index 29a5d0d..89af0e9 100644 ---- a/hw/mips/Makefile.objs -+++ b/hw/mips/Makefile.objs -@@ -1,6 +1,7 @@ - obj-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o - obj-y += mips_addr.o mips_timer.o mips_int.o - obj-y += gt64xxx.o mc146818rtc.o -+obj-y += acpi.o acpi_piix4.o - obj-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o - - obj-y := $(addprefix ../,$(obj-y)) --- -1.7.12.1 - diff --git a/0801-configure-Add-disable-kvm-options.patch b/0801-configure-Add-disable-kvm-options.patch deleted file mode 100644 index 05021f1..0000000 --- a/0801-configure-Add-disable-kvm-options.patch +++ /dev/null @@ -1,72 +0,0 @@ -From b80fff00ed7f9baff808edb6c2c9f98f7e75e8ca Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Mon, 13 Aug 2012 18:39:54 -0400 -Subject: [PATCH] configure: Add --disable-kvm-options - -In Fedora, our qemu package is based on qemu-kvm, and we go to convoluted -lengths to provide a qemu-kvm binary with KVM on by default, but all -qemu-system-* with KVM off by default (using ./configure --disable-kvm) - -For qemu-system*, what we really want is upstream qemu symantics of TCG -by default, but the opt in option for KVM. CONFIG_KVM_OPTIONS fits the -bill, so let's expose it through ./configure. This will also simplify -our packaging for non-x86 KVM. - -Signed-off-by: Cole Robinson ---- - configure | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/configure b/configure -index f019526..933754d 100755 ---- a/configure -+++ b/configure -@@ -210,6 +210,7 @@ bsd_user="no" - guest_base="" - uname_release="" - mixemu="no" -+kvmoptions="yes" - aix="no" - blobs="yes" - pkgversion=" ($(kvm_version))" -@@ -732,6 +733,8 @@ for opt do - ;; - --enable-kvm) kvm="yes" - ;; -+ --disable-kvm-options) kvmoptions="no" -+ ;; - --disable-tcg-interpreter) tcg_interpreter="no" - ;; - --enable-tcg-interpreter) tcg_interpreter="yes" -@@ -1080,6 +1083,8 @@ echo " --enable-bluez enable bluez stack connectivity" - echo " --disable-slirp disable SLIRP userspace network connectivity" - echo " --disable-kvm disable KVM acceleration support" - echo " --enable-kvm enable KVM acceleration support" -+echo " --disable-kvm-options if KVM is enabled, default to KVM=off, and" -+echo " remove non-upstream cli options" - echo " --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)" - echo " --disable-nptl disable usermode NPTL support" - echo " --enable-nptl enable usermode NPTL support" -@@ -3160,6 +3165,7 @@ echo "ATTR/XATTR support $attr" - echo "Install blobs $blobs" - echo "KVM support $kvm" - echo "TCG interpreter $tcg_interpreter" -+echo "KVM CLI options $kvmoptions" - echo "fdt support $fdt" - echo "preadv support $preadv" - echo "fdatasync $fdatasync" -@@ -3893,7 +3899,10 @@ case "$target_arch2" in - \( "$target_arch2" = "x86_64" -a "$cpu" = "i386" \) -o \ - \( "$target_arch2" = "i386" -a "$cpu" = "x86_64" \) \) ; then - echo "CONFIG_KVM=y" >> $config_target_mak -- echo "CONFIG_KVM_OPTIONS=y" >> $config_host_mak -+ -+ if test "$kvmoptions" = "yes" ; then -+ echo "CONFIG_KVM_OPTIONS=y" >> $config_host_mak -+ fi - if test "$vhost_net" = "yes" ; then - echo "CONFIG_VHOST_NET=y" >> $config_target_mak - fi --- -1.7.12.1 - diff --git a/0802-arm_boot-Change-initrd-load-address-to-halfway-throu.patch b/0802-arm_boot-Change-initrd-load-address-to-halfway-throu.patch deleted file mode 100644 index 649fb0e..0000000 --- a/0802-arm_boot-Change-initrd-load-address-to-halfway-throu.patch +++ /dev/null @@ -1,138 +0,0 @@ -From d3a43fe4b870154032db4651824bc88e3cb81dc5 Mon Sep 17 00:00:00 2001 -From: Peter Maydell -Date: Fri, 26 Oct 2012 16:29:38 +0100 -Subject: [PATCH] arm_boot: Change initrd load address to "halfway through - RAM" - -To avoid continually having to bump the initrd load address -to account for larger kernel images, put the initrd halfway -through RAM. This allows large kernels on new boards with lots -of RAM to work OK, without breaking existing usecases for -boards with only 32MB of RAM. - -Note that this change fixes in passing a bug where we were -passing an overly large max_size to load_image_targphys() -for the initrd, which meant that we wouldn't correctly refuse -to load an enormous initrd that didn't actually fit into RAM. - -Signed-off-by: Peter Maydell ---- - hw/arm-misc.h | 1 + - hw/arm_boot.c | 41 ++++++++++++++++++++++++++--------------- - 2 files changed, 27 insertions(+), 15 deletions(-) - -diff --git a/hw/arm-misc.h b/hw/arm-misc.h -index bdd8fec..0f7deb5 100644 ---- a/hw/arm-misc.h -+++ b/hw/arm-misc.h -@@ -56,6 +56,7 @@ struct arm_boot_info { - const struct arm_boot_info *info); - /* Used internally by arm_boot.c */ - int is_linux; -+ target_phys_addr_t initrd_start; - target_phys_addr_t initrd_size; - target_phys_addr_t entry; - }; -diff --git a/hw/arm_boot.c b/hw/arm_boot.c -index a6e9143..920c337 100644 ---- a/hw/arm_boot.c -+++ b/hw/arm_boot.c -@@ -18,7 +18,6 @@ - - #define KERNEL_ARGS_ADDR 0x100 - #define KERNEL_LOAD_ADDR 0x00010000 --#define INITRD_LOAD_ADDR 0x00d00000 - - /* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */ - static uint32_t bootloader[] = { -@@ -109,7 +108,7 @@ static void set_kernel_args(const struct arm_boot_info *info) - /* ATAG_INITRD2 */ - WRITE_WORD(p, 4); - WRITE_WORD(p, 0x54420005); -- WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR); -+ WRITE_WORD(p, info->initrd_start); - WRITE_WORD(p, initrd_size); - } - if (info->kernel_cmdline && *info->kernel_cmdline) { -@@ -185,10 +184,11 @@ static void set_kernel_args_old(const struct arm_boot_info *info) - /* pages_in_vram */ - WRITE_WORD(p, 0); - /* initrd_start */ -- if (initrd_size) -- WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR); -- else -+ if (initrd_size) { -+ WRITE_WORD(p, info->initrd_start); -+ } else { - WRITE_WORD(p, 0); -+ } - /* initrd_size */ - WRITE_WORD(p, initrd_size); - /* rd_start */ -@@ -281,14 +281,13 @@ static int load_dtb(target_phys_addr_t addr, const struct arm_boot_info *binfo) - - if (binfo->initrd_size) { - rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", -- binfo->loader_start + INITRD_LOAD_ADDR); -+ binfo->initrd_start); - if (rc < 0) { - fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); - } - - rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", -- binfo->loader_start + INITRD_LOAD_ADDR + -- binfo->initrd_size); -+ binfo->initrd_start + binfo->initrd_size); - if (rc < 0) { - fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); - } -@@ -375,6 +374,19 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) - big_endian = 0; - #endif - -+ /* We want to put the initrd far enough into RAM that when the -+ * kernel is uncompressed it will not clobber the initrd. However -+ * on boards without much RAM we must ensure that we still leave -+ * enough room for a decent sized initrd, and on boards with large -+ * amounts of RAM we must avoid the initrd being so far up in RAM -+ * that it is outside lowmem and inaccessible to the kernel. -+ * So for boards with less than 256MB of RAM we put the initrd -+ * halfway into RAM, and for boards with 256MB of RAM or more we put -+ * the initrd at 128MB. -+ */ -+ info->initrd_start = info->loader_start + -+ MIN(info->ram_size / 2, 128 * 1024 * 1024); -+ - /* Assume that raw images are linux kernels, and ELF images are not. */ - kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry, - NULL, NULL, big_endian, ELF_MACHINE, 1); -@@ -398,10 +410,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) - if (is_linux) { - if (info->initrd_filename) { - initrd_size = load_image_targphys(info->initrd_filename, -- info->loader_start -- + INITRD_LOAD_ADDR, -- info->ram_size -- - INITRD_LOAD_ADDR); -+ info->initrd_start, -+ info->ram_size - -+ info->initrd_start); - if (initrd_size < 0) { - fprintf(stderr, "qemu: could not load initrd '%s'\n", - info->initrd_filename); -@@ -419,9 +430,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) - */ - if (info->dtb_filename) { - /* Place the DTB after the initrd in memory */ -- target_phys_addr_t dtb_start = TARGET_PAGE_ALIGN(info->loader_start -- + INITRD_LOAD_ADDR -- + initrd_size); -+ target_phys_addr_t dtb_start = TARGET_PAGE_ALIGN( -+ info->initrd_start + -+ initrd_size); - if (load_dtb(dtb_start, info)) { - exit(1); - } --- -1.7.12.1 - diff --git a/0803-dtrace-backend-add-function-to-reserved-words.patch b/0803-dtrace-backend-add-function-to-reserved-words.patch deleted file mode 100644 index cc58c6f..0000000 --- a/0803-dtrace-backend-add-function-to-reserved-words.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4780bb16558d2753e2277e1570644bec49551534 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Sun, 2 Sep 2012 02:04:16 +0300 -Subject: [PATCH] dtrace backend: add function to reserved words - -Signed-off-by: Alon Levy -Signed-off-by: Stefan Hajnoczi ---- - scripts/tracetool/backend/dtrace.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py -index 9cab75c..6be7047 100644 ---- a/scripts/tracetool/backend/dtrace.py -+++ b/scripts/tracetool/backend/dtrace.py -@@ -87,7 +87,7 @@ def stap(events): - if len(e.args) > 0: - for name in e.args.names(): - # Append underscore to reserved keywords -- if name in ('limit', 'in', 'next', 'self'): -+ if name in ('limit', 'in', 'next', 'self', 'function'): - name += '_' - out(' %s = $arg%d;' % (name, i)) - i += 1 --- -1.7.12.1 - diff --git a/0804-wip-hw-qxl-inject-interrupts-in-any-state.patch b/0804-wip-hw-qxl-inject-interrupts-in-any-state.patch deleted file mode 100644 index 4e5222d..0000000 --- a/0804-wip-hw-qxl-inject-interrupts-in-any-state.patch +++ /dev/null @@ -1,24 +0,0 @@ -From e0575d0a1a14e8f4e8fc11d549cbd07cca433383 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 30 Oct 2012 18:00:33 +0200 -Subject: [PATCH] wip: hw/qxl: inject interrupts in any state - ---- - hw/qxl.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 9389752..b137731 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -1714,7 +1714,6 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events) - uint32_t le_events = cpu_to_le32(events); - - trace_qxl_send_events(d->id, events); -- assert(qemu_spice_display_is_running(&d->ssd)); - old_pending = __sync_fetch_and_or(&d->ram->int_pending, le_events); - if ((old_pending & le_events) == le_events) { - return; --- -1.7.12.1 - diff --git a/0805-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch b/0805-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch deleted file mode 100644 index dfaf285..0000000 --- a/0805-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 38f419f35225decdbaea9fe1fd00218f8924ce84 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Wed, 17 Oct 2012 19:09:25 +0200 -Subject: [PATCH] configure: Fix CONFIG_QEMU_HELPERDIR generation - -We need to evaluate $libexecdir in configure, otherwise we literally end -up with "${prefix}/libexec" instead of the absolute path as -CONFIG_QEMU_HELPERDIR. - -Signed-off-by: Jan Kiszka -Signed-off-by: Aurelien Jarno ---- - configure | 2 +- - 1 file modificato, 1 inserzione(+). 1 rimozione(-) - -diff --git a/configure b/configure -index f9c31f4..9f33c7d 100755 ---- a/configure -+++ b/configure -@@ -3200,7 +3200,7 @@ echo "qemu_confdir=$qemu_confdir" >> $config_host_mak - echo "qemu_confdir=$qemu_confdir" >> $config_host_mak - echo "qemu_datadir=$qemu_datadir" >> $config_host_mak - echo "qemu_docdir=$qemu_docdir" >> $config_host_mak --echo "CONFIG_QEMU_HELPERDIR=\"$libexecdir\"" >> $config_host_mak -+echo "CONFIG_QEMU_HELPERDIR=\"`eval echo $libexecdir`\"" >> $config_host_mak - - echo "ARCH=$ARCH" >> $config_host_mak - if test "$debug_tcg" = "yes" ; then --- -1.7.12.1 - diff --git a/qemu.spec b/qemu.spec index c3748b0..e4be2c8 100644 --- a/qemu.spec +++ b/qemu.spec @@ -196,8 +196,8 @@ Summary: QEMU is a FAST! processor emulator Name: qemu -Version: 1.2.0 -Release: 22%{?dist} +Version: 1.2.2 +Release: 7%{?dist} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD @@ -213,9 +213,8 @@ ExclusiveArch: %{kvm_archs} %define _smp_mflags %{nil} %endif -# This is generated from the git qemu-kvm-1.2.0 tag, replace with proper -# upstream tarbal once available -Source0: qemu-kvm-%{version}.tar.gz +# There aren't qemu-kvm 1.2 maint releases yet, so we are carrying patches +Source0: http://downloads.sourceforge.net/sourceforge/kvm/qemu-kvm-1.2.0.tar.gz #Source0: http://downloads.sourceforge.net/sourceforge/kvm/qemu-kvm-%{version}.tar.gz Source1: qemu.binfmt @@ -242,7 +241,8 @@ Source11: 99-qemu-guest-agent.rules Source66610: qemu-ga.init Source12: bridge.conf -# Patches queued for 1.2.1 stable + +# Stable 1.2.1 patches Patch0001: 0001-target-xtensa-convert-host-errno-values-to-guest.patch Patch0002: 0002-target-cris-Fix-buffer-overflow.patch Patch0003: 0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch @@ -486,93 +486,148 @@ Patch0240: 0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch Patch0241: 0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch Patch0242: 0242-update-VERSION-for-v1.2.1.patch -# The infamous chardev flow control patches -Patch0400: 0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch -Patch0401: 0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch -Patch0402: 0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch -Patch0403: 0403-char-Add-framework-for-a-write-unblocked-callback.patch -Patch0404: 0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch -Patch0405: 0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch -Patch0406: 0406-char-Throttle-when-host-connection-is-down.patch -Patch0407: 0407-virtio-console-Enable-port-throttling-when-chardev-i.patch -Patch0408: 0408-spice-qemu-char.c-add-throttling.patch -Patch0409: 0409-spice-qemu-char.c-remove-intermediate-buffer.patch -Patch0410: 0410-usb-redir-Add-flow-control-support.patch -Patch0411: 0411-virtio-serial-bus-replay-guest_open-on-migration.patch -Patch0412: 0412-char-Disable-write-callback-if-throttled-chardev-is-.patch - -# Spice features from upstream master: seamless migration & dynamic monitors -Patch0500: 0500-qxl-disallow-unknown-revisions.patch -Patch0501: 0501-spice-make-number-of-surfaces-runtime-configurable.patch -Patch0502: 0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch -Patch0503: 0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch -Patch0504: 0504-spice-switch-to-queue-for-vga-mode-updates.patch -Patch0505: 0505-spice-split-qemu_spice_create_update.patch -Patch0506: 0506-spice-add-screen-mirror.patch -Patch0507: 0507-spice-send-updates-only-for-changed-screen-content.patch -Patch0508: 0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch -Patch0509: 0509-qxl-add-trace-event-for-QXL_IO_LOG.patch -Patch0510: 0510-hw-qxl-support-client-monitor-configuration-via-devi.patch -Patch0511: 0511-qxl-always-update-displaysurface-on-resize.patch +# Stable 1.2.2 patches +Patch0301: 0301-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch +Patch0302: 0302-fix-CONFIG_QEMU_HELPERDIR-generation-again.patch +Patch0303: 0303-ui-vnc-Only-report-use-TIGHT_PNG-encoding-if-enabled.patch +Patch0304: 0304-vnc-fix-info-vnc-with-vnc-.-reverse-on.patch +Patch0305: 0305-uhci-Raise-interrupt-when-requested-even-for-non-act.patch +Patch0306: 0306-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch +Patch0307: 0307-qxl-always-update-displaysurface-on-resize.patch +Patch0308: 0308-rtc-fix-overflow-in-mktimegm.patch +Patch0309: 0309-hw-Fix-return-value-check-for-bdrv_read-bdrv_write.patch +Patch0310: 0310-target-i386-Allow-tsc-frequency-to-be-larger-then-2..patch +Patch0311: 0311-e1000-drop-check_rxov-always-treat-RX-ring-with-RDH-.patch +Patch0312: 0312-memory-fix-rendering-of-a-region-obscured-by-another.patch +Patch0313: 0313-s390x-fix-initrd-in-virtio-machine.patch +Patch0314: 0314-PPC-Bamboo-Fix-memory-size-DT-property.patch +Patch0315: 0315-target-sparc64-disable-VGA-cirrus.patch +Patch0316: 0316-xhci-fix-usb-name-in-caps.patch +Patch0317: 0317-tools-initialize-main-loop-before-block-layer.patch +Patch0318: 0318-m68k-Return-semihosting-errno-values-correctly.patch +Patch0319: 0319-nbd-fixes-to-read-only-handling.patch +Patch0320: 0320-mips-malta-fix-CBUS-UART-interrupt-pin.patch +Patch0321: 0321-target-mips-fix-wrong-microMIPS-opcode-encoding.patch +Patch0322: 0322-tcg-arm-fix-TLB-access-in-qemu-ld-st-ops.patch +Patch0323: 0323-tcg-arm-fix-cross-endian-qemu_st16.patch +Patch0324: 0324-target-openrisc-remove-conflicting-definitions-from-.patch +Patch0325: 0325-configure-avoid-compiler-warning-in-pipe2-detection.patch +Patch0326: 0326-qcow2-Fix-refcount-table-size-calculation.patch +Patch0327: 0327-tci-Fix-type-of-tci_read_label.patch +Patch0328: 0328-block-Fix-regression-for-MinGW-assertion-caused-by-s.patch +Patch0329: 0329-qom-dynamic_cast-of-NULL-is-always-NULL.patch +Patch0330: 0330-hmp-do-not-crash-on-invalid-SCSI-hotplug.patch +Patch0331: 0331-PPC-Fix-missing-TRACE-exception.patch +Patch0332: 0332-qom-fix-refcount-of-non-heap-allocated-objects.patch +Patch0333: 0333-qapi-handle-visitor-type_size-in-QapiDeallocVisitor.patch +Patch0334: 0334-qapi-fix-qapi_dealloc_type_size-parameter-type.patch +Patch0335: 0335-iscsi-fix-segfault-in-url-parsing.patch +Patch0336: 0336-iscsi-fix-deadlock-during-login.patch +Patch0337: 0337-iscsi-do-not-assume-device-is-zero-initialized.patch +Patch0338: 0338-virtio-scsi-Fix-some-endian-bugs-with-virtio-scsi.patch +Patch0339: 0339-virtio-scsi-Fix-subtle-guest-endian-bug.patch +Patch0340: 0340-qxl-reload-memslots-after-migration-when-qxl-is-in-U.patch +Patch0341: 0341-usb-fail-usbdevice_create-when-there-is-no-USB-bus.patch +Patch0342: 0342-stream-fix-ratelimit_set_speed.patch +Patch0343: 0343-e1000-Discard-packets-that-are-too-long-if-SBP-and-L.patch + +# chardev flow control series +Patch0401: 0401-update-VERSION-for-v1.2.2.patch +Patch0402: 0402-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch +Patch0403: 0403-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch +Patch0404: 0404-iohandlers-Add-enable-disable_write_fd_handler-funct.patch +Patch0405: 0405-char-Add-framework-for-a-write-unblocked-callback.patch +Patch0406: 0406-char-Update-send_all-to-handle-nonblocking-chardev-w.patch +Patch0407: 0407-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch +Patch0408: 0408-char-Throttle-when-host-connection-is-down.patch +Patch0409: 0409-virtio-console-Enable-port-throttling-when-chardev-i.patch +Patch0410: 0410-spice-qemu-char.c-add-throttling.patch +Patch0411: 0411-spice-qemu-char.c-remove-intermediate-buffer.patch +Patch0412: 0412-usb-redir-Add-flow-control-support.patch +Patch0413: 0413-virtio-serial-bus-replay-guest_open-on-migration.patch +Patch0414: 0414-char-Disable-write-callback-if-throttled-chardev-is-.patch + +# spice seamless migration, dynamic monitors, spice/qxl bug fixes +Patch0501: 0501-qxl-disallow-unknown-revisions.patch +Patch0502: 0502-spice-make-number-of-surfaces-runtime-configurable.patch +Patch0503: 0503-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch +Patch0504: 0504-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch +Patch0505: 0505-spice-switch-to-queue-for-vga-mode-updates.patch +Patch0506: 0506-spice-split-qemu_spice_create_update.patch +Patch0507: 0507-spice-add-screen-mirror.patch +Patch0508: 0508-spice-send-updates-only-for-changed-screen-content.patch +Patch0509: 0509-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch +Patch0510: 0510-qxl-add-trace-event-for-QXL_IO_LOG.patch +Patch0511: 0511-hw-qxl-support-client-monitor-configuration-via-devi.patch Patch0512: 0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch Patch0513: 0513-qxl-fix-range-check-for-rev3-io-commands.patch -Patch0514: 0514-hw-qxl-exit-on-failure-to-register-qxl-interface.patch -Patch0515: 0515-hw-qxl-fix-condition-for-exiting-guest_bug.patch -Patch0516: 0516-hw-qxl-qxl_dirty_surfaces-use-uintptr_t.patch -Patch0517: 0517-spice-raise-requirement-to-0.12.patch -Patch0518: 0518-qxl-set-default-revision-to-4.patch - -# usb-redir live-migration and misc bits, will be in before 1.3.0 -Patch0600: 0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch -Patch0601: 0601-usb-redir-Set-ep-max_packet_size-if-available.patch -Patch0602: 0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch -Patch0603: 0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch -Patch0604: 0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch -Patch0605: 0605-xhci-move-device-lookup-into-xhci_setup_packet.patch -Patch0606: 0606-xhci-implement-mfindex.patch -Patch0607: 0607-xhci-iso-xfer-support.patch -Patch0608: 0608-xhci-trace-cc-codes-in-cleartext.patch -Patch0609: 0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch -Patch0610: 0610-xhci-update-register-layout.patch -Patch0611: 0611-xhci-update-port-handling.patch -Patch0612: 0612-usb3-superspeed-descriptors.patch -Patch0613: 0613-usb3-superspeed-endpoint-companion.patch -Patch0614: 0614-usb3-bos-decriptor.patch -Patch0615: 0615-usb-storage-usb3-support.patch -Patch0616: 0616-xhci-fix-cleanup-msi.patch -Patch0617: 0617-xhci-rework-interrupt-handling.patch -Patch0618: 0618-xhci-add-msix-support.patch -Patch0619: 0619-xhci-move-register-update-into-xhci_intr_raise.patch -Patch0620: 0620-xhci-add-XHCIInterrupter.patch -Patch0621: 0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch -Patch0622: 0622-xhci-pick-target-interrupter.patch -Patch0623: 0623-xhci-support-multiple-interrupters.patch -Patch0624: 0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch -Patch0625: 0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch -Patch0626: 0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch -Patch0627: 0627-usb-redir-Store-max_packet_size-in-endp_data.patch -Patch0628: 0628-usb-redir-Add-support-for-migration.patch -Patch0629: 0629-usb-redir-Add-chardev-open-close-debug-logging.patch -Patch0630: 0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch -Patch0631: 0631-ehci-Fix-interrupt-packet-MULT-handling.patch -Patch0632: 0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch -Patch0633: 0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch -Patch0634: 0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch +Patch0514: 0514-qxl-vnc-register-a-vm-state-change-handler-for-dummy.patch +Patch0515: 0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch +Patch0516: 0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch +Patch0517: 0517-hw-qxl-qxl_send_events-nop-if-stopped.patch +Patch0518: 0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch +Patch0519: 0519-spice-fix-initialization-order.patch +Patch0520: 0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch +Patch0521: 0521-qxl-save-qemu_create_displaysurface_from-result.patch + +# usb-redir live-migration and misc bits from upstream master +Patch0601: 0601-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch +Patch0602: 0602-usb-redir-Set-ep-max_packet_size-if-available.patch +Patch0603: 0603-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch +Patch0604: 0604-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch +Patch0605: 0605-usb-redir-Enable-pipelining-for-bulk-endpoints.patch +Patch0606: 0606-xhci-move-device-lookup-into-xhci_setup_packet.patch +Patch0607: 0607-xhci-implement-mfindex.patch +Patch0608: 0608-xhci-iso-xfer-support.patch +Patch0609: 0609-xhci-trace-cc-codes-in-cleartext.patch +Patch0610: 0610-xhci-add-trace_usb_xhci_ep_set_dequeue.patch +Patch0611: 0611-xhci-update-register-layout.patch +Patch0612: 0612-xhci-update-port-handling.patch +Patch0613: 0613-usb3-superspeed-descriptors.patch +Patch0614: 0614-usb3-superspeed-endpoint-companion.patch +Patch0615: 0615-usb3-bos-decriptor.patch +Patch0616: 0616-usb-storage-usb3-support.patch +Patch0617: 0617-xhci-fix-cleanup-msi.patch +Patch0618: 0618-xhci-rework-interrupt-handling.patch +Patch0619: 0619-xhci-add-msix-support.patch +Patch0620: 0620-xhci-move-register-update-into-xhci_intr_raise.patch +Patch0621: 0621-xhci-add-XHCIInterrupter.patch +Patch0622: 0622-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch +Patch0623: 0623-xhci-pick-target-interrupter.patch +Patch0624: 0624-xhci-support-multiple-interrupters.patch +Patch0625: 0625-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch +Patch0626: 0626-usb-redir-Change-cancelled-packet-code-into-a-generi.patch +Patch0627: 0627-usb-redir-Add-an-already_in_flight-packet-id-queue.patch +Patch0628: 0628-usb-redir-Store-max_packet_size-in-endp_data.patch +Patch0629: 0629-usb-redir-Add-support-for-migration.patch +Patch0630: 0630-usb-redir-Add-chardev-open-close-debug-logging.patch +Patch0631: 0631-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch +Patch0632: 0632-ehci-Fix-interrupt-packet-MULT-handling.patch +Patch0633: 0633-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch +Patch0634: 0634-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch +Patch0635: 0635-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch # Non upstream build fix, http://www.spinics.net/lists/kvm/msg80589.html -Patch0800: 0800-mips-Fix-link-error-with-piix4_pm_init.patch +Patch0701: 0701-mips-Fix-link-error-with-piix4_pm_init.patch # Add ./configure --disable-kvm-options -# keep: Carrying locally until qemu-kvm is fully merged into qemu.git -Patch0801: 0801-configure-Add-disable-kvm-options.patch +Patch0702: 0702-configure-Add-disable-kvm-options.patch # Fix loading arm initrd if kernel is very large (bz 862766) -Patch802: 0802-arm_boot-Change-initrd-load-address-to-halfway-throu.patch -# Don't use reserved word 'function' in systemtap files (bz 870972) -Patch803: 0803-dtrace-backend-add-function-to-reserved-words.patch -# Drop assertion that was triggering when pausing guests w/ qxl (bz -# 870972) -Patch804: 0804-wip-hw-qxl-inject-interrupts-in-any-state.patch -# 38f419f (configure: Fix CONFIG_QEMU_HELPERDIR generation, 2012-10-17) -Patch805: 0805-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch +Patch0703: 0703-arm_boot-Change-initrd-load-address-to-halfway-throu.patch +# libcacard build fixes +Patch0704: 0704-dtrace-backend-add-function-to-reserved-words.patch +Patch0705: 0705-libcacard-fix-missing-symbols-in-libcacard.so.patch +Patch0706: 0706-configure-move-vscclient-binary-under-libcacard.patch +# Fix libvirt + seccomp combo (bz 855162) +Patch0707: 0707-libcacard-fix-missing-symbol-in-libcacard.so.patch +# CVE-2012-6075: Buffer overflow in e1000 nic (bz 889301, bz 889304) +Patch0708: 0708-seccomp-adding-new-syscalls-bugzilla-855162.patch +# Fix boot hang if console is not connected (bz 894451) +Patch0709: 0709-e1000-Discard-oversized-packets-based-on-SBP-LPE.patch +# Fix segfault with zero length virtio-scsi disk (bz 847549) +Patch0710: 0710-Revert-serial-fix-retry-logic.patch +Patch0711: 0711-scsi-fix-segfault-with-0-byte-disk.patch +# Adapt to libiscsi packaging in Fedora (included upstream) +Patch0712: 0712-iscsi-look-for-pkg-config-file-too.patch BuildRequires: SDL-devel @@ -586,6 +641,7 @@ BuildRequires: libaio-devel BuildRequires: rsync BuildRequires: pciutils-devel BuildRequires: pulseaudio-libs-devel +BuildRequires: libiscsi-devel BuildRequires: ncurses-devel BuildRequires: libattr-devel %if %{with have_usbredir} @@ -773,7 +829,6 @@ if [ $1 -ge 1 ] ; then fi - %if 0%{?user:1} %package %{user} Summary: QEMU user mode emulation of qemu targets @@ -1001,9 +1056,36 @@ This package contains some diagnostics and debugging tools for KVM, such as kvm_stat. %endif +%if %{without separate_kvm} +%package -n libcacard +Summary: Common Access Card (CAC) Emulation +Group: Development/Libraries + +%description -n libcacard +Common Access Card (CAC) emulation library. + +%package -n libcacard-tools +Summary: CAC Emulation tools +Group: Development/Libraries +Requires: libcacard = %{epoch}:%{version}-%{release} + +%description -n libcacard-tools +CAC emulation tools. + +%package -n libcacard-devel +Summary: CAC Emulation devel +Group: Development/Libraries +Requires: libcacard = %{epoch}:%{version}-%{release} + +%description -n libcacard-devel +CAC emulation development files. +%endif + %prep -%setup -q -n qemu-kvm-%{version} +#%setup -q -n qemu-kvm-%{version} +%setup -q -n qemu-kvm-1.2.0 +# Stable 1.2.1 patches %patch0001 -p1 %patch0002 -p1 %patch0003 -p1 @@ -1247,7 +1329,52 @@ such as kvm_stat. %patch0241 -p1 %patch0242 -p1 -%patch0400 -p1 +# Stable 1.2.2 patches +%patch0301 -p1 +%patch0302 -p1 +%patch0303 -p1 +%patch0304 -p1 +%patch0305 -p1 +%patch0306 -p1 +%patch0307 -p1 +%patch0308 -p1 +%patch0309 -p1 +%patch0310 -p1 +%patch0311 -p1 +%patch0312 -p1 +%patch0313 -p1 +%patch0314 -p1 +%patch0315 -p1 +%patch0316 -p1 +%patch0317 -p1 +%patch0318 -p1 +%patch0319 -p1 +%patch0320 -p1 +%patch0321 -p1 +%patch0322 -p1 +%patch0323 -p1 +%patch0324 -p1 +%patch0325 -p1 +%patch0326 -p1 +%patch0327 -p1 +%patch0328 -p1 +%patch0329 -p1 +%patch0330 -p1 +%patch0331 -p1 +%patch0332 -p1 +%patch0333 -p1 +%patch0334 -p1 +%patch0335 -p1 +%patch0336 -p1 +%patch0337 -p1 +%patch0338 -p1 +%patch0339 -p1 +%patch0340 -p1 +%patch0341 -p1 +%patch0342 -p1 +%patch0343 -p1 + +# chardev flow control series %patch0401 -p1 %patch0402 -p1 %patch0403 -p1 @@ -1260,8 +1387,10 @@ such as kvm_stat. %patch0410 -p1 %patch0411 -p1 %patch0412 -p1 +%patch0413 -p1 +%patch0414 -p1 -%patch0500 -p1 +# spice seamless migration, dynamic monitors, spice/qxl bug fixes %patch0501 -p1 %patch0502 -p1 %patch0503 -p1 @@ -1280,8 +1409,11 @@ such as kvm_stat. %patch0516 -p1 %patch0517 -p1 %patch0518 -p1 +%patch0519 -p1 +%patch0520 -p1 +%patch0521 -p1 -%patch0600 -p1 +# usb-redir live-migration and misc bits from upstream master %patch0601 -p1 %patch0602 -p1 %patch0603 -p1 @@ -1316,24 +1448,40 @@ such as kvm_stat. %patch0632 -p1 %patch0633 -p1 %patch0634 -p1 +%patch0635 -p1 -%patch0800 -p1 -%patch0801 -p1 -%patch802 -p1 -%patch803 -p1 -%patch804 -p1 -%patch805 -p1 +# Non upstream build fix, http://www.spinics.net/lists/kvm/msg80589.html +%patch0701 -p1 +# Add ./configure --disable-kvm-options +%patch0702 -p1 +# Fix loading arm initrd if kernel is very large (bz 862766) +%patch0703 -p1 +# libcacard build fixes +%patch0704 -p1 +%patch0705 -p1 +%patch0706 -p1 +# Fix libvirt + seccomp combo (bz 855162) +%patch0707 -p1 +# CVE-2012-6075: Buffer overflow in e1000 nic (bz 889301, bz 889304) +%patch0708 -p1 +# Fix boot hang if console is not connected (bz 894451) +%patch0709 -p1 +# Fix segfault with zero length virtio-scsi disk (bz 847549) +%patch0710 -p1 +%patch0711 -p1 +# Adapt to libiscsi packaging in Fedora (included upstream) +%patch0712 -p1 %build %if %{with kvmonly} buildarch="%{kvm_target}-softmmu" %else -buildarch="i386-softmmu x86_64-softmmu alpha-softmmu arm-softmmu cris-softmmu \ - lm32-softmmu m68k-softmmu microblaze-softmmu microblazeel-softmmu \ - mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu \ - or32-softmmu ppc-softmmu ppcemb-softmmu ppc64-softmmu s390x-softmmu \ - sh4-softmmu sh4eb-softmmu sparc-softmmu sparc64-softmmu \ + buildarch="i386-softmmu x86_64-softmmu alpha-softmmu arm-softmmu \ + cris-softmmu lm32-softmmu m68k-softmmu microblaze-softmmu \ + microblazeel-softmmu mips-softmmu mipsel-softmmu mips64-softmmu \ + mips64el-softmmu or32-softmmu ppc-softmmu ppcemb-softmmu ppc64-softmmu \ + s390x-softmmu sh4-softmmu sh4eb-softmmu sparc-softmmu sparc64-softmmu \ xtensa-softmmu xtensaeb-softmmu unicore32-softmmu \ i386-linux-user x86_64-linux-user alpha-linux-user arm-linux-user \ armeb-linux-user cris-linux-user m68k-linux-user \ @@ -1358,6 +1506,7 @@ sed -i.debug 's/"-g $CFLAGS"/"$CFLAGS"/g' configure dobuild() { ./configure \ --prefix=%{_prefix} \ + --libdir=%{_libdir} \ --sysconfdir=%{_sysconfdir} \ --interp-prefix=%{_prefix}/qemu-%%M \ --audio-drv-list=pa,sdl,alsa,oss \ @@ -1391,6 +1540,10 @@ dobuild() { echo "===" make V=1 %{?_smp_mflags} $buildldflags +%if %{without separate_kvm} + make V=1 %{?_smp_mflags} $buildldflags libcacard.la + make V=1 %{?_smp_mflags} $buildldflags libcacard/vscclient +%endif } # This is kind of confusing. We run ./configure + make twice here to @@ -1544,9 +1697,11 @@ install -D -p -m 0755 %{SOURCE66610} $RPM_BUILD_ROOT%{_initddir}/qemu-ga %if %{with separate_kvm} rm $RPM_BUILD_ROOT%{_bindir}/qemu-img +rm $RPM_BUILD_ROOT%{_bindir}/qemu-nbd rm $RPM_BUILD_ROOT%{_bindir}/qemu-io rm $RPM_BUILD_ROOT%{_bindir}/vscclient rm $RPM_BUILD_ROOT%{_mandir}/man1/qemu-img.1* +rm $RPM_BUILD_ROOT%{_mandir}/man8/qemu-nbd.8* rm $RPM_BUILD_ROOT%{_bindir}/qemu-ga rm $RPM_BUILD_ROOT%{_initddir}/qemu-ga @@ -1556,6 +1711,12 @@ rm $RPM_BUILD_ROOT%{_initddir}/qemu-ga install -m 0644 %{SOURCE12} $RPM_BUILD_ROOT%{_sysconfdir}/qemu chmod u+s $RPM_BUILD_ROOT%{_libexecdir}/qemu-bridge-helper +%if %{without separate_kvm} +make %{?_smp_mflags} $buildldflags DESTDIR=$RPM_BUILD_ROOT install-libcacard +find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f +find $RPM_BUILD_ROOT -name "libcacard.so*" -exec chmod +x \{\} \; +%endif + %check make check @@ -1581,6 +1742,7 @@ getent passwd qemu >/dev/null || \ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ -c "qemu user" qemu + %preun common if [ $1 -eq 0 ] ; then # Package removal, not upgrade @@ -1599,6 +1761,7 @@ fi %endif + %if 0%{?user:1} %post %{user} /sbin/chkconfig --add qemu @@ -1649,8 +1812,6 @@ fi %{_datadir}/%{name}/keymaps/ %{_mandir}/man1/qemu.1* %{_mandir}/man1/virtfs-proxy-helper.1* -%{_mandir}/man8/qemu-nbd.8* -%{_bindir}/qemu-nbd %{_bindir}/virtfs-proxy-helper %{_libexecdir}/qemu-bridge-helper %config(noreplace) %{_sysconfdir}/sasl2/qemu.conf @@ -1915,11 +2076,67 @@ fi %defattr(-,root,root) %{_bindir}/qemu-img %{_bindir}/qemu-io -%{_bindir}/vscclient +%{_bindir}/qemu-nbd %{_mandir}/man1/qemu-img.1* +%{_mandir}/man8/qemu-nbd.8* + +%files -n libcacard +%defattr(-,root,root,-) +%{_libdir}/libcacard.so.* + +%files -n libcacard-tools +%defattr(-,root,root,-) +%{_bindir}/vscclient + +%files -n libcacard-devel +%defattr(-,root,root,-) +%{_includedir}/cacard +%{_libdir}/libcacard.so +%{_libdir}/pkgconfig/libcacard.pc %endif %changelog +* Mon Mar 11 2013 Paolo Bonzini - 2:1.2.2-7 +- Added libiscsi-devel BuildRequires +- Use pkg-config to search for libiscsi + +* Sat Feb 02 2013 Cole Robinson - 2:1.2.2-6 +- Fix boot hang if console is not connected (bz #894451) +- Fix segfault with zero length virtio-scsi disk (bz #847549) + +* Wed Jan 23 2013 Alon Levy - 2:1.2.2-5 +- Add fix for missing error_set in libcacard.so picked from upstream. + +* Mon Jan 21 2013 Hans de Goede - 2:1.2.2-4 +- Add "qxl: call dpy_gfx_resize when entering vga mode" patch, fixing + an often reported use after free crash (rhbz#873845) +- Replace "wip: hw/qxl: inject interrupts in any state" patch with the + official upstream fix +- Add 5 other spice/qxl crash/bug fixes cherry-picked from upstream + +* Fri Jan 18 2013 Hans de Goede - 2:1.2.2-3 +- Fix a crash when using -vga qxl without -spice (bz #892075) + +* Wed Jan 16 2013 Cole Robinson - 2:1.2.2-2 +- CVE-2012-6075: Buffer overflow in e1000 nic (bz #889301, bz #889304) +- Use systemd spec macros (bz #850285) + +* Sun Dec 16 2012 Cole Robinson - 2:1.2.2-1 +- Update to qemu 1.2.2 stable +- Fix libvirt + seccomp combo (bz #855162) +- Fix scsi hotplug crash (bz #879657) +- Fix QOM refcount crash (bz #881486) + +* Wed Nov 28 2012 Alon Levy - 2:1.2.0-25 +* Merge libcacard into qemu, since they both use the same sources now. + +* Thu Nov 22 2012 Paolo Bonzini - 2:1.2.0-24 +- Move vscclient to qemu-common, qemu-nbd to qemu-img + +* Tue Nov 20 2012 Alon Levy - 2:1.2.0-23 +- Rewrite fix for bz #725965 based on fix for bz #867366 +- Resolve bz #867366 + * Fri Nov 16 2012 Paolo Bonzini - 2:1.2.0-22 - Fix previous commit