loader: add rom transaction API
Image file loaders may add a series of roms. If an error occurs partway through loading there is no easy way to drop previously added roms. This patch adds a transaction mechanism that works like this: rom_transaction_begin(); ...call rom_add_*()... rom_transaction_end(ok); If ok is false then roms added in this transaction are dropped. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20180814162739.11814-5-stefanha@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									e7f5993354
								
							
						
					
					
						commit
						e2336043cc
					
				| @ -840,6 +840,8 @@ struct Rom { | ||||
|     char *fw_dir; | ||||
|     char *fw_file; | ||||
| 
 | ||||
|     bool committed; | ||||
| 
 | ||||
|     hwaddr addr; | ||||
|     QTAILQ_ENTRY(Rom) next; | ||||
| }; | ||||
| @ -877,6 +879,8 @@ static void rom_insert(Rom *rom) | ||||
|         rom->as = &address_space_memory; | ||||
|     } | ||||
| 
 | ||||
|     rom->committed = false; | ||||
| 
 | ||||
|     /* List is ordered by load address in the same address space */ | ||||
|     QTAILQ_FOREACH(item, &roms, next) { | ||||
|         if (rom_order_compare(rom, item)) { | ||||
| @ -1168,6 +1172,34 @@ void rom_reset_order_override(void) | ||||
|     fw_cfg_reset_order_override(fw_cfg); | ||||
| } | ||||
| 
 | ||||
| void rom_transaction_begin(void) | ||||
| { | ||||
|     Rom *rom; | ||||
| 
 | ||||
|     /* Ignore ROMs added without the transaction API */ | ||||
|     QTAILQ_FOREACH(rom, &roms, next) { | ||||
|         rom->committed = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void rom_transaction_end(bool commit) | ||||
| { | ||||
|     Rom *rom; | ||||
|     Rom *tmp; | ||||
| 
 | ||||
|     QTAILQ_FOREACH_SAFE(rom, &roms, next, tmp) { | ||||
|         if (rom->committed) { | ||||
|             continue; | ||||
|         } | ||||
|         if (commit) { | ||||
|             rom->committed = true; | ||||
|         } else { | ||||
|             QTAILQ_REMOVE(&roms, rom, next); | ||||
|             rom_free(rom); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static Rom *find_rom(hwaddr addr, size_t size) | ||||
| { | ||||
|     Rom *rom; | ||||
|  | ||||
| @ -225,6 +225,25 @@ int rom_check_and_register_reset(void); | ||||
| void rom_set_fw(FWCfgState *f); | ||||
| void rom_set_order_override(int order); | ||||
| void rom_reset_order_override(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * rom_transaction_begin: | ||||
|  * | ||||
|  * Call this before of a series of rom_add_*() calls.  Call | ||||
|  * rom_transaction_end() afterwards to commit or abort.  These functions are | ||||
|  * useful for undoing a series of rom_add_*() calls if image file loading fails | ||||
|  * partway through. | ||||
|  */ | ||||
| void rom_transaction_begin(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * rom_transaction_end: | ||||
|  * @commit: true to commit added roms, false to drop added roms | ||||
|  * | ||||
|  * Call this after a series of rom_add_*() calls.  See rom_transaction_begin(). | ||||
|  */ | ||||
| void rom_transaction_end(bool commit); | ||||
| 
 | ||||
| int rom_copy(uint8_t *dest, hwaddr addr, size_t size); | ||||
| void *rom_ptr(hwaddr addr, size_t size); | ||||
| void hmp_info_roms(Monitor *mon, const QDict *qdict); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Stefan Hajnoczi
						Stefan Hajnoczi